From be46de646413bc113b447bdbeb2d44d00f1c86d8 Mon Sep 17 00:00:00 2001 From: Julian Descottes Date: Tue, 30 Jul 2019 06:08:01 +0000 Subject: [PATCH] Bug 1566870 - Fix FormAutoFill leak when focusing input in HTML frame r=kmag,MattN Cleaning the FormAutofillContent on blur seems to fix the leak. Differential Revision: https://phabricator.services.mozilla.com/D39716 --HG-- extra : moz-landing-system : lando --- .../content/FormAutofillFrameScript.js | 11 ++++ browser/extensions/formautofill/moz.build | 1 + .../test/browser/focus-leak/browser.ini | 10 ++++ .../browser_iframe_typecontent_input_focus.js | 55 +++++++++++++++++++ .../doc_iframe_typecontent_input_focus.xul | 7 +++ ..._iframe_typecontent_input_focus_frame.html | 6 ++ 6 files changed, 90 insertions(+) create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/browser.ini create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/browser_iframe_typecontent_input_focus.js create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus.xul create mode 100644 browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus_frame.html diff --git a/browser/extensions/formautofill/content/FormAutofillFrameScript.js b/browser/extensions/formautofill/content/FormAutofillFrameScript.js index 7fedc1c76218..d37fd573365b 100644 --- a/browser/extensions/formautofill/content/FormAutofillFrameScript.js +++ b/browser/extensions/formautofill/content/FormAutofillFrameScript.js @@ -60,6 +60,7 @@ var FormAutofillFrameScript = { init() { addEventListener("focusin", this); + addEventListener("focusout", this); addEventListener("DOMFormBeforeSubmit", this); addMessageListener("FormAutofill:PreviewProfile", this); addMessageListener("FormAutofill:ClearForm", this); @@ -77,6 +78,10 @@ var FormAutofillFrameScript = { this.onFocusIn(evt); break; } + case "focusout": { + this.onFocusOut(); + break; + } case "DOMFormBeforeSubmit": { this.onDOMFormBeforeSubmit(evt); break; @@ -115,6 +120,12 @@ var FormAutofillFrameScript = { this._doIdentifyAutofillFields(); }, + onFocusOut() { + // Update active input on blur to release references on the previously + // focused element in FormAutofillContent. + FormAutofillContent.updateActiveInput(); + }, + /** * Handle the DOMFormBeforeSubmit event. * @param {Event} evt diff --git a/browser/extensions/formautofill/moz.build b/browser/extensions/formautofill/moz.build index 5a8764c7dd14..8907797a50e9 100644 --- a/browser/extensions/formautofill/moz.build +++ b/browser/extensions/formautofill/moz.build @@ -37,6 +37,7 @@ TESTING_JS_MODULES += ['test/fixtures/OSKeyStoreTestUtils.jsm'] BROWSER_CHROME_MANIFESTS += [ 'test/browser/browser.ini', 'test/browser/creditCard/browser.ini', + 'test/browser/focus-leak/browser.ini', ] XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini'] diff --git a/browser/extensions/formautofill/test/browser/focus-leak/browser.ini b/browser/extensions/formautofill/test/browser/focus-leak/browser.ini new file mode 100644 index 000000000000..55575085017e --- /dev/null +++ b/browser/extensions/formautofill/test/browser/focus-leak/browser.ini @@ -0,0 +1,10 @@ +[DEFAULT] +support-files = + doc_iframe_typecontent_input_focus.xul + doc_iframe_typecontent_input_focus_frame.html + ../head.js + +# This test is used to detect a leak. +# Keep it isolated in a dedicated test folder to make sure the leak is cleaned +# up as a sideeffect of another test. +[browser_iframe_typecontent_input_focus.js] diff --git a/browser/extensions/formautofill/test/browser/focus-leak/browser_iframe_typecontent_input_focus.js b/browser/extensions/formautofill/test/browser/focus-leak/browser_iframe_typecontent_input_focus.js new file mode 100644 index 000000000000..3091dc12566c --- /dev/null +++ b/browser/extensions/formautofill/test/browser/focus-leak/browser_iframe_typecontent_input_focus.js @@ -0,0 +1,55 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const URL_ROOT = + "chrome://mochitests/content/browser/browser/extensions/formautofill/test/browser/focus-leak/"; + +const XUL_FRAME_URI = URL_ROOT + "doc_iframe_typecontent_input_focus.xul"; +const INNER_HTML_FRAME_URI = + URL_ROOT + "doc_iframe_typecontent_input_focus_frame.html"; + +/** + * Check that focusing an input in a frame with type=content embedded in a xul + * document does not leak. + */ +add_task(async function() { + const doc = gBrowser.ownerDocument; + const linkedBrowser = gBrowser.selectedTab.linkedBrowser; + const browserContainer = gBrowser.getBrowserContainer(linkedBrowser); + + info("Load the test page in a frame with type content"); + const frame = doc.createXULElement("iframe"); + frame.setAttribute("type", "content"); + browserContainer.appendChild(frame); + + info("Wait for the xul iframe to be loaded"); + const onXulFrameLoad = BrowserTestUtils.waitForEvent(frame, "load", true); + frame.setAttribute("src", XUL_FRAME_URI); + await onXulFrameLoad; + + const panelFrame = frame.contentDocument.querySelector("#html-iframe"); + + info("Wait for the html iframe to be loaded"); + const onFrameLoad = BrowserTestUtils.waitForEvent(panelFrame, "load", true); + panelFrame.setAttribute("src", INNER_HTML_FRAME_URI); + await onFrameLoad; + + info("Focus an input inside the iframe"); + const focusMeInput = panelFrame.contentDocument.querySelector(".focusme"); + const onFocus = BrowserTestUtils.waitForEvent(focusMeInput, "focus"); + focusMeInput.focus(); + await onFocus; + + // This assert is not really meaningful, the main purpose of the test is + // to check against leaks. + is( + focusMeInput, + panelFrame.contentDocument.activeElement, + "The .focusme input is the active element" + ); + + // Stop the test without blurring the input, the cleanup should still prevent + // leaks in the test. +}); diff --git a/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus.xul b/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus.xul new file mode 100644 index 000000000000..ec3aaa2648a0 --- /dev/null +++ b/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus.xul @@ -0,0 +1,7 @@ + + + + + + diff --git a/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus_frame.html b/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus_frame.html new file mode 100644 index 000000000000..00853d8eecf8 --- /dev/null +++ b/browser/extensions/formautofill/test/browser/focus-leak/doc_iframe_typecontent_input_focus_frame.html @@ -0,0 +1,6 @@ + + + + + +