From 599d3ecb6b31df59a1bbac92d7e79c1773bfcfee Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 24 Jan 2019 08:40:36 -0500 Subject: [PATCH] Bug 1519486 - convert autocomplete-richlistitem XBL binding to CE, r=MattN --- .../browser_urlbar_keyed_search.js | 14 +-- .../test/performance/browser_urlbar_search.js | 16 +-- .../formautofill/test/mochitest/mochitest.ini | 1 + .../test_autofill_and_ordinal_forms.html | 115 ++++++++++++++++++ .../browser_ext_themes_autocomplete_popup.js | 12 +- .../components/satchel/test/parent_utils.js | 13 ++ .../components/satchel/test/satchel_common.js | 10 ++ .../widgets/autocomplete-richlistitem.js | 14 ++- toolkit/content/widgets/autocomplete.xml | 37 ++++-- toolkit/content/xul.css | 3 +- 10 files changed, 195 insertions(+), 40 deletions(-) create mode 100644 browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html diff --git a/browser/base/content/test/performance/browser_urlbar_keyed_search.js b/browser/base/content/test/performance/browser_urlbar_keyed_search.js index a746246f046f..b46ded493464 100644 --- a/browser/base/content/test/performance/browser_urlbar_keyed_search.js +++ b/browser/base/content/test/performance/browser_urlbar_keyed_search.js @@ -37,9 +37,9 @@ if (AppConstants.DEBUG || EXPECTED_REFLOWS_FIRST_OPEN.push( { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml", - "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "handleOverUnderflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "_reuseAcItem@chrome://global/content/elements/autocomplete-richlistitem.js", "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml", "_invalidate@chrome://global/content/bindings/autocomplete.xml", "invalidate@chrome://global/content/bindings/autocomplete.xml", @@ -49,8 +49,8 @@ EXPECTED_REFLOWS_FIRST_OPEN.push( { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "handleOverUnderflow@chrome://global/content/elements/autocomplete-richlistitem.js", "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml", "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml", "openPopup@chrome://global/content/bindings/autocomplete.xml", @@ -91,8 +91,8 @@ if (AppConstants.RELEASE_OR_BETA) { }, { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "_adjustAcItem@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "_adjustAcItem@chrome://global/content/elements/autocomplete-richlistitem.js", "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml", "_invalidate@chrome://global/content/bindings/autocomplete.xml", "invalidate@chrome://global/content/bindings/autocomplete.xml", diff --git a/browser/base/content/test/performance/browser_urlbar_search.js b/browser/base/content/test/performance/browser_urlbar_search.js index ec25a2066202..1bc95dd24b2f 100644 --- a/browser/base/content/test/performance/browser_urlbar_search.js +++ b/browser/base/content/test/performance/browser_urlbar_search.js @@ -38,9 +38,9 @@ if (AppConstants.DEBUG || EXPECTED_REFLOWS_FIRST_OPEN.push( { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml", - "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "handleOverUnderflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "_reuseAcItem@chrome://global/content/elements/autocomplete-richlistitem.js", "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml", "_invalidate@chrome://global/content/bindings/autocomplete.xml", "invalidate@chrome://global/content/bindings/autocomplete.xml", @@ -50,8 +50,8 @@ EXPECTED_REFLOWS_FIRST_OPEN.push( { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "handleOverUnderflow@chrome://global/content/elements/autocomplete-richlistitem.js", "_openAutocompletePopup@chrome://browser/content/urlbarBindings.xml", "openAutocompletePopup@chrome://browser/content/urlbarBindings.xml", "openPopup@chrome://global/content/bindings/autocomplete.xml", @@ -75,9 +75,9 @@ EXPECTED_REFLOWS_FIRST_OPEN.push( const EXPECTED_REFLOWS_SECOND_OPEN = [ { stack: [ - "_handleOverflow@chrome://global/content/bindings/autocomplete.xml", - "handleOverUnderflow@chrome://global/content/bindings/autocomplete.xml", - "_reuseAcItem@chrome://global/content/bindings/autocomplete.xml", + "_handleOverflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "handleOverUnderflow@chrome://global/content/elements/autocomplete-richlistitem.js", + "_reuseAcItem@chrome://global/content/elements/autocomplete-richlistitem.js", "_appendCurrentResult@chrome://global/content/bindings/autocomplete.xml", "_invalidate@chrome://global/content/bindings/autocomplete.xml", "invalidate@chrome://global/content/bindings/autocomplete.xml", diff --git a/browser/extensions/formautofill/test/mochitest/mochitest.ini b/browser/extensions/formautofill/test/mochitest/mochitest.ini index c1d649ef208a..f9a8de9086f0 100644 --- a/browser/extensions/formautofill/test/mochitest/mochitest.ini +++ b/browser/extensions/formautofill/test/mochitest/mochitest.ini @@ -6,6 +6,7 @@ support-files = formautofill_parent_utils.js [test_address_level_1_submission.html] +[test_autofill_and_ordinal_forms.html] [test_autofocus_form.html] skip-if = verify [test_basic_autocomplete_form.html] diff --git a/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html new file mode 100644 index 000000000000..ad3654b463c1 --- /dev/null +++ b/browser/extensions/formautofill/test/mochitest/test_autofill_and_ordinal_forms.html @@ -0,0 +1,115 @@ + + + + + Test autofill submit + + + + + + + + + + + +
+ +

Address form

+
+ + + + + + + + + + +

+ + +

+
+ +

Ordinal form

+
+ +

+
+ +
+ + diff --git a/toolkit/components/extensions/test/browser/browser_ext_themes_autocomplete_popup.js b/toolkit/components/extensions/test/browser/browser_ext_themes_autocomplete_popup.js index 48ef1b086e35..f86ce78ac77c 100644 --- a/toolkit/components/extensions/test/browser/browser_ext_themes_autocomplete_popup.js +++ b/toolkit/components/extensions/test/browser/browser_ext_themes_autocomplete_popup.js @@ -150,12 +150,12 @@ add_task(async function test_popup_url() { results[1].removeAttribute("selected"); - let urlText = document.getAnonymousElementByAttribute(results[1], "anonid", "url-text"); + let urlText = results[1]._urlText; Assert.equal(window.getComputedStyle(urlText).color, `rgb(${hexToRGB(POPUP_URL_COLOR_DARK).join(", ")})`, `Urlbar popup url color should be set to ${POPUP_URL_COLOR_DARK}`); - let actionText = document.getAnonymousElementByAttribute(results[1], "anonid", "action-text"); + let actionText = results[1]._actionText; Assert.equal(window.getComputedStyle(actionText).color, `rgb(${hexToRGB(POPUP_ACTION_COLOR_DARK).join(", ")})`, `Urlbar popup action color should be set to ${POPUP_ACTION_COLOR_DARK}`); @@ -203,19 +203,19 @@ add_task(async function test_popup_url() { `rgb(${hexToRGB(POPUP_TEXT_COLOR_BRIGHT).join(", ")})`, `Popup color should be set to ${POPUP_TEXT_COLOR_BRIGHT}`); - urlText = document.getAnonymousElementByAttribute(results[1], "anonid", "url-text"); + urlText = results[1]._urlText; Assert.equal(window.getComputedStyle(urlText).color, `rgb(${hexToRGB(POPUP_URL_COLOR_BRIGHT).join(", ")})`, `Urlbar popup url color should be set to ${POPUP_URL_COLOR_BRIGHT}`); - actionText = document.getAnonymousElementByAttribute(results[1], "anonid", "action-text"); + actionText = results[1]._actionText; Assert.equal(window.getComputedStyle(actionText).color, `rgb(${hexToRGB(POPUP_ACTION_COLOR_BRIGHT).join(", ")})`, `Urlbar popup action color should be set to ${POPUP_ACTION_COLOR_BRIGHT}`); // Since brighttext is enabled, the seperator color should be // POPUP_TEXT_COLOR_BRIGHT with added alpha. - let separator = document.getAnonymousElementByAttribute(results[1], "anonid", "separator"); + let separator = results[1]._separator; Assert.equal(window.getComputedStyle(separator).color, `rgba(${hexToRGB(POPUP_TEXT_COLOR_BRIGHT).join(", ")}, 0.5)`, `Urlbar popup separator color should be set to ${POPUP_TEXT_COLOR_BRIGHT} with alpha`); @@ -245,7 +245,7 @@ add_task(async function test_popup_url() { let GRAY_TEXT = window.getComputedStyle(span).color; span.remove(); - separator = document.getAnonymousElementByAttribute(results[1], "anonid", "separator"); + separator = results[1]._separator; Assert.equal(window.getComputedStyle(separator).color, GRAY_TEXT, `Urlbar popup separator color should be set to ${GRAY_TEXT}`); diff --git a/toolkit/components/satchel/test/parent_utils.js b/toolkit/components/satchel/test/parent_utils.js index a97eb11fe610..5841f7f4a823 100644 --- a/toolkit/components/satchel/test/parent_utils.js +++ b/toolkit/components/satchel/test/parent_utils.js @@ -101,6 +101,16 @@ var ParentUtils = { }); }, + testMenuEntry(index, statement) { + ContentTaskUtils.waitForCondition(() => { + let el = gAutocompletePopup.richlistbox.getItemAtIndex(index); + let testFunc = new Services.ww.activeWindow.Function("el", `return ${statement}`); + return gAutocompletePopup.popupOpen && el && testFunc(el); + }, "Testing menu entry").then(() => { + sendAsyncMessage("menuEntryTested"); + }); + }, + getPopupState() { sendAsyncMessage("gotPopupState", { open: gAutocompletePopup.popupOpen, @@ -142,6 +152,9 @@ addMessageListener("waitForMenuChange", ({ expectedCount, expectedFirstValue }) addMessageListener("waitForSelectedIndex", ({ expectedIndex }) => { ParentUtils.checkSelectedIndex(expectedIndex); }); +addMessageListener("waitForMenuEntryTest", ({ index, statement }) => { + ParentUtils.testMenuEntry(index, statement); +}); addMessageListener("getPopupState", () => { ParentUtils.getPopupState(); diff --git a/toolkit/components/satchel/test/satchel_common.js b/toolkit/components/satchel/test/satchel_common.js index 36d6276e065c..80771d8f5c94 100644 --- a/toolkit/components/satchel/test/satchel_common.js +++ b/toolkit/components/satchel/test/satchel_common.js @@ -206,6 +206,16 @@ function notifySelectedIndex(expectedIndex, then = null) { }); } +function testMenuEntry(index, statement) { + return new Promise(resolve => { + gChromeScript.sendAsyncMessage("waitForMenuEntryTest", { index, statement }); + gChromeScript.addMessageListener("menuEntryTested", function changed() { + gChromeScript.removeMessageListener("menuEntryTested", changed); + resolve(); + }); + }); +} + function getPopupState(then = null) { return new Promise(resolve => { gChromeScript.sendAsyncMessage("getPopupState"); diff --git a/toolkit/content/widgets/autocomplete-richlistitem.js b/toolkit/content/widgets/autocomplete-richlistitem.js index 0b51201527c1..c6cbf7dadde8 100644 --- a/toolkit/content/widgets/autocomplete-richlistitem.js +++ b/toolkit/content/widgets/autocomplete-richlistitem.js @@ -9,7 +9,7 @@ { const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm"); -class MozAutocompleteRichlistitem extends MozElements.MozRichlistitem { +MozElements.MozAutocompleteRichlistitem = class MozAutocompleteRichlistitem extends MozElements.MozRichlistitem { constructor() { super(); @@ -62,8 +62,6 @@ class MozAutocompleteRichlistitem extends MozElements.MozRichlistitem { this.textContent = ""; this.appendChild(MozXULElement.parseXULToFragment(this._markup)); - this.setAttribute("align", "center"); - this._boundaryCutoff = null; this._inOverflow = false; @@ -908,14 +906,14 @@ class MozAutocompleteRichlistitem extends MozElements.MozRichlistitem { return action; } -} +}; MozXULElement.implementCustomInterface( - MozAutocompleteRichlistitem, + MozElements.MozAutocompleteRichlistitem, [Ci.nsIDOMXULSelectControlItemElement] ); -class MozAutocompleteRichlistitemInsecureWarning extends MozAutocompleteRichlistitem { +class MozAutocompleteRichlistitemInsecureWarning extends MozElements.MozAutocompleteRichlistitem { constructor() { super(); @@ -1019,6 +1017,10 @@ class MozAutocompleteRichlistitemInsecureWarning extends MozAutocompleteRichlist } } +customElements.define("autocomplete-richlistitem", MozElements.MozAutocompleteRichlistitem, { + extends: "richlistitem", +}); + customElements.define("autocomplete-richlistitem-insecure-warning", MozAutocompleteRichlistitemInsecureWarning, { extends: "richlistitem", }); diff --git a/toolkit/content/widgets/autocomplete.xml b/toolkit/content/widgets/autocomplete.xml index dc10311019b8..65e38f416015 100644 --- a/toolkit/content/widgets/autocomplete.xml +++ b/toolkit/content/widgets/autocomplete.xml @@ -1014,7 +1014,6 @@ break; } let item; - let reusable = false; let itemExists = this._currentIndex < existingItemsCount; let originalValue, originalText, originalType; @@ -1029,6 +1028,7 @@ // trim the leading/trailing whitespace let trimmedSearchString = controller.searchString.replace(/^\s+/, "").replace(/\s+$/, ""); + let reusable = false; if (itemExists) { item = this.richlistbox.children[this._currentIndex]; @@ -1049,11 +1049,26 @@ // neither of their style are in the UNREUSEABLE_STYLES. reusable = originalType === style || !(UNREUSEABLE_STYLES.includes(style) || UNREUSEABLE_STYLES.includes(originalType)); - } else { - // need to create a new item - let options = style == "insecureWarning" ? - { is: "autocomplete-richlistitem-insecure-warning" } : null; + } + + // If no reusable item available, then create a new item. + if (!reusable) { + let options = null; + switch (style) { + case "autofill-profile": + case "autofill-footer": + case "autofill-clear-button": + case "autofill-insecureWarning": + // implemented via XBL bindings, no CE for them + break; + case "insecureWarning": + options = { is: "autocomplete-richlistitem-insecure-warning" }; + break; + default: + options = { is: "autocomplete-richlistitem" }; + } item = document.createXULElement("richlistitem", options); + item.className = "autocomplete-richlistitem"; } item.setAttribute("dir", this.style.direction); @@ -1086,20 +1101,18 @@ item.setAttribute("originaltype", style); } - if (itemExists) { + if (reusable) { // Adjust only when the result's type is reusable for existing // item's. Otherwise, we might insensibly call old _adjustAcItem() // as new binding has not been attached yet. // We don't need to worry about switching to new binding, since // _adjustAcItem() will fired by its own constructor accordingly. - if (reusable) { - item._adjustAcItem(); - } + item._adjustAcItem(); item.collapsed = false; + } else if (itemExists) { + let oldItem = this.richlistbox.children[this._currentIndex]; + this.richlistbox.replaceChild(item, oldItem); } else { - // set the class at the end so we can use the attributes - // in the xbl constructor - item.className = "autocomplete-richlistitem"; this.richlistbox.appendChild(item); } diff --git a/toolkit/content/xul.css b/toolkit/content/xul.css index f6a2a3af6a4a..f16b9c66af1c 100644 --- a/toolkit/content/xul.css +++ b/toolkit/content/xul.css @@ -582,8 +582,9 @@ panel[type="autocomplete-richlistbox"] { } .autocomplete-richlistitem { - -moz-binding: url("chrome://global/content/bindings/autocomplete.xml#autocomplete-richlistitem"); + -moz-binding: none; -moz-box-orient: vertical; + -moz-box-align: center; overflow: -moz-hidden-unscrollable; }