Skip to content
This repository was archived by the owner on Jun 17, 2020. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions src/execute-js-func.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const requestChannel = 'execute-javascript-request';
const responseChannel = 'execute-javascript-response';
const rootEvalProxyName = 'electron-remote-eval-proxy';
const requireElectronModule = '__requireElectronModule__';
const defaultTimeout = 5*1000;

const electron = require('electron');
const isBrowser = (process.type === 'browser');
Expand Down Expand Up @@ -219,7 +220,7 @@ export function setParentInformation(windowOrWebView) {
* @return {Observable} The result of the evaluation.
* Must be JSON-serializable.
*/
export function remoteEvalObservable(windowOrWebView, str, timeout=5*1000) {
export function remoteEvalObservable(windowOrWebView, str, timeout=defaultTimeout) {
let send = getSendMethod(windowOrWebView || findTargetFromParentInfo());
if (!send) {
return Observable.throw(new Error(`Unable to find a target for: ${JSON.stringify(window.parentInfo)}`));
Expand Down Expand Up @@ -247,7 +248,7 @@ export function remoteEvalObservable(windowOrWebView, str, timeout=5*1000) {
* @return {Promise} The result of the evaluation.
* Must be JSON-serializable.
*/
export function remoteEval(windowOrWebView, str, timeout=5*1000) {
export function remoteEval(windowOrWebView, str, timeout=defaultTimeout) {
return remoteEvalObservable(windowOrWebView, str, timeout).toPromise();
}

Expand Down Expand Up @@ -322,7 +323,7 @@ export function executeJavaScriptMethodObservable(windowOrWebView, timeout, path
* property. Must be JSON serializable.
*/
export function executeJavaScriptMethod(windowOrWebView, pathToObject, ...args) {
return executeJavaScriptMethodObservable(windowOrWebView, 5*1000, pathToObject, ...args).toPromise();
return executeJavaScriptMethodObservable(windowOrWebView, defaultTimeout, pathToObject, ...args).toPromise();
}

/**
Expand All @@ -333,18 +334,19 @@ export function executeJavaScriptMethod(windowOrWebView, pathToObject, ...args)
* in. If this parameter is
* null, this will reference
* the browser process.
* @param {Number} timeout The timeout in milliseconds
*
* @return {Object} A Proxy object that will invoke methods remotely.
* Similar to {executeJavaScriptMethod}, methods will return
* a Promise even if the target method returns a normal
* value.
*/
export function createProxyForRemote(windowOrWebView) {
export function createProxyForRemote(windowOrWebView, timeout=defaultTimeout) {
return RecursiveProxyHandler.create(rootEvalProxyName, (methodChain, args) => {
let chain = methodChain.splice(1);

d(`Invoking ${chain.join('.')}(${JSON.stringify(args)})`);
return executeJavaScriptMethod(windowOrWebView, chain, ...args);
return executeJavaScriptMethodObservable(windowOrWebView, timeout, chain, ...args).toPromise();
});
}

Expand All @@ -353,11 +355,13 @@ export function createProxyForRemote(windowOrWebView) {
* but with all of its methods Promisified.
*
* @param {String} moduleName The name of the main process module to proxy
* @param {Number} timeout The timeout in milliseconds
*
* @returns {Object} A Proxy object that will invoke methods remotely.
* All methods will return a Promise.
*/
export function createProxyForMainProcessModule(moduleName) {
return createProxyForRemote(null)[requireElectronModule][moduleName];
export function createProxyForMainProcessModule(moduleName, timeout=defaultTimeout) {
return createProxyForRemote(null, timeout)[requireElectronModule][moduleName];
}

/**
Expand Down
38 changes: 38 additions & 0 deletions test/execute-js-func.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {remote} from 'electron';
import {createProxyForRemote} from '../src/execute-js-func';
import {fromRemoteWindow} from '../src/remote-event';

const {BrowserWindow} = remote;

describe('createProxyForRemote', function() {
this.timeout(10*1000);

async function initWindow(proxyTimeout) {
const bw = new BrowserWindow({width: 500, height: 500, show: false});
const proxy = createProxyForRemote(bw, proxyTimeout);
const ready = fromRemoteWindow(bw, 'dom-ready', true).take(1).toPromise();

bw.loadURL(`file://${__dirname}/fixture/renderer-with-eval-handler.html`);
await ready;

return { bw, proxy };
}

it('should fail to execute slow method exceeding timeout', async function() {
const { proxy } = await initWindow(500);

return proxy.slowMethod().should.be.rejected;
});

it('should execute slow method if timeout is large', async function() {
const { proxy } = await initWindow();

return proxy.slowMethod().should.be.fulfilled;
});

it('should fail to execute nonexistent method', async function () {
const { proxy } = await initWindow();

return proxy.a.b().should.be.rejected;
});
});
13 changes: 13 additions & 0 deletions test/fixture/renderer-with-eval-handler.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<script>
require('../../src/execute-js-func').initializeEvalHandler();
window.slowMethod = function() {
return new Promise(res => setTimeout(res, 1000));
};
</script>
</head>
<body>
</body>
</html>