Merge pull request #794 from atom/webivew-preload
Add "preload" attribute for <webview>
This commit is contained in:
commit
111dcbac25
13 changed files with 71 additions and 3 deletions
|
@ -156,6 +156,10 @@ void AtomBrowserClient::AppendExtraCommandLineSwitches(
|
||||||
info.node_integration ? "true" : "false");
|
info.node_integration ? "true" : "false");
|
||||||
if (info.plugins)
|
if (info.plugins)
|
||||||
command_line->AppendSwitch(switches::kEnablePlugins);
|
command_line->AppendSwitch(switches::kEnablePlugins);
|
||||||
|
if (!info.preload_script.empty())
|
||||||
|
command_line->AppendSwitchPath(
|
||||||
|
switches::kPreloadScript,
|
||||||
|
info.preload_script);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ createGuest = (embedder, params) ->
|
||||||
guestInstanceId: id
|
guestInstanceId: id
|
||||||
storagePartitionId: params.storagePartitionId
|
storagePartitionId: params.storagePartitionId
|
||||||
guestInstances[id] = {guest, embedder}
|
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.
|
# Destroy guest when the embedder is gone.
|
||||||
embedder.once 'render-view-deleted', ->
|
embedder.once 'render-view-deleted', ->
|
||||||
|
|
|
@ -7,12 +7,14 @@
|
||||||
#include "atom/browser/api/atom_api_web_contents.h"
|
#include "atom/browser/api/atom_api_web_contents.h"
|
||||||
#include "atom/browser/atom_browser_context.h"
|
#include "atom/browser/atom_browser_context.h"
|
||||||
#include "atom/browser/web_view/web_view_renderer_state.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/bind.h"
|
||||||
#include "base/stl_util.h"
|
#include "base/stl_util.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "content/public/browser/render_process_host.h"
|
#include "content/public/browser/render_process_host.h"
|
||||||
#include "native_mate/dictionary.h"
|
#include "native_mate/dictionary.h"
|
||||||
#include "native_mate/object_template_builder.h"
|
#include "native_mate/object_template_builder.h"
|
||||||
|
#include "net/base/filename_util.h"
|
||||||
|
|
||||||
#include "atom/common/node_includes.h"
|
#include "atom/common/node_includes.h"
|
||||||
|
|
||||||
|
@ -44,12 +46,14 @@ void WebViewManager::AddGuest(int guest_instance_id,
|
||||||
content::WebContents* embedder,
|
content::WebContents* embedder,
|
||||||
content::WebContents* web_contents,
|
content::WebContents* web_contents,
|
||||||
bool node_integration,
|
bool node_integration,
|
||||||
bool plugins) {
|
bool plugins,
|
||||||
|
const GURL& preload_url) {
|
||||||
web_contents_map_[guest_instance_id] = { web_contents, embedder };
|
web_contents_map_[guest_instance_id] = { web_contents, embedder };
|
||||||
|
|
||||||
WebViewRendererState::WebViewInfo web_view_info = {
|
WebViewRendererState::WebViewInfo web_view_info = {
|
||||||
guest_instance_id, node_integration, plugins
|
guest_instance_id, node_integration, plugins
|
||||||
};
|
};
|
||||||
|
net::FileURLToFilePath(preload_url, &web_view_info.preload_script);
|
||||||
content::BrowserThread::PostTask(
|
content::BrowserThread::PostTask(
|
||||||
content::BrowserThread::IO,
|
content::BrowserThread::IO,
|
||||||
FROM_HERE,
|
FROM_HERE,
|
||||||
|
|
|
@ -24,7 +24,8 @@ class WebViewManager : public content::BrowserPluginGuestManager {
|
||||||
content::WebContents* embedder,
|
content::WebContents* embedder,
|
||||||
content::WebContents* web_contents,
|
content::WebContents* web_contents,
|
||||||
bool node_integration,
|
bool node_integration,
|
||||||
bool plugins);
|
bool plugins,
|
||||||
|
const GURL& preload_url);
|
||||||
void RemoveGuest(int guest_instance_id);
|
void RemoveGuest(int guest_instance_id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/singleton.h"
|
#include "base/memory/singleton.h"
|
||||||
|
|
||||||
namespace atom {
|
namespace atom {
|
||||||
|
@ -23,6 +24,7 @@ class WebViewRendererState {
|
||||||
int guest_instance_id;
|
int guest_instance_id;
|
||||||
bool node_integration;
|
bool node_integration;
|
||||||
bool plugins;
|
bool plugins;
|
||||||
|
base::FilePath preload_script;
|
||||||
};
|
};
|
||||||
|
|
||||||
static WebViewRendererState* GetInstance();
|
static WebViewRendererState* GetInstance();
|
||||||
|
|
|
@ -66,6 +66,9 @@ const char kEnablePlugins[] = "enable-plugins";
|
||||||
// Instancd ID of guest WebContents.
|
// Instancd ID of guest WebContents.
|
||||||
const char kGuestInstanceID[] = "guest-instance-id";
|
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.
|
// Web runtime features.
|
||||||
const char kExperimentalFeatures[] = "experimental-features";
|
const char kExperimentalFeatures[] = "experimental-features";
|
||||||
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
const char kExperimentalCanvasFeatures[] = "experimental-canvas-features";
|
||||||
|
|
|
@ -38,6 +38,7 @@ extern const char kDarkTheme[];
|
||||||
extern const char kDirectWrite[];
|
extern const char kDirectWrite[];
|
||||||
extern const char kEnablePlugins[];
|
extern const char kEnablePlugins[];
|
||||||
extern const char kGuestInstanceID[];
|
extern const char kGuestInstanceID[];
|
||||||
|
extern const char kPreloadScript[];
|
||||||
|
|
||||||
extern const char kExperimentalFeatures[];
|
extern const char kExperimentalFeatures[];
|
||||||
extern const char kExperimentalCanvasFeatures[];
|
extern const char kExperimentalCanvasFeatures[];
|
||||||
|
|
|
@ -31,6 +31,8 @@ for arg in process.argv
|
||||||
require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW'
|
require('web-frame').setName 'ATOM_SHELL_GUEST_WEB_VIEW'
|
||||||
else if arg.indexOf('--node-integration=') == 0
|
else if arg.indexOf('--node-integration=') == 0
|
||||||
nodeIntegration = arg.substr arg.indexOf('=') + 1
|
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:'
|
if location.protocol is 'chrome-devtools:'
|
||||||
# Override some inspector APIs.
|
# Override some inspector APIs.
|
||||||
|
@ -86,3 +88,6 @@ else
|
||||||
delete global.process
|
delete global.process
|
||||||
delete global.setImmediate
|
delete global.setImmediate
|
||||||
delete global.clearImmediate
|
delete global.clearImmediate
|
||||||
|
|
||||||
|
# Load the script specfied by the "preload" attribute.
|
||||||
|
require preloadScript if preloadScript
|
||||||
|
|
|
@ -21,6 +21,7 @@ WEB_VIEW_ATTRIBUTE_MINWIDTH = 'minwidth'
|
||||||
WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'
|
WEB_VIEW_ATTRIBUTE_PARTITION = 'partition'
|
||||||
WEB_VIEW_ATTRIBUTE_NODEINTEGRATION = 'nodeintegration'
|
WEB_VIEW_ATTRIBUTE_NODEINTEGRATION = 'nodeintegration'
|
||||||
WEB_VIEW_ATTRIBUTE_PLUGINS = 'plugins'
|
WEB_VIEW_ATTRIBUTE_PLUGINS = 'plugins'
|
||||||
|
WEB_VIEW_ATTRIBUTE_PRELOAD = 'preload'
|
||||||
AUTO_SIZE_ATTRIBUTES = [
|
AUTO_SIZE_ATTRIBUTES = [
|
||||||
WEB_VIEW_ATTRIBUTE_AUTOSIZE,
|
WEB_VIEW_ATTRIBUTE_AUTOSIZE,
|
||||||
WEB_VIEW_ATTRIBUTE_MAXHEIGHT,
|
WEB_VIEW_ATTRIBUTE_MAXHEIGHT,
|
||||||
|
@ -38,6 +39,8 @@ ERROR_MSG_CONTENTWINDOW_NOT_AVAILABLE = '<webview>: ' +
|
||||||
'contentWindow is not available at this time. It will become available ' +
|
'contentWindow is not available at this time. It will become available ' +
|
||||||
'when the page has finished loading.'
|
'when the page has finished loading.'
|
||||||
ERROR_MSG_INVALID_PARTITION_ATTRIBUTE = 'Invalid partition attribute.'
|
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.
|
# Represents the state of the storage partition.
|
||||||
class Partition
|
class Partition
|
||||||
|
@ -379,6 +382,17 @@ class WebView
|
||||||
storagePartitionId: storagePartitionId
|
storagePartitionId: storagePartitionId
|
||||||
nodeIntegration: @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_NODEINTEGRATION
|
nodeIntegration: @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_NODEINTEGRATION
|
||||||
plugins: @webviewNode.hasAttribute WEB_VIEW_ATTRIBUTE_PLUGINS
|
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) =>
|
guestViewInternal.createGuest 'webview', params, (guestInstanceId) =>
|
||||||
@pendingGuestCreation = false
|
@pendingGuestCreation = false
|
||||||
unless @elementAttached
|
unless @elementAttached
|
||||||
|
|
|
@ -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.
|
If "on", the guest page in `webview` will be able to use browser plugins.
|
||||||
|
|
||||||
|
### preload
|
||||||
|
|
||||||
|
```html
|
||||||
|
<webview src="https://www.github.com/" preload="./test.js"></webview>
|
||||||
|
```
|
||||||
|
|
||||||
|
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
|
## Methods
|
||||||
|
|
||||||
### `<webview>`.getUrl()
|
### `<webview>`.getUrl()
|
||||||
|
|
1
spec/fixtures/module/preload.js
vendored
Normal file
1
spec/fixtures/module/preload.js
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
console.log([typeof require, typeof module, typeof process].join(' '));
|
7
spec/fixtures/pages/e.html
vendored
Normal file
7
spec/fixtures/pages/e.html
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
console.log('Window script is loaded before preload script');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -47,6 +47,17 @@ describe '<webview> tag', ->
|
||||||
webview.src = "file://#{fixtures}/pages/d.html"
|
webview.src = "file://#{fixtures}/pages/d.html"
|
||||||
document.body.appendChild webview
|
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', ->
|
describe 'new-window event', ->
|
||||||
it 'emits when window.open is called', (done) ->
|
it 'emits when window.open is called', (done) ->
|
||||||
webview.addEventListener 'new-window', (e) ->
|
webview.addEventListener 'new-window', (e) ->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue