зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1589938
, convert FormHistory modules into JSWindowActors, allowing the test test_form_submission.html to work with fission enabled, r=MattN
Differential Revision: https://phabricator.services.mozilla.com/D49969 --HG-- rename : toolkit/components/satchel/FormSubmitChild.jsm => toolkit/components/satchel/FormHistoryChild.jsm extra : moz-landing-system : lando
This commit is contained in:
Родитель
44f6080af9
Коммит
41f434a1d8
|
@ -39,17 +39,14 @@ function isAutocompleteDisabled(aField) {
|
||||||
function FormHistoryClient({ formField, inputName }) {
|
function FormHistoryClient({ formField, inputName }) {
|
||||||
if (formField && inputName != this.SEARCHBAR_ID) {
|
if (formField && inputName != this.SEARCHBAR_ID) {
|
||||||
let window = formField.ownerGlobal;
|
let window = formField.ownerGlobal;
|
||||||
this.mm = window.docShell.messageManager;
|
this.windowGlobal = window.getWindowGlobalChild();
|
||||||
} else {
|
} else if (inputName == this.SEARCHBAR_ID && formField) {
|
||||||
if (inputName == this.SEARCHBAR_ID && formField) {
|
throw new Error(
|
||||||
throw new Error(
|
"FormHistoryClient constructed with both a " +
|
||||||
"FormHistoryClient constructed with both a " +
|
"formField and an inputName. This is not " +
|
||||||
"formField and an inputName. This is not " +
|
"supported, and only empty results will be " +
|
||||||
"supported, and only empty results will be " +
|
"returned."
|
||||||
"returned."
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
this.mm = Services.cpmm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.inputName = inputName;
|
this.inputName = inputName;
|
||||||
|
@ -59,15 +56,16 @@ function FormHistoryClient({ formField, inputName }) {
|
||||||
FormHistoryClient.prototype = {
|
FormHistoryClient.prototype = {
|
||||||
SEARCHBAR_ID: "searchbar-history",
|
SEARCHBAR_ID: "searchbar-history",
|
||||||
|
|
||||||
// It is assumed that nsFormAutoComplete only uses / cares about
|
cancelled: false,
|
||||||
// one FormHistoryClient at a time, and won't attempt to have
|
|
||||||
// multiple in-flight searches occurring with the same FormHistoryClient.
|
|
||||||
// We use an ID number per instantiated FormHistoryClient to make
|
|
||||||
// sure we only respond to messages that were meant for us.
|
|
||||||
id: 0,
|
|
||||||
callback: null,
|
|
||||||
inputName: "",
|
inputName: "",
|
||||||
mm: null,
|
|
||||||
|
getActor() {
|
||||||
|
if (this.windowGlobal) {
|
||||||
|
return this.windowGlobal.getActor("FormHistory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Query FormHistory for some results.
|
* Query FormHistory for some results.
|
||||||
|
@ -83,14 +81,50 @@ FormHistoryClient.prototype = {
|
||||||
* argument (the found entries).
|
* argument (the found entries).
|
||||||
*/
|
*/
|
||||||
requestAutoCompleteResults(searchString, params, callback) {
|
requestAutoCompleteResults(searchString, params, callback) {
|
||||||
this.mm.sendAsyncMessage("FormHistory:AutoCompleteSearchAsync", {
|
this.cancelled = false;
|
||||||
id: this.id,
|
|
||||||
searchString,
|
|
||||||
params,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.mm.addMessageListener("FormHistory:AutoCompleteSearchResults", this);
|
// Use the actor if possible, otherwise for the searchbar,
|
||||||
this.callback = callback;
|
// use the more roundabout per-process message manager which has
|
||||||
|
// no sendQuery method.
|
||||||
|
let actor = this.getActor();
|
||||||
|
if (actor) {
|
||||||
|
actor
|
||||||
|
.sendQuery("FormHistory:AutoCompleteSearchAsync", {
|
||||||
|
searchString,
|
||||||
|
params,
|
||||||
|
})
|
||||||
|
.then(
|
||||||
|
results => {
|
||||||
|
this.handleAutoCompleteResults(results, callback);
|
||||||
|
},
|
||||||
|
() => this.cancel()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
this.callback = callback;
|
||||||
|
Services.cpmm.addMessageListener(
|
||||||
|
"FormHistory:AutoCompleteSearchResults",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
Services.cpmm.sendAsyncMessage("FormHistory:AutoCompleteSearchAsync", {
|
||||||
|
id: this.id,
|
||||||
|
searchString,
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAutoCompleteResults(results, callback) {
|
||||||
|
if (this.cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!callback) {
|
||||||
|
Cu.reportError("FormHistoryClient received response with no callback");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(results);
|
||||||
|
this.cancel();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -99,7 +133,14 @@ FormHistoryClient.prototype = {
|
||||||
* called from this FormHistoryClient.
|
* called from this FormHistoryClient.
|
||||||
*/
|
*/
|
||||||
cancel() {
|
cancel() {
|
||||||
this.clearListeners();
|
if (this.callback) {
|
||||||
|
Services.cpmm.removeMessageListener(
|
||||||
|
"FormHistory:AutoCompleteSearchResults",
|
||||||
|
this
|
||||||
|
);
|
||||||
|
this.callback = null;
|
||||||
|
}
|
||||||
|
this.cancelled = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,34 +156,19 @@ FormHistoryClient.prototype = {
|
||||||
* The guid for the item being removed.
|
* The guid for the item being removed.
|
||||||
*/
|
*/
|
||||||
remove(value, guid) {
|
remove(value, guid) {
|
||||||
this.mm.sendAsyncMessage("FormHistory:RemoveEntry", {
|
let actor = this.getActor() || Services.cpmm;
|
||||||
|
actor.sendAsyncMessage("FormHistory:RemoveEntry", {
|
||||||
inputName: this.inputName,
|
inputName: this.inputName,
|
||||||
value,
|
value,
|
||||||
guid,
|
guid,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// Private methods
|
|
||||||
|
|
||||||
receiveMessage(msg) {
|
receiveMessage(msg) {
|
||||||
let { id, results } = msg.data;
|
let { id, results } = msg.data;
|
||||||
if (id != this.id) {
|
if (id == this.id) {
|
||||||
return;
|
this.handleAutoCompleteResults(results, this.callback);
|
||||||
}
|
}
|
||||||
if (!this.callback) {
|
|
||||||
Cu.reportError("FormHistoryClient received message with no callback");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.callback(results);
|
|
||||||
this.clearListeners();
|
|
||||||
},
|
|
||||||
|
|
||||||
clearListeners() {
|
|
||||||
this.mm.removeMessageListener(
|
|
||||||
"FormHistory:AutoCompleteSearchResults",
|
|
||||||
this
|
|
||||||
);
|
|
||||||
this.callback = null;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var EXPORTED_SYMBOLS = ["FormSubmitChild"];
|
var EXPORTED_SYMBOLS = ["FormHistoryChild"];
|
||||||
|
|
||||||
const { ActorChild } = ChromeUtils.import(
|
const { XPCOMUtils } = ChromeUtils.import(
|
||||||
"resource://gre/modules/ActorChild.jsm"
|
"resource://gre/modules/XPCOMUtils.jsm"
|
||||||
);
|
);
|
||||||
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
@ -22,46 +22,18 @@ ChromeUtils.defineModuleGetter(
|
||||||
"resource://gre/modules/PrivateBrowsingUtils.jsm"
|
"resource://gre/modules/PrivateBrowsingUtils.jsm"
|
||||||
);
|
);
|
||||||
|
|
||||||
class FormSubmitChild extends ActorChild {
|
XPCOMUtils.defineLazyPreferenceGetter(this, "gDebug", "browser.formfill.debug");
|
||||||
constructor(dispatcher) {
|
XPCOMUtils.defineLazyPreferenceGetter(this, "gEnabled", "browser.formfill.enable");
|
||||||
super(dispatcher);
|
|
||||||
|
|
||||||
this.QueryInterface = ChromeUtils.generateQI([
|
function log(message) {
|
||||||
Ci.nsIObserver,
|
if (!gDebug) {
|
||||||
Ci.nsISupportsWeakReference,
|
return;
|
||||||
]);
|
|
||||||
|
|
||||||
Services.prefs.addObserver("browser.formfill.", this);
|
|
||||||
this.updatePrefs();
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
|
||||||
Services.prefs.removeObserver("browser.formfill.", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePrefs() {
|
|
||||||
this.debug = Services.prefs.getBoolPref("browser.formfill.debug");
|
|
||||||
this.enabled = Services.prefs.getBoolPref("browser.formfill.enable");
|
|
||||||
}
|
|
||||||
|
|
||||||
log(message) {
|
|
||||||
if (!this.debug) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dump("satchelFormListener: " + message + "\n");
|
|
||||||
Services.console.logStringMessage("satchelFormListener: " + message);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---- nsIObserver interface ---- */
|
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
|
||||||
if (topic == "nsPref:changed") {
|
|
||||||
this.updatePrefs();
|
|
||||||
} else {
|
|
||||||
this.log("Oops! Unexpected notification: " + topic);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
dump("satchelFormListener: " + message + "\n");
|
||||||
|
Services.console.logStringMessage("satchelFormListener: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormHistoryChild extends JSWindowActorChild {
|
||||||
handleEvent(event) {
|
handleEvent(event) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case "DOMFormBeforeSubmit": {
|
case "DOMFormBeforeSubmit": {
|
||||||
|
@ -77,13 +49,13 @@ class FormSubmitChild extends ActorChild {
|
||||||
onDOMFormBeforeSubmit(event) {
|
onDOMFormBeforeSubmit(event) {
|
||||||
let form = event.target;
|
let form = event.target;
|
||||||
if (
|
if (
|
||||||
!this.enabled ||
|
!gEnabled ||
|
||||||
PrivateBrowsingUtils.isContentWindowPrivate(form.ownerGlobal)
|
PrivateBrowsingUtils.isContentWindowPrivate(form.ownerGlobal)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.log("Form submit observer notified.");
|
log("Form submit observer notified.");
|
||||||
|
|
||||||
if (
|
if (
|
||||||
form.hasAttribute("autocomplete") &&
|
form.hasAttribute("autocomplete") &&
|
||||||
|
@ -127,7 +99,7 @@ class FormSubmitChild extends ActorChild {
|
||||||
|
|
||||||
// Don't save credit card numbers.
|
// Don't save credit card numbers.
|
||||||
if (CreditCard.isValidNumber(value)) {
|
if (CreditCard.isValidNumber(value)) {
|
||||||
this.log("skipping saving a credit card number");
|
log("skipping saving a credit card number");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,19 +109,19 @@ class FormSubmitChild extends ActorChild {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (name == "searchbar-history") {
|
if (name == "searchbar-history") {
|
||||||
this.log('addEntry for input name "' + name + '" is denied');
|
log('addEntry for input name "' + name + '" is denied');
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit stored data to 200 characters.
|
// Limit stored data to 200 characters.
|
||||||
if (name.length > 200 || value.length > 200) {
|
if (name.length > 200 || value.length > 200) {
|
||||||
this.log("skipping input that has a name/value too large");
|
log("skipping input that has a name/value too large");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Limit number of fields stored per form.
|
// Limit number of fields stored per form.
|
||||||
if (entries.length >= 100) {
|
if (entries.length >= 100) {
|
||||||
this.log("not saving any more entries for this form.");
|
log("not saving any more entries for this form.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +129,7 @@ class FormSubmitChild extends ActorChild {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entries.length) {
|
if (entries.length) {
|
||||||
this.log("sending entries to parent process for form " + form.id);
|
log("sending entries to parent process for form " + form.id);
|
||||||
this.sendAsyncMessage("FormHistory:FormSubmitEntries", entries);
|
this.sendAsyncMessage("FormHistory:FormSubmitEntries", entries);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/* 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/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var EXPORTED_SYMBOLS = ["FormHistoryParent"];
|
||||||
|
|
||||||
|
ChromeUtils.defineModuleGetter(
|
||||||
|
this,
|
||||||
|
"FormHistory",
|
||||||
|
"resource://gre/modules/FormHistory.jsm"
|
||||||
|
);
|
||||||
|
|
||||||
|
class FormHistoryParent extends JSWindowActorParent {
|
||||||
|
receiveMessage(message) {
|
||||||
|
switch (message.name) {
|
||||||
|
case "FormHistory:FormSubmitEntries": {
|
||||||
|
let entries = message.data;
|
||||||
|
let changes = entries.map(entry => ({
|
||||||
|
op: "bump",
|
||||||
|
fieldname: entry.name,
|
||||||
|
value: entry.value,
|
||||||
|
}));
|
||||||
|
|
||||||
|
FormHistory.update(changes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "FormHistory:AutoCompleteSearchAsync":
|
||||||
|
return this.autoCompleteSearch(message);
|
||||||
|
|
||||||
|
case "FormHistory:RemoveEntry":
|
||||||
|
this.removeEntry(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
autoCompleteSearch(message) {
|
||||||
|
let { searchString, params } = message.data;
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
let results = [];
|
||||||
|
let processResults = {
|
||||||
|
handleResult: aResult => {
|
||||||
|
results.push(aResult);
|
||||||
|
},
|
||||||
|
handleCompletion: aReason => {
|
||||||
|
if (!aReason) {
|
||||||
|
resolve(results);
|
||||||
|
} else {
|
||||||
|
reject();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
FormHistory.getAutoCompleteResults(searchString, params, processResults);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEntry(message) {
|
||||||
|
let { inputName, value, guid } = message.data;
|
||||||
|
FormHistory.update({
|
||||||
|
op: "remove",
|
||||||
|
fieldname: inputName,
|
||||||
|
value,
|
||||||
|
guid,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,32 +50,20 @@ FormHistoryStartup.prototype = {
|
||||||
Services.obs.addObserver(this, "idle-daily", true);
|
Services.obs.addObserver(this, "idle-daily", true);
|
||||||
Services.obs.addObserver(this, "formhistory-expire-now", true);
|
Services.obs.addObserver(this, "formhistory-expire-now", true);
|
||||||
|
|
||||||
Services.mm.addMessageListener("FormHistory:FormSubmitEntries", this);
|
Services.ppmm.addMessageListener(
|
||||||
|
"FormHistory:AutoCompleteSearchAsync",
|
||||||
// For each of these messages, we could receive them from content,
|
this
|
||||||
// or we might receive them from the ppmm if the searchbar is
|
);
|
||||||
// having its history queried.
|
Services.ppmm.addMessageListener("FormHistory:RemoveEntry", this);
|
||||||
for (let manager of [Services.mm, Services.ppmm]) {
|
|
||||||
manager.addMessageListener("FormHistory:AutoCompleteSearchAsync", this);
|
|
||||||
manager.addMessageListener("FormHistory:RemoveEntry", this);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
receiveMessage(message) {
|
receiveMessage(message) {
|
||||||
switch (message.name) {
|
switch (message.name) {
|
||||||
case "FormHistory:FormSubmitEntries": {
|
|
||||||
let entries = message.data;
|
|
||||||
let changes = entries.map(entry => ({
|
|
||||||
op: "bump",
|
|
||||||
fieldname: entry.name,
|
|
||||||
value: entry.value,
|
|
||||||
}));
|
|
||||||
|
|
||||||
FormHistory.update(changes);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case "FormHistory:AutoCompleteSearchAsync": {
|
case "FormHistory:AutoCompleteSearchAsync": {
|
||||||
|
// This case is only used for the search field. There is a
|
||||||
|
// similar algorithm in FormHistoryParent.jsm that uses
|
||||||
|
// sendQuery for other form fields.
|
||||||
|
|
||||||
let { id, searchString, params } = message.data;
|
let { id, searchString, params } = message.data;
|
||||||
|
|
||||||
if (this.pendingQuery) {
|
if (this.pendingQuery) {
|
||||||
|
@ -83,19 +71,7 @@ FormHistoryStartup.prototype = {
|
||||||
this.pendingQuery = null;
|
this.pendingQuery = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mm;
|
|
||||||
let query = null;
|
let query = null;
|
||||||
// MessageListenerManager is a Mozilla-only interface, so disable the eslint error
|
|
||||||
// for it.
|
|
||||||
// eslint-disable-next-line no-undef
|
|
||||||
if (message.target instanceof MessageListenerManager) {
|
|
||||||
// The target is the PPMM, meaning that the parent process
|
|
||||||
// is requesting FormHistory data on the searchbar.
|
|
||||||
mm = message.target;
|
|
||||||
} else {
|
|
||||||
// Otherwise, the target is a <xul:browser>.
|
|
||||||
mm = message.target.messageManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
let results = [];
|
let results = [];
|
||||||
let processResults = {
|
let processResults = {
|
||||||
|
@ -109,10 +85,13 @@ FormHistoryStartup.prototype = {
|
||||||
if (query === this.pendingQuery) {
|
if (query === this.pendingQuery) {
|
||||||
this.pendingQuery = null;
|
this.pendingQuery = null;
|
||||||
if (!aReason) {
|
if (!aReason) {
|
||||||
mm.sendAsyncMessage("FormHistory:AutoCompleteSearchResults", {
|
message.target.sendAsyncMessage(
|
||||||
id,
|
"FormHistory:AutoCompleteSearchResults",
|
||||||
results,
|
{
|
||||||
});
|
id,
|
||||||
|
results,
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -42,7 +42,8 @@ XPCOM_MANIFESTS += [
|
||||||
include('/ipc/chromium/chromium-config.mozbuild')
|
include('/ipc/chromium/chromium-config.mozbuild')
|
||||||
|
|
||||||
FINAL_TARGET_FILES.actors += [
|
FINAL_TARGET_FILES.actors += [
|
||||||
'FormSubmitChild.jsm',
|
'FormHistoryChild.jsm',
|
||||||
|
'FormHistoryParent.jsm',
|
||||||
]
|
]
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul'
|
FINAL_LIBRARY = 'xul'
|
||||||
|
|
|
@ -16,7 +16,6 @@ skip-if = (verify && debug && (os == 'win')) || (os == 'mac') # Bug 1514249
|
||||||
[test_form_autocomplete_validation_at_input_event.html]
|
[test_form_autocomplete_validation_at_input_event.html]
|
||||||
[test_form_autocomplete_with_list.html]
|
[test_form_autocomplete_with_list.html]
|
||||||
[test_form_submission.html]
|
[test_form_submission.html]
|
||||||
fail-if = fission
|
|
||||||
[test_form_submission_cap.html]
|
[test_form_submission_cap.html]
|
||||||
[test_form_submission_cap2.html]
|
[test_form_submission_cap2.html]
|
||||||
[test_input_valid_state_with_autocomplete.html]
|
[test_input_valid_state_with_autocomplete.html]
|
||||||
|
|
|
@ -6,23 +6,12 @@
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<form id="subform2" onsubmit="return checkSubmit(100)">
|
<form id="subform2" onsubmit="return false">
|
||||||
<input id="subtest2" type="text" name="subtest2">
|
<input id="subtest2" type="text" name="subtest2">
|
||||||
<button type="submit">Submit</button>
|
<button type="submit">Submit</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/* exported checkSubmit clickButton */
|
|
||||||
function checkSubmit(num) {
|
|
||||||
return SpecialPowers.wrap(parent).wrappedJSObject.checkSubmit(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
function clickButton(num) {
|
|
||||||
if (num == 100) {
|
|
||||||
document.querySelectorAll("button")[0].click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the input's value (can't use a default value, as satchel will ignore it)
|
// set the input's value (can't use a default value, as satchel will ignore it)
|
||||||
document.getElementById("subtest2").value = "subtestValue";
|
document.getElementById("subtest2").value = "subtestValue";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -490,8 +490,18 @@ function submitForm(formNum) {
|
||||||
// from an HTTPS domain in an iframe.
|
// from an HTTPS domain in an iframe.
|
||||||
if (nextFormNum == 100) {
|
if (nextFormNum == 100) {
|
||||||
ok(true, "submitting iframe test " + nextFormNum);
|
ok(true, "submitting iframe test " + nextFormNum);
|
||||||
SpecialPowers.wrap(document.getElementById("iframe").contentWindow)
|
|
||||||
.wrappedJSObject.clickButton(nextFormNum);
|
// Need to call checkSubmit first, as the iframe's document can be in another
|
||||||
|
// process and won't be able to notify back before the submit occurs.
|
||||||
|
checkSubmit(100);
|
||||||
|
|
||||||
|
let browsingContext = SpecialPowers.unwrap(
|
||||||
|
SpecialPowers.wrap(document.getElementById("iframe")).browsingContext);
|
||||||
|
SpecialPowers.spawn(browsingContext, [], () => {
|
||||||
|
/* eslint-disable no-undef */
|
||||||
|
content.document.querySelectorAll("button")[0].click();
|
||||||
|
/* eslint-enable no-undef */
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
let button = getFormSubmitButton(nextFormNum);
|
let button = getFormSubmitButton(nextFormNum);
|
||||||
button.click();
|
button.click();
|
||||||
|
|
|
@ -263,6 +263,20 @@ let ACTORS = {
|
||||||
allFrames: true,
|
allFrames: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
FormHistory: {
|
||||||
|
parent: {
|
||||||
|
moduleURI: "resource://gre/actors/FormHistoryParent.jsm",
|
||||||
|
},
|
||||||
|
child: {
|
||||||
|
moduleURI: "resource://gre/actors/FormHistoryChild.jsm",
|
||||||
|
events: {
|
||||||
|
DOMFormBeforeSubmit: {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
allFrames: true,
|
||||||
|
},
|
||||||
|
|
||||||
InlineSpellChecker: {
|
InlineSpellChecker: {
|
||||||
parent: {
|
parent: {
|
||||||
moduleURI: "resource://gre/actors/InlineSpellCheckerParent.jsm",
|
moduleURI: "resource://gre/actors/InlineSpellCheckerParent.jsm",
|
||||||
|
@ -367,16 +381,6 @@ let LEGACY_ACTORS = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
FormSubmit: {
|
|
||||||
child: {
|
|
||||||
module: "resource://gre/actors/FormSubmitChild.jsm",
|
|
||||||
allFrames: true,
|
|
||||||
events: {
|
|
||||||
DOMFormBeforeSubmit: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
KeyPressEventModelChecker: {
|
KeyPressEventModelChecker: {
|
||||||
child: {
|
child: {
|
||||||
module: "resource://gre/actors/KeyPressEventModelCheckerChild.jsm",
|
module: "resource://gre/actors/KeyPressEventModelCheckerChild.jsm",
|
||||||
|
|
Загрузка…
Ссылка в новой задаче