Bug 1330111 - Add FormLikeFactory.findRootForField API. r=johannh
MozReview-Commit-ID: 8xgtfs9iADG
--- a/toolkit/modules/FormLikeFactory.jsm
+++ b/toolkit/modules/FormLikeFactory.jsm
@@ -63,42 +63,61 @@ let FormLikeFactory = {
* @throws Error if aField isn't a password or username field in a document
*/
createFromField(aField) {
if (!(aField instanceof Ci.nsIDOMHTMLInputElement) ||
!aField.ownerDocument) {
throw new Error("createFromField requires a field in a document");
}
- if (aField.form) {
- return this.createFromForm(aField.form);
+ let rootElement = this.findRootForField(aField);
+ if (rootElement instanceof Ci.nsIDOMHTMLFormElement) {
+ return this.createFromForm(rootElement);
}
let doc = aField.ownerDocument;
let elements = [];
- for (let el of doc.documentElement.querySelectorAll("input")) {
+ for (let el of rootElement.querySelectorAll("input")) {
+ // Exclude elements inside the rootElement that are already in a <form> as
+ // they will be handled by their own FormLike.
if (!el.form) {
elements.push(el);
}
}
let formLike = {
action: doc.baseURI,
autocomplete: "on",
- // Exclude elements inside the rootElement that are already in a <form> as
- // they will be handled by their own FormLike.
elements,
ownerDocument: doc,
- rootElement: doc.documentElement,
+ rootElement,
};
this._addToJSONProperty(formLike);
return formLike;
},
/**
+ * Determine the Element that encapsulates the related fields. For example, if
+ * a page contains a login form and a checkout form which are "submitted"
+ * separately, and the username field is passed in, ideally this would return
+ * an ancestor Element of the username and password fields which doesn't
+ * include any of the checkout fields.
+ *
+ * @param {HTMLInputElement} aField - a field in a document
+ * @return {HTMLElement} - the root element surrounding related fields
+ */
+ findRootForField(aField) {
+ if (aField.form) {
+ return aField.form;
+ }
+
+ return aField.ownerDocument.documentElement;
+ },
+
+ /**
* Add a `toJSON` property to a FormLike so logging which ends up going
* through dump doesn't include usless garbage from DOM objects.
*/
_addToJSONProperty(aFormLike) {
function prettyElementOutput(aElement) {
let idText = aElement.id ? "#" + aElement.id : "";
let classText = "";
for (let className of aElement.classList) {