mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Backed out changeset fcd3e501bdac (bug 1828477) for causing gv-junit failures. CLOSED TREE
This commit is contained in:
parent
4b96f8c849
commit
dbc5b34a3f
@ -136,6 +136,21 @@
|
||||
noautofocus="true"
|
||||
hidden="true" />
|
||||
|
||||
<html:template id="dateTimePickerTemplate">
|
||||
<!-- for date/time picker. consumeoutsideclicks is set to never, so that
|
||||
clicks on the anchored input box are never consumed. -->
|
||||
<panel id="DateTimePickerPanel"
|
||||
type="arrow"
|
||||
orient="vertical"
|
||||
ignorekeys="true"
|
||||
norolluponanchor="true"
|
||||
noautofocus="true"
|
||||
consumeoutsideclicks="never"
|
||||
level="parent"
|
||||
tabspecific="true">
|
||||
</panel>
|
||||
</html:template>
|
||||
|
||||
<html:template id="printPreviewStackTemplate">
|
||||
<stack class="previewStack" rendering="true" flex="1" previewtype="primary">
|
||||
<vbox class="previewRendering" flex="1">
|
||||
|
@ -172,6 +172,8 @@
|
||||
|
||||
arrowKeysShouldWrap: AppConstants == "macosx",
|
||||
|
||||
_dateTimePicker: null,
|
||||
|
||||
_previewMode: false,
|
||||
|
||||
_lastFindValue: "",
|
||||
@ -804,6 +806,16 @@
|
||||
}
|
||||
},
|
||||
|
||||
_getAndMaybeCreateDateTimePickerPanel() {
|
||||
if (!this._dateTimePicker) {
|
||||
let wrapper = document.getElementById("dateTimePickerTemplate");
|
||||
wrapper.replaceWith(wrapper.content);
|
||||
this._dateTimePicker = document.getElementById("DateTimePickerPanel");
|
||||
}
|
||||
|
||||
return this._dateTimePicker;
|
||||
},
|
||||
|
||||
syncThrobberAnimations(aTab) {
|
||||
aTab.ownerGlobal.promiseDocumentFlushed(() => {
|
||||
if (!aTab.container) {
|
||||
|
@ -1412,87 +1412,6 @@ export var BrowserTestUtils = {
|
||||
return menulist.menupopup;
|
||||
},
|
||||
|
||||
/**
|
||||
* Waits for the datetime picker popup to be shown.
|
||||
*
|
||||
* @param {Window} win
|
||||
* A window to expect the popup in.
|
||||
*
|
||||
* @return {Promise}
|
||||
* Resolves when the popup has been fully opened. The resolution value
|
||||
* is the select popup.
|
||||
*/
|
||||
async waitForDateTimePickerPanelShown(win) {
|
||||
let getPanel = () => win.document.getElementById("DateTimePickerPanel");
|
||||
let panel = getPanel();
|
||||
let ensureReady = async () => {
|
||||
let frame = panel.querySelector("#dateTimePopupFrame");
|
||||
let isValidUrl = () => {
|
||||
return (
|
||||
frame.browsingContext?.currentURI?.spec ==
|
||||
"chrome://global/content/datepicker.xhtml" ||
|
||||
frame.browsingContext?.currentURI?.spec ==
|
||||
"chrome://global/content/timepicker.xhtml"
|
||||
);
|
||||
};
|
||||
|
||||
// Ensure it's loaded.
|
||||
if (!isValidUrl() || frame.contentDocument.readyState != "complete") {
|
||||
await new Promise(resolve => {
|
||||
frame.addEventListener(
|
||||
"load",
|
||||
function listener() {
|
||||
if (isValidUrl()) {
|
||||
frame.removeEventListener("load", listener, { capture: true });
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
{ capture: true }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Ensure it's ready.
|
||||
if (!frame.contentWindow.PICKER_READY) {
|
||||
await new Promise(resolve => {
|
||||
frame.contentDocument.addEventListener("PickerReady", resolve, {
|
||||
once: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
// And that l10n mutations are flushed.
|
||||
// FIXME(bug 1828721): We should ideally localize everything before
|
||||
// showing the panel.
|
||||
if (frame.contentDocument.hasPendingL10nMutations) {
|
||||
await new Promise(resolve => {
|
||||
frame.contentDocument.addEventListener(
|
||||
"L10nMutationsFinished",
|
||||
resolve,
|
||||
{
|
||||
once: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (!panel) {
|
||||
await this.waitForMutationCondition(
|
||||
win.document,
|
||||
{ childList: true, subtree: true },
|
||||
getPanel
|
||||
);
|
||||
panel = getPanel();
|
||||
if (panel.state == "open") {
|
||||
await ensureReady();
|
||||
return panel;
|
||||
}
|
||||
}
|
||||
await this.waitForEvent(panel, "popupshown");
|
||||
await ensureReady();
|
||||
return panel;
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds a content event listener on the given browser
|
||||
* element. Similar to waitForContentEvent, but the listener will
|
||||
|
@ -25,13 +25,16 @@ export class DateTimePickerParent extends JSWindowActorParent {
|
||||
debug("receiveMessage: " + aMessage.name);
|
||||
switch (aMessage.name) {
|
||||
case "FormDateTime:OpenPicker": {
|
||||
this.showPicker(aMessage.data);
|
||||
let topBrowsingContext = this.manager.browsingContext.top;
|
||||
let browser = topBrowsingContext.embedderElement;
|
||||
this.showPicker(browser, aMessage.data);
|
||||
break;
|
||||
}
|
||||
case "FormDateTime:ClosePicker": {
|
||||
if (!this._picker) {
|
||||
return;
|
||||
}
|
||||
this._picker.closePicker();
|
||||
this.close();
|
||||
break;
|
||||
}
|
||||
@ -60,6 +63,7 @@ export class DateTimePickerParent extends JSWindowActorParent {
|
||||
}
|
||||
case "popuphidden": {
|
||||
this.sendAsyncMessage("FormDateTime:PickerClosed", {});
|
||||
this._picker.closePicker();
|
||||
this.close();
|
||||
break;
|
||||
}
|
||||
@ -69,62 +73,45 @@ export class DateTimePickerParent extends JSWindowActorParent {
|
||||
}
|
||||
|
||||
// Get picker from browser and show it anchored to the input box.
|
||||
showPicker(aData) {
|
||||
showPicker(aBrowser, aData) {
|
||||
let rect = aData.rect;
|
||||
let type = aData.type;
|
||||
let detail = aData.detail;
|
||||
|
||||
debug("Opening picker with details: " + JSON.stringify(detail));
|
||||
let topBC = this.browsingContext.top;
|
||||
let window = topBC.topChromeWindow;
|
||||
if (Services.focus.activeWindow != window) {
|
||||
debug("Not in the active window");
|
||||
|
||||
let window = aBrowser.ownerGlobal;
|
||||
let tabbrowser = window.gBrowser;
|
||||
if (!tabbrowser) {
|
||||
// TODO(bug 1828477): Support non-<tabbrowser> windows
|
||||
debug("no tabbrowser, exiting now.");
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
let browser = topBC.embedderElement;
|
||||
if (
|
||||
browser &&
|
||||
browser.ownerGlobal.gBrowser &&
|
||||
browser.ownerGlobal.gBrowser.selectedBrowser != browser
|
||||
Services.focus.activeWindow != window ||
|
||||
tabbrowser.selectedBrowser != aBrowser
|
||||
) {
|
||||
debug("In background tab");
|
||||
// We were sent a message from a window or tab that went into the
|
||||
// background, so we'll ignore it for now.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let doc = window.document;
|
||||
let panel = doc.getElementById("DateTimePickerPanel");
|
||||
if (!panel) {
|
||||
panel = doc.createXULElement("panel");
|
||||
panel.id = "DateTimePickerPanel";
|
||||
panel.setAttribute("type", "arrow");
|
||||
panel.setAttribute("orient", "vertical");
|
||||
panel.setAttribute("ignorekeys", "true");
|
||||
panel.setAttribute("noautofocus", "true");
|
||||
// This ensures that clicks on the anchored input box are never consumed.
|
||||
panel.setAttribute("consumeoutsideclicks", "never");
|
||||
panel.setAttribute("level", "parent");
|
||||
panel.setAttribute("tabspecific", "true");
|
||||
let container =
|
||||
doc.getElementById("mainPopupSet") ||
|
||||
doc.querySelector("popupset") ||
|
||||
doc.documentElement.appendChild(doc.createXULElement("popupset"));
|
||||
container.appendChild(panel);
|
||||
}
|
||||
this._oldFocus = doc.activeElement;
|
||||
let panel = tabbrowser._getAndMaybeCreateDateTimePickerPanel();
|
||||
this.oldFocus = window.document.activeElement;
|
||||
this._picker = new lazy.DateTimePickerPanel(panel);
|
||||
this._picker.openPicker(type, rect, detail);
|
||||
|
||||
this.addPickerListeners();
|
||||
}
|
||||
|
||||
// Close the picker and do some cleanup.
|
||||
// Picker is closed, do some cleanup.
|
||||
close() {
|
||||
this._picker.closePicker();
|
||||
if (this.oldFocus) {
|
||||
// Restore focus to where it was before the picker opened.
|
||||
this._oldFocus?.focus();
|
||||
this._oldFocus = null;
|
||||
this.oldFocus.focus();
|
||||
this.oldFocus = null;
|
||||
}
|
||||
this.removePickerListeners();
|
||||
this._picker = null;
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ skip-if =
|
||||
os == "linux" && fission && socketprocess_networking && !debug # high frequency intermittent, Bug 1673140
|
||||
[browser_datetime_showPicker.js]
|
||||
# do not skip
|
||||
[browser_datetime_toplevel.js]
|
||||
[browser_spinner.js]
|
||||
skip-if =
|
||||
tsan # Frequently times out on TSan
|
||||
|
@ -1,27 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* https://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
add_task(async function() {
|
||||
let input = document.createElement("input");
|
||||
input.type = "date";
|
||||
registerCleanupFunction(() => input.remove());
|
||||
document.body.appendChild(input);
|
||||
|
||||
let shown = BrowserTestUtils.waitForDateTimePickerPanelShown(window);
|
||||
|
||||
const shadowRoot = SpecialPowers.wrap(input).openOrClosedShadowRoot;
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(
|
||||
shadowRoot.getElementById("calendar-button"),
|
||||
{}
|
||||
);
|
||||
|
||||
let popup = await shown;
|
||||
ok(!!popup, "Should've shown the popup");
|
||||
|
||||
let hidden = BrowserTestUtils.waitForPopupEvent(popup, "hidden");
|
||||
popup.hidePopup();
|
||||
|
||||
await hidden;
|
||||
popup.remove();
|
||||
});
|
@ -9,7 +9,8 @@
|
||||
*/
|
||||
class DateTimeTestHelper {
|
||||
constructor() {
|
||||
this.panel = null;
|
||||
this.panel = gBrowser._getAndMaybeCreateDateTimePickerPanel();
|
||||
this.panel.setAttribute("animate", false);
|
||||
this.tab = null;
|
||||
this.frame = null;
|
||||
}
|
||||
@ -39,8 +40,6 @@ class DateTimeTestHelper {
|
||||
await SpecialPowers.contentTransformsReceived(content);
|
||||
});
|
||||
|
||||
let shown = this.waitForPickerReady();
|
||||
|
||||
if (openMethod === "click") {
|
||||
await SpecialPowers.spawn(bc, [], () => {
|
||||
const input = content.document.querySelector("input");
|
||||
@ -53,8 +52,8 @@ class DateTimeTestHelper {
|
||||
content.document.querySelector("input").showPicker();
|
||||
});
|
||||
}
|
||||
this.panel = await shown;
|
||||
this.frame = this.panel.querySelector("#dateTimePopupFrame");
|
||||
await this.waitForPickerReady();
|
||||
}
|
||||
|
||||
promisePickerClosed() {
|
||||
@ -80,8 +79,35 @@ class DateTimeTestHelper {
|
||||
);
|
||||
}
|
||||
|
||||
waitForPickerReady() {
|
||||
return BrowserTestUtils.waitForDateTimePickerPanelShown(window);
|
||||
async waitForPickerReady() {
|
||||
let readyPromise;
|
||||
let loadPromise = new Promise(resolve => {
|
||||
let listener = () => {
|
||||
if (
|
||||
this.frame.browsingContext.currentURI.spec !=
|
||||
"chrome://global/content/datepicker.xhtml" &&
|
||||
this.frame.browsingContext.currentURI.spec !=
|
||||
"chrome://global/content/timepicker.xhtml"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.frame.removeEventListener("load", listener, { capture: true });
|
||||
// Add the PickerReady event listener directly inside the load event
|
||||
// listener to avoid missing the event.
|
||||
readyPromise = BrowserTestUtils.waitForEvent(
|
||||
this.frame.contentDocument,
|
||||
"PickerReady"
|
||||
);
|
||||
resolve();
|
||||
};
|
||||
|
||||
this.frame.addEventListener("load", listener, { capture: true });
|
||||
});
|
||||
|
||||
await loadPromise;
|
||||
// Wait for picker elements to be ready
|
||||
await readyPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -130,8 +156,9 @@ class DateTimeTestHelper {
|
||||
* Clean up after tests. Remove the frame to prevent leak.
|
||||
*/
|
||||
cleanup() {
|
||||
this.frame?.remove();
|
||||
this.frame.remove();
|
||||
this.frame = null;
|
||||
this.panel.removeAttribute("animate");
|
||||
this.panel = null;
|
||||
}
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ function DatePicker(context) {
|
||||
this._createComponents();
|
||||
this._update();
|
||||
this.components.calendar.focusDay();
|
||||
// TODO(bug 1828721): This is a bit sad.
|
||||
window.PICKER_READY = true;
|
||||
document.dispatchEvent(new CustomEvent("PickerReady"));
|
||||
},
|
||||
|
||||
|
@ -617,28 +617,15 @@ this.DateTimeBoxWidget = class {
|
||||
let target = aEvent.originalTarget;
|
||||
target.setAttribute("typeBuffer", "");
|
||||
this.setInputValueFromFields();
|
||||
// No need to set and unset the focus state (or closing the picker) if the
|
||||
// focus is staying within our input.
|
||||
if (aEvent.relatedTarget == this.mInputElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're in chrome and the focus moves to a separate document
|
||||
// (relatedTarget is null) we also don't want to close it, since it
|
||||
// could've moved to the datetime popup itself.
|
||||
if (
|
||||
!aEvent.relatedTarget &&
|
||||
this.mInputElement.nodePrincipal.isSystemPrincipal &&
|
||||
this.window == this.window.top
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// No need to set and unset the focus state if the focus is staying within
|
||||
// our input. Same about closing the picker.
|
||||
if (aEvent.relatedTarget != this.mInputElement) {
|
||||
this.mInputElement.setFocusState(false);
|
||||
if (this.mIsPickerOpen) {
|
||||
this.closeDateTimePicker();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isTimeField(field) {
|
||||
return (
|
||||
|
@ -35,8 +35,6 @@ function TimePicker(context) {
|
||||
this._setDefaultState();
|
||||
this._createComponents();
|
||||
this._setComponentStates();
|
||||
// TODO(bug 1828721): This is a bit sad.
|
||||
window.PICKER_READY = true;
|
||||
document.dispatchEvent(new CustomEvent("PickerReady"));
|
||||
},
|
||||
|
||||
|
@ -236,6 +236,23 @@ let JSWINDOWACTORS = {
|
||||
enablePreference: "cookiebanners.bannerClicking.enabled",
|
||||
},
|
||||
|
||||
DateTimePicker: {
|
||||
parent: {
|
||||
esModuleURI: "resource://gre/actors/DateTimePickerParent.sys.mjs",
|
||||
},
|
||||
|
||||
child: {
|
||||
esModuleURI: "resource://gre/actors/DateTimePickerChild.sys.mjs",
|
||||
events: {
|
||||
MozOpenDateTimePicker: {},
|
||||
MozUpdateDateTimePicker: {},
|
||||
MozCloseDateTimePicker: {},
|
||||
},
|
||||
},
|
||||
|
||||
allFrames: true,
|
||||
},
|
||||
|
||||
ExtFind: {
|
||||
child: {
|
||||
esModuleURI: "resource://gre/actors/ExtFindChild.sys.mjs",
|
||||
@ -507,7 +524,6 @@ let JSWINDOWACTORS = {
|
||||
},
|
||||
},
|
||||
|
||||
includeChrome: true,
|
||||
allFrames: true,
|
||||
},
|
||||
|
||||
@ -566,7 +582,9 @@ if (AppConstants.platform != "android") {
|
||||
allFrames: true,
|
||||
};
|
||||
|
||||
// Note that GeckoView has another implementation in mobile/android/actors.
|
||||
/**
|
||||
* Note that GeckoView has another implementation in mobile/android/actors.
|
||||
*/
|
||||
JSWINDOWACTORS.Select = {
|
||||
parent: {
|
||||
esModuleURI: "resource://gre/actors/SelectParent.sys.mjs",
|
||||
@ -584,25 +602,6 @@ if (AppConstants.platform != "android") {
|
||||
includeChrome: true,
|
||||
allFrames: true,
|
||||
};
|
||||
|
||||
// Note that GeckoView handles MozOpenDateTimePicker in GeckoViewPrompt.
|
||||
JSWINDOWACTORS.DateTimePicker = {
|
||||
parent: {
|
||||
esModuleURI: "resource://gre/actors/DateTimePickerParent.sys.mjs",
|
||||
},
|
||||
|
||||
child: {
|
||||
esModuleURI: "resource://gre/actors/DateTimePickerChild.sys.mjs",
|
||||
events: {
|
||||
MozOpenDateTimePicker: {},
|
||||
MozUpdateDateTimePicker: {},
|
||||
MozCloseDateTimePicker: {},
|
||||
},
|
||||
},
|
||||
|
||||
includeChrome: true,
|
||||
allFrames: true,
|
||||
};
|
||||
}
|
||||
|
||||
export var ActorManagerParent = {
|
||||
|
Loading…
Reference in New Issue
Block a user