Changeset 176453 in webkit


Ignore:
Timestamp:
Nov 21, 2014 10:43:21 AM (9 years ago)
Author:
commit-queue@webkit.org
Message:

[CSS Font Loading] Switch to dispatching events asynchronously
https://bugs.webkit.org/show_bug.cgi?id=138755

Patch by Bear Travis <betravis@gmail.com> on 2014-11-21
Reviewed by Simon Fraser.

Source/WebCore:

Moving FontLoader to dispatch events and notify callbacks similarly
to EventSender or the GenericEventQueue. Several bugs have popped
up in the past because FontLoader has been sending events during
layout, and there is no need for that to be the case.

Covered by existing font loader event tests. Added an additional
test for the svg case, fontloader-svg-select.

  • css/FontLoader.cpp:

(WebCore::FontLoader::didLayout):
(WebCore::FontLoader::timerFired): Adding asynchronous callback.
(WebCore::FontLoader::scheduleEvent): Add an event to the dispatch
queue.
(WebCore::FontLoader::firePendingEvents): Modified to handle the
loading done event and callbacks.
(WebCore::FontLoader::loadingDone): Modified to spin up the timer
rather than immediately dispatching events.

  • css/FontLoader.h:

LayoutTests:

Refactoring tests to check for all events only after the FontLoader
itself has completed. Tests were previously checking after a specific font
had loaded, at which point some of the events may have yet to fire.

  • fast/css/fontloader-multiple-faces-download-error-expected.txt:
  • fast/css/fontloader-multiple-faces-download-error.html:
  • fast/css/fontloader-multiple-faces-expected.txt:
  • fast/css/fontloader-multiple-faces.html:
  • fast/css/fontloader-multiple-families-expected.txt:
  • fast/css/fontloader-multiple-families.html:
  • fast/css/fontloader-svg-select-expected.txt: Added
  • fast/css/fontloader-svg-select.svg: Added
Location:
trunk
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r176447 r176453  
     12014-11-21  Bear Travis  <betravis@gmail.com>
     2
     3        [CSS Font Loading] Switch to dispatching events asynchronously
     4        https://bugs.webkit.org/show_bug.cgi?id=138755
     5
     6        Reviewed by Simon Fraser.
     7
     8        Refactoring tests to check for all events only after the FontLoader
     9        itself has completed. Tests were previously checking after a specific font
     10        had loaded, at which point some of the events may have yet to fire.
     11
     12        * fast/css/fontloader-multiple-faces-download-error-expected.txt:
     13        * fast/css/fontloader-multiple-faces-download-error.html:
     14        * fast/css/fontloader-multiple-faces-expected.txt:
     15        * fast/css/fontloader-multiple-faces.html:
     16        * fast/css/fontloader-multiple-families-expected.txt:
     17        * fast/css/fontloader-multiple-families.html:
     18        * fast/css/fontloader-svg-select-expected.txt: Added
     19        * fast/css/fontloader-svg-select.svg: Added
     20
    1212014-11-21  Chris Fleizach  <cfleizach@apple.com>
    222
  • trunk/LayoutTests/fast/css/fontloader-multiple-faces-download-error-expected.txt

    r171886 r176453  
    88PASS events['load'] is 1
    99PASS events['error'] is 1
    10 PASS events['loadingdone'] is undefined
     10PASS events['loadingdone'] is 1
    1111PASS document.fonts.checkFont('10px TestFont') is false
    12 PASS events['loadingdone'] is 1
    1312PASS successfullyParsed is true
    1413
  • trunk/LayoutTests/fast/css/fontloader-multiple-faces-download-error.html

    r171886 r176453  
    4444
    4545function onerror() {
     46}
     47
     48function verify() {
    4649    shouldBe("events['loading']", "1");
    4750    shouldBe("events['loadstart']", "2");
    4851    shouldBe("events['load']", "1");
    4952    shouldBe("events['error']", "1");
    50     shouldBe("events['loadingdone']", "undefined");
     53    shouldBe("events['loadingdone']", "1");
    5154    shouldBe("document.fonts.checkFont('10px TestFont')", "false");
    52 }
    53 
    54 function verify() {
    55     shouldBe("events['loadingdone']", "1");
    5655    finishJSTest();
    5756}
  • trunk/LayoutTests/fast/css/fontloader-multiple-faces-expected.txt

    r171886 r176453  
    88PASS events['load'] is 2
    99PASS events['error'] is undefined
    10 PASS events['loadingdone'] is undefined
     10PASS events['loadingdone'] is 1
    1111PASS document.fonts.checkFont('10px TestFont') is true
    12 PASS events['loadingdone'] is 1
    1312PASS successfullyParsed is true
    1413
  • trunk/LayoutTests/fast/css/fontloader-multiple-faces.html

    r171886 r176453  
    3939
    4040function onsuccess() {
    41     shouldBe("events['loading']", "1");
    42     shouldBe("events['loadstart']", "2");
    43     shouldBe("events['load']", "2");
    44     shouldBe("events['error']", "undefined");
    45     shouldBe("events['loadingdone']", "undefined");
    46     shouldBe("document.fonts.checkFont('10px TestFont')", "true");
    4741}
    4842
     
    5347
    5448function verify() {
     49    shouldBe("events['loading']", "1");
     50    shouldBe("events['loadstart']", "2");
     51    shouldBe("events['load']", "2");
     52    shouldBe("events['error']", "undefined");
    5553    shouldBe("events['loadingdone']", "1");
     54    shouldBe("document.fonts.checkFont('10px TestFont')", "true");
    5655    finishJSTest();
    5756}
  • trunk/LayoutTests/fast/css/fontloader-multiple-families-expected.txt

    r171886 r176453  
    88PASS events['load'] is 2
    99PASS events['error'] is undefined
    10 PASS events['loadingdone'] is undefined
     10PASS events['loadingdone'] is 1
    1111PASS document.fonts.checkFont('10px TestFont1, TestFont2') is true
    12 PASS events['loadingdone'] is 1
    1312PASS successfullyParsed is true
    1413
  • trunk/LayoutTests/fast/css/fontloader-multiple-families.html

    r171886 r176453  
    3939
    4040function onsuccess() {
    41     shouldBe("events['loading']", "1");
    42     shouldBe("events['loadstart']", "2");
    43     shouldBe("events['load']", "2");
    44     shouldBe("events['error']", "undefined");
    45     shouldBe("events['loadingdone']", "undefined");
    46     shouldBe("document.fonts.checkFont('10px TestFont1, TestFont2')", "true");
    4741}
    4842
     
    5246
    5347function verify() {
     48    shouldBe("events['loading']", "1");
     49    shouldBe("events['loadstart']", "2");
     50    shouldBe("events['load']", "2");
     51    shouldBe("events['error']", "undefined");
    5452    shouldBe("events['loadingdone']", "1");
     53    shouldBe("document.fonts.checkFont('10px TestFont1, TestFont2')", "true");
    5554    finishJSTest();
    5655}
  • trunk/Source/WebCore/ChangeLog

    r176451 r176453  
     12014-11-21  Bear Travis  <betravis@gmail.com>
     2
     3        [CSS Font Loading] Switch to dispatching events asynchronously
     4        https://bugs.webkit.org/show_bug.cgi?id=138755
     5
     6        Reviewed by Simon Fraser.
     7
     8        Moving FontLoader to dispatch events and notify callbacks similarly
     9        to EventSender or the GenericEventQueue. Several bugs have popped
     10        up in the past because FontLoader has been sending events during
     11        layout, and there is no need for that to be the case.
     12
     13        Covered by existing font loader event tests. Added an additional
     14        test for the svg case, fontloader-svg-select.
     15
     16        * css/FontLoader.cpp:
     17        (WebCore::FontLoader::didLayout):
     18        (WebCore::FontLoader::timerFired): Adding asynchronous callback.
     19        (WebCore::FontLoader::scheduleEvent): Add an event to the dispatch
     20        queue.
     21        (WebCore::FontLoader::firePendingEvents): Modified to handle the
     22        loading done event and callbacks.
     23        (WebCore::FontLoader::loadingDone): Modified to spin up the timer
     24        rather than immediately dispatching events.
     25        * css/FontLoader.h:
     26
    1272014-11-21  Daniel Bates  <dabates@apple.com>
    228
  • trunk/Source/WebCore/css/FontLoader.cpp

    r174515 r176453  
    123123    , m_numLoadingFromCSS(0)
    124124    , m_numLoadingFromJS(0)
     125    , m_pendingEventsTimer(this, &FontLoader::pendingEventsTimerFired)
    125126{
    126127    suspendIfNeeded();
     
    153154void FontLoader::didLayout()
    154155{
    155     firePendingEvents();
    156156    loadingDone();
    157157}
     
    159159void FontLoader::scheduleEvent(PassRefPtr<Event> event)
    160160{
    161     if (FrameView* view = m_document->view()) {
    162         if (view->isInLayout()) {
    163             m_pendingEvents.append(event);
    164             return;
    165         }
    166     }
    167     firePendingEvents();
    168     dispatchEvent(event);
     161    m_pendingEvents.append(event);
     162    if (!m_pendingEventsTimer.isActive())
     163        m_pendingEventsTimer.startOneShot(0);
    169164}
    170165
    171166void FontLoader::firePendingEvents()
    172167{
    173     if (m_pendingEvents.isEmpty())
    174         return;
    175 
    176     Vector<RefPtr<Event> > pendingEvents;
     168    if (m_pendingEvents.isEmpty() && !m_loadingDoneEvent && !m_callbacks.isEmpty())
     169        return;
     170
     171    Vector<RefPtr<Event>> pendingEvents;
    177172    m_pendingEvents.swap(pendingEvents);
     173
     174    bool loadingDone = false;
     175    if (m_loadingDoneEvent) {
     176        pendingEvents.append(m_loadingDoneEvent.release());
     177        loadingDone = true;
     178    }
     179
    178180    for (size_t index = 0; index < pendingEvents.size(); ++index)
    179181        dispatchEvent(pendingEvents[index].release());
     182
     183    if (loadingDone && !m_callbacks.isEmpty()) {
     184        Vector<RefPtr<VoidCallback>> callbacks;
     185        m_callbacks.swap(callbacks);
     186        for (size_t index = 0; index < callbacks.size(); ++index)
     187            callbacks[index]->handleEvent();
     188    }
    180189}
    181190
     
    219228    if (loading() || !m_document->haveStylesheetsLoaded())
    220229        return;
    221     if (!m_loadingDoneEvent && m_callbacks.isEmpty())
     230    if (!m_loadingDoneEvent && m_callbacks.isEmpty() && m_pendingEvents.isEmpty())
    222231        return;
    223232
     
    227236    }
    228237
    229     if (m_loadingDoneEvent)
    230         dispatchEvent(m_loadingDoneEvent.release());
    231 
    232     if (!m_callbacks.isEmpty()) {
    233         Vector<RefPtr<VoidCallback> > callbacks;
    234         m_callbacks.swap(callbacks);
    235         for (size_t index = 0; index < callbacks.size(); ++index)
    236             callbacks[index]->handleEvent();
    237     }
     238    if (!m_pendingEventsTimer.isActive())
     239        m_pendingEventsTimer.startOneShot(0);
    238240}
    239241
  • trunk/Source/WebCore/css/FontLoader.h

    r175391 r176453  
    3232#include "EventListener.h"
    3333#include "EventTarget.h"
     34#include "Timer.h"
    3435#include "VoidCallback.h"
    3536#include <wtf/PassRefPtr.h>
     
    9596    virtual EventTargetData& ensureEventTargetData() override;
    9697
     98    void pendingEventsTimerFired(Timer&) { firePendingEvents(); }
    9799    void scheduleEvent(PassRefPtr<Event>);
    98100    void firePendingEvents();
     
    106108    Vector<RefPtr<VoidCallback>> m_callbacks;
    107109    RefPtr<Event> m_loadingDoneEvent;
     110    Timer m_pendingEventsTimer;
    108111};
    109112
Note: See TracChangeset for help on using the changeset viewer.