Merge pull request #7631 from beakerbrowser/webview-policy-flags2
Add 'webpreferences' attribute to webview
This commit is contained in:
commit
39a5c7dab9
8 changed files with 91 additions and 14 deletions
|
@ -194,6 +194,20 @@ value will fail with a DOM exception.
|
|||
|
||||
If "on", the guest page will be allowed to open new windows.
|
||||
|
||||
### `webpreferences`
|
||||
|
||||
```html
|
||||
<webview src="https://github.com" webpreferences="allowDisplayingInsecureContent, javascript=no"></webview>
|
||||
```
|
||||
|
||||
A list of strings which specifies the web preferences to be set on the webview, separated by `,`.
|
||||
The full list of supported preference strings can be found in [BrowserWindow](browser-window.md#new-browserwindowoptions).
|
||||
|
||||
The string follows the same format as the features string in `window.open`.
|
||||
A name by itself is given a `true` boolean value.
|
||||
A preference can be set to another value by including an `=`, followed by the value.
|
||||
Special values `yes` and `1` are interpreted as `true`, while `no` and `0` are interpreted as `false`.
|
||||
|
||||
### `blinkfeatures`
|
||||
|
||||
```html
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
'lib/common/api/native-image.js',
|
||||
'lib/common/api/shell.js',
|
||||
'lib/common/init.js',
|
||||
'lib/common/parse-features-string.js',
|
||||
'lib/common/reset-search-paths.js',
|
||||
'lib/renderer/chrome-api.js',
|
||||
'lib/renderer/content-scripts-injector.js',
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const ipcMain = require('electron').ipcMain
|
||||
const webContents = require('electron').webContents
|
||||
const parseFeaturesString = require('../common/parse-features-string')
|
||||
|
||||
// Doesn't exist in early initialization.
|
||||
let webViewManager = null
|
||||
|
@ -184,6 +185,18 @@ const attachGuest = function (embedder, elementInstanceId, guestInstanceId, para
|
|||
disableBlinkFeatures: params.disableblinkfeatures
|
||||
}
|
||||
|
||||
// parse the 'webpreferences' attribute string, if set
|
||||
// this uses the same parsing rules as window.open uses for its features
|
||||
if (typeof params.webpreferences === 'string') {
|
||||
parseFeaturesString(params.webpreferences, function (key, value) {
|
||||
if (value === undefined) {
|
||||
// no value was specified, default it to true
|
||||
value = true
|
||||
}
|
||||
webPreferences[key] = value
|
||||
})
|
||||
}
|
||||
|
||||
if (params.preload) {
|
||||
webPreferences.preloadURL = params.preload
|
||||
}
|
||||
|
|
18
lib/common/parse-features-string.js
Normal file
18
lib/common/parse-features-string.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
// parses a feature string that has the format used in window.open()
|
||||
// - `features` input string
|
||||
// - `emit` function(key, value) - called for each parsed KV
|
||||
module.exports = function parseFeaturesString (features, emit) {
|
||||
// split the string by ','
|
||||
features.split(/,\s*/).forEach((feature) => {
|
||||
// expected form is either a key by itself or a key/value pair in the form of
|
||||
// 'key=value'
|
||||
let [key, value] = feature.split(/\s*=/)
|
||||
if (!key) return
|
||||
|
||||
// interpret the value as a boolean, if possible
|
||||
value = (value === 'yes' || value === '1') ? true : (value === 'no' || value === '0') ? false : value
|
||||
|
||||
// emit the parsed pair
|
||||
emit(key, value)
|
||||
})
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const ipcRenderer = require('electron').ipcRenderer
|
||||
const remote = require('electron').remote
|
||||
const parseFeaturesString = require('../common/parse-features-string')
|
||||
|
||||
// Helper function to resolve relative url.
|
||||
var a = window.top.document.createElement('a')
|
||||
|
@ -88,7 +89,7 @@ if (process.guestInstanceId == null) {
|
|||
|
||||
// Make the browser window or guest view emit "new-window" event.
|
||||
window.open = function (url, frameName, features) {
|
||||
var feature, guestId, i, j, len, len1, name, options, ref1, ref2, value, additionalFeatures
|
||||
var guestId, j, len1, name, options, additionalFeatures
|
||||
if (frameName == null) {
|
||||
frameName = ''
|
||||
}
|
||||
|
@ -104,27 +105,21 @@ window.open = function (url, frameName, features) {
|
|||
// Used to store additional features
|
||||
additionalFeatures = []
|
||||
|
||||
// Make sure to get rid of excessive whitespace in the property name
|
||||
ref1 = features.split(/,\s*/)
|
||||
for (i = 0, len = ref1.length; i < len; i++) {
|
||||
feature = ref1[i]
|
||||
ref2 = feature.split(/\s*=/)
|
||||
name = ref2[0]
|
||||
value = ref2[1]
|
||||
value = value === 'yes' || value === '1' ? true : value === 'no' || value === '0' ? false : value
|
||||
// Parse the features
|
||||
parseFeaturesString(features, function (key, value) {
|
||||
if (value === undefined) {
|
||||
additionalFeatures.push(feature)
|
||||
additionalFeatures.push(key)
|
||||
} else {
|
||||
if (webPreferences.includes(name)) {
|
||||
if (webPreferences.includes(key)) {
|
||||
if (options.webPreferences == null) {
|
||||
options.webPreferences = {}
|
||||
}
|
||||
options.webPreferences[name] = value
|
||||
options.webPreferences[key] = value
|
||||
} else {
|
||||
options[name] = value
|
||||
options[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
if (options.left) {
|
||||
if (options.x == null) {
|
||||
options.x = options.left
|
||||
|
|
|
@ -312,6 +312,13 @@ class DisableBlinkFeaturesAttribute extends WebViewAttribute {
|
|||
}
|
||||
}
|
||||
|
||||
// Attribute that specifies the web preferences to be enabled.
|
||||
class WebPreferencesAttribute extends WebViewAttribute {
|
||||
constructor (webViewImpl) {
|
||||
super(webViewConstants.ATTRIBUTE_WEBPREFERENCES, webViewImpl)
|
||||
}
|
||||
}
|
||||
|
||||
// Sets up all of the webview attributes.
|
||||
WebViewImpl.prototype.setupWebViewAttributes = function () {
|
||||
this.attributes = {}
|
||||
|
@ -328,6 +335,7 @@ WebViewImpl.prototype.setupWebViewAttributes = function () {
|
|||
this.attributes[webViewConstants.ATTRIBUTE_BLINKFEATURES] = new BlinkFeaturesAttribute(this)
|
||||
this.attributes[webViewConstants.ATTRIBUTE_DISABLEBLINKFEATURES] = new DisableBlinkFeaturesAttribute(this)
|
||||
this.attributes[webViewConstants.ATTRIBUTE_GUESTINSTANCE] = new GuestInstanceAttribute(this)
|
||||
this.attributes[webViewConstants.ATTRIBUTE_WEBPREFERENCES] = new WebPreferencesAttribute(this)
|
||||
|
||||
const autosizeAttributes = [webViewConstants.ATTRIBUTE_MAXHEIGHT, webViewConstants.ATTRIBUTE_MAXWIDTH, webViewConstants.ATTRIBUTE_MINHEIGHT, webViewConstants.ATTRIBUTE_MINWIDTH]
|
||||
autosizeAttributes.forEach((attribute) => {
|
||||
|
|
|
@ -18,6 +18,7 @@ module.exports = {
|
|||
ATTRIBUTE_BLINKFEATURES: 'blinkfeatures',
|
||||
ATTRIBUTE_DISABLEBLINKFEATURES: 'disableblinkfeatures',
|
||||
ATTRIBUTE_GUESTINSTANCE: 'guestinstance',
|
||||
ATTRIBUTE_WEBPREFERENCES: 'webpreferences',
|
||||
|
||||
// Internal attribute.
|
||||
ATTRIBUTE_INTERNALINSTANCEID: 'internalinstanceid',
|
||||
|
|
|
@ -406,6 +406,33 @@ describe('<webview> tag', function () {
|
|||
})
|
||||
})
|
||||
|
||||
describe('webpreferences attribute', function () {
|
||||
it('can enable nodeintegration', function (done) {
|
||||
webview.addEventListener('console-message', function (e) {
|
||||
assert.equal(e.message, 'function object object')
|
||||
done()
|
||||
})
|
||||
webview.setAttribute('webpreferences', 'nodeIntegration')
|
||||
webview.src = 'file://' + fixtures + '/pages/d.html'
|
||||
document.body.appendChild(webview)
|
||||
})
|
||||
|
||||
it('can disables web security and enable nodeintegration', function (done) {
|
||||
var jqueryPath = path.join(__dirname, '/static/jquery-2.0.3.min.js')
|
||||
var src = `<script src='file://${jqueryPath}'></script> <script>console.log('ok '+(typeof require));</script>`
|
||||
var encoded = btoa(unescape(encodeURIComponent(src)))
|
||||
var listener = function (e) {
|
||||
assert.equal(e.message, 'ok function')
|
||||
webview.removeEventListener('console-message', listener)
|
||||
done()
|
||||
}
|
||||
webview.addEventListener('console-message', listener)
|
||||
webview.setAttribute('webpreferences', 'webSecurity=no, nodeIntegration=yes')
|
||||
webview.src = 'data:text/html;base64,' + encoded
|
||||
document.body.appendChild(webview)
|
||||
})
|
||||
})
|
||||
|
||||
describe('new-window event', function () {
|
||||
if (process.env.TRAVIS === 'true' && process.platform === 'darwin') {
|
||||
return
|
||||
|
|
Loading…
Reference in a new issue