Bug 1399356: Delay input to autofill popup r=zbraniecki,MattN

Differential Revision: https://phabricator.services.mozilla.com/D79775
This commit is contained in:
Adam Roach [:abr] 2020-06-26 00:36:57 +00:00
Родитель 8ce6deaff2
Коммит b3e0a05bb9
3 изменённых файлов: 43 добавлений и 1 удалений

Просмотреть файл

@ -30,6 +30,10 @@
min-width: 200px !important;
}
#PopupAutoComplete > richlistbox > richlistitem[disabled="true"] {
opacity: 0.5;
}
/* Form Autofill Doorhanger */
#autofill-address-notification popupnotificationcontent > .desc-message-box,
#autofill-credit-card-notification popupnotificationcontent > .desc-message-box {

Просмотреть файл

@ -23,6 +23,14 @@ XPCOMUtils.defineLazyPreferenceGetter(
false
);
ChromeUtils.defineModuleGetter(
this,
"setTimeout",
"resource://gre/modules/Timer.jsm"
);
const PREF_SECURITY_DELAY = "security.notification_enable_delay";
// Stores the browser and actor that has the active popup, used by formfill
let currentBrowserWeakRef = null;
let currentActor = null;
@ -413,6 +421,7 @@ class AutoCompleteParent extends JSWindowActorParent {
this.showPopupWithResults({ results, rect, dir });
this.notifyListeners();
}
this.delayPopupInput();
break;
}
@ -441,6 +450,25 @@ class AutoCompleteParent extends JSWindowActorParent {
return false;
}
// Imposes a brief period during which the popup will not respond to
// a click, so as to reduce the chances of a successful clickjacking
// attempt
delayPopupInput() {
if (!this.openedPopup) {
return;
}
const popupDelay = Services.prefs.getIntPref(PREF_SECURITY_DELAY);
const items = Array.from(
this.openedPopup.getElementsByTagName("richlistitem")
);
items.forEach(item => (item.disabled = true));
setTimeout(
() => items.forEach(item => (item.disabled = false)),
popupDelay
);
}
notifyListeners() {
let window = this.browsingContext.top.embedderElement.ownerGlobal;
for (let listener of autoCompleteListeners) {

Просмотреть файл

@ -15,6 +15,7 @@
this.mInput = null;
this.mPopupOpen = false;
this._currentIndex = 0;
this._disabledItemClicked = false;
this.setListeners();
}
@ -59,16 +60,23 @@
}
switch (event.type) {
case "mousedown":
this._disabledItemClicked = !!event.target.closest(
"richlistitem"
)?.disabled;
break;
case "mouseup":
// Don't call onPopupClick for the scrollbar buttons, thumb,
// slider, etc. If we hit the richlistbox and not a
// richlistitem, we ignore the event.
if (
event.target.closest("richlistbox,richlistitem").localName ==
"richlistitem"
"richlistitem" &&
!this._disabledItemClicked
) {
this.onPopupClick(event);
}
this._disabledItemClicked = false;
break;
case "mousemove":
if (Date.now() - this.mLastMoveTime <= 30) {
@ -97,6 +105,7 @@
},
};
}
this.richlistbox.addEventListener("mousedown", this.listEvents);
this.richlistbox.addEventListener("mouseup", this.listEvents);
this.richlistbox.addEventListener("mousemove", this.listEvents);
}
@ -535,6 +544,7 @@
disconnectedCallback() {
if (this.listEvents) {
this.richlistbox.removeEventListener("mousedown", this.listEvents);
this.richlistbox.removeEventListener("mouseup", this.listEvents);
this.richlistbox.removeEventListener("mousemove", this.listEvents);
delete this.listEvents;