зеркало из https://github.com/mozilla/gecko-dev.git
Merge inbound to m-c. a=merge
This commit is contained in:
Коммит
ee4484bd10
|
@ -7,6 +7,10 @@
|
|||
const ORIGIN = "https://example.com";
|
||||
const PERMISSIONS_PAGE = getRootDirectory(gTestPath).replace("chrome://mochitests/content", ORIGIN) + "permissions.html";
|
||||
|
||||
// Ignore promise rejection caused by clicking Deny button.
|
||||
const { PromiseTestUtils } = Cu.import("resource://testing-common/PromiseTestUtils.jsm", {});
|
||||
PromiseTestUtils.whitelistRejectionsGlobally(/The request is not allowed/);
|
||||
|
||||
const EXPIRE_TIME_MS = 100;
|
||||
const TIMEOUT_MS = 500;
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ function promiseWindow(url) {
|
|||
}
|
||||
|
||||
Services.obs.removeObserver(obs, "domwindowopened");
|
||||
resolve(win);
|
||||
executeSoon(() => resolve(win));
|
||||
}, {once: true});
|
||||
}, "domwindowopened");
|
||||
});
|
||||
|
@ -120,7 +120,7 @@ async function assertWebRTCIndicatorStatus(expected) {
|
|||
win.addEventListener("unload", function listener(e) {
|
||||
if (e.target == win.document) {
|
||||
win.removeEventListener("unload", listener);
|
||||
resolve();
|
||||
executeSoon(resolve);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -141,7 +141,7 @@ async function assertWebRTCIndicatorStatus(expected) {
|
|||
if (document.readyState != "complete")
|
||||
return;
|
||||
document.removeEventListener("readystatechange", onReadyStateChange);
|
||||
resolve();
|
||||
executeSoon(resolve);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ function promisePopupEvent(popup, eventSuffix) {
|
|||
let eventType = "popup" + eventSuffix;
|
||||
return new Promise(resolve => {
|
||||
popup.addEventListener(eventType, function(event) {
|
||||
resolve();
|
||||
executeSoon(resolve);
|
||||
}, {once: true});
|
||||
|
||||
});
|
||||
|
@ -297,7 +297,7 @@ function promisePopupNotificationShown(aName, aAction) {
|
|||
ok(PopupNotifications.isPanelOpen, "notification panel open");
|
||||
ok(!!PopupNotifications.panel.firstChild, "notification panel populated");
|
||||
|
||||
resolve();
|
||||
executeSoon(resolve);
|
||||
}, {once: true});
|
||||
|
||||
if (aAction)
|
||||
|
|
|
@ -30,18 +30,25 @@ add_task(async function testAddOnBeforeCreatedWidget() {
|
|||
let viewNode = document.getElementById(kWidgetId + "idontexistyet");
|
||||
ok(widgetNode, "Widget should exist");
|
||||
ok(viewNode, "Panelview should exist");
|
||||
|
||||
let widgetPanel;
|
||||
let panelShownPromise;
|
||||
let viewShownPromise = new Promise(resolve => {
|
||||
viewNode.addEventListener("ViewShown", () => {
|
||||
widgetPanel = document.getElementById("customizationui-widget-panel");
|
||||
ok(widgetPanel, "Widget panel should exist");
|
||||
// Add the popupshown event listener directly inside the ViewShown event
|
||||
// listener to avoid missing the event.
|
||||
panelShownPromise = promisePanelElementShown(window, widgetPanel);
|
||||
resolve();
|
||||
}, { once: true });
|
||||
});
|
||||
widgetNode.click();
|
||||
await viewShownPromise;
|
||||
await panelShownPromise;
|
||||
|
||||
let tempPanel = document.getElementById("customizationui-widget-panel");
|
||||
let panelShownPromise = promisePanelElementShown(window, tempPanel);
|
||||
|
||||
await Promise.all([
|
||||
BrowserTestUtils.waitForEvent(viewNode, "ViewShown"),
|
||||
panelShownPromise
|
||||
]);
|
||||
|
||||
let panelHiddenPromise = promisePanelElementHidden(window, tempPanel);
|
||||
tempPanel.hidePopup();
|
||||
let panelHiddenPromise = promisePanelElementHidden(window, widgetPanel);
|
||||
widgetPanel.hidePopup();
|
||||
await panelHiddenPromise;
|
||||
|
||||
CustomizableUI.addWidgetToArea(kWidgetId, CustomizableUI.AREA_FIXED_OVERFLOW_PANEL);
|
||||
|
|
|
@ -25,9 +25,11 @@ async function testModeMenuitem(mode, modePref) {
|
|||
is(normalItem.getAttribute("active"), "true",
|
||||
"Normal mode menuitem should be active by default");
|
||||
|
||||
// Hover over the mode menuitem and wait until the UI density is updated.
|
||||
// Hover over the mode menuitem and wait for the event that updates the UI
|
||||
// density.
|
||||
let mouseoverPromise = BrowserTestUtils.waitForEvent(item, "mouseover");
|
||||
EventUtils.synthesizeMouseAtCenter(item, { type: "mouseover" });
|
||||
await BrowserTestUtils.waitForAttribute("uidensity", win, mode);
|
||||
await mouseoverPromise;
|
||||
|
||||
is(win.getAttribute("uidensity"), mode,
|
||||
`UI Density should be set to ${mode} on ${mode} menuitem hover`);
|
||||
|
|
|
@ -361,7 +361,7 @@ add_task(async function test_close_tab_after_crash() {
|
|||
// Crash the tab
|
||||
await BrowserTestUtils.crashBrowser(browser);
|
||||
|
||||
let promise = promiseEvent(gBrowser.tabContainer, "TabClose");
|
||||
let promise = BrowserTestUtils.waitForEvent(gBrowser.tabContainer, "TabClose");
|
||||
|
||||
// Click the close tab button
|
||||
clickButton(browser, "closeTab");
|
||||
|
|
|
@ -471,20 +471,12 @@ function promiseDelayedStartupFinished(aWindow) {
|
|||
return new Promise(resolve => whenDelayedStartupFinished(aWindow, resolve));
|
||||
}
|
||||
|
||||
function promiseEvent(element, eventType, isCapturing = false) {
|
||||
return new Promise(resolve => {
|
||||
element.addEventListener(eventType, function(event) {
|
||||
resolve(event);
|
||||
}, {capture: isCapturing, once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function promiseTabRestored(tab) {
|
||||
return promiseEvent(tab, "SSTabRestored");
|
||||
return BrowserTestUtils.waitForEvent(tab, "SSTabRestored");
|
||||
}
|
||||
|
||||
function promiseTabRestoring(tab) {
|
||||
return promiseEvent(tab, "SSTabRestoring");
|
||||
return BrowserTestUtils.waitForEvent(tab, "SSTabRestoring");
|
||||
}
|
||||
|
||||
function sendMessage(browser, name, data = {}) {
|
||||
|
|
|
@ -75,7 +75,7 @@ function openPopup(aPopup) {
|
|||
return new Promise(resolve => {
|
||||
|
||||
aPopup.addEventListener("popupshown", function() {
|
||||
resolve();
|
||||
TestUtils.executeSoon(resolve);
|
||||
}, {once: true});
|
||||
|
||||
aPopup.focus();
|
||||
|
@ -90,7 +90,7 @@ function waitForWindowLoad(aWin) {
|
|||
return new Promise(resolve => {
|
||||
|
||||
aWin.addEventListener("load", function() {
|
||||
resolve();
|
||||
TestUtils.executeSoon(resolve);
|
||||
}, {capture: true, once: true});
|
||||
|
||||
});
|
||||
|
|
|
@ -48,6 +48,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMIntersectionObserver)
|
|||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mQueuedEntries)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
@ -55,6 +56,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMIntersectionObserver)
|
|||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOwner)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mQueuedEntries)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
|
@ -80,10 +82,7 @@ DOMIntersectionObserver::Constructor(const mozilla::dom::GlobalObject& aGlobal,
|
|||
RefPtr<DOMIntersectionObserver> observer =
|
||||
new DOMIntersectionObserver(window.forget(), aCb);
|
||||
|
||||
if (aOptions.mRoot) {
|
||||
observer->mRoot = aOptions.mRoot;
|
||||
observer->mRoot->RegisterIntersectionObserver(observer);
|
||||
}
|
||||
observer->mRoot = aOptions.mRoot;
|
||||
|
||||
if (!observer->SetRootMargin(aOptions.mRootMargin)) {
|
||||
aRv.ThrowDOMException(NS_ERROR_DOM_SYNTAX_ERR,
|
||||
|
@ -182,13 +181,8 @@ DOMIntersectionObserver::Unobserve(Element& aTarget)
|
|||
}
|
||||
|
||||
void
|
||||
DOMIntersectionObserver::UnlinkElement(Element& aTarget)
|
||||
DOMIntersectionObserver::UnlinkTarget(Element& aTarget)
|
||||
{
|
||||
if (mRoot && mRoot == &aTarget) {
|
||||
mRoot = nullptr;
|
||||
Disconnect();
|
||||
return;
|
||||
}
|
||||
mObservationTargets.RemoveElement(&aTarget);
|
||||
if (mObservationTargets.Length() == 0) {
|
||||
Disconnect();
|
||||
|
|
|
@ -116,11 +116,7 @@ class DOMIntersectionObserver final : public nsISupports,
|
|||
public:
|
||||
DOMIntersectionObserver(already_AddRefed<nsPIDOMWindowInner>&& aOwner,
|
||||
mozilla::dom::IntersectionCallback& aCb)
|
||||
: mOwner(aOwner),
|
||||
mDocument(mOwner->GetExtantDoc()),
|
||||
mCallback(&aCb),
|
||||
mRoot(nullptr),
|
||||
mConnected(false)
|
||||
: mOwner(aOwner), mDocument(mOwner->GetExtantDoc()), mCallback(&aCb), mConnected(false)
|
||||
{
|
||||
}
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
@ -156,7 +152,7 @@ public:
|
|||
void Observe(Element& aTarget);
|
||||
void Unobserve(Element& aTarget);
|
||||
|
||||
void UnlinkElement(Element& aTarget);
|
||||
void UnlinkTarget(Element& aTarget);
|
||||
void Disconnect();
|
||||
|
||||
void TakeRecords(nsTArray<RefPtr<DOMIntersectionObserverEntry>>& aRetVal);
|
||||
|
@ -180,12 +176,11 @@ protected:
|
|||
nsCOMPtr<nsPIDOMWindowInner> mOwner;
|
||||
RefPtr<nsIDocument> mDocument;
|
||||
RefPtr<mozilla::dom::IntersectionCallback> mCallback;
|
||||
// Raw pointer which is explicitly cleared by UnlinkElement().
|
||||
Element* mRoot;
|
||||
RefPtr<Element> mRoot;
|
||||
nsCSSRect mRootMargin;
|
||||
nsTArray<double> mThresholds;
|
||||
|
||||
// Holds raw pointers which are explicitly cleared by UnlinkElement().
|
||||
// Holds raw pointers which are explicitly cleared by UnlinkTarget().
|
||||
nsTArray<Element*> mObservationTargets;
|
||||
|
||||
nsTArray<RefPtr<DOMIntersectionObserverEntry>> mQueuedEntries;
|
||||
|
|
|
@ -4332,7 +4332,7 @@ IntersectionObserverPropertyDtor(void* aObject, nsAtom* aPropertyName,
|
|||
static_cast<IntersectionObserverList*>(aPropertyValue);
|
||||
for (auto iter = observers->Iter(); !iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkElement(*element);
|
||||
observer->UnlinkTarget(*element);
|
||||
}
|
||||
delete observers;
|
||||
}
|
||||
|
@ -4354,7 +4354,7 @@ Element::RegisterIntersectionObserver(DOMIntersectionObserver* aObserver)
|
|||
}
|
||||
|
||||
observers->LookupForAdd(aObserver).OrInsert([]() {
|
||||
// If element is being observed, value can be:
|
||||
// Value can be:
|
||||
// -2: Makes sure next calculated threshold always differs, leading to a
|
||||
// notification task being scheduled.
|
||||
// -1: Non-intersecting.
|
||||
|
@ -4387,7 +4387,7 @@ Element::UnlinkIntersectionObservers()
|
|||
}
|
||||
for (auto iter = observers->Iter(); !iter.Done(); iter.Next()) {
|
||||
DOMIntersectionObserver* observer = iter.Key();
|
||||
observer->UnlinkElement(*this);
|
||||
observer->UnlinkTarget(*this);
|
||||
}
|
||||
observers->Clear();
|
||||
}
|
||||
|
|
|
@ -610,7 +610,6 @@ skip-if = toolkit == 'android'
|
|||
[test_bug1375050.html]
|
||||
[test_bug1381710.html]
|
||||
[test_bug1384661.html]
|
||||
[test_bug1399603.html]
|
||||
[test_bug1399605.html]
|
||||
[test_bug1404385.html]
|
||||
[test_bug1406102.html]
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Bug 1399603</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1399603">Mozilla Bug 1399603</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
<div id="root">
|
||||
<div id="target"></div>
|
||||
</div>
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
function waitForNotification(f) {
|
||||
requestAnimationFrame(function() {
|
||||
setTimeout(function() { setTimeout(f); });
|
||||
});
|
||||
}
|
||||
|
||||
function forceGC() {
|
||||
SpecialPowers.gc();
|
||||
SpecialPowers.forceShrinkingGC();
|
||||
SpecialPowers.forceCC();
|
||||
SpecialPowers.gc();
|
||||
SpecialPowers.forceShrinkingGC();
|
||||
SpecialPowers.forceCC();
|
||||
}
|
||||
|
||||
let content = document.getElementById('content');
|
||||
let root = document.getElementById('root');
|
||||
let target = document.getElementById('target');
|
||||
let entries = [];
|
||||
let observer = new IntersectionObserver(function(changes) {
|
||||
entries = entries.concat(changes);
|
||||
}, { root: root });
|
||||
observer.observe(target);
|
||||
|
||||
waitForNotification(function () {
|
||||
is(entries.length, 1, "Initial notification.");
|
||||
root.removeChild(target);
|
||||
content.removeChild(root);
|
||||
root = null;
|
||||
forceGC();
|
||||
waitForNotification(function () {
|
||||
is(entries.length, 1, "No new notifications.");
|
||||
SimpleTest.finish();
|
||||
});
|
||||
});
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
<div id="log">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -4136,33 +4136,36 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> targetContent = aTargetContent;
|
||||
nsCOMPtr<nsIContent> relatedContent = aRelatedContent;
|
||||
|
||||
nsAutoPtr<WidgetMouseEvent> dispatchEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, aMessage,
|
||||
aRelatedContent, dispatchEvent);
|
||||
relatedContent, dispatchEvent);
|
||||
|
||||
AutoWeakFrame previousTarget = mCurrentTarget;
|
||||
mCurrentTargetContent = aTargetContent;
|
||||
mCurrentTargetContent = targetContent;
|
||||
|
||||
nsIFrame* targetFrame = nullptr;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
ESMEventCB callback(aTargetContent);
|
||||
EventDispatcher::Dispatch(aTargetContent, mPresContext, dispatchEvent, nullptr,
|
||||
ESMEventCB callback(targetContent);
|
||||
EventDispatcher::Dispatch(targetContent, mPresContext, dispatchEvent, nullptr,
|
||||
&status, &callback);
|
||||
|
||||
if (mPresContext) {
|
||||
// Although the primary frame was checked in event callback, it may not be
|
||||
// the same object after event dispatch and handling, so refetch it.
|
||||
targetFrame = mPresContext->GetPrimaryFrameFor(aTargetContent);
|
||||
targetFrame = mPresContext->GetPrimaryFrameFor(targetContent);
|
||||
|
||||
// If we are entering/leaving remote content, dispatch a mouse enter/exit
|
||||
// event to the remote frame.
|
||||
if (IsRemoteTarget(aTargetContent)) {
|
||||
if (IsRemoteTarget(targetContent)) {
|
||||
if (aMessage == eMouseOut) {
|
||||
// For remote content, send a "top-level" widget mouse exit event.
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseExitFromWidget,
|
||||
aRelatedContent, remoteEvent);
|
||||
relatedContent, remoteEvent);
|
||||
remoteEvent->mExitFrom = WidgetMouseEvent::eTopLevel;
|
||||
|
||||
// mCurrentTarget is set to the new target, so we must reset it to the
|
||||
|
@ -4174,7 +4177,7 @@ EventStateManager::DispatchMouseOrPointerEvent(WidgetMouseEvent* aMouseEvent,
|
|||
} else if (aMessage == eMouseOver) {
|
||||
nsAutoPtr<WidgetMouseEvent> remoteEvent;
|
||||
CreateMouseOrPointerWidgetEvent(aMouseEvent, eMouseEnterIntoWidget,
|
||||
aRelatedContent, remoteEvent);
|
||||
relatedContent, remoteEvent);
|
||||
HandleCrossProcessEvent(remoteEvent, &status);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,19 +13,19 @@ add_task(async function() {
|
|||
SpecialPowers.pushPrefEnv({"set": [["ui.tooltipDelay", 0]]}, resolve);
|
||||
});
|
||||
|
||||
// Send a mousemove at a known position to start the test.
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(document, "popupshown", false, event => {
|
||||
is(event.originalTarget.localName, "tooltip", "tooltip is showing");
|
||||
return true;
|
||||
});
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, browser);
|
||||
await popupShownPromise;
|
||||
|
||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(document, "popuphidden", false, event => {
|
||||
is(event.originalTarget.localName, "tooltip", "tooltip is hidden");
|
||||
return true;
|
||||
});
|
||||
|
||||
// Send a mousemove at a known position to start the test.
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p1", { type: "mousemove" }, browser);
|
||||
await popupShownPromise;
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("#p2", { type: "mousemove" }, browser);
|
||||
await popupHiddenPromise;
|
||||
|
||||
|
|
|
@ -741,8 +741,28 @@ this.BrowserTestUtils = {
|
|||
* let promiseEvent = BrowserTestUtils.waitForEvent(element, "eventName");
|
||||
* // Do some processing here that will cause the event to be fired
|
||||
* // ...
|
||||
* // Now yield until the Promise is fulfilled
|
||||
* let receivedEvent = yield promiseEvent;
|
||||
* // Now wait until the Promise is fulfilled
|
||||
* let receivedEvent = await promiseEvent;
|
||||
*
|
||||
* The promise resolution/rejection handler for the returned promise is
|
||||
* guaranteed not to be called until the next event tick after the event
|
||||
* listener gets called, so that all other event listeners for the element
|
||||
* are executed before the handler is executed.
|
||||
*
|
||||
* let promiseEvent = BrowserTestUtils.waitForEvent(element, "eventName");
|
||||
* // Same event tick here.
|
||||
* await promiseEvent;
|
||||
* // Next event tick here.
|
||||
*
|
||||
* If some code, such like adding yet another event listener, needs to be
|
||||
* executed in the same event tick, use raw addEventListener instead and
|
||||
* place the code inside the event listener.
|
||||
*
|
||||
* element.addEventListener("load", () => {
|
||||
* // Add yet another event listener in the same event tick as the load
|
||||
* // event listener.
|
||||
* p = BrowserTestUtils.waitForEvent(element, "ready");
|
||||
* }, { once: true });
|
||||
*
|
||||
* @param {Element} subject
|
||||
* The element that should receive the event.
|
||||
|
@ -773,14 +793,14 @@ this.BrowserTestUtils = {
|
|||
return;
|
||||
}
|
||||
subject.removeEventListener(eventName, listener, capture);
|
||||
resolve(event);
|
||||
TestUtils.executeSoon(() => resolve(event));
|
||||
} catch (ex) {
|
||||
try {
|
||||
subject.removeEventListener(eventName, listener, capture);
|
||||
} catch (ex2) {
|
||||
// Maybe the provided object does not support removeEventListener.
|
||||
}
|
||||
reject(ex);
|
||||
TestUtils.executeSoon(() => reject(ex));
|
||||
}
|
||||
}, capture, wantsUntrusted);
|
||||
});
|
||||
|
|
|
@ -68,3 +68,30 @@ add_task(async function() {
|
|||
ok(true, "Should have returned a rejected promise trying to unregister an unknown about page");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testWaitForEvent() {
|
||||
// A promise returned by BrowserTestUtils.waitForEvent should not be resolved
|
||||
// in the same event tick as the event listener is called.
|
||||
let eventListenerCalled = false;
|
||||
let waitForEventResolved = false;
|
||||
// Use capturing phase to make sure the event listener added by
|
||||
// BrowserTestUtils.waitForEvent is called before the normal event listener
|
||||
// below.
|
||||
let eventPromise = BrowserTestUtils.waitForEvent(gBrowser, "dummyevent", true);
|
||||
eventPromise.then(() => {
|
||||
waitForEventResolved = true;
|
||||
});
|
||||
// Add normal event listener that is called after the event listener added by
|
||||
// BrowserTestUtils.waitForEvent.
|
||||
gBrowser.addEventListener("dummyevent", () => {
|
||||
eventListenerCalled = true;
|
||||
is(waitForEventResolved, false, "BrowserTestUtils.waitForEvent promise resolution handler shouldn't be called at this point.");
|
||||
}, { once: true });
|
||||
|
||||
var event = new CustomEvent("dummyevent");
|
||||
gBrowser.dispatchEvent(event);
|
||||
|
||||
await eventPromise;
|
||||
|
||||
is(eventListenerCalled, true, "dummyevent listener should be called");
|
||||
});
|
||||
|
|
|
@ -143,7 +143,10 @@ class DateTimeTestHelper {
|
|||
async openPicker(pageUrl) {
|
||||
this.tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, pageUrl);
|
||||
await BrowserTestUtils.synthesizeMouseAtCenter("input", {}, gBrowser.selectedBrowser);
|
||||
// If dateTimePopupFrame doesn't exist yet, wait for the binding to be attached
|
||||
// If dateTimePopupFrame doesn't exist yet, wait for the binding to be
|
||||
// attached.
|
||||
// FIXME: This has a race condition and we may miss the following events.
|
||||
// (bug 1423498)
|
||||
if (!this.panel.dateTimePopupFrame) {
|
||||
await BrowserTestUtils.waitForEvent(this.panel, "DateTimePickerBindingReady");
|
||||
}
|
||||
|
@ -152,9 +155,19 @@ class DateTimeTestHelper {
|
|||
}
|
||||
|
||||
async waitForPickerReady() {
|
||||
await BrowserTestUtils.waitForEvent(this.frame, "load", true);
|
||||
let readyPromise;
|
||||
let loadPromise = new Promise(resolve => {
|
||||
this.frame.addEventListener("load", () => {
|
||||
// Add the PickerReady event listener directly inside the load event
|
||||
// listener to avoid missing the event.
|
||||
readyPromise = BrowserTestUtils.waitForEvent(this.frame.contentDocument, "PickerReady");
|
||||
resolve();
|
||||
}, { capture: true, once: true });
|
||||
});
|
||||
|
||||
await loadPromise;
|
||||
// Wait for picker elements to be ready
|
||||
await BrowserTestUtils.waitForEvent(this.frame.contentDocument, "PickerReady");
|
||||
await readyPromise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче