Bug 1021172 - Electrolysis (e10s) support for requestAutocomplete. r=MattN

This commit is contained in:
Paolo Amadini 2014-07-30 18:06:45 +01:00
parent 174fa34500
commit ba1cf91015
9 changed files with 137 additions and 9 deletions

View File

@ -489,6 +489,7 @@
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/contentSecurityPolicy.manifest
@BINPATH@/components/contentSecurityPolicy.js
@BINPATH@/components/contentAreaDropListener.manifest

View File

@ -451,6 +451,7 @@
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/contentSecurityPolicy.manifest
@BINPATH@/components/contentSecurityPolicy.js
@BINPATH@/components/contentAreaDropListener.manifest

View File

@ -380,6 +380,7 @@
@BINPATH@/components/nsInputListAutoComplete.js
@BINPATH@/components/formautofill.manifest
@BINPATH@/components/FormAutofillContentService.js
@BINPATH@/components/FormAutofillStartup.js
@BINPATH@/components/contentSecurityPolicy.manifest
@BINPATH@/components/contentSecurityPolicy.js
@BINPATH@/components/contentAreaDropListener.manifest

View File

@ -112,4 +112,18 @@ this.FormAutofill = {
this.integration = combined;
},
/**
* Processes a requestAutocomplete message asynchronously.
*
* @param aData
* Provided to FormAutofillIntegration.createRequestAutocompleteUI.
*
* @return {Promise}
* @resolves Structured data received from the requestAutocomplete UI.
*/
processRequestAutocomplete: Task.async(function* (aData) {
let ui = yield FormAutofill.integration.createRequestAutocompleteUI(aData);
return yield ui.show();
}),
};

View File

@ -95,8 +95,37 @@ FormHandler.prototype = {
return "disabled";
}
let ui = yield FormAutofill.integration.createRequestAutocompleteUI(data);
let result = yield ui.show();
// Access the frame message manager of the window starting the request.
let rootDocShell = this.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDocShell)
.sameTypeRootTreeItem
.QueryInterface(Ci.nsIDocShell);
let frameMM = rootDocShell.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIContentFrameMessageManager);
// We need to set up a temporary message listener for our result before we
// send the request to the parent process. At present, there is no check
// for reentrancy (bug 1020459), thus it is possible that we'll receive a
// message for a different request, but this will not be normally allowed.
let promiseRequestAutocompleteResult = new Promise((resolve, reject) => {
frameMM.addMessageListener("FormAutofill:RequestAutocompleteResult",
function onResult(aMessage) {
frameMM.removeMessageListener(
"FormAutofill:RequestAutocompleteResult", onResult);
// Exceptions in the parent process are serialized and propagated in
// the response message that we received.
if ("exception" in aMessage.data) {
reject(aMessage.data.exception);
} else {
resolve(aMessage.data);
}
});
});
// Send the message to the parent process, and wait for the result. This
// will throw an exception if one occurred in the parent process.
frameMM.sendAsyncMessage("FormAutofill:RequestAutocomplete", data);
let result = yield promiseRequestAutocompleteResult;
if (result.canceled) {
return "cancel";
}

View File

@ -0,0 +1,64 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Handles startup in the parent process.
*/
"use strict";
const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "FormAutofill",
"resource://gre/modules/FormAutofill.jsm");
/**
* Handles startup in the parent process.
*/
function FormAutofillStartup() {
}
FormAutofillStartup.prototype = {
classID: Components.ID("{51c95b3d-7431-467b-8d50-383f158ce9e5}"),
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIFrameMessageListener,
Ci.nsIObserver,
Ci.nsISupportsWeakReference,
]),
// nsIObserver
observe: function (aSubject, aTopic, aData) {
// This method is called by the "profile-after-change" category on startup,
// which is called before any web page loads. At this time, we need to
// register a global message listener in the parent process preemptively,
// because we can receive requests from child processes at any time. For
// performance reasons, we use this object as a message listener, so that we
// don't have to load the FormAutoFill module at startup.
let globalMM = Cc["@mozilla.org/globalmessagemanager;1"]
.getService(Ci.nsIMessageListenerManager);
globalMM.addMessageListener("FormAutofill:RequestAutocomplete", this);
},
// nsIFrameMessageListener
receiveMessage: function (aMessage) {
// Process the "FormAutofill:RequestAutocomplete" message. Any exception
// raised in the parent process is caught and serialized into the reply
// message that is sent to the requesting child process.
FormAutofill.processRequestAutocomplete(aMessage.data)
.catch(ex => { exception: ex })
.then(result => {
// The browser message manager in the parent will send the reply to the
// associated frame message manager in the child.
let browserMM = aMessage.target.messageManager;
browserMM.sendAsyncMessage("FormAutofill:RequestAutocompleteResult",
result);
})
.catch(Cu.reportError);
},
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FormAutofillStartup]);

View File

@ -1,2 +1,7 @@
component {ed9c2c3c-3f86-4ae5-8e31-10f71b0f19e6} FormAutofillContentService.js
contract @mozilla.org/formautofill/content-service;1 {ed9c2c3c-3f86-4ae5-8e31-10f71b0f19e6}
component {51c95b3d-7431-467b-8d50-383f158ce9e5} FormAutofillStartup.js
contract @mozilla.org/formautofill/startup;1 {51c95b3d-7431-467b-8d50-383f158ce9e5}
#ifdef NIGHTLY_BUILD
category profile-after-change FormAutofillStartup @mozilla.org/formautofill/startup;1
#endif

View File

@ -4,13 +4,14 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
BROWSER_CHROME_MANIFESTS += [
'test/browser/browser.ini',
]
if CONFIG['NIGHTLY_BUILD']:
BROWSER_CHROME_MANIFESTS += [
'test/browser/browser.ini',
]
MOCHITEST_CHROME_MANIFESTS += [
'test/chrome/chrome.ini',
]
MOCHITEST_CHROME_MANIFESTS += [
'test/chrome/chrome.ini',
]
XPCSHELL_TESTS_MANIFESTS += [
'test/xpcshell/xpcshell.ini',
@ -23,8 +24,12 @@ XPIDL_SOURCES += [
XPIDL_MODULE = 'toolkit_formautofill'
EXTRA_COMPONENTS += [
'formautofill.manifest',
'FormAutofillContentService.js',
'FormAutofillStartup.js',
]
EXTRA_PP_COMPONENTS += [
'formautofill.manifest',
]
EXTRA_JS_MODULES += [

View File

@ -13,3 +13,11 @@
// xpcshell specific test initialization here. If you need shared functions or
// initialization that are not specific to xpcshell, consider adding them to
// "head_common.js" in the parent folder instead.
add_task_in_parent_process(function* test_xpcshell_initialize_profile() {
// We need to send the profile-after-change notification manually to the
// startup component to ensure it has been initialized.
Cc["@mozilla.org/formautofill/startup;1"]
.getService(Ci.nsIObserver)
.observe(null, "profile-after-change", "");
});