From 095e79b043810498b053f67ea35c004258579118 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Thu, 23 Feb 2017 09:55:05 +1100 Subject: [PATCH 1/4] Ensure the callback is a function when executing JS --- lib/browser/api/web-contents.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index 6c03800bcd..fe3259cedf 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -115,8 +115,8 @@ const asyncWebFrameMethods = function (requestId, method, callback, ...args) { this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args) ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, error, result) { if (error == null) { - if (callback != null) callback(result) resolve(result) + if (typeof callback === 'function') callback(result) } else { reject(error) } From 6fcb784f6ec5d84559e6478e3da5511e136ca852 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Mar 2017 10:49:23 -0800 Subject: [PATCH 2/4] Add failing spec for no callback --- spec/api-browser-window-spec.js | 10 +++++++++- spec/static/main.js | 19 +++++++++++++------ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/spec/api-browser-window-spec.js b/spec/api-browser-window-spec.js index 4ee9c5b583..b5985e4b74 100644 --- a/spec/api-browser-window-spec.js +++ b/spec/api-browser-window-spec.js @@ -1851,7 +1851,7 @@ describe('BrowserWindow module', function () { }) }) - it('resolves the returned promise with the result', function (done) { + it('resolves the returned promise with the result when a callback is specified', function (done) { ipcRenderer.send('executeJavaScript', code, true) ipcRenderer.once('executeJavaScript-promise-response', function (event, result) { assert.equal(result, expected) @@ -1859,6 +1859,14 @@ describe('BrowserWindow module', function () { }) }) + it('resolves the returned promise with the result when no callback is specified', function (done) { + ipcRenderer.send('executeJavaScript', code, false) + ipcRenderer.once('executeJavaScript-promise-response', function (event, result) { + assert.equal(result, expected) + done() + }) + }) + it('resolves the returned promise with the result if the code returns an asyncronous promise', function (done) { ipcRenderer.send('executeJavaScript', asyncCode, true) ipcRenderer.once('executeJavaScript-promise-response', function (event, result) { diff --git a/spec/static/main.js b/spec/static/main.js index cfc21249b5..1ac489ecae 100644 --- a/spec/static/main.js +++ b/spec/static/main.js @@ -193,16 +193,23 @@ app.on('ready', function () { }) ipcMain.on('executeJavaScript', function (event, code, hasCallback) { + let promise + if (hasCallback) { - window.webContents.executeJavaScript(code, (result) => { + promise = window.webContents.executeJavaScript(code, (result) => { window.webContents.send('executeJavaScript-response', result) - }).then((result) => { - window.webContents.send('executeJavaScript-promise-response', result) - }).catch((err) => { - window.webContents.send('executeJavaScript-promise-error', err) }) } else { - window.webContents.executeJavaScript(code) + promise = window.webContents.executeJavaScript(code) + } + + promise.then((result) => { + window.webContents.send('executeJavaScript-promise-response', result) + }).catch((error) => { + window.webContents.send('executeJavaScript-promise-error', error) + }) + + if (!hasCallback) { event.returnValue = 'success' } }) From 6240e30be15a7bc82a2b3f3be4397a2072ca41b7 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Mar 2017 10:51:17 -0800 Subject: [PATCH 3/4] Default hasUserGesture to false when null --- lib/browser/api/web-contents.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/browser/api/web-contents.js b/lib/browser/api/web-contents.js index fe3259cedf..6af96e1757 100644 --- a/lib/browser/api/web-contents.js +++ b/lib/browser/api/web-contents.js @@ -115,8 +115,8 @@ const asyncWebFrameMethods = function (requestId, method, callback, ...args) { this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', requestId, method, args) ipcMain.once(`ELECTRON_INTERNAL_BROWSER_ASYNC_WEB_FRAME_RESPONSE_${requestId}`, function (event, error, result) { if (error == null) { - resolve(result) if (typeof callback === 'function') callback(result) + resolve(result) } else { reject(error) } @@ -149,10 +149,17 @@ for (const method of webFrameMethodsWithResult) { // WebContents has been loaded. WebContents.prototype.executeJavaScript = function (code, hasUserGesture, callback) { const requestId = getNextId() + if (typeof hasUserGesture === 'function') { + // Shift. callback = hasUserGesture + hasUserGesture = null + } + + if (hasUserGesture == null) { hasUserGesture = false } + if (this.getURL() && !this.isLoadingMainFrame()) { return asyncWebFrameMethods.call(this, requestId, 'executeJavaScript', callback, code, hasUserGesture) } else { From 6bc464d4b060349155db5e43df1761e3036b8c05 Mon Sep 17 00:00:00 2001 From: Kevin Sawicki Date: Mon, 6 Mar 2017 10:51:48 -0800 Subject: [PATCH 4/4] Mention userGesture default --- docs/api/web-contents.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/web-contents.md b/docs/api/web-contents.md index 5e3e8dd697..a665fae963 100644 --- a/docs/api/web-contents.md +++ b/docs/api/web-contents.md @@ -541,7 +541,7 @@ that can't be set via `` attributes. * `userAgent` String (optional) - A user agent originating the request. * `extraHeaders` String (optional) - Extra headers separated by "\n" * `postData` ([UploadRawData](structures/upload-raw-data.md) | [UploadFile](structures/upload-file.md) | [UploadFileSystem](structures/upload-file-system.md) | [UploadBlob](structures/upload-blob.md))[] - (optional) - * `baseURLForDataURL` String (optional) - Base url (with trailing path separator) for files to be loaded by the data url. This is needed only if the specified `url` is a data url and needs to load other files. + * `baseURLForDataURL` String (optional) - Base url (with trailing path separator) for files to be loaded by the data url. This is needed only if the specified `url` is a data url and needs to load other files. Loads the `url` in the window. The `url` must contain the protocol prefix, e.g. the `http://` or `file://`. If the load should bypass http cache then @@ -672,7 +672,7 @@ Injects CSS into the current web page. #### `contents.executeJavaScript(code[, userGesture, callback])` * `code` String -* `userGesture` Boolean (optional) +* `userGesture` Boolean (optional) - Default is `false`. * `callback` Function (optional) - Called after script has been executed. * `result` Any