track async api requests

This commit is contained in:
Robo 2016-02-22 19:30:21 +05:30
parent 2b547bd44a
commit a734326907
8 changed files with 39 additions and 39 deletions

View file

@ -11,6 +11,8 @@ const debuggerBinding = process.atomBinding('debugger');
let slice = [].slice;
let nextId = 0;
// Map of requestId and response callback.
let responseCallback = {};
let getNextId = function() {
@ -59,13 +61,16 @@ let PDFPageSize = {
// Following methods are mapped to webFrame.
const webFrameMethods = [
'executeJavaScript',
'insertText',
'setZoomFactor',
'setZoomLevel',
'setZoomLevelLimits'
];
const asyncWebFrameMethods = [
'executeJavaScript',
];
let wrapWebContents = function(webContents) {
// webContents is an EventEmitter.
var controller, method, name, ref1;
@ -107,25 +112,35 @@ let wrapWebContents = function(webContents) {
};
}
for (let method of asyncWebFrameMethods) {
webContents[method] = function() {
let args = Array.prototype.slice.call(arguments);
this.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', method, args);
};
}
// Make sure webContents.executeJavaScript would run the code only when the
// webContents has been loaded.
const executeJavaScript = webContents.executeJavaScript;
webContents.executeJavaScript = function(code, hasUserGesture, callback) {
let requestId = getNextId();
if (typeof hasUserGesture === "function") {
callback = hasUserGesture;
hasUserGesture = false;
}
if (callback !== null)
responseCallback["executeJavaScript"] = callback;
responseCallback[requestId] = callback;
if (this.getURL() && !this.isLoading())
return executeJavaScript.call(this, code, hasUserGesture);
return executeJavaScript.call(this, requestId, code, hasUserGesture);
else
return this.once('did-finish-load', executeJavaScript.bind(this, code, hasUserGesture));
return this.once('did-finish-load', executeJavaScript.bind(this, requestId, code, hasUserGesture));
};
ipcMain.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', function(event, method, result) {
if (responseCallback[method])
responseCallback[method].apply(null, [result]);
ipcMain.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', function(event, id, result) {
if (responseCallback[id]) {
responseCallback[id].apply(null, [result]);
delete responseCallback[id];
}
});
// Dispatch IPC messages to the ipc module.

View file

@ -6,7 +6,6 @@
#define ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_
#include "native_mate/converter.h"
#include "third_party/WebKit/public/platform/WebVector.h"
namespace blink {
class WebInputEvent;
@ -88,19 +87,6 @@ struct Converter<blink::WebFindOptions> {
blink::WebFindOptions* out);
};
template<typename T>
struct Converter<blink::WebVector<T> > {
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
const blink::WebVector<T>& val) {
v8::Local<v8::Array> result(
MATE_ARRAY_NEW(isolate, static_cast<int>(val.size())));
for (size_t i = 0; i < val.size(); ++i) {
result->Set(static_cast<int>(i), Converter<T>::ToV8(isolate, val[i]));
}
return result;
}
};
} // namespace mate
#endif // ATOM_COMMON_NATIVE_MATE_CONVERTERS_BLINK_CONVERTER_H_

View file

@ -8,7 +8,6 @@
#include "atom/common/native_mate_converters/callback.h"
#include "atom/common/native_mate_converters/gfx_converter.h"
#include "atom/common/native_mate_converters/string16_converter.h"
#include "atom/common/native_mate_converters/blink_converter.h"
#include "atom/renderer/api/atom_api_spell_check_client.h"
#include "content/public/renderer/render_frame.h"
#include "content/public/renderer/render_view.h"
@ -33,7 +32,7 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
public:
using CompletionCallback =
base::Callback<void(
const blink::WebVector<v8::Local<v8::Value>>& result)>;
const v8::Local<v8::Value>& result)>;
explicit ScriptExecutionCallback(const CompletionCallback& callback)
: callback_(callback) {}
@ -42,7 +41,8 @@ class ScriptExecutionCallback : public blink::WebScriptExecutionCallback {
void completed(
const blink::WebVector<v8::Local<v8::Value>>& result) override {
if (!callback_.is_null())
callback_.Run(result);
// Right now only single results per frame is supported.
callback_.Run(result[0]);
delete this;
}

View file

@ -32,17 +32,16 @@ v8Util.setHiddenValue(global, 'ipc', new events.EventEmitter);
const electron = require('electron');
// Call webFrame method.
const asyncWebFrameMethods = [
'executeJavaScript'
];
electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_METHOD', (event, method, args) => {
if (asyncWebFrameMethods.includes(method)) {
const responseCallback = function(result) {
event.sender.send('ELECTRON_INTERNAL_RENDERER_WEB_FRAME_RESPONSE', method, result);
};
args.push(responseCallback);
}
electron.webFrame[method].apply(electron.webFrame, args);
});
electron.ipcRenderer.on('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_METHOD', (event, method, args) => {
let requestId = args.shift();
const responseCallback = function(result) {
event.sender.send('ELECTRON_INTERNAL_RENDERER_ASYNC_WEB_FRAME_RESPONSE', requestId, result);
};
args.push(responseCallback);
electron.webFrame[method].apply(electron.webFrame, args);
});

View file

@ -393,14 +393,14 @@ var registerWebViewElement = function() {
nonblockMethods = [
'insertCSS',
'send',
'sendInputEvent'
'sendInputEvent',
];
webFrameMethods = [
'executeJavaScript',
'insertText',
'setZoomFactor',
'setZoomLevel',
'setZoomLevelLimits'
'setZoomLevelLimits',
];
// Forward proto.foo* method calls to WebViewImpl.foo*.

View file

@ -430,7 +430,7 @@ Injects CSS into the current web page.
* `code` String
* `userGesture` Boolean (optional)
* `callback` Function (optional) - Called after script has been executed.
* `result` Array
* `result`
Evaluates `code` in page.

View file

@ -284,7 +284,7 @@ Injects CSS into the guest page.
* `code` String
* `userGesture` Boolean - Default `false`.
* `callback` Function (optional) - Called after script has been executed.
* `result` Array
* `result`
Evaluates `code` in page. If `userGesture` is set, it will create the user
gesture context in the page. HTML APIs like `requestFullScreen`, which require

View file

@ -572,7 +572,7 @@ describe('<webview> tag', function() {
var listener = function() {
var jsScript = "'4'+2";
webview.executeJavaScript(jsScript, false, function(result) {
assert.equal(result[0], '42');
assert.equal(result, '42');
done();
});
webview.removeEventListener('did-finish-load', listener);