Changeset 251867 in webkit


Ignore:
Timestamp:
Oct 31, 2019 12:26:10 PM (4 years ago)
Author:
rniwa@webkit.org
Message:

Integrate resize event with HTML5 event loop
https://bugs.webkit.org/show_bug.cgi?id=202964

Reviewed by Geoffrey Garen and Simon Fraser.

Source/WebCore:

Dispatch resize events in "run the resize steps" during the "update the rendering":
https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering

Existing code in WebCore which was dispatching or scheduling dispatching of resize events now simply sets
a flag on document and schedules a rendering update. In Page::updateRendering, we fire resize events on
any documents with this flag set.

Test: fast/events/resize-subframe-in-rendering-update.html

  • css/CSSFontSelector.cpp:

(WebCore::CSSFontSelector::beginLoadTimerFired): Fixed the flakiness in SVG animation tests observed
after this patch was landed previously. The issue was that this code was calling FrameLoader's
checkLoadComplete before checkCompleted. checkCompleted starts SVG animations in Document::implicitClose
whereas checkLoadComplete can cause DumpRenderTree to end the test. As a result, depending on when this
function was called relative to other work being done in the main thread, DumpRenderTree could prematurely
end and dump the test result even though SVG animation would have immediately started in either scenario.
Unfortunately I couldn't come up with a new deterministic test for this issue since the exact condition
under which this problem comes up seems quite racy (which makes sense given this only manifested as flaky
failures in existing tests).

  • dom/Document.cpp:

(WebCore::Document::setNeedsDOMWindowResizeEvent): Added.
(WebCore::Document::setNeedsVisualViewportResize): Added.
(WebCore::Document::runResizeSteps): Added. https://drafts.csswg.org/cssom-view/#run-the-resize-steps

  • dom/Document.h:
  • page/FrameView.cpp:

(WebCore::FrameView::sendResizeEventIfNeeded): Now sets m_needsDOMWindowResizeEvent on Document instead of
enqueuing a resize event.

  • page/Page.cpp:

(WebCore::Page::updateRendering): Call runResizeSteps on each document.
(WebCore::Page::collectDocuments): Added.

  • page/Page.h:
  • page/VisualViewport.cpp:

(WebCore::VisualViewport::enqueueResizeEvent):

LayoutTests:

Added a regression test and fixed an existing test to work with the new behavior.

  • fast/events/resize-subframe-in-rendering-update-expected.txt: Added.
  • fast/events/resize-subframe-in-rendering-update.html: Added.
  • fast/shadow-dom/trusted-event-scoped-flags.html:
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r251865 r251867  
     12019-10-31  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Integrate resize event with HTML5 event loop
     4        https://bugs.webkit.org/show_bug.cgi?id=202964
     5
     6        Reviewed by Geoffrey Garen and Simon Fraser.
     7
     8        Added a regression test and fixed an existing test to work with the new behavior.
     9
     10        * fast/events/resize-subframe-in-rendering-update-expected.txt: Added.
     11        * fast/events/resize-subframe-in-rendering-update.html: Added.
     12        * fast/shadow-dom/trusted-event-scoped-flags.html:
     13
    1142019-10-31  Truitt Savell  <tsavell@apple.com>
    215
  • trunk/LayoutTests/fast/shadow-dom/trusted-event-scoped-flags.html

    r251567 r251867  
    111111
    112112    iframe.onload = function () {
    113         iframe.contentDocument.body.getBoundingClientRect();
    114         log(iframe.contentWindow, "resize");
    115         setTimeout(function () {
    116             iframe.style.width = '200px';
    117             iframe.style.height = '200px';
    118             iframe.contentDocument.body.getBoundingClientRect();
     113        requestAnimationFrame(function () {
    119114            setTimeout(function () {
    120                 checkFlags('', {eventType: 'resize', composed: false});
    121                 finishJSTest();
     115                iframe.contentDocument.body.getBoundingClientRect();
     116                log(iframe.contentWindow, "resize");
     117                iframe.style.width = '200px';
     118                iframe.style.height = '200px';
     119                iframe.contentDocument.body.getBoundingClientRect();
     120                requestAnimationFrame(function () {
     121                    checkFlags('', {eventType: 'resize', composed: false});
     122                    finishJSTest();
     123                });
    122124            }, 0);
    123         }, 0);
     125        });
    124126    }
    125127
  • trunk/Source/WebCore/ChangeLog

    r251866 r251867  
     12019-10-31  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Integrate resize event with HTML5 event loop
     4        https://bugs.webkit.org/show_bug.cgi?id=202964
     5
     6        Reviewed by Geoffrey Garen and Simon Fraser.
     7
     8        Dispatch resize events in "run the resize steps" during the "update the rendering":
     9        https://html.spec.whatwg.org/multipage/webappapis.html#update-the-rendering
     10
     11        Existing code in WebCore which was dispatching or scheduling dispatching of resize events now simply sets
     12        a flag on document and schedules a rendering update. In Page::updateRendering, we fire resize events on
     13        any documents with this flag set.
     14
     15        Test: fast/events/resize-subframe-in-rendering-update.html
     16
     17        * css/CSSFontSelector.cpp:
     18        (WebCore::CSSFontSelector::beginLoadTimerFired): Fixed the flakiness in SVG animation tests observed
     19        after this patch was landed previously. The issue was that this code was calling FrameLoader's
     20        checkLoadComplete before checkCompleted. checkCompleted starts SVG animations in Document::implicitClose
     21        whereas checkLoadComplete can cause DumpRenderTree to end the test. As a result, depending on when this
     22        function was called relative to other work being done in the main thread, DumpRenderTree could prematurely
     23        end and dump the test result even though SVG animation would have immediately started in either scenario.
     24        Unfortunately I couldn't come up with a new deterministic test for this issue since the exact condition
     25        under which this problem comes up seems quite racy (which makes sense given this only manifested as flaky
     26        failures in existing tests).
     27        * dom/Document.cpp:
     28        (WebCore::Document::setNeedsDOMWindowResizeEvent): Added.
     29        (WebCore::Document::setNeedsVisualViewportResize): Added.
     30        (WebCore::Document::runResizeSteps): Added. https://drafts.csswg.org/cssom-view/#run-the-resize-steps
     31        * dom/Document.h:
     32        * page/FrameView.cpp:
     33        (WebCore::FrameView::sendResizeEventIfNeeded): Now sets m_needsDOMWindowResizeEvent on Document instead of
     34        enqueuing a resize event.
     35        * page/Page.cpp:
     36        (WebCore::Page::updateRendering): Call runResizeSteps on each document.
     37        (WebCore::Page::collectDocuments): Added.
     38        * page/Page.h:
     39        * page/VisualViewport.cpp:
     40        (WebCore::VisualViewport::enqueueResizeEvent):
     41
    1422019-10-31  Jer Noble  <jer.noble@apple.com>
    243
  • trunk/Source/WebCore/css/CSSFontSelector.cpp

    r251508 r251867  
    398398        cachedResourceLoader.decrementRequestCount(*fontHandle);
    399399    }
     400    // FIXME: Use SubresourceLoader instead.
     401    // Call FrameLoader::loadDone before FrameLoader::subresourceLoadDone to match the order in SubresourceLoader::notifyDone.
     402    cachedResourceLoader.loadDone(LoadCompletionType::Finish);
    400403    // Ensure that if the request count reaches zero, the frame loader will know about it.
    401404    // New font loads may be triggered by layout after the document load is complete but before we have dispatched
     
    403406    if (m_document && m_document->frame())
    404407        m_document->frame()->loader().checkLoadComplete();
    405     cachedResourceLoader.loadDone(LoadCompletionType::Finish);
    406408}
    407409
  • trunk/Source/WebCore/dom/Document.cpp

    r251792 r251867  
    224224#include "VisibilityChangeClient.h"
    225225#include "VisitedLinkState.h"
     226#include "VisualViewport.h"
    226227#include "WebAnimation.h"
    227228#include "WheelEvent.h"
     
    39603961}
    39613962
     3963void Document::setNeedsDOMWindowResizeEvent()
     3964{
     3965    m_needsDOMWindowResizeEvent = true;
     3966    scheduleTimedRenderingUpdate();
     3967}
     3968
     3969void Document::setNeedsVisualViewportResize()
     3970{
     3971    m_needsVisualViewportResizeEvent = true;
     3972    scheduleTimedRenderingUpdate();
     3973}
     3974
     3975// https://drafts.csswg.org/cssom-view/#run-the-resize-steps
     3976void Document::runResizeSteps()
     3977{
     3978    // FIXME: The order of dispatching is not specified: https://github.com/WICG/visual-viewport/issues/65.
     3979    if (m_needsDOMWindowResizeEvent) {
     3980        LOG_WITH_STREAM(Events, stream << "Document" << this << "sending resize events to window");
     3981        m_needsDOMWindowResizeEvent = false;
     3982        dispatchWindowEvent(Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No));
     3983    }
     3984    if (m_needsVisualViewportResizeEvent) {
     3985        LOG_WITH_STREAM(Events, stream << "Document" << this << "sending resize events to visualViewport");
     3986        m_needsVisualViewportResizeEvent = false;
     3987        if (auto* window = domWindow())
     3988            window->visualViewport().dispatchEvent(Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No));
     3989    }
     3990}
     3991
    39623992void Document::addAudioProducer(MediaProducer& audioProducer)
    39633993{
  • trunk/Source/WebCore/dom/Document.h

    r251792 r251867  
    13611361    void updateViewportUnitsOnResize();
    13621362
     1363    void setNeedsDOMWindowResizeEvent();
     1364    void setNeedsVisualViewportResize();
     1365    void runResizeSteps();
     1366
    13631367    WEBCORE_EXPORT void addAudioProducer(MediaProducer&);
    13641368    WEBCORE_EXPORT void removeAudioProducer(MediaProducer&);
     
    20142018
    20152019    bool m_hasStyleWithViewportUnits { false };
     2020    bool m_needsDOMWindowResizeEvent { false };
     2021    bool m_needsVisualViewportResizeEvent { false };
    20162022    bool m_isTimerThrottlingEnabled { false };
    20172023    bool m_isSuspended { false };
  • trunk/Source/WebCore/page/FrameView.cpp

    r251640 r251867  
    34233423#endif
    34243424
     3425    LOG_WITH_STREAM(Events, stream << "FrameView" << this << "sendResizeEventIfNeeded scheduling resize event for document" << frame().document() << ", size " << currentSize);
     3426    frame().document()->setNeedsDOMWindowResizeEvent();
     3427
    34253428    bool isMainFrame = frame().isMainFrame();
    3426     bool canSendResizeEventSynchronously = isMainFrame && !m_shouldAutoSize;
    3427 
    3428     LOG(Events, "FrameView %p sendResizeEventIfNeeded sending resize event, size %dx%d (canSendResizeEventSynchronously %d)", this, currentSize.width(), currentSize.height(), canSendResizeEventSynchronously);
    3429 
    3430     Ref<Event> resizeEvent = Event::create(eventNames().resizeEvent, Event::CanBubble::No, Event::IsCancelable::No);
    3431     if (canSendResizeEventSynchronously)
    3432         frame().document()->dispatchWindowEvent(resizeEvent);
    3433     else {
    3434         // FIXME: Queueing this event for an unpredictable time in the future seems
    3435         // intrinsically racy. By the time this resize event fires, the frame might
    3436         // be resized again, so we could end up with two resize events for the same size.
    3437         frame().document()->enqueueWindowEvent(WTFMove(resizeEvent));
    3438     }
    3439 
    34403429    if (InspectorInstrumentation::hasFrontends() && isMainFrame) {
    34413430        if (Page* page = frame().page()) {
  • trunk/Source/WebCore/page/Page.cpp

    r251737 r251867  
    12951295    SetForScope<bool> change(m_inUpdateRendering, true);
    12961296
    1297     Vector<RefPtr<Document>> documents;
    1298 
    1299     // The requestAnimationFrame callbacks may change the frame hierarchy of the page
    1300     forEachDocument([&documents] (Document& document) {
    1301         documents.append(&document);
     1297    layoutIfNeeded();
     1298
     1299    forEachDocument([&] (Document& document) {
     1300        document.runResizeSteps();
    13021301    });
    13031302
    1304     // FIXME: Run the resize steps
    1305 
    13061303    // FIXME: Run the scroll steps
    13071304
    13081305    // FIXME: Evaluate media queries and report changes.
    13091306
     1307    Vector<Ref<Document>> documents = collectDocuments(); // The requestAnimationFrame callbacks may change the frame hierarchy of the page
    13101308    for (auto& document : documents) {
    13111309        DOMHighResTimeStamp timestamp = document->domWindow()->nowTimestamp();
Note: See TracChangeset for help on using the changeset viewer.