diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index df11a0d3ea..46d0e66249 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1655,7 +1655,7 @@ } if (animate) { - mozRequestAnimationFrame(function () { + requestAnimationFrame(function () { this.tabContainer._handleTabTelemetryStart(t, aURI); // kick the animation off diff --git a/dom/base/nsDOMWindowList.cpp b/dom/base/nsDOMWindowList.cpp index bccc2cf43d..e9424aff3e 100644 --- a/dom/base/nsDOMWindowList.cpp +++ b/dom/base/nsDOMWindowList.cpp @@ -83,10 +83,8 @@ nsDOMWindowList::GetLength(uint32_t* aLength) } already_AddRefed -nsDOMWindowList::IndexedGetter(uint32_t aIndex, bool& aFound) +nsDOMWindowList::IndexedGetter(uint32_t aIndex) { - aFound = false; - nsCOMPtr item = GetDocShellTreeItemAt(aIndex); if (!item) { return nullptr; @@ -95,15 +93,13 @@ nsDOMWindowList::IndexedGetter(uint32_t aIndex, bool& aFound) nsCOMPtr window = item->GetWindow(); MOZ_ASSERT(window); - aFound = true; return window.forget(); } NS_IMETHODIMP nsDOMWindowList::Item(uint32_t aIndex, nsIDOMWindow** aReturn) { - bool found; - nsCOMPtr window = IndexedGetter(aIndex, found); + nsCOMPtr window = IndexedGetter(aIndex); window.forget(aReturn); return NS_OK; } diff --git a/dom/base/nsDOMWindowList.h b/dom/base/nsDOMWindowList.h index c97c30b0f7..65f6d138bd 100644 --- a/dom/base/nsDOMWindowList.h +++ b/dom/base/nsDOMWindowList.h @@ -23,7 +23,7 @@ public: NS_DECL_NSIDOMWINDOWCOLLECTION uint32_t GetLength(); - already_AddRefed IndexedGetter(uint32_t aIndex, bool& aFound); + already_AddRefed IndexedGetter(uint32_t aIndex); //local methods NS_IMETHOD SetDocShell(nsIDocShell* aDocShell); diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 709974a3f9..551e10a71d 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -2434,6 +2434,18 @@ nsDOMWindowUtils::GetIsTestControllingRefreshes(bool *aResult) return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::GetAsyncPanZoomEnabled(bool *aResult) +{ + nsIWidget* widget = GetWidget(); + if (widget) { + *aResult = widget->AsyncPanZoomEnabled(); + } else { + *aResult = gfxPlatform::AsyncPanZoomEnabled(); + } + return NS_OK; +} + NS_IMETHODIMP nsDOMWindowUtils::SetAsyncScrollOffset(nsIDOMNode* aNode, int32_t aX, int32_t aY) diff --git a/dom/base/nsDeprecatedOperationList.h b/dom/base/nsDeprecatedOperationList.h index a7c09f46e6..5fd79ed0cf 100644 --- a/dom/base/nsDeprecatedOperationList.h +++ b/dom/base/nsDeprecatedOperationList.h @@ -22,7 +22,6 @@ DEPRECATED_OPERATION(NodeValue) DEPRECATED_OPERATION(TextContent) DEPRECATED_OPERATION(EnablePrivilege) DEPRECATED_OPERATION(InputEncoding) -DEPRECATED_OPERATION(MozBeforePaint) DEPRECATED_OPERATION(DOMExceptionCode) DEPRECATED_OPERATION(NoExposedProps) DEPRECATED_OPERATION(MutationEvent) diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index 18861a486c..11edf5b1a0 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -1503,15 +1503,15 @@ void nsIDocument::SelectorCache::NotifyExpired(SelectorCacheKey* aSelector) struct nsIDocument::FrameRequest { - FrameRequest(const FrameRequestCallbackHolder& aCallback, + FrameRequest(FrameRequestCallback& aCallback, int32_t aHandle) : - mCallback(aCallback), + mCallback(&aCallback), mHandle(aHandle) {} // Conversion operator so that we can append these to a // FrameRequestCallbackList - operator const FrameRequestCallbackHolder& () const { + operator const nsRefPtr& () const { return mCallback; } @@ -1524,7 +1524,7 @@ struct nsIDocument::FrameRequest return mHandle < aHandle; } - FrameRequestCallbackHolder mCallback; + nsRefPtr mCallback; int32_t mHandle; }; @@ -1989,7 +1989,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument) for (uint32_t i = 0; i < tmp->mFrameRequestCallbacks.Length(); ++i) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mFrameRequestCallbacks[i]"); - cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i].mCallback.GetISupports()); + cb.NoteXPCOMChild(tmp->mFrameRequestCallbacks[i].mCallback); } // Traverse animation components @@ -10338,7 +10338,7 @@ nsIDocument::UnlinkOriginalDocumentIfStatic() } nsresult -nsIDocument::ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback, +nsIDocument::ScheduleFrameRequestCallback(FrameRequestCallback& aCallback, int32_t *aHandle) { if (mFrameRequestCallbackCounter == INT32_MAX) { diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 72f69af707..bc247c950c 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -146,7 +146,6 @@ #include "nsMenuPopupFrame.h" #endif #include "mozilla/dom/CustomEvent.h" -#include "nsIFrameRequestCallback.h" #include "nsIJARChannel.h" #include "xpcprivate.h" @@ -969,8 +968,8 @@ nsOuterWindowProxy::GetSubframeWindow(JSContext *cx, } nsGlobalWindow* win = GetWindow(proxy); - bool unused; - return win->IndexedGetter(index, unused); + MOZ_ASSERT(win->IsOuterWindow()); + return win->IndexedGetterOuter(index); } bool @@ -1648,7 +1647,6 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow) // Make sure this matches the cast in nsGlobalWindow::FromWrapper() NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventTarget) NS_INTERFACE_MAP_ENTRY(nsIDOMWindow) - NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow) if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) { foundInterface = static_cast(this); if (!sWarnedAboutWindowInternal) { @@ -3638,14 +3636,6 @@ nsGlobalWindow::GetHistory(nsISupports** aHistory) return rv.StealNSResult(); } -nsPerformance* -nsGlobalWindow::GetPerformance() -{ - FORWARD_TO_INNER(GetPerformance, (), nullptr); - - return nsPIDOMWindow::GetPerformance(); -} - nsPerformance* nsPIDOMWindow::GetPerformance() { @@ -4011,7 +4001,7 @@ nsGlobalWindow::GetMozSelfSupport(ErrorResult& aError) return mMozSelfSupport; } -NS_IMETHODIMP +nsresult nsGlobalWindow::GetScriptableContent(JSContext* aCx, JS::MutableHandle aVal) { ErrorResult rv; @@ -4236,16 +4226,21 @@ nsGlobalWindow::GetFrames(nsIDOMWindowCollection** aFrames) } already_AddRefed -nsGlobalWindow::IndexedGetter(uint32_t aIndex, bool& aFound) +nsGlobalWindow::IndexedGetterOuter(uint32_t aIndex) { - aFound = false; - - FORWARD_TO_OUTER(IndexedGetter, (aIndex, aFound), nullptr); + MOZ_RELEASE_ASSERT(IsOuterWindow()); nsDOMWindowList* windows = GetWindowList(); NS_ENSURE_TRUE(windows, nullptr); - return windows->IndexedGetter(aIndex, aFound); + return windows->IndexedGetter(aIndex); +} + +already_AddRefed +nsGlobalWindow::IndexedGetter(uint32_t aIndex) +{ + FORWARD_TO_OUTER(IndexedGetterOuter, (aIndex), nullptr); + MOZ_CRASH(); } void @@ -5485,51 +5480,12 @@ nsGlobalWindow::GetMozPaintCount(uint64_t* aResult) return rv.StealNSResult(); } -NS_IMETHODIMP -nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback, - int32_t *aHandle) -{ - FORWARD_TO_INNER(MozRequestAnimationFrame, (aCallback, aHandle), NS_ERROR_UNEXPECTED); - - if (!aCallback) { - if (mDoc) { - mDoc->WarnOnceAbout(nsIDocument::eMozBeforePaint); - } - return NS_ERROR_XPC_BAD_CONVERT_JS; - } - - ErrorResult rv; - nsIDocument::FrameRequestCallbackHolder holder(aCallback); - *aHandle = RequestAnimationFrame(holder, rv); - - return rv.StealNSResult(); -} - int32_t nsGlobalWindow::RequestAnimationFrame(FrameRequestCallback& aCallback, ErrorResult& aError) { MOZ_RELEASE_ASSERT(IsInnerWindow()); - nsIDocument::FrameRequestCallbackHolder holder(&aCallback); - return RequestAnimationFrame(holder, aError); -} - -int32_t -nsGlobalWindow::MozRequestAnimationFrame(nsIFrameRequestCallback* aCallback, - ErrorResult& aError) -{ - MOZ_RELEASE_ASSERT(IsInnerWindow()); - nsIDocument::FrameRequestCallbackHolder holder(aCallback); - return RequestAnimationFrame(holder, aError); -} - -int32_t -nsGlobalWindow::RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback, - ErrorResult& aError) -{ - MOZ_RELEASE_ASSERT(IsInnerWindow()); - if (!mDoc) { return 0; } @@ -5563,20 +5519,6 @@ nsGlobalWindow::RequestAnimationFrame(JS::Handle aCallback, return rv.StealNSResult(); } -NS_IMETHODIMP -nsGlobalWindow::MozCancelRequestAnimationFrame(int32_t aHandle) -{ - FORWARD_TO_INNER(MozCancelRequestAnimationFrame, (aHandle), NS_ERROR_UNEXPECTED); - return CancelAnimationFrame(aHandle); -} - -NS_IMETHODIMP -nsGlobalWindow::MozCancelAnimationFrame(int32_t aHandle) -{ - FORWARD_TO_INNER(MozCancelAnimationFrame, (aHandle), NS_ERROR_UNEXPECTED); - return CancelAnimationFrame(aHandle); -} - void nsGlobalWindow::CancelAnimationFrame(int32_t aHandle, ErrorResult& aError) { @@ -5600,34 +5542,6 @@ nsGlobalWindow::CancelAnimationFrame(int32_t aHandle) return rv.StealNSResult(); } -int64_t -nsGlobalWindow::GetMozAnimationStartTime(ErrorResult& aError) -{ - MOZ_RELEASE_ASSERT(IsInnerWindow()); - - if (mDoc) { - nsIPresShell* presShell = mDoc->GetShell(); - if (presShell) { - return presShell->GetPresContext()->RefreshDriver()-> - MostRecentRefreshEpochTime() / PR_USEC_PER_MSEC; - } - } - - // If all else fails, just be compatible with Date.now() - return JS_Now() / PR_USEC_PER_MSEC; -} - -NS_IMETHODIMP -nsGlobalWindow::GetMozAnimationStartTime(int64_t *aTime) -{ - FORWARD_TO_INNER(GetMozAnimationStartTime, (aTime), NS_ERROR_UNEXPECTED); - - ErrorResult rv; - *aTime = GetMozAnimationStartTime(rv); - - return rv.StealNSResult(); -} - already_AddRefed nsGlobalWindow::MatchMediaOuter(const nsAString& aMediaQueryList) { @@ -6479,11 +6393,11 @@ nsGlobalWindow::GetFullScreen(bool* aFullScreen) return rv.StealNSResult(); } -NS_IMETHODIMP +void nsGlobalWindow::Dump(const nsAString& aStr) { if (!nsContentUtils::DOMWindowDumpEnabled()) { - return NS_OK; + return; } char *cstr = ToNewUTF8String(aStr); @@ -6510,8 +6424,6 @@ nsGlobalWindow::Dump(const nsAString& aStr) fflush(fp); free(cstr); } - - return NS_OK; } void @@ -6760,6 +6672,7 @@ nsGlobalWindow::AlertOrConfirm(bool aAlert, void nsGlobalWindow::Alert(mozilla::ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); Alert(EmptyString(), aError); } @@ -7815,6 +7728,8 @@ nsGlobalWindow::ScrollBy(const ScrollToOptions& aOptions) NS_IMETHODIMP nsGlobalWindow::ScrollByLines(int32_t numLines) { + FORWARD_TO_INNER(ScrollByLines, (numLines), NS_ERROR_UNEXPECTED); + ScrollByLines(numLines, ScrollOptions()); return NS_OK; @@ -7824,6 +7739,8 @@ void nsGlobalWindow::ScrollByLines(int32_t numLines, const ScrollOptions& aOptions) { + MOZ_ASSERT(IsInnerWindow()); + FlushPendingNotifications(Flush_Layout); nsIScrollableFrame *sf = GetScrollFrame(); if (sf) { @@ -7842,6 +7759,8 @@ nsGlobalWindow::ScrollByLines(int32_t numLines, NS_IMETHODIMP nsGlobalWindow::ScrollByPages(int32_t numPages) { + FORWARD_TO_INNER(ScrollByPages, (numPages), NS_ERROR_UNEXPECTED); + ScrollByPages(numPages, ScrollOptions()); return NS_OK; @@ -7851,6 +7770,8 @@ void nsGlobalWindow::ScrollByPages(int32_t numPages, const ScrollOptions& aOptions) { + MOZ_ASSERT(IsInnerWindow()); + FlushPendingNotifications(Flush_Layout); nsIScrollableFrame *sf = GetScrollFrame(); if (sf) { @@ -7869,6 +7790,8 @@ nsGlobalWindow::ScrollByPages(int32_t numPages, void nsGlobalWindow::MozScrollSnap() { + MOZ_ASSERT(IsInnerWindow()); + FlushPendingNotifications(Flush_Layout); nsIScrollableFrame *sf = GetScrollFrame(); if (sf) { @@ -7880,6 +7803,8 @@ void nsGlobalWindow::MozRequestOverfill(OverfillCallback& aCallback, mozilla::ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsIWidget* widget = nsContentUtils::WidgetForDocument(mDoc); if (widget) { mozilla::layers::LayerManager* manager = widget->GetLayerManager(); @@ -7902,17 +7827,6 @@ nsGlobalWindow::ClearTimeout(int32_t aHandle, ErrorResult& aError) } } -NS_IMETHODIMP -nsGlobalWindow::ClearTimeout(int32_t aHandle) -{ - FORWARD_TO_INNER(ClearTimeout, (aHandle), NS_ERROR_UNEXPECTED); - - ErrorResult rv; - ClearTimeout(aHandle, rv); - - return rv.StealNSResult(); -} - void nsGlobalWindow::ClearInterval(int32_t aHandle, ErrorResult& aError) { @@ -7921,41 +7835,26 @@ nsGlobalWindow::ClearInterval(int32_t aHandle, ErrorResult& aError) } } -NS_IMETHODIMP -nsGlobalWindow::ClearInterval(int32_t aHandle) -{ - ErrorResult rv; - ClearInterval(aHandle, rv); - - return rv.StealNSResult(); -} - -NS_IMETHODIMP -nsGlobalWindow::SetResizable(bool aResizable) +void +nsGlobalWindow::SetResizable(bool aResizable) const { // nop - - return NS_OK; } -NS_IMETHODIMP +void nsGlobalWindow::CaptureEvents() { if (mDoc) { mDoc->WarnOnceAbout(nsIDocument::eUseOfCaptureEvents); } - - return NS_OK; } -NS_IMETHODIMP +void nsGlobalWindow::ReleaseEvents() { if (mDoc) { mDoc->WarnOnceAbout(nsIDocument::eUseOfReleaseEvents); } - - return NS_OK; } static @@ -8158,12 +8057,11 @@ nsGlobalWindow::Open(const nsAString& aUrl, const nsAString& aName, return rv; } -NS_IMETHODIMP +nsresult nsGlobalWindow::OpenJS(const nsAString& aUrl, const nsAString& aName, const nsAString& aOptions, nsIDOMWindow **_retval) { - FORWARD_TO_OUTER(OpenJS, (aUrl, aName, aOptions, _retval), - NS_ERROR_NOT_INITIALIZED); + MOZ_ASSERT(IsOuterWindow()); return OpenInternal(aUrl, aName, aOptions, false, // aDialog false, // aContentModal @@ -8267,58 +8165,6 @@ nsGlobalWindow::OpenDialog(JSContext* aCx, const nsAString& aUrl, aError, nullptr); } -NS_IMETHODIMP -nsGlobalWindow::OpenDialog(const nsAString& aUrl, const nsAString& aName, - const nsAString& aOptions, nsIDOMWindow** _retval) -{ - FORWARD_TO_OUTER(OpenDialog, (aUrl, aName, aOptions, _retval), - NS_ERROR_NOT_INITIALIZED); - - if (!nsContentUtils::IsCallerChrome()) { - return NS_ERROR_DOM_SECURITY_ERR; - } - - nsAXPCNativeCallContext *ncc = nullptr; - nsresult rv = nsContentUtils::XPConnect()-> - GetCurrentNativeCallContext(&ncc); - NS_ENSURE_SUCCESS(rv, rv); - - if (!ncc) - return NS_ERROR_NOT_AVAILABLE; - - JSContext *cx = nullptr; - - rv = ncc->GetJSContext(&cx); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t argc; - JS::Value *argv = nullptr; - - // XXX - need to get this as nsISupports? - ncc->GetArgc(&argc); - ncc->GetArgvPtr(&argv); - - // Strip the url, name and options from the args seen by scripts. - uint32_t argOffset = argc < 3 ? argc : 3; - nsCOMPtr argvArray; - rv = NS_CreateJSArgv(cx, argc - argOffset, argv + argOffset, - getter_AddRefs(argvArray)); - NS_ENSURE_SUCCESS(rv, rv); - - return OpenInternal(aUrl, aName, aOptions, - true, // aDialog - false, // aContentModal - false, // aCalledNoScript - false, // aDoJSFixups - true, // aNavigate - argvArray, nullptr, // Arguments - nullptr, // aLoadInfo - false, // aForceNoOpener - GetPrincipal(), // aCalleePrincipal - cx, // aJSCallerContext - _retval); -} - already_AddRefed nsGlobalWindow::GetFramesOuter() { @@ -8333,18 +8179,6 @@ nsGlobalWindow::GetFrames(ErrorResult& aError) FORWARD_TO_OUTER_OR_THROW(GetFramesOuter, (), aError, nullptr); } -NS_IMETHODIMP -nsGlobalWindow::GetFrames(nsIDOMWindow** aFrames) -{ - FORWARD_TO_INNER(GetFrames, (aFrames), NS_ERROR_UNEXPECTED); - - ErrorResult rv; - nsCOMPtr frames = GetFrames(rv); - frames.forget(aFrames); - - return rv.StealNSResult(); -} - nsGlobalWindow* nsGlobalWindow::CallerInnerWindow() { @@ -9761,6 +9595,7 @@ void nsGlobalWindow::Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); aError = nsContentUtils::Atob(aAsciiBase64String, aBinaryData); } @@ -9768,6 +9603,8 @@ NS_IMETHODIMP nsGlobalWindow::Atob(const nsAString& aAsciiBase64String, nsAString& aBinaryData) { + FORWARD_TO_INNER(Atob, (aAsciiBase64String, aBinaryData), NS_ERROR_UNEXPECTED); + ErrorResult rv; Atob(aAsciiBase64String, aBinaryData, rv); @@ -9778,6 +9615,7 @@ void nsGlobalWindow::Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); aError = nsContentUtils::Btoa(aBinaryData, aAsciiBase64String); } @@ -9785,6 +9623,8 @@ NS_IMETHODIMP nsGlobalWindow::Btoa(const nsAString& aBinaryData, nsAString& aAsciiBase64String) { + FORWARD_TO_INNER(Btoa, (aBinaryData, aAsciiBase64String), NS_ERROR_UNEXPECTED); + ErrorResult rv; Btoa(aBinaryData, aAsciiBase64String, rv); @@ -10604,6 +10444,7 @@ already_AddRefed nsGlobalWindow::GetComputedStyle(Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); return GetComputedStyleHelper(aElt, aPseudoElt, false, aError); } @@ -10612,6 +10453,7 @@ nsGlobalWindow::GetComputedStyle(nsIDOMElement* aElt, const nsAString& aPseudoElt, nsIDOMCSSStyleDeclaration** aReturn) { + FORWARD_TO_INNER(GetComputedStyle, (aElt, aPseudoElt, aReturn), NS_ERROR_UNEXPECTED); return GetComputedStyleHelper(aElt, aPseudoElt, false, aReturn); } @@ -10620,6 +10462,7 @@ nsGlobalWindow::GetDefaultComputedStyle(Element& aElt, const nsAString& aPseudoElt, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); return GetComputedStyleHelper(aElt, aPseudoElt, true, aError); } @@ -10628,6 +10471,7 @@ nsGlobalWindow::GetDefaultComputedStyle(nsIDOMElement* aElt, const nsAString& aPseudoElt, nsIDOMCSSStyleDeclaration** aReturn) { + FORWARD_TO_INNER(GetDefaultComputedStyle, (aElt, aPseudoElt, aReturn), NS_ERROR_UNEXPECTED); return GetComputedStyleHelper(aElt, aPseudoElt, true, aReturn); } @@ -10637,9 +10481,7 @@ nsGlobalWindow::GetComputedStyleHelper(nsIDOMElement* aElt, bool aDefaultStylesOnly, nsIDOMCSSStyleDeclaration** aReturn) { - FORWARD_TO_INNER(GetComputedStyleHelper, - (aElt, aPseudoElt, aDefaultStylesOnly, aReturn), - NS_ERROR_UNEXPECTED); + MOZ_ASSERT(IsInnerWindow()); NS_ENSURE_ARG_POINTER(aReturn); *aReturn = nullptr; @@ -10969,12 +10811,15 @@ nsGlobalWindow::GetInterface(JSContext* aCx, nsIJSID* aIID, JS::MutableHandle aRetval, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); dom::GetInterface(aCx, this, aIID, aRetval, aError); } already_AddRefed nsGlobalWindow::GetCaches(ErrorResult& aRv) { + MOZ_ASSERT(IsInnerWindow()); + if (!mCacheStorage) { bool forceTrustedOrigin = GetOuterWindowInternal()->GetServiceWorkersTestingEnabled(); @@ -13723,6 +13568,8 @@ nsGlobalChromeWindow::Create(nsGlobalWindow *aOuterWindow) NS_IMETHODIMP nsGlobalChromeWindow::GetWindowState(uint16_t* aWindowState) { + FORWARD_TO_INNER_CHROME(GetWindowState, (aWindowState), NS_ERROR_UNEXPECTED); + *aWindowState = WindowState(); return NS_OK; } @@ -13730,6 +13577,7 @@ nsGlobalChromeWindow::GetWindowState(uint16_t* aWindowState) uint16_t nsGlobalWindow::WindowState() { + MOZ_ASSERT(IsInnerWindow()); nsCOMPtr widget = GetMainWidget(); int32_t mode = widget ? widget->SizeMode() : 0; @@ -13754,6 +13602,8 @@ nsGlobalWindow::WindowState() NS_IMETHODIMP nsGlobalChromeWindow::Maximize() { + FORWARD_TO_INNER_CHROME(Maximize, (), NS_ERROR_UNEXPECTED); + ErrorResult rv; Maximize(rv); return rv.StealNSResult(); @@ -13762,6 +13612,8 @@ nsGlobalChromeWindow::Maximize() void nsGlobalWindow::Maximize(ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsCOMPtr widget = GetMainWidget(); if (widget) { @@ -13772,6 +13624,8 @@ nsGlobalWindow::Maximize(ErrorResult& aError) NS_IMETHODIMP nsGlobalChromeWindow::Minimize() { + FORWARD_TO_INNER_CHROME(Minimize, (), NS_ERROR_UNEXPECTED); + ErrorResult rv; Minimize(rv); return rv.StealNSResult(); @@ -13780,6 +13634,8 @@ nsGlobalChromeWindow::Minimize() void nsGlobalWindow::Minimize(ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsCOMPtr widget = GetMainWidget(); if (widget) { @@ -13790,6 +13646,8 @@ nsGlobalWindow::Minimize(ErrorResult& aError) NS_IMETHODIMP nsGlobalChromeWindow::Restore() { + FORWARD_TO_INNER_CHROME(Restore, (), NS_ERROR_UNEXPECTED); + ErrorResult rv; Restore(rv); return rv.StealNSResult(); @@ -13798,6 +13656,8 @@ nsGlobalChromeWindow::Restore() void nsGlobalWindow::Restore(ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsCOMPtr widget = GetMainWidget(); if (widget) { @@ -13808,6 +13668,8 @@ nsGlobalWindow::Restore(ErrorResult& aError) NS_IMETHODIMP nsGlobalChromeWindow::GetAttention() { + FORWARD_TO_INNER_CHROME(GetAttention, (), NS_ERROR_UNEXPECTED); + ErrorResult rv; GetAttention(rv); return rv.StealNSResult(); @@ -13816,12 +13678,15 @@ nsGlobalChromeWindow::GetAttention() void nsGlobalWindow::GetAttention(ErrorResult& aResult) { + MOZ_ASSERT(IsInnerWindow()); return GetAttentionWithCycleCount(-1, aResult); } NS_IMETHODIMP nsGlobalChromeWindow::GetAttentionWithCycleCount(int32_t aCycleCount) { + FORWARD_TO_INNER_CHROME(GetAttentionWithCycleCount, (aCycleCount), NS_ERROR_UNEXPECTED); + ErrorResult rv; GetAttentionWithCycleCount(aCycleCount, rv); return rv.StealNSResult(); @@ -13831,6 +13696,8 @@ void nsGlobalWindow::GetAttentionWithCycleCount(int32_t aCycleCount, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsCOMPtr widget = GetMainWidget(); if (widget) { @@ -13841,6 +13708,8 @@ nsGlobalWindow::GetAttentionWithCycleCount(int32_t aCycleCount, NS_IMETHODIMP nsGlobalChromeWindow::BeginWindowMove(nsIDOMEvent *aMouseDownEvent, nsIDOMElement* aPanel) { + FORWARD_TO_INNER_CHROME(BeginWindowMove, (aMouseDownEvent, aPanel), NS_ERROR_UNEXPECTED); + NS_ENSURE_TRUE(aMouseDownEvent, NS_ERROR_FAILURE); Event* mouseDownEvent = aMouseDownEvent->InternalDOMEvent(); NS_ENSURE_TRUE(mouseDownEvent, NS_ERROR_FAILURE); @@ -13857,6 +13726,8 @@ void nsGlobalWindow::BeginWindowMove(Event& aMouseDownEvent, Element* aPanel, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); + nsCOMPtr widget; // if a panel was supplied, use its widget instead. @@ -14029,6 +13900,9 @@ nsGlobalWindow::SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserWindow, NS_IMETHODIMP nsGlobalChromeWindow::NotifyDefaultButtonLoaded(nsIDOMElement* aDefaultButton) { + FORWARD_TO_INNER_CHROME(NotifyDefaultButtonLoaded, + (aDefaultButton), NS_ERROR_UNEXPECTED); + nsCOMPtr defaultButton = do_QueryInterface(aDefaultButton); NS_ENSURE_ARG(defaultButton); @@ -14041,6 +13915,7 @@ void nsGlobalWindow::NotifyDefaultButtonLoaded(Element& aDefaultButton, ErrorResult& aError) { + MOZ_ASSERT(IsInnerWindow()); #ifdef MOZ_XUL // Don't snap to a disabled button. nsCOMPtr xulControl = diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 1788bafd37..a8ca0e642e 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -27,7 +27,6 @@ #include "nsIBrowserDOMWindow.h" #include "nsIDOMEventTarget.h" #include "nsIInterfaceRequestor.h" -#include "nsIDOMJSWindow.h" #include "nsIDOMChromeWindow.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptObjectPrincipal.h" @@ -325,7 +324,6 @@ class nsGlobalWindow : public mozilla::dom::EventTarget, public nsPIDOMWindow, public nsIScriptGlobalObject, public nsIScriptObjectPrincipal, - public nsIDOMJSWindow, public nsSupportsWeakReference, public nsIInterfaceRequestor, public PRCListStr @@ -385,8 +383,15 @@ public: // nsIDOMWindow NS_DECL_NSIDOMWINDOW - // nsIDOMJSWindow - NS_DECL_NSIDOMJSWINDOW + nsresult + OpenJS(const nsAString& aUrl, const nsAString& aName, + const nsAString& aOptions, nsIDOMWindow **_retval); + void CaptureEvents(); + void ReleaseEvents(); + void Dump(const nsAString& aStr); + void SetResizable(bool aResizable) const; + nsresult GetScriptableContent(JSContext* aCx, + JS::MutableHandle aVal); // nsIDOMEventTarget NS_DECL_NSIDOMEVENTTARGET @@ -496,7 +501,8 @@ public: NS_DECL_NSIINTERFACEREQUESTOR // WebIDL interface. - already_AddRefed IndexedGetter(uint32_t aIndex, bool& aFound); + already_AddRefed IndexedGetterOuter(uint32_t aIndex); + already_AddRefed IndexedGetter(uint32_t aIndex); void GetSupportedNames(nsTArray& aNames); @@ -1040,7 +1046,6 @@ public: int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback, mozilla::ErrorResult& aError); void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError); - nsPerformance* GetPerformance(); #ifdef MOZ_WEBSPEECH mozilla::dom::SpeechSynthesis* GetSpeechSynthesis(mozilla::ErrorResult& aError); @@ -1049,18 +1054,6 @@ public: GetDefaultComputedStyle(mozilla::dom::Element& aElt, const nsAString& aPseudoElt, mozilla::ErrorResult& aError); - int32_t MozRequestAnimationFrame(nsIFrameRequestCallback* aRequestCallback, - mozilla::ErrorResult& aError); - void MozCancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError) - { - return CancelAnimationFrame(aHandle, aError); - } - void MozCancelRequestAnimationFrame(int32_t aHandle, - mozilla::ErrorResult& aError) - { - return CancelAnimationFrame(aHandle, aError); - } - int64_t GetMozAnimationStartTime(mozilla::ErrorResult& aError); void SizeToContentOuter(mozilla::ErrorResult& aError); void SizeToContent(mozilla::ErrorResult& aError); mozilla::dom::Crypto* GetCrypto(mozilla::ErrorResult& aError); @@ -1589,9 +1582,6 @@ protected: // Returns device pixels. Outer windows only. nsIntPoint GetScreenXY(mozilla::ErrorResult& aError); - int32_t RequestAnimationFrame(const nsIDocument::FrameRequestCallbackHolder& aCallback, - mozilla::ErrorResult& aError); - nsGlobalWindow* InnerForSetTimeoutOrInterval(mozilla::ErrorResult& aError); void PostMessageMozOuter(JSContext* aCx, JS::Handle aMessage, diff --git a/dom/base/nsIDocument.h b/dom/base/nsIDocument.h index ecc1673fea..c1ded381e4 100644 --- a/dom/base/nsIDocument.h +++ b/dom/base/nsIDocument.h @@ -2156,14 +2156,11 @@ public: virtual mozilla::dom::DocumentTimeline* Timeline() = 0; - typedef mozilla::dom::CallbackObjectHolder< - mozilla::dom::FrameRequestCallback, - nsIFrameRequestCallback> FrameRequestCallbackHolder; - nsresult ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCallback, + nsresult ScheduleFrameRequestCallback(mozilla::dom::FrameRequestCallback& aCallback, int32_t *aHandle); void CancelFrameRequestCallback(int32_t aHandle); - typedef nsTArray FrameRequestCallbackList; + typedef nsTArray> FrameRequestCallbackList; /** * Put this document's frame request callbacks into the provided * list, and forget about them. diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 8dbe684b85..5bc0b08937 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1926,8 +1926,6 @@ addExternalIface('imgIRequest', nativeType='imgIRequest', notflattened=True) addExternalIface('MenuBuilder', nativeType='nsIMenuBuilder', notflattened=True) addExternalIface('MozControllers', nativeType='nsIControllers') addExternalIface('MozFrameLoader', nativeType='nsIFrameLoader', notflattened=True) -addExternalIface('MozFrameRequestCallback', nativeType='nsIFrameRequestCallback', - notflattened=True) addExternalIface('MozMmsMessage') addExternalIface('MozObserver', nativeType='nsIObserver', notflattened=True) addExternalIface('MozRDFCompositeDataSource', nativeType='nsIRDFCompositeDataSource', diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index d56fc55068..4de96315b3 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -7917,23 +7917,23 @@ class CGJsonifierMethod(CGSpecializedMethod): } """) - jsonInterfaces = [] - interface = self.descriptor.interface + jsonDescriptors = [ self.descriptor ] + interface = self.descriptor.interface.parent while interface: descriptor = self.descriptor.getDescriptor(interface.identifier.name) if descriptor.operations['Jsonifier']: - jsonInterfaces.append(interface) + jsonDescriptors.append(descriptor) interface = interface.parent # Iterate the array in reverse: oldest ancestor first - for interface in jsonInterfaces[::-1]: + for descriptor in jsonDescriptors[::-1]: ret += fill( """ if (!${parentclass}::JsonifyAttributes(cx, obj, self, result)) { return false; } """, - parentclass=toBindingNamespace(interface.identifier.name) + parentclass=toBindingNamespace(descriptor.name) ) ret += ('args.rval().setObject(*result);\n' 'return true;\n') diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp index 1a53cbcb03..1124121c3d 100644 --- a/dom/html/nsHTMLDocument.cpp +++ b/dom/html/nsHTMLDocument.cpp @@ -103,7 +103,6 @@ #include "nsIRequest.h" #include "nsHtml5TreeOpExecutor.h" #include "nsHtml5Parser.h" -#include "nsIDOMJSWindow.h" #include "nsSandboxFlags.h" #include "nsIImageDocument.h" #include "mozilla/dom/HTMLBodyElement.h" @@ -1402,12 +1401,17 @@ nsHTMLDocument::Open(JSContext* /* unused */, NS_ASSERTION(nsContentUtils::CanCallerAccess(static_cast(this)), "XOW should have caught this!"); - nsCOMPtr window = GetInnerWindow(); + nsCOMPtr window = GetInnerWindow(); if (!window) { rv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR); return nullptr; } - nsCOMPtr win = do_QueryInterface(window); + window = nsPIDOMWindow::GetOuterFromCurrentInner(window); + if (!window) { + rv.Throw(NS_ERROR_NOT_INITIALIZED); + return nullptr; + } + nsRefPtr win = static_cast(window.get()); nsCOMPtr newWindow; // XXXbz We ignore aReplace for now. rv = win->OpenJS(aURL, aName, aFeatures, getter_AddRefs(newWindow)); diff --git a/dom/interfaces/base/moz.build b/dom/interfaces/base/moz.build index e30e7c82b6..db3e7736b8 100644 --- a/dom/interfaces/base/moz.build +++ b/dom/interfaces/base/moz.build @@ -18,7 +18,6 @@ XPIDL_SOURCES += [ 'nsIDOMCrypto.idl', 'nsIDOMGlobalPropertyInitializer.idl', 'nsIDOMHistory.idl', - 'nsIDOMJSWindow.idl', 'nsIDOMLocation.idl', 'nsIDOMModalContentWindow.idl', 'nsIDOMNavigator.idl', @@ -27,7 +26,6 @@ XPIDL_SOURCES += [ 'nsIDOMWindowCollection.idl', 'nsIDOMWindowUtils.idl', 'nsIFocusManager.idl', - 'nsIFrameRequestCallback.idl', 'nsIIdleObserver.idl', 'nsIQueryContentEventResult.idl', 'nsIRemoteBrowser.idl', diff --git a/dom/interfaces/base/nsIDOMJSWindow.idl b/dom/interfaces/base/nsIDOMJSWindow.idl deleted file mode 100644 index 62bcc9650a..0000000000 --- a/dom/interfaces/base/nsIDOMJSWindow.idl +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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/. */ - -#include "domstubs.idl" - -[scriptable, uuid(e0f739e3-47e2-4007-af30-181939e97a51)] -interface nsIDOMJSWindow : nsISupports -{ - void dump(in DOMString str); - - /** - * These methods take one optional argument that's the timer ID to - * clear. Often in existing code these methods are passed undefined, - * which is a nop so we need to support that as well. - */ - void clearTimeout([optional] in long handle); - void clearInterval([optional] in long handle); - - /** - * This method is here for backwards compatibility with 4.x only, - * its implementation is a no-op - */ - void setResizable(in boolean resizable); - - /** - * @deprecated These are old Netscape 4 methods. Do not use, - * the implementation is no-op. - */ - void captureEvents(); - void releaseEvents(); - - /** - * This is the scriptable version of nsIDOMWindow::open() - * that takes 3 optional arguments. Its binary name is OpenJS to - * avoid colliding with nsIDOMWindow::open(), which has the - * same signature. The reason we can't have that collision is that - * the implementation needs to know whether it was called from JS or - * not. - * - * IOW, DO NOT CALL THIS FROM C++ - */ - [binaryname(OpenJS)] nsIDOMWindow open([optional] in DOMString url, - [optional] in DOMString name, - [optional] in DOMString options); - - /** - * This is the scriptable version of - * nsIDOMWindow::openDialog() that takes 3 optional - * arguments, plus any additional arguments are passed on as - * arguments on the dialog's window object (window.arguments). - */ - nsIDOMWindow openDialog([optional] in DOMString url, - [optional] in DOMString name, - [optional] in DOMString options); - - /** - * window.frames in Netscape 4.x and IE is just a reference to the - * window itself (i.e. window.frames === window), but this doesn't - * make sense from a generic API point of view so that's why this is - * JS specific. - * - * This property is "replaceable" in JavaScript. - */ - readonly attribute nsIDOMWindow frames; - - [implicit_jscontext, binaryname(ScriptableContent)] - readonly attribute jsval content; -}; diff --git a/dom/interfaces/base/nsIDOMWindow.idl b/dom/interfaces/base/nsIDOMWindow.idl index fa30106cac..b583adc043 100644 --- a/dom/interfaces/base/nsIDOMWindow.idl +++ b/dom/interfaces/base/nsIDOMWindow.idl @@ -5,7 +5,6 @@ #include "domstubs.idl" -interface nsIFrameRequestCallback; interface nsIControllers; interface nsIDOMBlob; interface nsIDOMLocation; @@ -23,7 +22,7 @@ interface nsIVariant; * @see */ -[scriptable, uuid(8146f3fc-9fc1-47c5-85ef-95d686e4ca6d)] +[scriptable, uuid(7e26f1bd-a694-4b65-8d9d-9eead0645fe3)] interface nsIDOMWindow : nsISupports { // the current browsing context @@ -377,9 +376,6 @@ interface nsIDOMWindow : nsISupports * * @see */ - // Argument is optional only so we can warn when it's null - long - mozRequestAnimationFrame([optional] in nsIFrameRequestCallback aCallback); // jsval because we want a WebIDL callback here [implicit_jscontext] long requestAnimationFrame(in jsval aCallback); @@ -387,16 +383,8 @@ interface nsIDOMWindow : nsISupports /** * Cancel a refresh callback. */ - void mozCancelAnimationFrame(in long aHandle); - // Backwards-compat shim for now to make Google maps work - void mozCancelRequestAnimationFrame(in long aHandle); void cancelAnimationFrame(in long aHandle); - /** - * The current animation start time in milliseconds since the epoch. - */ - readonly attribute long long mozAnimationStartTime; - /** * Console API */ diff --git a/dom/interfaces/base/nsIDOMWindowUtils.idl b/dom/interfaces/base/nsIDOMWindowUtils.idl index 310ce89f6d..2d0976734c 100644 --- a/dom/interfaces/base/nsIDOMWindowUtils.idl +++ b/dom/interfaces/base/nsIDOMWindowUtils.idl @@ -49,7 +49,7 @@ interface nsIJSRAIIHelper; interface nsIContentPermissionRequest; interface nsIObserver; -[scriptable, uuid(bbcb87fb-ce2e-4e05-906b-9258687664e2)] +[scriptable, uuid(7a37e173-ea6e-495e-8702-013f8063352a)] interface nsIDOMWindowUtils : nsISupports { /** @@ -1423,6 +1423,13 @@ interface nsIDOMWindowUtils : nsISupports { */ readonly attribute bool isTestControllingRefreshes; + /** + * Reports whether APZ is enabled on the widget that this window is attached + * to. If there is no widget it will report the default platform value of + * whether or not APZ is enabled. + */ + readonly attribute bool asyncPanZoomEnabled; + /** * Set async scroll offset on an element. The next composite will render * with that offset if async scrolling is enabled, and then the offset diff --git a/dom/interfaces/base/nsIFrameRequestCallback.idl b/dom/interfaces/base/nsIFrameRequestCallback.idl deleted file mode 100644 index e6957c425c..0000000000 --- a/dom/interfaces/base/nsIFrameRequestCallback.idl +++ /dev/null @@ -1,18 +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/. */ - -/** - * Interface that represents a callback to be passed to requestAnimationFrame - */ - -#include "domstubs.idl" - -[scriptable, function, uuid(e8d887f0-2ed7-406f-9f1d-edeb2c54c0a2)] -interface nsIFrameRequestCallback : nsISupports -{ - /** - * The timestamp is the time to be used for the animation sample. - */ - void sample(in DOMTimeStamp timeStamp); -}; diff --git a/dom/locales/en-US/chrome/dom/dom.properties b/dom/locales/en-US/chrome/dom/dom.properties index eb5757280f..a0bab702de 100644 --- a/dom/locales/en-US/chrome/dom/dom.properties +++ b/dom/locales/en-US/chrome/dom/dom.properties @@ -66,8 +66,6 @@ nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated. Please use JSON.pa nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated. Please use JSON.stringify instead. nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead. InputEncodingWarning=Use of inputEncoding is deprecated. -# LOCALIZATION NOTE: Do not translate "MozBeforePaint" and "mozRequestAnimationFrame" -MozBeforePaintWarning=MozBeforePaint events are no longer supported. mozRequestAnimationFrame must be passed a non-null callback argument. FullScreenDeniedBlocked=Request for full-screen was denied because this domain has been blocked from full-screen by user. FullScreenDeniedDisabled=Request for full-screen was denied because full-screen API is disabled by user preference. FullScreenDeniedFocusedPlugin=Request for full-screen was denied because a windowed plugin is focused. diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 7e3f13fbf1..813be98f14 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -17,7 +17,6 @@ interface ApplicationCache; interface IID; -interface MozFrameRequestCallback; interface nsIBrowserDOMWindow; interface nsIMessageBroadcaster; interface nsIDOMCrypto; @@ -276,20 +275,6 @@ partial interface Window { //[NewObject, Throws] CSSStyleDeclaration getDefaultComputedStyle(Element elt, optional DOMString pseudoElt = ""); [NewObject, Throws] CSSStyleDeclaration? getDefaultComputedStyle(Element elt, optional DOMString pseudoElt = ""); - [Throws] long mozRequestAnimationFrame(MozFrameRequestCallback aCallback); - - /** - * Cancel a refresh callback. - */ - [Throws] void mozCancelAnimationFrame(long aHandle); - // Backwards-compat shim for now to make Google maps work - [Throws] void mozCancelRequestAnimationFrame(long aHandle); - - /** - * The current animation start time in milliseconds since the epoch. - */ - [Throws] readonly attribute long long mozAnimationStartTime; - // Mozilla extensions /** * Method for scrolling this window by a number of lines. diff --git a/dom/workers/ServiceWorkerManager.cpp b/dom/workers/ServiceWorkerManager.cpp index a2a0fc5de4..d8de02ab3e 100644 --- a/dom/workers/ServiceWorkerManager.cpp +++ b/dom/workers/ServiceWorkerManager.cpp @@ -4055,11 +4055,8 @@ FireControllerChangeOnDocument(nsIDocument* aDocument) nsCOMPtr w = aDocument->GetWindow(); MOZ_ASSERT(w); + w = w->GetCurrentInnerWindow(); auto* window = static_cast(w.get()); - if (NS_WARN_IF(!window)) { - NS_WARNING("No valid nsGlobalWindow"); - return; - } ErrorResult result; dom::Navigator* navigator = window->GetNavigator(result); diff --git a/js/public/Fifo.h b/js/public/Fifo.h new file mode 100644 index 0000000000..de482e7a24 --- /dev/null +++ b/js/public/Fifo.h @@ -0,0 +1,154 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/. */ + +#ifndef js_Fifo_h +#define js_Fifo_h + +#include "mozilla/Move.h" + +#include "js/Vector.h" + +namespace js { + +// A first-in-first-out queue container type. Fifo calls constructors and +// destructors of all elements added so non-PODs may be used safely. |Fifo| +// stores the first |MinInlineCapacity| elements in-place before resorting to +// dynamic allocation. +// +// T requirements: +// - Either movable or copyable. +// MinInlineCapacity requirements: +// - Must be even. +// AllocPolicy: +// - see "Allocation policies" in AllocPolicy.h +template +class Fifo +{ + static_assert(MinInlineCapacity % 2 == 0, "MinInlineCapacity must be even!"); + + protected: + // An element A is "younger" than an element B if B was inserted into the + // |Fifo| before A was. + // + // Invariant 1: Every element within |front_| is younger than every element + // within |rear_|. + // Invariant 2: Entries within |front_| are sorted from younger to older. + // Invariant 3: Entries within |rear_| are sorted from older to younger. + // Invariant 4: If the |Fifo| is not empty, then |front_| is not empty. + Vector front_; + Vector rear_; + + private: + // Maintain invariants after adding or removing entries. + bool fixup() { + if (!front_.empty()) + return true; + + if (!front_.reserve(rear_.length())) + return false; + + while (!rear_.empty()) { + front_.infallibleAppend(mozilla::Move(rear_.back())); + rear_.popBack(); + } + + return true; + } + + public: + explicit Fifo(AllocPolicy alloc = AllocPolicy()) + : front_(alloc) + , rear_(alloc) + { } + + Fifo(Fifo&& rhs) + : front_(mozilla::Move(rhs.front_)) + , rear_(mozilla::Move(rhs.rear_)) + { } + + Fifo& operator=(Fifo&& rhs) { + MOZ_ASSERT(&rhs != this, "self-move disallowed"); + this->~Fifo(); + new (this) Fifo(mozilla::Move(rhs)); + return *this; + } + + Fifo(const Fifo&) = delete; + Fifo& operator=(const Fifo&) = delete; + + size_t length() const { + MOZ_ASSERT_IF(rear_.length() > 0, front_.length() > 0); // Invariant 4. + return front_.length() + rear_.length(); + } + + bool empty() const { + MOZ_ASSERT_IF(rear_.length() > 0, front_.length() > 0); // Invariant 4. + return front_.empty(); + } + + // Push an element to the back of the queue. This method can take either a + // |const T&| or a |T&&|. + template + bool pushBack(U&& u) { + if (!rear_.append(mozilla::Forward(u))) + return false; + if (!fixup()) { + rear_.popBack(); + return false; + } + return true; + } + + // Construct a T in-place at the back of the queue. + template + bool emplaceBack(Args&&... args) { + if (!rear_.emplaceBack(mozilla::Forward(args)...)) + return false; + if (!fixup()) { + rear_.popBack(); + return false; + } + return true; + } + + // Access the element at the front of the queue. + T& front() { + MOZ_ASSERT(!empty()); + return front_.back(); + } + const T& front() const { + MOZ_ASSERT(!empty()); + return front_.back(); + } + + // Remove the front element from the queue. + bool popFront() { + MOZ_ASSERT(!empty()); + T t(mozilla::Move(front())); + front_.popBack(); + if (!fixup()) { + // Attempt to remain in a valid state by reinserting the element + // back at the front. If we can't remain in a valid state in the + // face of OOMs, crash. + if (!front_.append(mozilla::Move(t))) + CrashAtUnhandlableOOM("js::Fifo::popFront"); + return false; + } + return true; + } + + // Clear all elements from the queue. + void clear() { + front_.clear(); + rear_.clear(); + } +}; + +} // namespace js + +#endif /* js_Fifo_h */ diff --git a/js/public/TraceableFifo.h b/js/public/TraceableFifo.h new file mode 100644 index 0000000000..b39e1a5649 --- /dev/null +++ b/js/public/TraceableFifo.h @@ -0,0 +1,130 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sts=4 et sw=4 tw=99: + * 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/. */ + +#ifndef js_TraceableFifo_h +#define js_TraceableFifo_h + +#include "js/RootingAPI.h" +#include "js/Fifo.h" + +namespace js { + +template struct DefaultTracer; + +// A TraceableFifo is a Fifo with an additional trace method that knows how to +// visit all of the items stored in the Fifo. For Fifos that contain GC things, +// this is usually more convenient than manually iterating and marking the +// contents. +// +// Most types of GC pointers as keys and values can be traced with no extra +// infrastructure. For structs and non-gc-pointer members, ensure that there is +// a specialization of DefaultTracer with an appropriate trace method +// available to handle the custom type. +// +// Note that although this Fifo's trace will deal correctly with moved items, it +// does not itself know when to barrier or trace items. To function properly it +// must either be used with Rooted, or barriered and traced manually. +template > +class TraceableFifo + : public js::Fifo, + public JS::Traceable +{ + using Base = js::Fifo; + + public: + explicit TraceableFifo(AllocPolicy alloc = AllocPolicy()) : Base(alloc) {} + + TraceableFifo(TraceableFifo&& rhs) : Base(mozilla::Move(rhs)) { } + TraceableFifo& operator=(TraceableFifo&& rhs) { return Base::operator=(mozilla::Move(rhs)); } + + TraceableFifo(const TraceableFifo&) = delete; + TraceableFifo& operator=(const TraceableFifo&) = delete; + + static void trace(TraceableFifo* tf, JSTracer* trc) { + for (size_t i = 0; i < tf->front_.length(); ++i) + TraceFunc::trace(trc, &tf->front_[i], "fifo element"); + for (size_t i = 0; i < tf->rear_.length(); ++i) + TraceFunc::trace(trc, &tf->rear_[i], "fifo element"); + } +}; + +template +class TraceableFifoOperations +{ + using TF = TraceableFifo; + const TF& fifo() const { return static_cast(this)->extract(); } + + public: + size_t length() const { return fifo().length(); } + bool empty() const { return fifo().empty(); } + const T& front() const { return fifo().front(); } +}; + +template +class MutableTraceableFifoOperations + : public TraceableFifoOperations +{ + using TF = TraceableFifo; + TF& fifo() { return static_cast(this)->extract(); } + + public: + T& front() { return fifo().front(); } + + template bool pushBack(U&& u) { return fifo().pushBack(mozilla::Forward(u)); } + template bool emplaceBack(Args&&... args) { + return fifo().emplaceBack(mozilla::Forward(args...)); + } + + bool popFront() { return fifo().popFront(); } + void clear() { fifo().clear(); } +}; + +template +class RootedBase> + : public MutableTraceableFifoOperations>, A,B,C,D> +{ + using TF = TraceableFifo; + + friend class TraceableFifoOperations, A,B,C,D>; + const TF& extract() const { return *static_cast*>(this)->address(); } + + friend class MutableTraceableFifoOperations, A,B,C,D>; + TF& extract() { return *static_cast*>(this)->address(); } +}; + +template +class MutableHandleBase> + : public MutableTraceableFifoOperations>, A,B,C,D> +{ + using TF = TraceableFifo; + + friend class TraceableFifoOperations, A,B,C,D>; + const TF& extract() const { + return *static_cast*>(this)->address(); + } + + friend class MutableTraceableFifoOperations, A,B,C,D>; + TF& extract() { return *static_cast*>(this)->address(); } +}; + +template +class HandleBase> + : public TraceableFifoOperations>, A,B,C,D> +{ + using TF = TraceableFifo; + + friend class TraceableFifoOperations, A,B,C,D>; + const TF& extract() const { + return *static_cast*>(this)->address(); + } +}; + +} // namespace js + +#endif // js_TraceableFifo_h diff --git a/js/public/Utility.h b/js/public/Utility.h index d533d12c49..4a26baab2a 100644 --- a/js/public/Utility.h +++ b/js/public/Utility.h @@ -120,6 +120,45 @@ static inline bool ShouldFailWithOOM() { return false; } # endif /* DEBUG || JS_OOM_BREAKPOINT */ +namespace js { + +MOZ_NORETURN MOZ_COLD void +CrashAtUnhandlableOOM(const char* reason); + +/* Disable OOM testing in sections which are not OOM safe. */ +struct MOZ_RAII AutoEnterOOMUnsafeRegion +{ + void crash(const char* reason) { + CrashAtUnhandlableOOM(reason); + } + +#if defined(DEBUG) || defined(JS_OOM_BREAKPOINT) + AutoEnterOOMUnsafeRegion() + : oomEnabled_(OOM_maxAllocations != UINT32_MAX), oomAfter_(0) + { + if (oomEnabled_) { + oomAfter_ = int64_t(OOM_maxAllocations) - OOM_counter; + OOM_maxAllocations = UINT32_MAX; + } + } + + ~AutoEnterOOMUnsafeRegion() { + MOZ_ASSERT(OOM_maxAllocations == UINT32_MAX); + if (oomEnabled_) { + int64_t maxAllocations = OOM_counter + oomAfter_; + MOZ_ASSERT(maxAllocations >= 0 && maxAllocations < UINT32_MAX); + OOM_maxAllocations = uint32_t(maxAllocations); + } + } + + private: + bool oomEnabled_; + int64_t oomAfter_; +#endif +}; + +} /* namespace js */ + static inline void* js_malloc(size_t bytes) { JS_OOM_POSSIBLY_FAIL(); diff --git a/js/src/jsapi-tests/testGCExactRooting.cpp b/js/src/jsapi-tests/testGCExactRooting.cpp index 6d73875eed..2c17ee160b 100644 --- a/js/src/jsapi-tests/testGCExactRooting.cpp +++ b/js/src/jsapi-tests/testGCExactRooting.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "js/RootingAPI.h" +#include "js/TraceableFifo.h" #include "js/TraceableHashTable.h" #include "js/TraceableVector.h" @@ -311,6 +312,45 @@ receiveMutableHandleToShapeVector(JS::MutableHandle> han } END_TEST(testGCRootedVector) +BEGIN_TEST(testTraceableFifo) +{ + using ShapeFifo = TraceableFifo; + JS::Rooted shapes(cx, ShapeFifo(cx)); + CHECK(shapes.empty()); + + for (size_t i = 0; i < 10; ++i) { + RootedObject obj(cx, JS_NewObject(cx, nullptr)); + RootedValue val(cx, UndefinedValue()); + // Construct a unique property name to ensure that the object creates a + // new shape. + char buffer[2]; + buffer[0] = 'a' + i; + buffer[1] = '\0'; + CHECK(JS_SetProperty(cx, obj, buffer, val)); + CHECK(shapes.pushBack(obj->as().lastProperty())); + } + + CHECK(shapes.length() == 10); + + JS_GC(rt); + JS_GC(rt); + + for (size_t i = 0; i < 10; ++i) { + // Check the shape to ensure it did not get collected. + char buffer[2]; + buffer[0] = 'a' + i; + buffer[1] = '\0'; + bool match; + CHECK(JS_StringEqualsAscii(cx, JSID_TO_STRING(shapes.front()->propid()), buffer, &match)); + CHECK(match); + CHECK(shapes.popFront()); + } + + CHECK(shapes.empty()); + return true; +} +END_TEST(testTraceableFifo) + using ShapeVec = TraceableVector; static bool diff --git a/js/src/jsgc.h b/js/src/jsgc.h index ffbaaac4d6..1db9b708ff 100644 --- a/js/src/jsgc.h +++ b/js/src/jsgc.h @@ -1313,33 +1313,6 @@ class AutoSuppressGC } }; -#ifdef DEBUG -/* Disable OOM testing in sections which are not OOM safe. */ -class AutoEnterOOMUnsafeRegion -{ - bool oomEnabled_; - int64_t oomAfter_; - - public: - AutoEnterOOMUnsafeRegion() - : oomEnabled_(OOM_maxAllocations != UINT32_MAX) - { - if (oomEnabled_) { - oomAfter_ = OOM_maxAllocations - OOM_counter; - OOM_maxAllocations = UINT32_MAX; - } - } - - ~AutoEnterOOMUnsafeRegion() { - MOZ_ASSERT(OOM_maxAllocations == UINT32_MAX); - if (oomEnabled_) - OOM_maxAllocations = OOM_counter + oomAfter_; - } -}; -#else -class AutoEnterOOMUnsafeRegion {}; -#endif /* DEBUG */ - // A singly linked list of zones. class ZoneList { diff --git a/js/src/jsutil.h b/js/src/jsutil.h index d33f45ad26..c47755d510 100644 --- a/js/src/jsutil.h +++ b/js/src/jsutil.h @@ -45,9 +45,6 @@ js_memcpy(void* dst_, const void* src_, size_t len) namespace js { -MOZ_NORETURN MOZ_COLD void -CrashAtUnhandlableOOM(const char* reason); - template struct AlignmentTestStruct { diff --git a/js/src/moz.build b/js/src/moz.build index 75a1d2fe86..1ce99155a5 100644 --- a/js/src/moz.build +++ b/js/src/moz.build @@ -109,6 +109,7 @@ EXPORTS.js += [ '../public/Conversions.h', '../public/Date.h', '../public/Debug.h', + '../public/Fifo.h', '../public/GCAPI.h', '../public/HashTable.h', '../public/HeapAPI.h', @@ -123,6 +124,7 @@ EXPORTS.js += [ '../public/RootingAPI.h', '../public/SliceBudget.h', '../public/StructuredClone.h', + '../public/TraceableFifo.h', '../public/TraceableHashTable.h', '../public/TraceableVector.h', '../public/TraceKind.h', diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index c6f02699c6..033acbb778 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1417,8 +1417,7 @@ XPCWrappedNativeXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsW nsGlobalWindow* win = AsWindow(cx, wrapper); // Note: As() unwraps outer windows to get to the inner window. if (win) { - bool unused; - nsCOMPtr subframe = win->IndexedGetter(index, unused); + nsCOMPtr subframe = win->IndexedGetter(index); if (subframe) { nsGlobalWindow* global = static_cast(subframe.get()); global->EnsureInnerWindow(); @@ -1564,8 +1563,7 @@ DOMXrayTraits::resolveOwnProperty(JSContext* cx, const Wrapper& jsWrapper, Handl nsGlobalWindow* win = AsWindow(cx, wrapper); // Note: As() unwraps outer windows to get to the inner window. if (win) { - bool unused; - nsCOMPtr subframe = win->IndexedGetter(index, unused); + nsCOMPtr subframe = win->IndexedGetter(index); if (subframe) { nsGlobalWindow* global = static_cast(subframe.get()); global->EnsureInnerWindow(); diff --git a/layout/base/nsRefreshDriver.cpp b/layout/base/nsRefreshDriver.cpp index de05ec3f59..a37d44d5b6 100644 --- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -48,7 +48,6 @@ #include "RestyleManager.h" #include "Layers.h" #include "imgIContainer.h" -#include "nsIFrameRequestCallback.h" #include "mozilla/dom/ScriptSettings.h" #include "nsDocShell.h" #include "nsISimpleEnumerator.h" @@ -1528,7 +1527,6 @@ nsRefreshDriver::RunFrameRequestCallbacks(int64_t aNowEpoch, TimeStamp aNowTime) if (!frameRequestCallbacks.IsEmpty()) { profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_START); - int64_t eventTime = aNowEpoch / PR_USEC_PER_MSEC; for (const DocumentFrameCallbacks& docCallbacks : frameRequestCallbacks) { // XXXbz Bug 863140: GetInnerWindow can return the outer // window in some cases. @@ -1541,15 +1539,10 @@ nsRefreshDriver::RunFrameRequestCallbacks(int64_t aNowEpoch, TimeStamp aNowTime) } // else window is partially torn down already } - for (const nsIDocument::FrameRequestCallbackHolder& holder : - docCallbacks.mCallbacks) { - nsAutoMicroTask mt; - if (holder.HasWebIDLCallback()) { - ErrorResult ignored; - holder.GetWebIDLCallback()->Call(timeStamp, ignored); - } else { - holder.GetXPCOMCallback()->Sample(eventTime); - } + for (auto& callback : docCallbacks.mCallbacks) { + ErrorResult ignored; + callback->Call(timeStamp, ignored); + ignored.SuppressException(); } } profiler_tracing("Paint", "Scripts", TRACING_INTERVAL_END); diff --git a/layout/base/nsRefreshDriver.h b/layout/base/nsRefreshDriver.h index a325898947..87831faa9c 100644 --- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -213,12 +213,12 @@ public: } /** - * Add a document for which we have nsIFrameRequestCallbacks + * Add a document for which we have FrameRequestCallbacks */ void ScheduleFrameRequestCallbacks(nsIDocument* aDocument); /** - * Remove a document for which we have nsIFrameRequestCallbacks + * Remove a document for which we have FrameRequestCallbacks */ void RevokeFrameRequestCallbacks(nsIDocument* aDocument); diff --git a/layout/base/tests/file_bug607529.html b/layout/base/tests/file_bug607529.html index 443e48078a..9fbd7f3931 100644 --- a/layout/base/tests/file_bug607529.html +++ b/layout/base/tests/file_bug607529.html @@ -11,7 +11,7 @@ if (report) { opener.postMessage("callbackHappened", "*"); } - window.mozRequestAnimationFrame(g); + window.requestAnimationFrame(g); } g(); diff --git a/layout/base/tests/test_bug569520.html b/layout/base/tests/test_bug569520.html index 891780e10a..cd6e5ad869 100644 --- a/layout/base/tests/test_bug569520.html +++ b/layout/base/tests/test_bug569520.html @@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520 SimpleTest.waitForExplicitFinish(); SimpleTest.requestFlakyTimeout("untriaged"); -var startNow = Date.now(); -var start = window.mozAnimationStartTime; +var start = window.performance.now(); var firstListenerArg; var secondListenerArg; var thirdListenerTime; -// callback arg is wallclock from mozRequestAnimationFrame +// callback arg is in the same timeline as performance.now() function thirdListener(t) { thirdListenerTime = t; - // They really shouldn't be more than 100ms apart, but we can get weird - // effects on slow machines. 5 minutes is our test timeout, though. - ok(Math.abs(startNow - start) <= 5 * 60 * 1000, "Bogus animation start time"); - - ok(secondListenerArg >= firstListenerArg, // callback args from consecutive unprefixed requestAnimationFrame + ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame "Second listener should fire after first listener"); - ok(thirdListenerTime >= start, "Third listener should fire after start"); + ok(thirdListenerTime >= secondListenerArg, + "Third listener should fire after second listener"); + + ok(firstListenerArg >= start, "First listener should fire after start"); SimpleTest.finish(); } @@ -46,7 +44,7 @@ function thirdListener(t) { // callback arg is from requestAnimationFrame and comparable to performance.now() function secondListener(t) { secondListenerArg = t; - mozRequestAnimationFrame(thirdListener); + requestAnimationFrame(thirdListener); } function firstListener(t) { diff --git a/layout/base/tests/test_bug588174.html b/layout/base/tests/test_bug588174.html index 891780e10a..cd6e5ad869 100644 --- a/layout/base/tests/test_bug588174.html +++ b/layout/base/tests/test_bug588174.html @@ -21,24 +21,22 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=569520 SimpleTest.waitForExplicitFinish(); SimpleTest.requestFlakyTimeout("untriaged"); -var startNow = Date.now(); -var start = window.mozAnimationStartTime; +var start = window.performance.now(); var firstListenerArg; var secondListenerArg; var thirdListenerTime; -// callback arg is wallclock from mozRequestAnimationFrame +// callback arg is in the same timeline as performance.now() function thirdListener(t) { thirdListenerTime = t; - // They really shouldn't be more than 100ms apart, but we can get weird - // effects on slow machines. 5 minutes is our test timeout, though. - ok(Math.abs(startNow - start) <= 5 * 60 * 1000, "Bogus animation start time"); - - ok(secondListenerArg >= firstListenerArg, // callback args from consecutive unprefixed requestAnimationFrame + ok(secondListenerArg >= firstListenerArg, // callback args from consecutive requestAnimationFrame "Second listener should fire after first listener"); - ok(thirdListenerTime >= start, "Third listener should fire after start"); + ok(thirdListenerTime >= secondListenerArg, + "Third listener should fire after second listener"); + + ok(firstListenerArg >= start, "First listener should fire after start"); SimpleTest.finish(); } @@ -46,7 +44,7 @@ function thirdListener(t) { // callback arg is from requestAnimationFrame and comparable to performance.now() function secondListener(t) { secondListenerArg = t; - mozRequestAnimationFrame(thirdListener); + requestAnimationFrame(thirdListener); } function firstListener(t) { diff --git a/layout/base/tests/test_bug607529.html b/layout/base/tests/test_bug607529.html index ed0cc0c322..3329960843 100644 --- a/layout/base/tests/test_bug607529.html +++ b/layout/base/tests/test_bug607529.html @@ -19,7 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=607529 SimpleTest.waitForExplicitFinish(); /* General idea: Open a new window (needed because we don't bfcache - subframes) that uses mozRequestAnimationFrame, navigate it, navigate it + subframes) that uses requestAnimationFrame, navigate it, navigate it back, and verify that the animations are still running. */ var doneOneLoad = false; diff --git a/layout/base/tests/test_scroll_event_ordering.html b/layout/base/tests/test_scroll_event_ordering.html index 8dd67d6426..be1764a7ad 100644 --- a/layout/base/tests/test_scroll_event_ordering.html +++ b/layout/base/tests/test_scroll_event_ordering.html @@ -42,7 +42,7 @@ function onScroll() { function doTest() { window.getSelection().collapse(inner.firstChild, 0); - window.mozRequestAnimationFrame(onFrame); + window.requestAnimationFrame(onFrame); d.onscroll = onScroll; sendKey("DOWN"); } @@ -50,7 +50,7 @@ function doTest() { function prepareTest() { // Start the test after we've gotten at least one rAF callback, to make sure // that rAF is no longer throttled. (See bug 1145439.) - window.mozRequestAnimationFrame(function() { + window.requestAnimationFrame(function() { SpecialPowers.pushPrefEnv({"set":[[smoothScrollPref, false]]}, doTest); }); } diff --git a/layout/generic/test/test_bug791616.html b/layout/generic/test/test_bug791616.html index 51bdd6607d..5443c90c1d 100644 --- a/layout/generic/test/test_bug791616.html +++ b/layout/generic/test/test_bug791616.html @@ -48,7 +48,7 @@ function runTest() { // Delay until next repaint in case stuff is asynchronous. Also // take a trip through the event loop. setTimeout(function() { - window.mozRequestAnimationFrame(function() { + window.requestAnimationFrame(function() { is(sel.anchorNode, target.firstChild, "Should have selected 'target' text node"); is(sel.anchorOffset, 1, "Selection should have moved left one character"); // We should not have needed to scroll the caret into view diff --git a/layout/reftests/position-dynamic-changes/horizontal/animate.js b/layout/reftests/position-dynamic-changes/horizontal/animate.js index 867870de41..142004743f 100644 --- a/layout/reftests/position-dynamic-changes/horizontal/animate.js +++ b/layout/reftests/position-dynamic-changes/horizontal/animate.js @@ -5,8 +5,6 @@ var property = "left"; var rfa = null; if (window.requestAnimationFrame) { rfa = requestAnimationFrame; -} else if (window.mozRequestAnimationFrame) { - rfa = mozRequestAnimationFrame; } else if (window.webkitRequestAnimationFrame) { rfa = webkitRequestAnimationFrame; } else if (window.msRequestAnimationFrame) { diff --git a/layout/reftests/position-dynamic-changes/relative/animate.js b/layout/reftests/position-dynamic-changes/relative/animate.js index 592e84bd54..38598e1d34 100644 --- a/layout/reftests/position-dynamic-changes/relative/animate.js +++ b/layout/reftests/position-dynamic-changes/relative/animate.js @@ -1,8 +1,6 @@ var rfa = null; if (window.requestAnimationFrame) { rfa = requestAnimationFrame; -} else if (window.mozRequestAnimationFrame) { - rfa = mozRequestAnimationFrame; } else if (window.webkitRequestAnimationFrame) { rfa = webkitRequestAnimationFrame; } else if (window.msRequestAnimationFrame) { diff --git a/layout/reftests/position-dynamic-changes/vertical/animate.js b/layout/reftests/position-dynamic-changes/vertical/animate.js index ce4cd2c996..a53d6a1800 100644 --- a/layout/reftests/position-dynamic-changes/vertical/animate.js +++ b/layout/reftests/position-dynamic-changes/vertical/animate.js @@ -5,8 +5,6 @@ var property = "top"; var rfa = null; if (window.requestAnimationFrame) { rfa = requestAnimationFrame; -} else if (window.mozRequestAnimationFrame) { - rfa = mozRequestAnimationFrame; } else if (window.webkitRequestAnimationFrame) { rfa = webkitRequestAnimationFrame; } else if (window.msRequestAnimationFrame) { diff --git a/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc b/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc index 6349b5c222..04e49be7a2 100644 --- a/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc +++ b/media/webrtc/trunk/webrtc/modules/audio_coding/codecs/opus/audio_encoder_opus.cc @@ -12,6 +12,8 @@ #include "webrtc/modules/audio_coding/codecs/opus/interface/opus_interface.h" +#include + namespace webrtc { namespace { diff --git a/mfbt/Attributes.h b/mfbt/Attributes.h index 2815092f3a..c4b7bfc119 100644 --- a/mfbt/Attributes.h +++ b/mfbt/Attributes.h @@ -553,6 +553,24 @@ # define MOZ_NON_AUTOABLE /* nothing */ #endif /* MOZ_CLANG_PLUGIN */ +#define MOZ_RAII MOZ_NON_TEMPORARY_CLASS MOZ_STACK_CLASS + +/* + * MOZ_HAVE_REF_QUALIFIERS is defined for compilers that support C++11's rvalue + * qualifier, "&&". + */ +#if defined(_MSC_VER) && _MSC_VER >= 1900 +# define MOZ_HAVE_REF_QUALIFIERS +#elif defined(__clang__) +// All supported Clang versions +# define MOZ_HAVE_REF_QUALIFIERS +#elif defined(__GNUC__) +# include "mozilla/Compiler.h" +# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 1) +# define MOZ_HAVE_REF_QUALIFIERS +# endif +#endif + #endif /* __cplusplus */ #endif /* mozilla_Attributes_h */ diff --git a/toolkit/content/browser-content.js b/toolkit/content/browser-content.js index 3293e14af2..2cebe42c83 100644 --- a/toolkit/content/browser-content.js +++ b/toolkit/content/browser-content.js @@ -22,6 +22,7 @@ let ClickEventHandler = { this._screenX = null; this._screenY = null; this._lastFrame = null; + this.autoscrollLoop = this.autoscrollLoop.bind(this); Services.els.addSystemEventListener(global, "mousedown", this, true); @@ -136,9 +137,9 @@ let ClickEventHandler = { this._screenY = event.screenY; this._scrollErrorX = 0; this._scrollErrorY = 0; - this._lastFrame = content.mozAnimationStartTime; + this._lastFrame = content.performance.now(); - content.mozRequestAnimationFrame(this); + content.requestAnimationFrame(this.autoscrollLoop); }, stopScroll: function() { @@ -205,11 +206,7 @@ let ClickEventHandler = { this._scrollable.scrollLeft += actualScrollX; this._scrollable.scrollTop += actualScrollY; } - content.mozRequestAnimationFrame(this); - }, - - sample: function(timestamp) { - this.autoscrollLoop(timestamp); + content.requestAnimationFrame(this.autoscrollLoop); }, handleEvent: function(event) { diff --git a/toolkit/content/tests/browser/browser_autoscroll_disabled.js b/toolkit/content/tests/browser/browser_autoscroll_disabled.js index 10a25fb1d5..507026b092 100644 --- a/toolkit/content/tests/browser/browser_autoscroll_disabled.js +++ b/toolkit/content/tests/browser/browser_autoscroll_disabled.js @@ -43,7 +43,7 @@ function test() var skipFrames = 1; var checkScroll = function () { if (skipFrames--) { - window.mozRequestAnimationFrame(checkScroll); + window.requestAnimationFrame(checkScroll); return; } ok(elem.scrollTop == 0, "element should not have scrolled vertically"); @@ -70,6 +70,6 @@ function test() * so request and force redraws to get the chance to check for scrolling at * all. */ - window.mozRequestAnimationFrame(checkScroll); + window.requestAnimationFrame(checkScroll); } } diff --git a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js index 77963d2d8e..1685a976f9 100644 --- a/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js +++ b/toolkit/content/tests/browser/browser_bug295977_autoscroll_overflow.js @@ -117,7 +117,7 @@ function test() // although it also depends on acceleration, which here in this test // should be > 1 due to how it synthesizes mouse events below. if (timeCompensation < 5) { - window.mozRequestAnimationFrame(checkScroll); + window.requestAnimationFrame(checkScroll); return; } @@ -174,7 +174,7 @@ function test() Services.prefs.clearUserPref("middlemouse.paste"); // Start checking for the scroll. - window.mozRequestAnimationFrame(checkScroll); + window.requestAnimationFrame(checkScroll); } waitForExplicitFinish(); diff --git a/toolkit/content/widgets/browser.xml b/toolkit/content/widgets/browser.xml index 0d02053977..4997f50282 100644 --- a/toolkit/content/widgets/browser.xml +++ b/toolkit/content/widgets/browser.xml @@ -17,7 +17,7 @@ - + diff --git a/toolkit/content/widgets/scrollbox.xml b/toolkit/content/widgets/scrollbox.xml index 435133f6f8..123b0846db 100644 --- a/toolkit/content/widgets/scrollbox.xml +++ b/toolkit/content/widgets/scrollbox.xml @@ -292,13 +292,13 @@ this.distance = distance; this.startPos = this.scrollbox.scrollPosition; this.duration = Math.min(1000, Math.round(50 * Math.sqrt(Math.abs(distance)))); - this.startTime = window.mozAnimationStartTime; + this.startTime = window.performance.now(); if (!this.requestHandle) - this.requestHandle = window.mozRequestAnimationFrame(this); + this.requestHandle = window.requestAnimationFrame(this.sample.bind(this)); }, stop: function scrollAnim_stop() { - window.mozCancelAnimationFrame(this.requestHandle); + window.cancelAnimationFrame(this.requestHandle); this.requestHandle = 0; }, sample: function scrollAnim_handleEvent(timeStamp) { @@ -311,7 +311,7 @@ if (pos == 1) this.scrollbox._stopSmoothScroll(); else - this.requestHandle = window.mozRequestAnimationFrame(this); + this.requestHandle = window.requestAnimationFrame(this.sample.bind(this)); } })]]> @@ -677,12 +677,12 @@ scrollbox: this, requestHandle: 0, /* 0 indicates there is no pending request */ start: function arrowSmoothScroll_start() { - this.lastFrameTime = window.mozAnimationStartTime; + this.lastFrameTime = window.performance.now(); if (!this.requestHandle) - this.requestHandle = window.mozRequestAnimationFrame(this); + this.requestHandle = window.requestAnimationFrame(this.sample.bind(this)); }, stop: function arrowSmoothScroll_stop() { - window.mozCancelAnimationFrame(this.requestHandle); + window.cancelAnimationFrame(this.requestHandle); this.requestHandle = 0; }, sample: function arrowSmoothScroll_handleEvent(timeStamp) { @@ -693,7 +693,7 @@ const scrollDelta = 0.5 * timePassed * scrollIndex; this.scrollbox.scrollPosition += scrollDelta; - this.requestHandle = window.mozRequestAnimationFrame(this); + this.requestHandle = window.requestAnimationFrame(this.sample.bind(this)); } })]]> diff --git a/toolkit/devtools/debugger/test/browser_dbg_breakpoints-editor.js b/toolkit/devtools/debugger/test/browser_dbg_breakpoints-editor.js index c7174c8f8c..d86eb54069 100644 --- a/toolkit/devtools/debugger/test/browser_dbg_breakpoints-editor.js +++ b/toolkit/devtools/debugger/test/browser_dbg_breakpoints-editor.js @@ -224,7 +224,7 @@ function test() { "The first source should be currently selected."); let window = gEditor.container.contentWindow; - executeSoon(() => window.mozRequestAnimationFrame(onReadyForClick)); + executeSoon(() => window.requestAnimationFrame(onReadyForClick)); } function onReadyForClick() { diff --git a/toolkit/devtools/server/actors/canvas.js b/toolkit/devtools/server/actors/canvas.js index 873f5b132f..f0e642abc4 100644 --- a/toolkit/devtools/server/actors/canvas.js +++ b/toolkit/devtools/server/actors/canvas.js @@ -19,8 +19,7 @@ const CANVAS_CONTEXTS = [ ]; const ANIMATION_GENERATORS = [ - "requestAnimationFrame", - "mozRequestAnimationFrame" + "requestAnimationFrame" ]; const LOOP_GENERATORS = [ diff --git a/toolkit/devtools/tilt/tilt-visualizer.js b/toolkit/devtools/tilt/tilt-visualizer.js index bd74c6e742..7d7671b87b 100644 --- a/toolkit/devtools/tilt/tilt-visualizer.js +++ b/toolkit/devtools/tilt/tilt-visualizer.js @@ -453,6 +453,7 @@ TiltVisualizer.Presenter.prototype = { _loop: function TVP__loop() { let renderer = this._renderer; + let frameStartTime = this.chromeWindow.performance.now(); // if the renderer was destroyed, don't continue rendering if (!renderer || !renderer.context) { @@ -460,7 +461,7 @@ TiltVisualizer.Presenter.prototype = { } // prepare for the next frame of the animation loop - this.chromeWindow.mozRequestAnimationFrame(this._loop); + this.chromeWindow.requestAnimationFrame(this._loop); // only redraw if we really have to if (this._redraw) { @@ -473,17 +474,17 @@ TiltVisualizer.Presenter.prototype = { this._controllerUpdate(this._time, this._delta); } - this._handleFrameDelta(); + this._handleFrameDelta(frameStartTime); this._handleKeyframeNotifications(); }, /** * Calculates the current frame delta time. */ - _handleFrameDelta: function TVP__handleFrameDelta() + _handleFrameDelta: function TVP__handleFrameDelta(frameStartTime) { this._prevFrameTime = this._currFrameTime; - this._currFrameTime = this.chromeWindow.mozAnimationStartTime; + this._currFrameTime = frameStartTime; this._delta = this._currFrameTime - this._prevFrameTime; }, diff --git a/toolkit/modules/Timer.jsm b/toolkit/modules/Timer.jsm index 46bc3e6982..90a16b024e 100644 --- a/toolkit/modules/Timer.jsm +++ b/toolkit/modules/Timer.jsm @@ -5,10 +5,10 @@ "use strict"; /** - * JS module implementation of nsIDOMJSWindow.setTimeout and clearTimeout. + * JS module implementation of setTimeout and clearTimeout. */ -this.EXPORTED_SYMBOLS = ["setTimeout", "clearTimeout"]; +this.EXPORTED_SYMBOLS = ["setTimeout", "clearTimeout", "setInterval", "clearInterval"]; const Cc = Components.classes; const Ci = Components.interfaces; @@ -17,26 +17,38 @@ const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); // This gives us >=2^30 unique timer IDs, enough for 1 per ms for 12.4 days. -let gNextTimeoutId = 1; // setTimeout must return a positive integer +let gNextId = 1; // setTimeout and setInterval must return a positive integer -let gTimeoutTable = new Map(); // int -> nsITimer +let gTimerTable = new Map(); // int -> nsITimer this.setTimeout = function setTimeout(aCallback, aMilliseconds) { - let id = gNextTimeoutId++; + let id = gNextId++; let args = Array.slice(arguments, 2); let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); timer.initWithCallback(function setTimeout_timer() { - gTimeoutTable.delete(id); + gTimerTable.delete(id); aCallback.apply(null, args); }, aMilliseconds, timer.TYPE_ONE_SHOT); - gTimeoutTable.set(id, timer); + gTimerTable.set(id, timer); return id; } -this.clearTimeout = function clearTimeout(aId) { - if (gTimeoutTable.has(aId)) { - gTimeoutTable.get(aId).cancel(); - gTimeoutTable.delete(aId); +this.setInterval = function setInterval(aCallback, aMilliseconds) { + let id = gNextId++; + let args = Array.slice(arguments, 2); + let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback(function setInterval_timer() { + aCallback.apply(null, args); + }, aMilliseconds, timer.TYPE_REPEATING_SLACK); + + gTimerTable.set(id, timer); + return id; +} + +this.clearInterval = this.clearTimeout = function clearTimeout(aId) { + if (gTimerTable.has(aId)) { + gTimerTable.get(aId).cancel(); + gTimerTable.delete(aId); } } diff --git a/toolkit/modules/tests/xpcshell/test_timer.js b/toolkit/modules/tests/xpcshell/test_timer.js index e8dc8ac468..e8730a8b3b 100644 --- a/toolkit/modules/tests/xpcshell/test_timer.js +++ b/toolkit/modules/tests/xpcshell/test_timer.js @@ -8,23 +8,50 @@ let imported = {}; Components.utils.import("resource://gre/modules/Timer.jsm", imported); -function run_test(browser, tab, document) { - do_test_pending(); +function run_test() { + run_next_test(); +} - let timeout1 = imported.setTimeout(function() do_throw("Should not be called"), 100); +add_task(function* test_setTimeout() { + let timeout1 = imported.setTimeout(() => do_throw("Should not be called"), 100); do_check_eq(typeof timeout1, "number", "setTimeout returns a number"); do_check_true(timeout1 > 0, "setTimeout returns a positive number"); - let timeout2 = imported.setTimeout(function(param1, param2) { - do_check_true(true, "Should be called"); - do_check_eq(param1, 5, "first parameter is correct"); - do_check_eq(param2, "test", "second parameter is correct"); - do_test_finished(); - }, 100, 5, "test"); - - do_check_eq(typeof timeout2, "number", "setTimeout returns a number"); - do_check_true(timeout2 > 0, "setTimeout returns a positive number"); - do_check_neq(timeout1, timeout2, "Calling setTimeout again returns a different value"); - imported.clearTimeout(timeout1); -} + + yield new Promise((resolve) => { + let timeout2 = imported.setTimeout((param1, param2) => { + do_check_true(true, "Should be called"); + do_check_eq(param1, 5, "first parameter is correct"); + do_check_eq(param2, "test", "second parameter is correct"); + resolve(); + }, 100, 5, "test"); + + do_check_eq(typeof timeout2, "number", "setTimeout returns a number"); + do_check_true(timeout2 > 0, "setTimeout returns a positive number"); + do_check_neq(timeout1, timeout2, "Calling setTimeout again returns a different value"); + }); +}); + +add_task(function* test_setInterval() { + let interval1 = imported.setInterval(function() do_throw("Should not be called!"), 100); + do_check_eq(typeof interval1, "number", "setInterval returns a number"); + do_check_true(interval1 > 0, "setTimeout returns a positive number"); + + imported.clearInterval(interval1); + + const EXPECTED_CALLS = 5; + let calls = 0; + + yield new Promise((resolve) => { + let interval2 = imported.setInterval((param1, param2) => { + do_check_true(true, "Should be called"); + do_check_eq(param1, 15, "first parameter is correct"); + do_check_eq(param2, "hola", "second parameter is correct"); + if (calls >= EXPECTED_CALLS) { + resolve(); + } + calls++; + }, 100, 15, "hola"); + }); +});