Bug 1092570 - Avoid exposing FontFace(Set) constructors when the Font Loading API pref is not set. r=bzbarsky, a=lsblakk
authorCameron McCormack <cam@mcc.id.au>
Tue, 11 Nov 2014 14:53:55 +1100
changeset 233861 2ca49027a199cc9e43a4bd5d77e2973b40584acc
parent 233860 f82b751275b17848539c6dae6986fe9d1f5fa84b
child 233862 0d83fa850744dcc4e350411ac24f84662a77b5f6
push id4187
push userbhearsum@mozilla.com
push dateFri, 28 Nov 2014 15:29:12 +0000
treeherdermozilla-beta@f23cc6a30c11 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbzbarsky, lsblakk
bugs1092570
milestone35.0a2
Bug 1092570 - Avoid exposing FontFace(Set) constructors when the Font Loading API pref is not set. r=bzbarsky, a=lsblakk
layout/style/FontFace.cpp
layout/style/FontFaceSet.cpp
layout/style/FontFaceSet.h
--- a/layout/style/FontFace.cpp
+++ b/layout/style/FontFace.cpp
@@ -221,17 +221,20 @@ FontFace::FontFace(nsISupports* aParent,
   , mInFontFaceSet(false)
   , mInitialized(false)
   , mLoadWhenInitialized(false)
 {
   MOZ_COUNT_CTOR(FontFace);
 
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aParent);
 
-  if (global) {
+  // If the pref is not set, don't create the Promise (which the page wouldn't
+  // be able to get to anyway) as it causes the window.FontFace constructor
+  // to be created.
+  if (global && FontFaceSet::PrefEnabled()) {
     ErrorResult rv;
     mLoaded = Promise::Create(global, rv);
   }
 }
 
 FontFace::~FontFace()
 {
   MOZ_COUNT_DTOR(FontFace);
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -45,16 +45,18 @@ GetFontFaceSetLog()
     sLog = PR_NewLogModule("fontfaceset");
   return sLog;
 }
 #endif /* PR_LOGGING */
 
 #define LOG(args) PR_LOG(GetFontFaceSetLog(), PR_LOG_DEBUG, args)
 #define LOG_ENABLED() PR_LOG_TEST(GetFontFaceSetLog(), PR_LOG_DEBUG)
 
+#define FONT_LOADING_API_ENABLED_PREF "layout.css.font-loading-api.enabled"
+
 NS_IMPL_CYCLE_COLLECTION_CLASS(FontFaceSet)
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FontFaceSet, DOMEventTargetHelper)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument);
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReady);
   for (size_t i = 0; i < tmp->mRuleFaces.Length(); i++) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRuleFaces[i].mFontFace);
   }
@@ -89,17 +91,20 @@ FontFaceSet::FontFaceSet(nsPIDOMWindow* 
   , mDispatchedLoadingEvent(false)
   , mHasLoadingFontFaces(false)
   , mHasLoadingFontFacesIsDirty(false)
 {
   MOZ_COUNT_CTOR(FontFaceSet);
 
   nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aWindow);
 
-  if (global) {
+  // If the pref is not set, don't create the Promise (which the page wouldn't
+  // be able to get to anyway) as it causes the window.FontFaceSet constructor
+  // to be created.
+  if (global && PrefEnabled()) {
     ErrorResult rv;
     mReady = Promise::Create(global, rv);
   }
 
   if (mReady) {
     mReady->MaybeResolve(this);
   }
 
@@ -1340,17 +1345,17 @@ FontFaceSet::CheckLoadingStarted()
 {
   if (HasLoadingFontFaces() && !mDispatchedLoadingEvent) {
     mStatus = FontFaceSetLoadStatus::Loading;
     mDispatchedLoadingEvent = true;
     (new AsyncEventDispatcher(this, NS_LITERAL_STRING("loading"),
                               false))->RunDOMEventWhenSafe();
   }
 
-  if (mReadyIsResolved) {
+  if (mReadyIsResolved && PrefEnabled()) {
     nsRefPtr<Promise> ready;
     if (GetParentObject()) {
       ErrorResult rv;
       ready = Promise::Create(GetParentObject(), rv);
     }
 
     if (ready) {
       mReady.swap(ready);
@@ -1499,16 +1504,28 @@ FontFaceSet::HandleEvent(nsIDOMEvent* aE
   }
 
   Disconnect();
   CheckLoadingFinished();
 
   return NS_OK;
 }
 
+/* static */ bool
+FontFaceSet::PrefEnabled()
+{
+  static bool initialized = false;
+  static bool enabled;
+  if (!initialized) {
+    initialized = true;
+    Preferences::AddBoolVarCache(&enabled, FONT_LOADING_API_ENABLED_PREF);
+  }
+  return enabled;
+}
+
 // nsICSSLoaderObserver
 
 NS_IMETHODIMP
 FontFaceSet::StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
                               bool aWasAlternate,
                               nsresult aStatus)
 {
   CheckLoadingFinished();
--- a/layout/style/FontFaceSet.h
+++ b/layout/style/FontFaceSet.h
@@ -152,16 +152,21 @@ public:
 
   /**
    * Notification method called by the nsPresContext to indicate that the
    * refresh driver ticked and flushed style and layout.
    * were just flushed.
    */
   void DidRefresh();
 
+  /**
+   * Returns whether the "layout.css.font-loading-api.enabled" pref is true.
+   */
+  static bool PrefEnabled();
+
   // nsICSSLoaderObserver
   NS_IMETHOD StyleSheetLoaded(mozilla::CSSStyleSheet* aSheet,
                               bool aWasAlternate,
                               nsresult aStatus);
 
   // -- Web IDL --------------------------------------------------------------
 
   IMPL_EVENT_HANDLER(loading)