Bug 1334876 - Go through the event loop to dispatch FontFaceSet events. r=bz
☠☠ backed out by 4dc3eb7f7b12 ☠ ☠
authorCameron McCormack <cam@mcc.id.au>
Tue, 07 Feb 2017 10:29:27 +0800
changeset 341047 c5d678ebcbcd24dce64426492e3f20ca5a1bd261
parent 341046 955dd973d5b7ed2426e87e805a080902d7098e3d
child 341048 5a43dbcb95cab9ff9728383f05780faa72e1ad5e
push id86617
push usercmccormack@mozilla.com
push dateTue, 07 Feb 2017 02:30:16 +0000
treeherdermozilla-inbound@c5d678ebcbcd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1334876
milestone54.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1334876 - Go through the event loop to dispatch FontFaceSet events. r=bz MozReview-Commit-ID: BX2I7tb25YM
layout/style/FontFaceSet.cpp
layout/style/test/test_font_loading_api.html
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -1497,17 +1497,17 @@ FontFaceSet::CheckLoadingStarted()
   if (mStatus == FontFaceSetLoadStatus::Loading) {
     // We have already dispatched a loading event and replaced mReady
     // with a fresh, unresolved promise.
     return;
   }
 
   mStatus = FontFaceSetLoadStatus::Loading;
   (new AsyncEventDispatcher(this, NS_LITERAL_STRING("loading"),
-                            false))->RunDOMEventWhenSafe();
+                            false))->PostDOMEvent();
 
   if (PrefEnabled()) {
     if (mReady) {
       if (GetParentObject()) {
         ErrorResult rv;
         mReady = Promise::Create(GetParentObject(), rv);
       }
     }
@@ -1653,17 +1653,17 @@ FontFaceSet::DispatchLoadingFinishedEven
   OwningNonNull<FontFace>* elements =
     init.mFontfaces.AppendElements(aFontFaces.Length(), fallible);
   MOZ_ASSERT(elements);
   for (size_t i = 0; i < aFontFaces.Length(); i++) {
     elements[i] = aFontFaces[i];
   }
   RefPtr<FontFaceSetLoadEvent> event =
     FontFaceSetLoadEvent::Constructor(this, aType, init);
-  (new AsyncEventDispatcher(this, event))->RunDOMEventWhenSafe();
+  (new AsyncEventDispatcher(this, event))->PostDOMEvent();
 }
 
 // nsIDOMEventListener
 
 NS_IMETHODIMP
 FontFaceSet::HandleEvent(nsIDOMEvent* aEvent)
 {
   nsString type;
--- a/layout/style/test/test_font_loading_api.html
+++ b/layout/style/test/test_font_loading_api.html
@@ -1121,22 +1121,24 @@ function runTest() {
     // (TEST 37) Test that a FontFace only has one loadingdone event dispatched
     // at the FontFaceSet containing it.
 
     var p = Promise.resolve();
     sources.forEach(function({ win, doc, what}, i) {
       p = p.then(function() {
         var events = [], face, face2;
 
-        doc.fonts.onloadingdone = function(e) {
-          events.push(e);
-        };
-        doc.fonts.onloadingerror = function(e) {
-          events.push(e);
-        };
+        var awaitEvents = new Promise(function(aResolve, aReject) {
+          doc.fonts.onloadingdone = doc.fonts.onloadingerror = function(e) {
+            events.push(e);
+            if (events.length == 2) {
+              aResolve();
+            }
+          };
+        });
 
         is(doc.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" (TEST 37) (" + what + ")");
 
         face = new win.FontFace("test", "url(BitPattern.woff?test37." + i + "a)");
         face.load();
         doc.fonts.add(face);
         is(doc.fonts.status, "loading", "document.fonts.status should have status \"loading\" after first font added (TEST 37) (" + what + ")");
 
@@ -1147,16 +1149,18 @@ function runTest() {
 
             face2 = new win.FontFace("test2", "url(BitPattern.woff?test37." + i + "b)");
             face2.load();
             doc.fonts.add(face2);
             is(doc.fonts.status, "loading", "document.fonts.status should have status \"loading\" after second font added (TEST 37) (" + what + ")");
 
             return doc.fonts.ready;
           }).then(function() {
+            return awaitEvents;
+          }).then(function() {
             is(doc.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" after second font loaded (TEST 37) (" + what + ")");
             is(face2.status, "loaded", "second FontFace should have status \"loaded\" (TEST 37) (" + what + ")");
 
             is(events.length, 2, "should receive two events (TEST 37) (" + what + ")");
 
             is(events[0].type, "loadingdone", "first event should be \"loadingdone\" (TEST 37) (" + what + ")");
             is(events[0].fontfaces.length, 1, "first event should have 1 FontFace (TEST 37) (" + what + ")");
             is(events[0].fontfaces[0], face, "first event should have the first FontFace");
@@ -1179,22 +1183,24 @@ function runTest() {
     // (TEST 38) Test that a FontFace only has one loadingerror event dispatched
     // at the FontFaceSet containing it.
 
     var p = Promise.resolve();
     sources.forEach(function({ win, doc, what }) {
       p = p.then(function() {
         var events = [], face, face2;
 
-        doc.fonts.onloadingdone = function(e) {
-          events.push(e);
-        };
-        doc.fonts.onloadingerror = function(e) {
-          events.push(e);
-        };
+        var awaitEvents = new Promise(function(aResolve, aReject) {
+          doc.fonts.onloadingdone = doc.fonts.onloadingerror = function(e) {
+            events.push(e);
+            if (events.length == 4) {
+              aResolve();
+            }
+          };
+        });
 
         is(doc.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" (TEST 38) (" + what + ")");
 
         face = new win.FontFace("test", "url(x)");
         face.load();
         doc.fonts.add(face);
         is(doc.fonts.status, "loading", "document.fonts.status should have status \"loading\" after first font added (TEST 38) (" + what + ")");
 
@@ -1205,16 +1211,18 @@ function runTest() {
 
             face2 = new win.FontFace("test2", "url(x)");
             face2.load();
             doc.fonts.add(face2);
             is(doc.fonts.status, "loading", "document.fonts.status should have status \"loading\" after second font added (TEST 38) (" + what + ")");
 
             return doc.fonts.ready;
           }).then(function() {
+            return awaitEvents;
+          }).then(function() {
             is(doc.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" after second font failed to load (TEST 38) (" + what + ")");
             is(face2.status, "error", "second FontFace should have status \"error\" (TEST 38) (" + what + ")");
 
             is(events.length, 4, "should receive four events (TEST 38) (" + what + ")");
 
             is(events[0].type, "loadingdone", "first event should be \"loadingdone\" (TEST 38) (" + what + ")");
             is(events[0].fontfaces.length, 0, "first event should have no FontFaces (TEST 38) (" + what + ")");
 
@@ -1247,22 +1255,24 @@ function runTest() {
     var ruleText = "@font-face { font-family: test; src: url(BitPattern.woff?test39a); } " +
                    "@font-face { font-family: test2; src: url(BitPattern.woff?test39b); }";
 
     style.textContent = ruleText;
 
     var all = Array.from(document.fonts);
     var events = [];
 
-    document.fonts.onloadingdone = function(e) {
-      events.push(e);
-    };
-    document.fonts.onloadingerror = function(e) {
-      events.push(e);
-    };
+    var awaitEvents = new Promise(function(aResolve, aReject) {
+      document.fonts.onloadingdone = document.fonts.onloadingerror = function(e) {
+        events.push(e);
+        if (events.length == 2) {
+          aResolve();
+        }
+      };
+    });
 
     is(document.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" (TEST 39)");
 
     all[0].load();
     is(document.fonts.status, "loading", "document.fonts.status should have status \"loading\" after first font loading (TEST 39)");
 
     return document.fonts.ready
       .then(function() {
@@ -1270,16 +1280,18 @@ function runTest() {
         is(all[0].status, "loaded", "first FontFace should have status \"loaded\" (TEST 39)");
         is(all[1].status, "unloaded", "second FontFace should have status \"unloaded\" (TEST 39)");
 
         all[1].load();
         is(document.fonts.status, "loading", "document.fonts.status should have status \"loading\" after second font loading (TEST 39)");
 
         return document.fonts.ready;
       }).then(function() {
+        return awaitEvents;
+      }).then(function() {
         is(document.fonts.status, "loaded", "document.fonts.status should have status \"loaded\" after second font loaded (TEST 39)");
         is(all[1].status, "loaded", "second FontFace should have status \"loaded\" (TEST 39)");
 
         is(events.length, 2, "should receive two events (TEST 39)");
 
         is(events[0].type, "loadingdone", "first event should be \"loadingdone\" (TEST 39)");
         is(events[0].fontfaces.length, 1, "first event should have 1 FontFace (TEST 39)");
         is(events[0].fontfaces[0], all[0], "first event should have the first FontFace");