зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1519486 - convert autocomplete-richlistitem XBL binding to CE, r=MattN
This commit is contained in:
Родитель
fccfd070c9
Коммит
599d3ecb6b
|
@ -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",
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test autofill submit</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/AddTask.js"></script>
|
||||
<script type="text/javascript" src="formautofill_common.js"></script>
|
||||
<script type="text/javascript" src="satchel_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
let MOCK_STORAGE = [{
|
||||
"given-name": "John",
|
||||
"additional-name": "R",
|
||||
"family-name": "Smith",
|
||||
"organization": "Sesame Street",
|
||||
"street-address": "123 Sesame Street.",
|
||||
"tel": "+13453453456",
|
||||
"country": "US",
|
||||
"address-level1": "NY",
|
||||
}];
|
||||
|
||||
initPopupListener();
|
||||
|
||||
add_task(async function setupStorage() {
|
||||
await addAddress(MOCK_STORAGE[0]);
|
||||
|
||||
await updateFormHistory([
|
||||
{op: "add", fieldname: "username", value: "petya"},
|
||||
{op: "add", fieldname: "current-password", value: "abrh#25_,K"},
|
||||
]);
|
||||
});
|
||||
|
||||
add_task(async function check_switch_autofill_form_popup() {
|
||||
await setInput("#tel", "");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await expectPopup();
|
||||
checkMenuEntries(
|
||||
[
|
||||
`{"primary":"+13453453456","secondary":"123 Sesame Street."}`,
|
||||
`{"primary":"","secondary":"","categories":["name","organization","address","tel"],"focusedCategory":"tel"}`,
|
||||
],
|
||||
false
|
||||
);
|
||||
|
||||
await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)");
|
||||
});
|
||||
|
||||
add_task(async function check_switch_oridnal_form_popup() {
|
||||
// We need an intentional wait here before switching form.
|
||||
await sleep();
|
||||
await setInput("#username", "");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await expectPopup();
|
||||
checkMenuEntries(["petya"], false);
|
||||
|
||||
await testMenuEntry(0, "el instanceof MozElements.MozAutocompleteRichlistitem");
|
||||
});
|
||||
|
||||
add_task(async function check_switch_autofill_form_popup_back() {
|
||||
// We need an intentional wait here before switching form.
|
||||
await sleep();
|
||||
await setInput("#tel", "");
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
await expectPopup();
|
||||
checkMenuEntries(
|
||||
[
|
||||
`{"primary":"+13453453456","secondary":"123 Sesame Street."}`,
|
||||
`{"primary":"","secondary":"","categories":["name","organization","address","tel"],"focusedCategory":"tel"}`,
|
||||
],
|
||||
false
|
||||
);
|
||||
|
||||
await testMenuEntry(0, "!(el instanceof MozElements.MozAutocompleteRichlistitem)");
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<div>
|
||||
|
||||
<h2>Address form</h2>
|
||||
<form class="alignedLabels">
|
||||
<label>given-name: <input autocomplete="given-name" autofocus></label>
|
||||
<label>additional-name: <input id="additional-name" autocomplete="additional-name"></label>
|
||||
<label>family-name: <input autocomplete="family-name"></label>
|
||||
<label>organization: <input autocomplete="organization"></label>
|
||||
<label>street-address: <input autocomplete="street-address"></label>
|
||||
<label>address-level1: <input autocomplete="address-level1"></label>
|
||||
<label>postal-code: <input autocomplete="postal-code"></label>
|
||||
<label>country: <input autocomplete="country"></label>
|
||||
<label>country-name: <input autocomplete="country-name"></label>
|
||||
<label>tel: <input id="tel" autocomplete="tel"></label>
|
||||
<p>
|
||||
<input type="submit" value="Submit">
|
||||
<button type="reset">Reset</button>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<h2>Ordinal form</h2>
|
||||
<form class="alignedLabels">
|
||||
<label>username: <input id="username" autocomplete="username"></label>
|
||||
<p><input type="submit" value="Username"></p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -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}`);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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",
|
||||
});
|
||||
|
|
|
@ -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.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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче