mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Bug 1883549, remove formautofill autocomplete item components and create one based on MozAutocompleteTwoLineRichlistitem, r=credential-management-reviewers,sgalich,geckoview-reviewers,owlish
Differential Revision: https://phabricator.services.mozilla.com/D203612
This commit is contained in:
parent
65ed3e5559
commit
6052b367ff
@ -13,12 +13,6 @@ let ignoreList = [
|
|||||||
// CodeMirror is imported as-is, see bug 1004423.
|
// CodeMirror is imported as-is, see bug 1004423.
|
||||||
{ sourceName: /codemirror\.css$/i, isFromDevTools: true },
|
{ sourceName: /codemirror\.css$/i, isFromDevTools: true },
|
||||||
// UA-only media features.
|
// UA-only media features.
|
||||||
{
|
|
||||||
sourceName: /\b(autocomplete-item)\.css$/,
|
|
||||||
errorMessage: /Expected media feature name but found \u2018-moz.*/i,
|
|
||||||
isFromDevTools: false,
|
|
||||||
platforms: ["windows"],
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
sourceName:
|
sourceName:
|
||||||
/\b(contenteditable|EditorOverride|svg|forms|html|mathml|ua)\.css$/i,
|
/\b(contenteditable|EditorOverride|svg|forms|html|mathml|ua)\.css$/i,
|
||||||
@ -27,7 +21,7 @@ let ignoreList = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
sourceName:
|
sourceName:
|
||||||
/\b(scrollbars|xul|html|mathml|ua|forms|svg|manageDialog|autocomplete-item-shared|formautofill)\.css$/i,
|
/\b(scrollbars|xul|html|mathml|ua|forms|svg|manageDialog|formautofill)\.css$/i,
|
||||||
errorMessage: /Unknown property.*-moz-/i,
|
errorMessage: /Unknown property.*-moz-/i,
|
||||||
isFromDevTools: false,
|
isFromDevTools: false,
|
||||||
},
|
},
|
||||||
|
@ -48,14 +48,6 @@ function ensureCssLoaded(domWindow) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css");
|
insertStyleSheet(domWindow, "chrome://formautofill/content/formautofill.css");
|
||||||
insertStyleSheet(
|
|
||||||
domWindow,
|
|
||||||
"chrome://formautofill/content/skin/autocomplete-item-shared.css"
|
|
||||||
);
|
|
||||||
insertStyleSheet(
|
|
||||||
domWindow,
|
|
||||||
"chrome://formautofill/content/skin/autocomplete-item.css"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.formautofill = class extends ExtensionAPI {
|
this.formautofill = class extends ExtensionAPI {
|
||||||
|
@ -1,157 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// This file is loaded into the browser window scope.
|
|
||||||
/* eslint-env mozilla/browser-window */
|
|
||||||
/* eslint-disable mozilla/balanced-listeners */ // Not relevant since the document gets unloaded.
|
|
||||||
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
// Wrap in a block to prevent leaking to window scope.
|
|
||||||
(() => {
|
|
||||||
function sendMessageToBrowser(msgName, data) {
|
|
||||||
let { AutoCompleteParent } = ChromeUtils.importESModule(
|
|
||||||
"resource://gre/actors/AutoCompleteParent.sys.mjs"
|
|
||||||
);
|
|
||||||
|
|
||||||
let actor = AutoCompleteParent.getCurrentActor();
|
|
||||||
if (!actor) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
actor.manager.getActor("FormAutofill").sendAsyncMessage(msgName, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
class MozAutocompleteProfileListitemBase extends MozElements.MozRichlistitem {
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For form autofill, we want to unify the selection no matter by
|
|
||||||
* keyboard navigation or mouseover in order not to confuse user which
|
|
||||||
* profile preview is being shown. This field is set to true to indicate
|
|
||||||
* that selectedIndex of popup should be changed while mouseover item
|
|
||||||
*/
|
|
||||||
this.selectedByMouseOver = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
get _stringBundle() {
|
|
||||||
if (!this.__stringBundle) {
|
|
||||||
this.__stringBundle = Services.strings.createBundle(
|
|
||||||
"chrome://formautofill/locale/formautofill.properties"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return this.__stringBundle;
|
|
||||||
}
|
|
||||||
|
|
||||||
_cleanup() {
|
|
||||||
this.removeAttribute("formautofillattached");
|
|
||||||
if (this._itemBox) {
|
|
||||||
this._itemBox.removeAttribute("size");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_onOverflow() {}
|
|
||||||
|
|
||||||
_onUnderflow() {}
|
|
||||||
|
|
||||||
handleOverUnderflow() {}
|
|
||||||
|
|
||||||
_adjustAutofillItemLayout() {
|
|
||||||
let outerBoxRect = this.parentNode.getBoundingClientRect();
|
|
||||||
|
|
||||||
// Make item fit in popup as XUL box could not constrain
|
|
||||||
// item's width
|
|
||||||
this._itemBox.style.width = outerBoxRect.width + "px";
|
|
||||||
// Use two-lines layout when width is smaller than 150px or
|
|
||||||
// 185px if an image precedes the label.
|
|
||||||
let oneLineMinRequiredWidth = this.getAttribute("ac-image") ? 185 : 150;
|
|
||||||
|
|
||||||
if (outerBoxRect.width <= oneLineMinRequiredWidth) {
|
|
||||||
this._itemBox.setAttribute("size", "small");
|
|
||||||
} else {
|
|
||||||
this._itemBox.removeAttribute("size");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MozElements.MozAutocompleteProfileListitem = class MozAutocompleteProfileListitem extends (
|
|
||||||
MozAutocompleteProfileListitemBase
|
|
||||||
) {
|
|
||||||
static get markup() {
|
|
||||||
return `
|
|
||||||
<div xmlns="http://www.w3.org/1999/xhtml" class="autofill-item-box">
|
|
||||||
<div class="profile-label-col profile-item-col">
|
|
||||||
<span class="profile-label"></span>
|
|
||||||
</div>
|
|
||||||
<div class="profile-comment-col profile-item-col">
|
|
||||||
<span class="profile-comment"></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
if (this.delayConnectedCallback()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.textContent = "";
|
|
||||||
|
|
||||||
this.appendChild(this.constructor.fragment);
|
|
||||||
|
|
||||||
this._itemBox = this.querySelector(".autofill-item-box");
|
|
||||||
this._label = this.querySelector(".profile-label");
|
|
||||||
this._comment = this.querySelector(".profile-comment");
|
|
||||||
|
|
||||||
this.initializeAttributeInheritance();
|
|
||||||
this._adjustAcItem();
|
|
||||||
}
|
|
||||||
|
|
||||||
static get inheritedAttributes() {
|
|
||||||
return {
|
|
||||||
".autofill-item-box": "ac-image",
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
set selected(val) {
|
|
||||||
if (val) {
|
|
||||||
this.setAttribute("selected", "true");
|
|
||||||
} else {
|
|
||||||
this.removeAttribute("selected");
|
|
||||||
}
|
|
||||||
|
|
||||||
sendMessageToBrowser("FormAutofill:PreviewProfile");
|
|
||||||
}
|
|
||||||
|
|
||||||
get selected() {
|
|
||||||
return this.getAttribute("selected") == "true";
|
|
||||||
}
|
|
||||||
|
|
||||||
_adjustAcItem() {
|
|
||||||
this._adjustAutofillItemLayout();
|
|
||||||
this.setAttribute("formautofillattached", "true");
|
|
||||||
this._itemBox.style.setProperty(
|
|
||||||
"--primary-icon",
|
|
||||||
`url(${this.getAttribute("ac-image")})`
|
|
||||||
);
|
|
||||||
|
|
||||||
let { primary, secondary, ariaLabel } = JSON.parse(
|
|
||||||
this.getAttribute("ac-value")
|
|
||||||
);
|
|
||||||
|
|
||||||
this._label.textContent = primary.toString().replaceAll("*", "•");
|
|
||||||
this._comment.textContent = secondary.toString().replaceAll("*", "•");
|
|
||||||
if (ariaLabel) {
|
|
||||||
this.setAttribute("aria-label", ariaLabel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
customElements.define(
|
|
||||||
"autocomplete-profile-listitem",
|
|
||||||
MozElements.MozAutocompleteProfileListitem,
|
|
||||||
{ extends: "richlistitem" }
|
|
||||||
);
|
|
||||||
})();
|
|
@ -3,12 +3,12 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#PopupAutoComplete {
|
#PopupAutoComplete {
|
||||||
&[resultstyles~="autofill-profile"] {
|
&[resultstyles~="autofill"] {
|
||||||
min-width: 150px !important;
|
min-width: 150px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
> richlistbox > richlistitem {
|
> richlistbox > richlistitem {
|
||||||
&[originaltype="autofill-profile"] {
|
&[originaltype="autofill"] {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -18,17 +18,14 @@ FINAL_TARGET_FILES.features["formautofill@mozilla.org"] += [
|
|||||||
|
|
||||||
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk":
|
||||||
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
||||||
"skin/linux/autocomplete-item.css",
|
|
||||||
"skin/linux/editDialog.css",
|
"skin/linux/editDialog.css",
|
||||||
]
|
]
|
||||||
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
|
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "cocoa":
|
||||||
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
||||||
"skin/osx/autocomplete-item.css",
|
|
||||||
"skin/osx/editDialog.css",
|
"skin/osx/editDialog.css",
|
||||||
]
|
]
|
||||||
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
|
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
|
||||||
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
FINAL_TARGET_FILES.features["formautofill@mozilla.org"].chrome.content.skin += [
|
||||||
"skin/windows/autocomplete-item.css",
|
|
||||||
"skin/windows/editDialog.css",
|
"skin/windows/editDialog.css",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
@namespace url("http://www.w3.org/1999/xhtml");
|
|
||||||
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
--default-font-size: 14.25;
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
@namespace url("http://www.w3.org/1999/xhtml");
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
--default-font-size: 11;
|
|
||||||
}
|
|
@ -1,105 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
@namespace url("http://www.w3.org/1999/xhtml");
|
|
||||||
@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
|
||||||
|
|
||||||
|
|
||||||
xul|richlistitem[originaltype="autofill-profile"][selected="true"] > .autofill-item-box {
|
|
||||||
background-color: SelectedItem;
|
|
||||||
color: SelectedItemText;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
--item-padding-vertical: 7px;
|
|
||||||
--item-padding-horizontal: 10px;
|
|
||||||
--col-spacer: 7px;
|
|
||||||
--item-width: calc(50% - (var(--col-spacer) / 2));
|
|
||||||
--comment-text-color: GreyText;
|
|
||||||
|
|
||||||
--default-font-size: 12;
|
|
||||||
--label-font-size: 12;
|
|
||||||
--comment-font-size: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box[size="small"] {
|
|
||||||
--item-padding-vertical: 7px;
|
|
||||||
--col-spacer: 0px;
|
|
||||||
--row-spacer: 3px;
|
|
||||||
--item-width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box:not([ac-image=""]) {
|
|
||||||
--item-padding-vertical: 6.5px;
|
|
||||||
--comment-font-size: 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
box-sizing: border-box;
|
|
||||||
margin: 0;
|
|
||||||
border-bottom: 1px solid rgba(38,38,38,.15);
|
|
||||||
padding: var(--item-padding-vertical) 0;
|
|
||||||
padding-inline: var(--item-padding-horizontal);
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
background-color: Field;
|
|
||||||
color: FieldText;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box:last-child {
|
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box > .profile-item-col {
|
|
||||||
box-sizing: border-box;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: var(--item-width);
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box > .profile-label-col {
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box:not([ac-image=""]) > .profile-label-col::before {
|
|
||||||
margin-inline-end: 5px;
|
|
||||||
float: inline-start;
|
|
||||||
content: "";
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
background-image: var(--primary-icon);
|
|
||||||
background-size: contain;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: center;
|
|
||||||
-moz-context-properties: fill;
|
|
||||||
fill: var(--comment-text-color)
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box > .profile-label-col > .profile-label {
|
|
||||||
font-size: calc(var(--label-font-size) / var(--default-font-size) * 1em);
|
|
||||||
unicode-bidi: plaintext;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box > .profile-comment-col {
|
|
||||||
margin-inline-start: var(--col-spacer);
|
|
||||||
text-align: end;
|
|
||||||
color: var(--comment-text-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box > .profile-comment-col > .profile-comment {
|
|
||||||
font-size: calc(var(--comment-font-size) / var(--default-font-size) * 1em);
|
|
||||||
unicode-bidi: plaintext;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box[size="small"] {
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box[size="small"] > .profile-comment-col {
|
|
||||||
margin-top: var(--row-spacer);
|
|
||||||
text-align: start;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
@namespace url("http://www.w3.org/1999/xhtml");
|
|
||||||
@namespace xul url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
--default-font-size: 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (prefers-contrast) {
|
|
||||||
xul|richlistitem[originaltype="autofill-profile"][selected="true"] > .autofill-item-box {
|
|
||||||
background-color: SelectedItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.autofill-item-box {
|
|
||||||
--comment-text-color: GrayText;
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,22 +7,6 @@ add_task(async function setup_storage() {
|
|||||||
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
|
await setStorage(TEST_ADDRESS_1, TEST_ADDRESS_2, TEST_ADDRESS_3);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function reopenPopupWithResizedInput(browser, selector, newSize) {
|
|
||||||
await closePopup(browser);
|
|
||||||
/* eslint no-shadow: ["error", { "allow": ["selector", "newSize"] }] */
|
|
||||||
await SpecialPowers.spawn(
|
|
||||||
browser,
|
|
||||||
[{ selector, newSize }],
|
|
||||||
async function ({ selector, newSize }) {
|
|
||||||
const input = content.document.querySelector(selector);
|
|
||||||
|
|
||||||
input.style.boxSizing = "border-box";
|
|
||||||
input.style.width = newSize + "px";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
await openPopupOn(browser, selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
add_task(async function test_address_dropdown() {
|
add_task(async function test_address_dropdown() {
|
||||||
await BrowserTestUtils.withNewTab(
|
await BrowserTestUtils.withNewTab(
|
||||||
{ gBrowser, url: URL },
|
{ gBrowser, url: URL },
|
||||||
@ -33,20 +17,6 @@ add_task(async function test_address_dropdown() {
|
|||||||
|
|
||||||
is(firstItem.getAttribute("ac-image"), "", "Should not show icon");
|
is(firstItem.getAttribute("ac-image"), "", "Should not show icon");
|
||||||
|
|
||||||
// The breakpoint of two-lines layout is 150px
|
|
||||||
await reopenPopupWithResizedInput(browser, focusInput, 140);
|
|
||||||
is(
|
|
||||||
firstItem._itemBox.getAttribute("size"),
|
|
||||||
"small",
|
|
||||||
"Show two-lines layout"
|
|
||||||
);
|
|
||||||
await reopenPopupWithResizedInput(browser, focusInput, 160);
|
|
||||||
is(
|
|
||||||
firstItem._itemBox.hasAttribute("size"),
|
|
||||||
false,
|
|
||||||
"Show one-line layout"
|
|
||||||
);
|
|
||||||
|
|
||||||
await closePopup(browser);
|
await closePopup(browser);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -79,7 +79,7 @@ add_task(async function test_credit_card_dropdown_icon_invalid_types_select() {
|
|||||||
|
|
||||||
const creditCardItems = getDisplayedPopupItems(
|
const creditCardItems = getDisplayedPopupItems(
|
||||||
browser,
|
browser,
|
||||||
"[originaltype='autofill-profile']"
|
"[originaltype='autofill']"
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const [index, creditCardItem] of creditCardItems.entries()) {
|
for (const [index, creditCardItem] of creditCardItems.entries()) {
|
||||||
|
@ -55,21 +55,21 @@ add_task(async function test_insecure_form() {
|
|||||||
urlPath: TEST_URL_PATH,
|
urlPath: TEST_URL_PATH,
|
||||||
protocol: "https",
|
protocol: "https",
|
||||||
focusInput: "#organization",
|
focusInput: "#organization",
|
||||||
expectedType: "autofill-profile",
|
expectedType: "autofill",
|
||||||
expectedResultLength: 3, // add one for the status row
|
expectedResultLength: 3, // add one for the status row
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
urlPath: TEST_URL_PATH,
|
urlPath: TEST_URL_PATH,
|
||||||
protocol: "http",
|
protocol: "http",
|
||||||
focusInput: "#organization",
|
focusInput: "#organization",
|
||||||
expectedType: "autofill-profile",
|
expectedType: "autofill",
|
||||||
expectedResultLength: 3, // add one for the status row
|
expectedResultLength: 3, // add one for the status row
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
urlPath: TEST_URL_PATH_CC,
|
urlPath: TEST_URL_PATH_CC,
|
||||||
protocol: "https",
|
protocol: "https",
|
||||||
focusInput: "#cc-name",
|
focusInput: "#cc-name",
|
||||||
expectedType: "autofill-profile",
|
expectedType: "autofill",
|
||||||
expectedResultLength: 3, // no status row here
|
expectedResultLength: 3, // no status row here
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -59,6 +59,11 @@ async function setupFormHistory() {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceStars(str)
|
||||||
|
{
|
||||||
|
return str.replaceAll("*", "•")
|
||||||
|
}
|
||||||
|
|
||||||
initPopupListener();
|
initPopupListener();
|
||||||
|
|
||||||
// Form with history only.
|
// Form with history only.
|
||||||
@ -86,7 +91,7 @@ add_task(async function all_saved_fields_less_than_threshold() {
|
|||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
checkMenuEntries([reducedMockRecord].map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries([reducedMockRecord].map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-name"],
|
primary: cc["cc-name"],
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `Visa ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `Visa ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -102,8 +107,8 @@ add_task(async function check_menu_when_both_existed() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc.ccNumberFmt,
|
primary: replaceStars(cc.ccNumberFmt),
|
||||||
secondary: cc["cc-name"],
|
secondary: cc["cc-name"].toString(),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -112,8 +117,8 @@ add_task(async function check_menu_when_both_existed() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-name"],
|
primary: cc["cc-name"].toString(),
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -122,8 +127,8 @@ add_task(async function check_menu_when_both_existed() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-exp-year"],
|
primary: cc["cc-exp-year"].toString(),
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -132,8 +137,8 @@ add_task(async function check_menu_when_both_existed() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-exp-month"],
|
primary: cc["cc-exp-month"].toString(),
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-month"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-month"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -185,8 +190,8 @@ add_task(async function check_fields_after_form_autofill() {
|
|||||||
// The popup doesn't auto-show on focus because the field isn't empty
|
// The popup doesn't auto-show on focus because the field isn't empty
|
||||||
await expectPopup();
|
await expectPopup();
|
||||||
checkMenuEntries(MOCK_STORAGE.slice(1).map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.slice(1).map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-exp-year"],
|
primary: cc["cc-exp-year"].toString(),
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-exp-year"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -220,7 +225,7 @@ add_task(async function check_cc_popup_on_field_blank() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-name"],
|
primary: cc["cc-name"],
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
@ -240,7 +245,7 @@ add_task(async function check_form_autofill_resume() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-name"],
|
primary: cc["cc-name"],
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
|
@ -49,6 +49,11 @@ async function setupFormHistory() {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function replaceStars(str)
|
||||||
|
{
|
||||||
|
return str.replaceAll("*", "•")
|
||||||
|
}
|
||||||
|
|
||||||
initPopupListener();
|
initPopupListener();
|
||||||
|
|
||||||
// Show Form History popup for non-autocomplete="off" field only
|
// Show Form History popup for non-autocomplete="off" field only
|
||||||
@ -73,7 +78,7 @@ add_task(async function check_menu_when_both_with_autocomplete_off() {
|
|||||||
synthesizeKey("KEY_ArrowDown");
|
synthesizeKey("KEY_ArrowDown");
|
||||||
await expectPopup();
|
await expectPopup();
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc.ccNumberFmt,
|
primary: replaceStars(cc.ccNumberFmt),
|
||||||
secondary: cc["cc-name"],
|
secondary: cc["cc-name"],
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc.ccNumberFmt.replaceAll("*", "")} ${cc["cc-name"]}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
@ -84,7 +89,7 @@ add_task(async function check_menu_when_both_with_autocomplete_off() {
|
|||||||
await expectPopup();
|
await expectPopup();
|
||||||
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
checkMenuEntries(MOCK_STORAGE.map(patchRecordCCNumber).map(({ cc, expected }) => JSON.stringify({
|
||||||
primary: cc["cc-name"],
|
primary: cc["cc-name"],
|
||||||
secondary: cc.ccNumberFmt,
|
secondary: replaceStars(cc.ccNumberFmt),
|
||||||
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
ariaLabel: `${getCCTypeName(cc)} ${cc["cc-name"]} ${cc.ccNumberFmt}`,
|
||||||
image: expected.image,
|
image: expected.image,
|
||||||
})));
|
})));
|
||||||
|
@ -65,7 +65,7 @@ let addressTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "Sesame Street",
|
primary: "Sesame Street",
|
||||||
@ -76,7 +76,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "Mozilla",
|
primary: "Mozilla",
|
||||||
@ -101,7 +101,7 @@ let addressTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "1-345-345-3456.",
|
primary: "1-345-345-3456.",
|
||||||
@ -112,7 +112,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "1-650-903-0800",
|
primary: "1-650-903-0800",
|
||||||
@ -123,7 +123,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[2]),
|
comment: JSON.stringify(matchingProfiles[2]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "1-000-000-0000",
|
primary: "1-000-000-0000",
|
||||||
@ -148,7 +148,7 @@ let addressTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "123 Sesame Street.",
|
primary: "123 Sesame Street.",
|
||||||
@ -159,7 +159,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "331 E. Evelyn Avenue",
|
primary: "331 E. Evelyn Avenue",
|
||||||
@ -170,7 +170,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[2]),
|
comment: JSON.stringify(matchingProfiles[2]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "321, No Name St. 2nd line 3rd line",
|
primary: "321, No Name St. 2nd line 3rd line",
|
||||||
@ -195,7 +195,7 @@ let addressTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "123 Sesame Street.",
|
primary: "123 Sesame Street.",
|
||||||
@ -206,7 +206,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "331 E. Evelyn Avenue",
|
primary: "331 E. Evelyn Avenue",
|
||||||
@ -217,7 +217,7 @@ let addressTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[2]),
|
comment: JSON.stringify(matchingProfiles[2]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "321, No Name St.",
|
primary: "321, No Name St.",
|
||||||
@ -298,11 +298,11 @@ let creditCardTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "Timothy Berners-Lee",
|
primary: "Timothy Berners-Lee",
|
||||||
secondary: "****6785",
|
secondary: "••••6785",
|
||||||
ariaLabel: "Visa Timothy Berners-Lee ****6785",
|
ariaLabel: "Visa Timothy Berners-Lee ****6785",
|
||||||
image: "chrome://formautofill/content/third-party/cc-logo-visa.svg",
|
image: "chrome://formautofill/content/third-party/cc-logo-visa.svg",
|
||||||
}),
|
}),
|
||||||
@ -310,11 +310,11 @@ let creditCardTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "John Doe",
|
primary: "John Doe",
|
||||||
secondary: "****1234",
|
secondary: "••••1234",
|
||||||
ariaLabel: "American Express John Doe ****1234",
|
ariaLabel: "American Express John Doe ****1234",
|
||||||
image: "chrome://formautofill/content/third-party/cc-logo-amex.png",
|
image: "chrome://formautofill/content/third-party/cc-logo-amex.png",
|
||||||
}),
|
}),
|
||||||
@ -336,10 +336,10 @@ let creditCardTestCases = [
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[0]),
|
comment: JSON.stringify(matchingProfiles[0]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "****6785",
|
primary: "••••6785",
|
||||||
secondary: "Timothy Berners-Lee",
|
secondary: "Timothy Berners-Lee",
|
||||||
ariaLabel: "Visa 6785 Timothy Berners-Lee",
|
ariaLabel: "Visa 6785 Timothy Berners-Lee",
|
||||||
image: "chrome://formautofill/content/third-party/cc-logo-visa.svg",
|
image: "chrome://formautofill/content/third-party/cc-logo-visa.svg",
|
||||||
@ -348,10 +348,10 @@ let creditCardTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[1]),
|
comment: JSON.stringify(matchingProfiles[1]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "****1234",
|
primary: "••••1234",
|
||||||
secondary: "John Doe",
|
secondary: "John Doe",
|
||||||
ariaLabel: "American Express 1234 John Doe",
|
ariaLabel: "American Express 1234 John Doe",
|
||||||
image: "chrome://formautofill/content/third-party/cc-logo-amex.png",
|
image: "chrome://formautofill/content/third-party/cc-logo-amex.png",
|
||||||
@ -360,10 +360,10 @@ let creditCardTestCases = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: "",
|
value: "",
|
||||||
style: "autofill-profile",
|
style: "autofill",
|
||||||
comment: JSON.stringify(matchingProfiles[2]),
|
comment: JSON.stringify(matchingProfiles[2]),
|
||||||
label: JSON.stringify({
|
label: JSON.stringify({
|
||||||
primary: "****5678",
|
primary: "••••5678",
|
||||||
secondary: "",
|
secondary: "",
|
||||||
ariaLabel: "5678",
|
ariaLabel: "5678",
|
||||||
image: "chrome://formautofill/content/icon-credit-card-generic.svg",
|
image: "chrome://formautofill/content/icon-credit-card-generic.svg",
|
||||||
|
@ -178,6 +178,13 @@
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[originaltype="autofill"] > .two-line-wrapper > .ac-site-icon {
|
||||||
|
width: auto;
|
||||||
|
min-height: 16px;
|
||||||
|
max-width: none; /* reset max-width so that credit card icons don't appear stretched */
|
||||||
|
max-height: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Insecure field warning */
|
/* Insecure field warning */
|
||||||
&[originaltype="insecureWarning"] {
|
&[originaltype="insecureWarning"] {
|
||||||
background-color: var(--arrowpanel-dimmed);
|
background-color: var(--arrowpanel-dimmed);
|
||||||
|
@ -609,7 +609,7 @@ export const GeckoViewAutocomplete = {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "autofill-profile": {
|
case "autofill": {
|
||||||
const comment = JSON.parse(option.comment);
|
const comment = JSON.parse(option.comment);
|
||||||
debug`delegateSelection ${comment}`;
|
debug`delegateSelection ${comment}`;
|
||||||
const creditCard = CreditCard.fromGecko(comment);
|
const creditCard = CreditCard.fromGecko(comment);
|
||||||
|
@ -247,7 +247,7 @@ export class AutoCompleteParent extends JSWindowActorParent {
|
|||||||
// the scrollbar in login or form autofill popups.
|
// the scrollbar in login or form autofill popups.
|
||||||
if (
|
if (
|
||||||
resultStyles.size &&
|
resultStyles.size &&
|
||||||
(resultStyles.has("autofill-profile") || resultStyles.has("loginsFooter"))
|
(resultStyles.has("autofill") || resultStyles.has("loginsFooter"))
|
||||||
) {
|
) {
|
||||||
this.openedPopup._normalMaxRows = this.openedPopup.maxRows;
|
this.openedPopup._normalMaxRows = this.openedPopup.maxRows;
|
||||||
this.openedPopup.mInput.maxRows = 10;
|
this.openedPopup.mInput.maxRows = 10;
|
||||||
|
@ -422,8 +422,7 @@ export const ProfileAutocomplete = {
|
|||||||
if (
|
if (
|
||||||
selectedIndex == -1 ||
|
selectedIndex == -1 ||
|
||||||
!this.lastProfileAutoCompleteResult ||
|
!this.lastProfileAutoCompleteResult ||
|
||||||
this.lastProfileAutoCompleteResult.getStyleAt(selectedIndex) !=
|
this.lastProfileAutoCompleteResult.getStyleAt(selectedIndex) != "autofill"
|
||||||
"autofill-profile"
|
|
||||||
) {
|
) {
|
||||||
await this.sendFillRequestToFormAutofillParent(focusedInput, comment);
|
await this.sendFillRequestToFormAutofillParent(focusedInput, comment);
|
||||||
return;
|
return;
|
||||||
@ -456,8 +455,7 @@ export const ProfileAutocomplete = {
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!this.lastProfileAutoCompleteResult ||
|
!this.lastProfileAutoCompleteResult ||
|
||||||
this.lastProfileAutoCompleteResult.getStyleAt(selectedIndex) !=
|
this.lastProfileAutoCompleteResult.getStyleAt(selectedIndex) != "autofill"
|
||||||
"autofill-profile"
|
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -478,11 +478,9 @@ export class FormAutofillChild extends JSWindowActorChild {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const doc = this.document;
|
|
||||||
|
|
||||||
switch (message.name) {
|
switch (message.name) {
|
||||||
case "FormAutofill:PreviewProfile": {
|
case "FormAutofill:PreviewProfile": {
|
||||||
this.previewProfile(doc);
|
this.previewProfile(message.data.selectedIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "FormAutofill:ClearForm": {
|
case "FormAutofill:ClearForm": {
|
||||||
@ -658,9 +656,7 @@ export class FormAutofillChild extends JSWindowActorChild {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
previewProfile(doc) {
|
previewProfile(selectedIndex) {
|
||||||
let docWin = doc.ownerGlobal;
|
|
||||||
let selectedIndex = lazy.ProfileAutocomplete._getSelectedIndex(docWin);
|
|
||||||
let lastAutoCompleteResult =
|
let lastAutoCompleteResult =
|
||||||
lazy.ProfileAutocomplete.lastProfileAutoCompleteResult;
|
lazy.ProfileAutocomplete.lastProfileAutoCompleteResult;
|
||||||
let focusedInput = this.activeInput;
|
let focusedInput = this.activeInput;
|
||||||
@ -669,7 +665,7 @@ export class FormAutofillChild extends JSWindowActorChild {
|
|||||||
selectedIndex === -1 ||
|
selectedIndex === -1 ||
|
||||||
!focusedInput ||
|
!focusedInput ||
|
||||||
!lastAutoCompleteResult ||
|
!lastAutoCompleteResult ||
|
||||||
lastAutoCompleteResult.getStyleAt(selectedIndex) != "autofill-profile"
|
lastAutoCompleteResult.getStyleAt(selectedIndex) != "autofill"
|
||||||
) {
|
) {
|
||||||
lazy.ProfileAutocomplete._clearProfilePreview();
|
lazy.ProfileAutocomplete._clearProfilePreview();
|
||||||
} else {
|
} else {
|
||||||
|
@ -84,21 +84,6 @@ export let FormAutofillStatus = {
|
|||||||
Services.prefs.addObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
|
Services.prefs.addObserver(ENABLED_AUTOFILL_CREDITCARDS_PREF, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have to use empty window type to get all opened windows here because the
|
|
||||||
// window type parameter may not be available during startup.
|
|
||||||
for (let win of Services.wm.getEnumerator("")) {
|
|
||||||
let { documentElement } = win.document;
|
|
||||||
if (documentElement?.getAttribute("windowtype") == "navigator:browser") {
|
|
||||||
this.injectElements(win.document);
|
|
||||||
} else {
|
|
||||||
// Manually call onOpenWindow for windows that are already opened but not
|
|
||||||
// yet have the window type set. This ensures we inject the elements we need
|
|
||||||
// when its docuemnt is ready.
|
|
||||||
this.onOpenWindow(win);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Services.wm.addListener(this);
|
|
||||||
|
|
||||||
Services.telemetry.setEventRecordingEnabled("creditcard", true);
|
Services.telemetry.setEventRecordingEnabled("creditcard", true);
|
||||||
Services.telemetry.setEventRecordingEnabled("address", true);
|
Services.telemetry.setEventRecordingEnabled("address", true);
|
||||||
},
|
},
|
||||||
@ -198,31 +183,6 @@ export let FormAutofillStatus = {
|
|||||||
this.updateStatus();
|
this.updateStatus();
|
||||||
},
|
},
|
||||||
|
|
||||||
injectElements(doc) {
|
|
||||||
Services.scriptloader.loadSubScript(
|
|
||||||
"chrome://formautofill/content/customElements.js",
|
|
||||||
doc.ownerGlobal
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
onOpenWindow(xulWindow) {
|
|
||||||
const win = xulWindow.docShell.domWindow;
|
|
||||||
win.addEventListener(
|
|
||||||
"load",
|
|
||||||
() => {
|
|
||||||
if (
|
|
||||||
win.document.documentElement.getAttribute("windowtype") ==
|
|
||||||
"navigator:browser"
|
|
||||||
) {
|
|
||||||
this.injectElements(win.document);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ once: true }
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
onCloseWindow() {},
|
|
||||||
|
|
||||||
async observe(subject, topic, data) {
|
async observe(subject, topic, data) {
|
||||||
lazy.log.debug("observe:", topic, "with data:", data);
|
lazy.log.debug("observe:", topic, "with data:", data);
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
|
@ -181,7 +181,7 @@ class ProfileAutoCompleteResult {
|
|||||||
case "insecure":
|
case "insecure":
|
||||||
return "insecureWarning";
|
return "insecureWarning";
|
||||||
default:
|
default:
|
||||||
return "autofill-profile";
|
return "autofill";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -541,8 +541,8 @@ export class CreditCardResult extends ProfileAutoCompleteResult {
|
|||||||
.filter(chunk => !!chunk) // Exclude empty chunks.
|
.filter(chunk => !!chunk) // Exclude empty chunks.
|
||||||
.join(" ");
|
.join(" ");
|
||||||
return {
|
return {
|
||||||
primary,
|
primary: primary.toString().replaceAll("*", "•"),
|
||||||
secondary,
|
secondary: secondary.toString().replaceAll("*", "•"),
|
||||||
ariaLabel,
|
ariaLabel,
|
||||||
image,
|
image,
|
||||||
};
|
};
|
||||||
|
@ -411,7 +411,7 @@
|
|||||||
// The styles on the list which have different <content> structure and overrided
|
// The styles on the list which have different <content> structure and overrided
|
||||||
// _adjustAcItem() are unreusable.
|
// _adjustAcItem() are unreusable.
|
||||||
const UNREUSEABLE_STYLES = [
|
const UNREUSEABLE_STYLES = [
|
||||||
"autofill-profile",
|
"autofill",
|
||||||
"action",
|
"action",
|
||||||
"status",
|
"status",
|
||||||
"generatedPassword",
|
"generatedPassword",
|
||||||
@ -436,8 +436,8 @@
|
|||||||
if (!reusable) {
|
if (!reusable) {
|
||||||
let options = null;
|
let options = null;
|
||||||
switch (style) {
|
switch (style) {
|
||||||
case "autofill-profile":
|
case "autofill":
|
||||||
options = { is: "autocomplete-profile-listitem" };
|
options = { is: "autocomplete-autofill-richlistitem" };
|
||||||
break;
|
break;
|
||||||
case "action":
|
case "action":
|
||||||
options = { is: "autocomplete-action-richlistitem" };
|
options = { is: "autocomplete-action-richlistitem" };
|
||||||
|
@ -725,6 +725,11 @@
|
|||||||
// and, optionally a secondary label, for example:
|
// and, optionally a secondary label, for example:
|
||||||
// { "fillMessageName": "Fill:Clear", secondary: "Second Label" }
|
// { "fillMessageName": "Fill:Clear", secondary: "Second Label" }
|
||||||
class MozAutocompleteActionRichlistitem extends MozAutocompleteTwoLineRichlistitem {
|
class MozAutocompleteActionRichlistitem extends MozAutocompleteTwoLineRichlistitem {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.selectedByMouseOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
_adjustAcItem() {
|
_adjustAcItem() {
|
||||||
super._adjustAcItem();
|
super._adjustAcItem();
|
||||||
|
|
||||||
@ -782,6 +787,58 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class MozAutocompleteAutoFillRichlistitem extends MozAutocompleteTwoLineRichlistitem {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.selectedByMouseOver = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_adjustAcItem() {
|
||||||
|
let { primary, secondary, ariaLabel } = JSON.parse(
|
||||||
|
this.getAttribute("ac-value")
|
||||||
|
);
|
||||||
|
|
||||||
|
let line1Label = this.querySelector(".line1-label");
|
||||||
|
line1Label.textContent = primary.toString();
|
||||||
|
|
||||||
|
let line2Label = this.querySelector(".line2-label");
|
||||||
|
line2Label.textContent = secondary.toString();
|
||||||
|
|
||||||
|
if (ariaLabel) {
|
||||||
|
this.setAttribute("aria-label", ariaLabel);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.querySelector(".ac-site-icon").collapsed =
|
||||||
|
this.getAttribute("ac-image") == "";
|
||||||
|
}
|
||||||
|
|
||||||
|
set selected(val) {
|
||||||
|
if (val) {
|
||||||
|
this.setAttribute("selected", "true");
|
||||||
|
} else {
|
||||||
|
this.removeAttribute("selected");
|
||||||
|
}
|
||||||
|
|
||||||
|
let { AutoCompleteParent } = ChromeUtils.importESModule(
|
||||||
|
"resource://gre/actors/AutoCompleteParent.sys.mjs"
|
||||||
|
);
|
||||||
|
|
||||||
|
let actor = AutoCompleteParent.getCurrentActor();
|
||||||
|
if (!actor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let selectedIndex = val ? this.control.getIndexOfItem(this) : -1;
|
||||||
|
actor.manager
|
||||||
|
.getActor("FormAutofill")
|
||||||
|
.sendAsyncMessage("FormAutofill:PreviewProfile", { selectedIndex });
|
||||||
|
}
|
||||||
|
|
||||||
|
get selected() {
|
||||||
|
return this.getAttribute("selected") == "true";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class MozAutocompleteGeneratedPasswordRichlistitem extends MozAutocompleteTwoLineRichlistitem {
|
class MozAutocompleteGeneratedPasswordRichlistitem extends MozAutocompleteTwoLineRichlistitem {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -906,6 +963,14 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
customElements.define(
|
||||||
|
"autocomplete-autofill-richlistitem",
|
||||||
|
MozAutocompleteAutoFillRichlistitem,
|
||||||
|
{
|
||||||
|
extends: "richlistitem",
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
customElements.define(
|
customElements.define(
|
||||||
"autocomplete-login-richlistitem",
|
"autocomplete-login-richlistitem",
|
||||||
MozAutocompleteLoginRichlistitem,
|
MozAutocompleteLoginRichlistitem,
|
||||||
|
Loading…
Reference in New Issue
Block a user