diff --git a/dom/base/IdleDeadline.cpp b/dom/base/IdleDeadline.cpp new file mode 100644 index 000000000..6e71b4930 --- /dev/null +++ b/dom/base/IdleDeadline.cpp @@ -0,0 +1,70 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 + +#include "mozilla/dom/IdleDeadline.h" +#include "mozilla/dom/IdleDeadlineBinding.h" +#include "nsPerformance.h" +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" +#include "nsDOMNavigationTiming.h" +#include "nsPIDOMWindow.h" + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(IdleDeadline, mWindow) +NS_IMPL_CYCLE_COLLECTING_ADDREF(IdleDeadline) +NS_IMPL_CYCLE_COLLECTING_RELEASE(IdleDeadline) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(IdleDeadline) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsISupports) +NS_INTERFACE_MAP_END + +IdleDeadline::IdleDeadline(nsPIDOMWindow* aWindow, bool aDidTimeout, + DOMHighResTimeStamp aDeadline) + : mWindow(aWindow) + , mDidTimeout(aDidTimeout) + , mDeadline(aDeadline) +{ +} + +IdleDeadline::~IdleDeadline() +{ +} + +JSObject* +IdleDeadline::WrapObject(JSContext* aCx, JS::Handle aGivenProto) +{ + return IdleDeadlineBinding::Wrap(aCx, this, aGivenProto); +} + +DOMHighResTimeStamp +IdleDeadline::TimeRemaining() +{ + if (mDidTimeout) { + return 0.0; + } + + RefPtr performance = mWindow->GetPerformance(); + if (!performance) { + // If there is no performance object the window is partially torn + // down, so we can safely say that there is no time remaining. + return 0.0; + } + + return std::max(mDeadline - performance->Now(), 0.0); +} + +bool +IdleDeadline::DidTimeout() const +{ + return mDidTimeout; +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/base/IdleDeadline.h b/dom/base/IdleDeadline.h new file mode 100644 index 000000000..f8cc46c47 --- /dev/null +++ b/dom/base/IdleDeadline.h @@ -0,0 +1,55 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* 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 mozilla_dom_IdleDeadline_h +#define mozilla_dom_IdleDeadline_h + +#include "js/TypeDecls.h" +#include "mozilla/Attributes.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/Maybe.h" +#include "mozilla/dom/BindingDeclarations.h" +#include "nsCOMPtr.h" +#include "nsCycleCollectionParticipant.h" +#include "nsDOMNavigationTiming.h" +#include "nsWrapperCache.h" + +class nsPIDOMWindow; + +namespace mozilla { +namespace dom { + +class IdleDeadline final + : public nsISupports + , public nsWrapperCache +{ +public: + IdleDeadline(nsPIDOMWindow* aWindow, bool aDidTimeout, + DOMHighResTimeStamp aDeadline); + + nsPIDOMWindow* GetParentObject() const { return mWindow; } + + virtual JSObject* WrapObject(JSContext* aCx, + JS::Handle aGivenProto) override; + + DOMHighResTimeStamp TimeRemaining(); + bool DidTimeout() const; + + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(IdleDeadline) + +private: + ~IdleDeadline(); + + nsCOMPtr mWindow; + const bool mDidTimeout; + const DOMHighResTimeStamp mDeadline; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_IdleDeadline_h diff --git a/dom/base/moz.build b/dom/base/moz.build index ef16c31ca..5e64c0b41 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -182,6 +182,7 @@ EXPORTS.mozilla.dom += [ 'FileReader.h', 'FragmentOrElement.h', 'FromParser.h', + 'IdleDeadline.h', 'ImageEncoder.h', 'ImportManager.h', 'Link.h', @@ -247,6 +248,7 @@ UNIFIED_SOURCES += [ 'FileList.cpp', 'FileReader.cpp', 'FragmentOrElement.cpp', + 'IdleDeadline.cpp', 'ImageEncoder.cpp', 'ImportManager.cpp', 'Link.cpp', diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index 179aeadf9..f8bf14a4f 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1143,6 +1143,7 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow) mTimeoutsSuspendDepth(0), mFocusMethod(0), mSerial(0), + mIdleRequestCallbackCounter(1), #ifdef DEBUG mSetOpenerWindowCalled(false), #endif @@ -13858,3 +13859,35 @@ nsGlobalWindow::CreateImageBitmap(const ImageBitmapSource& aImage, { return ImageBitmap::Create(this, aImage, Some(gfx::IntRect(aSx, aSy, aSw, aSh)), aRv); } + +/* Support for requestIdleCallback() from TenFourFox issue 463 */ + +uint32_t +nsGlobalWindow::RequestIdleCallback(JSContext* aCx, + IdleRequestCallback& aCallback, + const IdleRequestOptions& aOptions, + ErrorResult& aError) +{ + MOZ_RELEASE_ASSERT(IsInnerWindow()); + AssertIsOnMainThread(); + + // uint32_t handle = ++mIdleRequestCallbackCounter; + + fprintf(stderr, "::RequestIdleCallback() is not yet implemented\n"); +#if DEBUG + MOZ_ASSERT(0); +#endif + return 0; // handle; +} + +void +nsGlobalWindow::CancelIdleCallback(uint32_t aHandle) +{ + MOZ_RELEASE_ASSERT(IsInnerWindow()); + + fprintf(stderr, "::CancelIdleCallback() is not yet implemented\n"); +#if DEBUG + MOZ_ASSERT(0); +#endif +} + diff --git a/dom/base/nsGlobalWindow.h b/dom/base/nsGlobalWindow.h index 9b73d8fcb..41d1b65e4 100644 --- a/dom/base/nsGlobalWindow.h +++ b/dom/base/nsGlobalWindow.h @@ -118,6 +118,7 @@ class RequestOrUSVString; class Selection; class SpeechSynthesis; class WakeLock; +class IdleRequestCallback; #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) class WindowOrientationObserver; #endif @@ -1042,6 +1043,13 @@ public: int32_t RequestAnimationFrame(mozilla::dom::FrameRequestCallback& aCallback, mozilla::ErrorResult& aError); void CancelAnimationFrame(int32_t aHandle, mozilla::ErrorResult& aError); + + uint32_t RequestIdleCallback(JSContext* aCx, + mozilla::dom::IdleRequestCallback& aCallback, + const mozilla::dom::IdleRequestOptions& aOptions, + mozilla::ErrorResult& aError); + void CancelIdleCallback(uint32_t aHandle); + #ifdef MOZ_WEBSPEECH mozilla::dom::SpeechSynthesis* GetSpeechSynthesis(mozilla::ErrorResult& aError); @@ -1791,6 +1799,9 @@ protected: uint32_t mSerial; + // requestIdleCallback() support + uint32_t mIdleRequestCallbackCounter; + #ifdef DEBUG bool mSetOpenerWindowCalled; nsCOMPtr mLastOpenedURI; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index e6323eada..c00f9c594 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1610,6 +1610,9 @@ DOMInterfaces = { 'binaryNames': { 'postMessage': 'postMessageMoz', }, + 'implicitJSContext': [ + 'requestIdleCallback' + ], }, 'WindowProxy': { diff --git a/dom/webidl/IdleDeadline.webidl b/dom/webidl/IdleDeadline.webidl new file mode 100644 index 000000000..afc834aea --- /dev/null +++ b/dom/webidl/IdleDeadline.webidl @@ -0,0 +1,15 @@ +/* -*- 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/. + * + * The origin of this IDL file is: + * https://w3c.github.io/requestidlecallback/ + */ + +[Pref="dom.requestIdleCallback.enabled"] +interface IdleDeadline { + DOMHighResTimeStamp timeRemaining(); + readonly attribute boolean didTimeout; +}; + diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 704c65636..0446f25d8 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -494,3 +494,17 @@ interface ChromeWindow { Window implements ChromeWindow; Window implements GlobalFetch; Window implements ImageBitmapFactories; + +partial interface Window { + [Throws, Pref="dom.requestIdleCallback.enabled"] + unsigned long requestIdleCallback(IdleRequestCallback callback, + optional IdleRequestOptions options); + [Pref="dom.requestIdleCallback.enabled"] + void cancelIdleCallback(unsigned long handle); +}; + +dictionary IdleRequestOptions { + unsigned long timeout; +}; + +callback IdleRequestCallback = void (IdleDeadline deadline); diff --git a/dom/webidl/moz.build b/dom/webidl/moz.build index beae51d9c..cffef9c89 100644 --- a/dom/webidl/moz.build +++ b/dom/webidl/moz.build @@ -264,6 +264,7 @@ WEBIDL_FILES = [ 'IDBRequest.webidl', 'IDBTransaction.webidl', 'IDBVersionChangeEvent.webidl', + 'IdleDeadline.webidl', 'ImageBitmap.webidl', 'ImageCapture.webidl', 'ImageData.webidl', diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 1d1f1474d..b3f3c4f1e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1042,6 +1042,9 @@ pref("dom.disable_window_open_feature.status", true); pref("dom.allow_scripts_to_close_windows", false); +// TenFourFox issue 463 +pref("dom.requestIdleCallback.enabled", false); + pref("dom.require_user_interaction_for_beforeunload", true); pref("dom.disable_open_during_load", false);