Skip to content

Commit 563bc80

Browse files
committed
Fix nwjs#4780: Node.js support in webview
1 parent 7439b61 commit 563bc80

File tree

4 files changed

+54
-19
lines changed

4 files changed

+54
-19
lines changed

src/browser/nw_content_browser_hooks.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ namespace nw {
5353
namespace {
5454

5555
bool g_pinning_renderer = true;
56-
56+
bool g_in_webview_apply_attr = false;
57+
bool g_in_webview_apply_attr_allow_nw = false;
5758
} //namespace
5859

5960
#if defined(OS_MACOSX)
@@ -190,4 +191,15 @@ void SetPinningRenderer(bool pin) {
190191
g_pinning_renderer = pin;
191192
}
192193

194+
void SetInWebViewApplyAttr(bool flag, bool allow_nw) {
195+
g_in_webview_apply_attr = flag;
196+
g_in_webview_apply_attr_allow_nw = allow_nw;
197+
}
198+
199+
bool GetInWebViewApplyAttr(bool* allow_nw) {
200+
if (allow_nw)
201+
*allow_nw = g_in_webview_apply_attr_allow_nw;
202+
return g_in_webview_apply_attr;
203+
}
204+
193205
} //namespace nw

src/browser/nw_content_browser_hooks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ CONTENT_EXPORT void SetPinningRenderer(bool pin);
6868
// content/nw/src/api/menuitem/menuitem_views.cc
6969
CONTENT_EXPORT bool GetImage(Package* package, const base::FilePath& icon_path, gfx::Image* image);
7070

71+
CONTENT_EXPORT void SetInWebViewApplyAttr(bool, bool);
72+
CONTENT_EXPORT bool GetInWebViewApplyAttr(bool* allow_nw);
73+
7174
//
7275
// implemented in nw_extensions_browser_hooks.cc
7376
//

src/nw_content.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,8 @@ void DocumentFinishHook(blink::WebLocalFrame* frame,
113113
#endif
114114
void SetMainExtensionId(const std::string& id);
115115
const std::string& GetMainExtensionId();
116+
void SetInWebViewApplyAttr(bool, bool);
117+
bool GetInWebViewApplyAttr(bool* allow_nw);
116118
}
117119

118120
#endif

src/renderer/nw_extensions_renderer_hooks.cc

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ namespace manifest_keys = extensions::manifest_keys;
7878
namespace nw {
7979

8080
namespace {
81-
std::string g_extension_id;
81+
std::string g_extension_id, g_extension_root;
8282
extensions::Dispatcher* g_dispatcher = NULL;
8383
bool g_skip_render_widget_hidden = false;
8484

@@ -150,7 +150,7 @@ void WebWorkerStartThreadHook(blink::Frame* frame, const char* path, std::string
150150
g_dispatcher->script_context_set().GetByV8Context(v8_context);
151151
if (!script_context || !script_context->extension())
152152
return;
153-
root_path = script_context->extension()->path().AsUTF8Unsafe();
153+
root_path = g_extension_root;
154154
} else {
155155
root_path = *script;
156156
}
@@ -172,29 +172,43 @@ void WebWorkerStartThreadHook(blink::Frame* frame, const char* path, std::string
172172
void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
173173
v8::Isolate* isolate = context->isolate();
174174

175-
if (g_extension_id.empty())
176-
g_extension_id = context->extension()->id();
175+
const Extension* extension = context->extension();
176+
std::string extension_root;
177+
178+
if (g_extension_id.empty() && extension)
179+
g_extension_id = extension->id();
177180

178181
bool nodejs_enabled = true;
179-
context->extension()->manifest()->GetBoolean(manifest_keys::kNWJSEnableNode, &nodejs_enabled);
182+
const base::CommandLine& command_line =
183+
*base::CommandLine::ForCurrentProcess();
184+
bool worker_support = command_line.HasSwitch(switches::kEnableNodeWorker);
185+
186+
if (extension) {
187+
extension->manifest()->GetBoolean(manifest_keys::kNWJSEnableNode, &nodejs_enabled);
188+
extension_root = extension->path().AsUTF8Unsafe();
189+
} else {
190+
extension_root = command_line.GetSwitchValuePath(switches::kNWAppPath).AsUTF8Unsafe();
191+
}
192+
g_extension_root = extension_root;
180193

181194
if (!nodejs_enabled)
182195
return;
183196

184-
const base::CommandLine& command_line =
185-
*base::CommandLine::ForCurrentProcess();
186-
bool worker_support = command_line.HasSwitch(switches::kEnableNodeWorker);
187-
188197
blink::set_web_worker_hooks((void*)WebWorkerStartThreadHook);
189198
g_web_worker_thread_new_fn = (VoidPtr2Fn)WebWorkerNewThreadHook;
190199
if (!g_is_node_initialized_fn())
191200
g_setup_nwnode_fn(0, nullptr, worker_support);
192201

193202
bool mixed_context = false;
194-
context->extension()->manifest()->GetBoolean(manifest_keys::kNWJSMixedContext, &mixed_context);
203+
bool node_init_run = false;
204+
bool nwjs_guest = nwjs_guest = command_line.HasSwitch("nwjs-guest");
205+
206+
if (extension)
207+
extension->manifest()->GetBoolean(manifest_keys::kNWJSMixedContext, &mixed_context);
195208
v8::Local<v8::Context> node_context;
196209
g_get_node_context_fn(&node_context);
197210
if (node_context.IsEmpty() || mixed_context) {
211+
node_init_run = true;
198212
{
199213
int argc = 1;
200214
char argv0[] = "node";
@@ -203,7 +217,7 @@ void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
203217
argv[1] = argv[2] = nullptr;
204218
std::string main_fn;
205219

206-
if (context->extension()->manifest()->GetString("node-main", &main_fn)) {
220+
if (extension && extension->manifest()->GetString("node-main", &main_fn)) {
207221
argc = 2;
208222
argv[1] = strdup(main_fn.c_str());
209223
}
@@ -231,13 +245,13 @@ void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
231245
script->Run();
232246
}
233247

234-
if (context->extension()->manifest()->GetString(manifest_keys::kNWJSInternalMainFilename, &main_fn)) {
248+
if (extension && extension->manifest()->GetString(manifest_keys::kNWJSInternalMainFilename, &main_fn)) {
235249
v8::Local<v8::Script> script = v8::Script::Compile(v8::String::NewFromUtf8(isolate,
236250
("global.__filename = '" + main_fn + "';").c_str()));
237251
script->Run();
238252
}
239253
{
240-
std::string root_path = context->extension()->path().AsUTF8Unsafe();
254+
std::string root_path = extension_root;
241255
#if defined(OS_WIN)
242256
base::ReplaceChars(root_path, "\\", "\\\\", &root_path);
243257
#endif
@@ -247,12 +261,12 @@ void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
247261
script->Run();
248262
}
249263
bool content_verification = false;
250-
if (context->extension()->manifest()->GetBoolean(manifest_keys::kNWJSContentVerifyFlag,
264+
if (extension && extension->manifest()->GetBoolean(manifest_keys::kNWJSContentVerifyFlag,
251265
&content_verification) && content_verification) {
252266
v8::Local<v8::Script> script =
253267
v8::Script::Compile(v8::String::NewFromUtf8(isolate,
254268
(std::string("global.__nwjs_cv = true;") +
255-
"global.__nwjs_ext_id = '" + context->extension()->id() + "';").c_str()));
269+
"global.__nwjs_ext_id = '" + extension->id() + "';").c_str()));
256270

257271
script->Run();
258272
}
@@ -287,6 +301,11 @@ void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
287301
v8::Local<v8::Value> key = symbols->Get(i);
288302
v8::Local<v8::Value> val = node_global->Get(key);
289303
nw->Set(key, val);
304+
if (nwjs_guest && !node_init_run) {
305+
//running in nwjs webview and node was initialized in
306+
//chromedriver automation extension
307+
context->v8_context()->Global()->Set(key, val);
308+
}
290309
}
291310
g_context->Exit();
292311

@@ -295,7 +314,7 @@ void ContextCreationHook(blink::WebLocalFrame* frame, ScriptContext* context) {
295314
v8::MicrotasksScope microtasks(isolate, v8::MicrotasksScope::kDoNotRunMicrotasks);
296315
v8::Context::Scope cscope(context->v8_context());
297316
// Make node's relative modules work
298-
std::string root_path = context->extension()->path().AsUTF8Unsafe();
317+
std::string root_path = extension_root;
299318
GURL frame_url = ScriptContext::GetDataSourceURLForFrame(frame);
300319
std::string url_path = frame_url.path();
301320
#if defined(OS_WIN)
@@ -421,8 +440,7 @@ void DocumentElementHook(blink::WebLocalFrame* frame,
421440
frame->setNodeJS(true);
422441
std::string path = effective_document_url.path();
423442
v8::Local<v8::Context> v8_context = frame->mainWorldScriptContext();
424-
std::string root_path = extension->path().AsUTF8Unsafe();
425-
base::FilePath root(extension->path());
443+
std::string root_path = g_extension_root;
426444
if (!v8_context.IsEmpty()) {
427445
v8::MicrotasksScope microtasks(v8::Isolate::GetCurrent(), v8::MicrotasksScope::kDoNotRunMicrotasks);
428446
v8::Context::Scope cscope(v8_context);

0 commit comments

Comments
 (0)