From 8d8bfcd120a43fb4943e7a8f001bfe0b9f0ab90e Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Nov 2014 14:35:32 +0800 Subject: [PATCH 1/4] Pass "preload" attribute to GuestViewManager --- atom/renderer/lib/web-view.coffee | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/atom/renderer/lib/web-view.coffee b/atom/renderer/lib/web-view.coffee index 456ce931f15e..ee11683d9a52 100644 --- a/atom/renderer/lib/web-view.coffee +++ b/atom/renderer/lib/web-view.coffee @@ -21,6 +21,7 @@ WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth' WEB_VIEW_ATTRIBUTE_PARTITION = 'partition' WEB_VIEW_ATTRIBUTE_NODEINTEGRATION = 'nodeintegration' WEB_VIEW_ATTRIBUTE_PLUGINS = 'plugins' +WEB_VIEW_ATTRIBUTE_PRELOAD = 'preload' AUTO_SIZE_ATTRIBUTES = [ WEB_VIEW_ATTRIBUTE_AUTOSIZE, WEB_VIEW_ATTRIBUTE_MAXHEIGHT, @@ -38,6 +39,8 @@ ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = ': ' + 'contentWindow is not available at this time. It will become available ' + 'when the page has finished loading.' ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.' +ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE = + 'Only "file:" or "asar:" protocol is supported in "preload" attribute.' # Represents the state of the storage partition. class Partition @@ -379,6 +382,17 @@ class WebView storagePartitionId: storagePartitionId nodeIntegration: @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_NODEINTEGRATION plugins: @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_PLUGINS + if @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_PRELOAD + preload = @webviewNode.getAttribute WEB_VIEW_ATTRIBUTE_PRELOAD + # Get the full path. + a = document.createElement 'a' + a.href = preload + params.preload = a.href + # Only support file: or asar: protocol. + protocol = params.preload.substr 0, 5 + unless protocol in ['file:', 'asar:'] + delete params.preload + console.error ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE guestViewInternal.createGuest 'webview', params, (guestInstanceId) => @pendingGuestCreation = false unless @elementAttached From 217b1afe8743d2c103ce0b4d326509984c75edca Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Nov 2014 15:13:37 +0800 Subject: [PATCH 2/4] Load the "preload" script in --- atom/browser/atom_browser_client.cc | 4 ++++ atom/browser/lib/guest-view-manager.coffee | 3 ++- atom/browser/web_view/web_view_manager.cc | 6 +++++- atom/browser/web_view/web_view_manager.h | 3 ++- atom/browser/web_view/web_view_renderer_state.h | 2 ++ atom/common/options_switches.cc | 3 +++ atom/common/options_switches.h | 1 + atom/renderer/lib/init.coffee | 5 +++++ 8 files changed, 24 insertions(+), 3 deletions(-) diff --git a/atom/browser/atom_browser_client.cc b/atom/browser/atom_browser_client.cc index 0ae8bfed6742..c39acc06ca2e 100644 --- a/atom/browser/atom_browser_client.cc +++ b/atom/browser/atom_browser_client.cc @@ -156,6 +156,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches( info.node_integration ? "true" : "false"); if (info.plugins) command_line->AppendSwitch(switches::kEnablePlugins); + if (!info.preload_script.empty()) + command_line->AppendSwitchPath( + switches::kPreloadScript, + info.preload_script); } } diff --git a/atom/browser/lib/guest-view-manager.coffee b/atom/browser/lib/guest-view-manager.coffee index bec53ef30f2c..a5c5d021f401 100644 --- a/atom/browser/lib/guest-view-manager.coffee +++ b/atom/browser/lib/guest-view-manager.coffee @@ -33,7 +33,8 @@ createGuest = (embedder, params) -> guestInstanceId: id storagePartitionId: params.storagePartitionId guestInstances[id] = {guest, embedder} - webViewManager.addGuest id, embedder, guest, params.nodeIntegration, params.plugins + preload = params.preload ? '' + webViewManager.addGuest id, embedder, guest, params.nodeIntegration, params.plugins, preload # Destroy guest when the embedder is gone. embedder.once 'render-view-deleted', -> diff --git a/atom/browser/web_view/web_view_manager.cc b/atom/browser/web_view/web_view_manager.cc index 88a1bdb2f7b2..5dd427c6a796 100644 --- a/atom/browser/web_view/web_view_manager.cc +++ b/atom/browser/web_view/web_view_manager.cc @@ -7,12 +7,14 @@ #include "atom/browser/api/atom_api_web_contents.h" #include "atom/browser/atom_browser_context.h" #include "atom/browser/web_view/web_view_renderer_state.h" +#include "atom/common/native_mate_converters/gurl_converter.h" #include "base/bind.h" #include "base/stl_util.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "native_mate/dictionary.h" #include "native_mate/object_template_builder.h" +#include "net/base/filename_util.h" #include "atom/common/node_includes.h" @@ -44,12 +46,14 @@ void WebViewManager::AddGuest(int guest_instance_id, content::WebContents* embedder, content::WebContents* web_contents, bool node_integration, - bool plugins) { + bool plugins, + const GURL& preload_url) { web_contents_map_[guest_instance_id] = { web_contents, embedder }; WebViewRendererState::WebViewInfo web_view_info = { guest_instance_id, node_integration, plugins }; + net::FileURLToFilePath(preload_url, &web_view_info.preload_script); content::BrowserThread::PostTask( content::BrowserThread::IO, FROM_HERE, diff --git a/atom/browser/web_view/web_view_manager.h b/atom/browser/web_view/web_view_manager.h index f00e5a6607f0..e68744089563 100644 --- a/atom/browser/web_view/web_view_manager.h +++ b/atom/browser/web_view/web_view_manager.h @@ -24,7 +24,8 @@ class WebViewManager : public content::BrowserPluginGuestManager { content::WebContents* embedder, content::WebContents* web_contents, bool node_integration, - bool plugins); + bool plugins, + const GURL& preload_url); void RemoveGuest(int guest_instance_id); protected: diff --git a/atom/browser/web_view/web_view_renderer_state.h b/atom/browser/web_view/web_view_renderer_state.h index 2de8308a9d4e..bddf803704aa 100644 --- a/atom/browser/web_view/web_view_renderer_state.h +++ b/atom/browser/web_view/web_view_renderer_state.h @@ -9,6 +9,7 @@ #include #include +#include "base/files/file_path.h" #include "base/memory/singleton.h" namespace atom { @@ -23,6 +24,7 @@ class WebViewRendererState { int guest_instance_id; bool node_integration; bool plugins; + base::FilePath preload_script; }; static WebViewRendererState* GetInstance(); diff --git a/atom/common/options_switches.cc b/atom/common/options_switches.cc index 3a61028c6b53..e6e65f204bbd 100644 --- a/atom/common/options_switches.cc +++ b/atom/common/options_switches.cc @@ -66,6 +66,9 @@ const char kEnablePlugins[] = "enable-plugins"; // Instancd ID of guest WebContents. const char kGuestInstanceID[] = "guest-instance-id"; +// Script that will be loaded by guest WebContents before other scripts. +const char kPreloadScript[] = "preload-script"; + // Web runtime features. const char kExperimentalFeatures[] = "experimental-features"; const char kExperimentalCanvasFeatures[] = "experimental-canvas-features"; diff --git a/atom/common/options_switches.h b/atom/common/options_switches.h index a0aeacc77039..a08983647ca1 100644 --- a/atom/common/options_switches.h +++ b/atom/common/options_switches.h @@ -38,6 +38,7 @@ extern const char kDarkTheme[]; extern const char kDirectWrite[]; extern const char kEnablePlugins[]; extern const char kGuestInstanceID[]; +extern const char kPreloadScript[]; extern const char kExperimentalFeatures[]; extern const char kExperimentalCanvasFeatures[]; diff --git a/atom/renderer/lib/init.coffee b/atom/renderer/lib/init.coffee index 011720e68b3b..b5059f33f38b 100644 --- a/atom/renderer/lib/init.coffee +++ b/atom/renderer/lib/init.coffee @@ -31,6 +31,8 @@ for arg in process.argv require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW' else if arg.indexOf('--node-integration=') == 0 nodeIntegration = arg.substr arg.indexOf('=') + 1 + else if arg.indexOf('--preload-script=') == 0 + preloadScript = arg.substr arg.indexOf('=') + 1 if location.protocol is 'chrome-devtools:' # Override some inspector APIs. @@ -86,3 +88,6 @@ else delete global.process delete global.setImmediate delete global.clearImmediate + +# Load the script specfied by the "preload" attribute. +require preloadScript if preloadScript From 395b0c4224fa1b40b5d1ecf5f3e5441f47f206e7 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Nov 2014 15:23:42 +0800 Subject: [PATCH 3/4] spec: "preload" attribute of --- spec/fixtures/module/preload.js | 1 + spec/fixtures/pages/e.html | 7 +++++++ spec/webview-spec.coffee | 11 +++++++++++ 3 files changed, 19 insertions(+) create mode 100644 spec/fixtures/module/preload.js create mode 100644 spec/fixtures/pages/e.html diff --git a/spec/fixtures/module/preload.js b/spec/fixtures/module/preload.js new file mode 100644 index 000000000000..205a077ddb10 --- /dev/null +++ b/spec/fixtures/module/preload.js @@ -0,0 +1 @@ +console.log([typeof require, typeof module, typeof process].join(' ')); diff --git a/spec/fixtures/pages/e.html b/spec/fixtures/pages/e.html new file mode 100644 index 000000000000..81a2d2b2d69e --- /dev/null +++ b/spec/fixtures/pages/e.html @@ -0,0 +1,7 @@ + + + + + diff --git a/spec/webview-spec.coffee b/spec/webview-spec.coffee index 09c7709c08be..71c4854d5ff9 100644 --- a/spec/webview-spec.coffee +++ b/spec/webview-spec.coffee @@ -47,6 +47,17 @@ describe ' tag', -> webview.src = "file://#{fixtures}/pages/d.html" document.body.appendChild webview + describe 'preload attribute', -> + it 'loads the script before other scripts in window', (done) -> + listener = (e) -> + assert.equal e.message, 'function object object' + webview.removeEventListener 'console-message', listener + done() + webview.addEventListener 'console-message', listener + webview.setAttribute 'preload', "#{fixtures}/module/preload.js" + webview.src = "file://#{fixtures}/pages/e.html" + document.body.appendChild webview + describe 'new-window event', -> it 'emits when window.open is called', (done) -> webview.addEventListener 'new-window', (e) -> From e28bdcdd46a9b904bc6f10af9b77d77970209ea2 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Thu, 6 Nov 2014 15:51:33 +0800 Subject: [PATCH 4/4] docs: "preload" attribute of --- docs/api/web-view-tag.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/api/web-view-tag.md b/docs/api/web-view-tag.md index 728fbc2d5d9a..0b5f63973843 100644 --- a/docs/api/web-view-tag.md +++ b/docs/api/web-view-tag.md @@ -90,6 +90,20 @@ APIs like `require` and `process` to access low level system resources. If "on", the guest page in `webview` will be able to use browser plugins. +### preload + +```html + +``` + +Specifies a script that will be loaded before other scripts run in the guest +page. The protocol of script's URL must be either `file:` or `asar:`, because it +will be loaded by `require` in guest page under the hood. + +When the guest page doesn't have node integration this script will still have +access to all Node APIs, but global objects injected by Node will be deleted +after this script has done execution. + ## Methods ### ``.getUrl()