From 4cb5ec686a5806fa18ae6a1b33249ea1c8888abb Mon Sep 17 00:00:00 2001 From: Matthew Noorenberghe Date: Tue, 31 Jan 2017 23:54:45 -0800 Subject: [PATCH] Bug 1330111 - Add FormLikeFactory.findRootForField API. r=johannh MozReview-Commit-ID: 6qo0hVx3J6p --- toolkit/modules/FormLikeFactory.jsm | 31 +++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/toolkit/modules/FormLikeFactory.jsm b/toolkit/modules/FormLikeFactory.jsm index 8052f1ed00bc..45f25187c6e7 100644 --- a/toolkit/modules/FormLikeFactory.jsm +++ b/toolkit/modules/FormLikeFactory.jsm @@ -68,13 +68,16 @@ let FormLikeFactory = { 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
as + // they will be handled by their own FormLike. if (!el.form) { elements.push(el); } @@ -82,17 +85,33 @@ let FormLikeFactory = { let formLike = { action: doc.baseURI, autocomplete: "on", - // Exclude elements inside the rootElement that are already in a 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.