Changeset 66110 in webkit


Ignore:
Timestamp:
Aug 26, 2010 9:45:43 AM (14 years ago)
Author:
eric.carlson@apple.com
Message:

2010-08-26 Eric Carlson <eric.carlson@apple.com>

Reviewed by Darin Adler and Maciej Stachowiak.

https://bugs.webkit.org/show_bug.cgi?id=44013
HTMLMediaElement should delay document load event

Test: media/video-delay-load-event.html

  • dom/Document.cpp: (WebCore::Document::Document): Initialize incrementLoadEventDelayCount. (WebCore::Document::decrementLoadEventDelayCount): New, decrement incrementLoadEventDelayCount and call loader->checkCompleted() when it reaches zero.
  • dom/Document.h: (WebCore::Document::incrementLoadEventDelayCount): New. (WebCore::Document::isDelayingLoadEvent): New.
  • html/HTMLMediaElement.cpp: (WebCore::HTMLMediaElement::~HTMLMediaElement): Stop delaying the load event if necessary. (WebCore::HTMLMediaElement::willMoveToNewOwnerDocument): Ditto. (WebCore::HTMLMediaElement::didMoveToNewOwnerDocument): Delay the load event if we don't the meta data for the movie yet. (WebCore::HTMLMediaElement::prepareForLoad): Delay the load event. (WebCore::HTMLMediaElement::selectMediaResource): Don't delay the load event when there are no more sources to consider. Don't change m_delayingTheLoadEvent directly, call setShouldDelayLoadEvent() instead. (WebCore::HTMLMediaElement::waitForSourceChange): Stop delaying the load event. (WebCore::HTMLMediaElement::noneSupported): Ditto. (WebCore::HTMLMediaElement::mediaEngineError): Ditto. (WebCore::HTMLMediaElement::setReadyState): Ditto. (WebCore::HTMLMediaElement::userCancelledLoad): Ditto. (WebCore::HTMLMediaElement::setShouldDelayLoadEvent): New, increment/decrement the document's load event delay count.
  • html/HTMLMediaElement.h:
  • loader/FrameLoader.cpp: (WebCore::FrameLoader::checkCompleted): See if the document wants to delay completion for elements that don't go through a FrameLoader. (WebCore::FrameLoader::checkCallImplicitClose): Ditto
  • page/Frame.cpp:

2010-08-26 Eric Carlson <eric.carlson@apple.com>

Reviewed by Darin Adler and Maciej Stachowiak.

https://bugs.webkit.org/show_bug.cgi?id=44013
HTMLMediaElement should delay document load event

  • media/video-delay-load-event-expected.txt: Added.
  • media/video-delay-load-event.html: Added.
  • media/video-layer-crash.html: Trigger test with script inline in the <body> instead of from an onload handler as that runs too late. Reformat script to make it readable.
Location:
trunk
Files:
2 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r66109 r66110  
     12010-08-26  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Reviewed by Darin Adler and Maciej Stachowiak.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=44013
     6        HTMLMediaElement should delay document load event
     7
     8        * media/video-delay-load-event-expected.txt: Added.
     9        * media/video-delay-load-event.html: Added.
     10        * media/video-layer-crash.html: Trigger test with script inline in the <body> instead
     11        of from an onload handler as that runs too late. Reformat script to make it readable.
     12
    1132010-08-26  Dan Bernstein  <mitz@apple.com>
    214
  • trunk/LayoutTests/media/video-layer-crash.html

    r48237 r66110  
    1 <script src="media-file.js"></script>
    2 <script src="video-paint-test.js"></script>
    3 <body onload="document.body.removeChild(document.getElementById('one')); document.body.offsetLeft; init()">
    4 <style>
    5 video { width:200px; border: 3px solid red; -webkit-box-reflect: below 5px; }
    6 </style>
    7 <p>Test dynamic removal of transformed and reflected video </p>
    8 &nbsp;<video id="one" style="-webkit-transform:rotate(20deg)"></video><br>
    9 &nbsp;<video style="-webkit-transform:scale(0.5)"></video><br>
    10 &nbsp;<video style="-webkit-transform:skew(20deg)"></video><br>
    11 <script>setSrcByTagName('video', findMediaFile('video', 'content/test'))</script>
    12 </body>
     1<html>
     2    <head>
     3        <script src="media-file.js"></script>
     4        <script src="video-paint-test.js"></script>
     5        <style>
     6            video { width:200px; border: 3px solid red; -webkit-box-reflect: below 5px; }
     7        </style>
     8    </head>
     9    <body>
     10        <p>Test dynamic removal of transformed and reflected video </p>
     11        &nbsp;<video id="one" style="-webkit-transform:rotate(20deg)"></video><br>
     12        &nbsp;<video style="-webkit-transform:scale(0.5)"></video><br>
     13        &nbsp;<video style="-webkit-transform:skew(20deg)"></video><br>
     14        <script>
     15            setSrcByTagName('video', findMediaFile('video', 'content/test'));
     16            document.body.removeChild(document.getElementById('one')); document.body.offsetLeft;
     17            init();
     18        </script>
     19    </body>
     20</html>
  • trunk/WebCore/ChangeLog

    r66109 r66110  
     12010-08-26  Eric Carlson  <eric.carlson@apple.com>
     2
     3        Reviewed by Darin Adler and Maciej Stachowiak.
     4
     5        https://bugs.webkit.org/show_bug.cgi?id=44013
     6        HTMLMediaElement should delay document load event
     7
     8        Test: media/video-delay-load-event.html
     9
     10        * dom/Document.cpp:
     11        (WebCore::Document::Document): Initialize incrementLoadEventDelayCount.
     12        (WebCore::Document::decrementLoadEventDelayCount): New, decrement incrementLoadEventDelayCount
     13        and call loader->checkCompleted() when it reaches zero.
     14        * dom/Document.h:
     15        (WebCore::Document::incrementLoadEventDelayCount): New.
     16        (WebCore::Document::isDelayingLoadEvent): New.
     17
     18        * html/HTMLMediaElement.cpp:
     19        (WebCore::HTMLMediaElement::~HTMLMediaElement): Stop delaying the load event if necessary.
     20        (WebCore::HTMLMediaElement::willMoveToNewOwnerDocument): Ditto.
     21        (WebCore::HTMLMediaElement::didMoveToNewOwnerDocument): Delay the load event if we don't the
     22        meta data for the movie yet.
     23        (WebCore::HTMLMediaElement::prepareForLoad): Delay the load event.
     24        (WebCore::HTMLMediaElement::selectMediaResource): Don't delay the load event when there are
     25        no more sources to consider. Don't change m_delayingTheLoadEvent directly, call
     26        setShouldDelayLoadEvent() instead.
     27        (WebCore::HTMLMediaElement::waitForSourceChange): Stop delaying the load event.
     28        (WebCore::HTMLMediaElement::noneSupported): Ditto.
     29        (WebCore::HTMLMediaElement::mediaEngineError): Ditto.
     30        (WebCore::HTMLMediaElement::setReadyState): Ditto.
     31        (WebCore::HTMLMediaElement::userCancelledLoad): Ditto.
     32        (WebCore::HTMLMediaElement::setShouldDelayLoadEvent): New, increment/decrement the document's
     33        load event delay count.
     34        * html/HTMLMediaElement.h:
     35
     36        * loader/FrameLoader.cpp:
     37        (WebCore::FrameLoader::checkCompleted): See if the document wants to delay completion for
     38        elements that don't go through a FrameLoader.
     39        (WebCore::FrameLoader::checkCallImplicitClose): Ditto
     40        * page/Frame.cpp:
     41
    1422010-08-26  Dan Bernstein  <mitz@apple.com>
    243
  • trunk/WebCore/dom/Document.cpp

    r66037 r66110  
    398398    , m_weakReference(DocumentWeakReference::create(this))
    399399    , m_idAttributeName(idAttr)
     400    , m_loadEventDelayCount(0)
    400401{
    401402    m_document = this;
     
    46024603#endif
    46034604
     4605void Document::decrementLoadEventDelayCount()
     4606{
     4607    ASSERT(m_loadEventDelayCount);
     4608    --m_loadEventDelayCount;
     4609
     4610    if (frame() && !m_loadEventDelayCount)
     4611        frame()->loader()->checkCompleted();
     4612}
     4613
    46044614} // namespace WebCore
  • trunk/WebCore/dom/Document.h

    r66037 r66110  
    996996    void setWriteDisabled(bool flag) { m_writeDisabled = flag; }
    997997
     998    // Used to allow element that loads data without going through a FrameLoader to delay the 'load' event.
     999    void incrementLoadEventDelayCount() { ++m_loadEventDelayCount; }
     1000    void decrementLoadEventDelayCount();
     1001    bool isDelayingLoadEvent() const { return m_loadEventDelayCount; }
     1002
    9981003protected:
    9991004    Document(Frame*, const KURL&, bool isXHTML, bool isHTML);
     
    12711276
    12721277    QualifiedName m_idAttributeName;
     1278
     1279    int m_loadEventDelayCount;
    12731280};
    12741281
  • trunk/WebCore/html/HTMLMediaElement.cpp

    r65986 r66110  
    3838#include "ClientRectList.h"
    3939#include "ContentType.h"
    40 #include "DocLoader.h"
    4140#include "Event.h"
    4241#include "EventNames.h"
     
    113112    , m_playing(false)
    114113    , m_isWaitingUntilMediaCanStart(false)
    115     , m_delayingTheLoadEvent(false)
     114    , m_shouldDelayLoadEvent(false)
    116115    , m_haveFiredLoadedData(false)
    117116    , m_inActiveDocument(true)
     
    141140    if (m_isWaitingUntilMediaCanStart)
    142141        document()->removeMediaCanStartListener(this);
     142    setShouldDelayLoadEvent(false);
    143143    document()->unregisterForDocumentActivationCallbacks(this);
    144144    document()->unregisterForMediaVolumeCallbacks(this);
     
    149149    if (m_isWaitingUntilMediaCanStart)
    150150        document()->removeMediaCanStartListener(this);
     151    setShouldDelayLoadEvent(false);
    151152    document()->unregisterForDocumentActivationCallbacks(this);
    152153    document()->unregisterForMediaVolumeCallbacks(this);
     
    158159    if (m_isWaitingUntilMediaCanStart)
    159160        document()->addMediaCanStartListener(this);
     161    if (m_readyState < HAVE_CURRENT_DATA)
     162        setShouldDelayLoadEvent(true);
    160163    document()->registerForDocumentActivationCallbacks(this);
    161164    document()->registerForMediaVolumeCallbacks(this);
     
    542545    m_lastSeekTime = 0;
    543546    m_closedCaptionsVisible = false;
     547
     548    // The spec doesn't say to block the load event until we actually run the asynchronous section
     549    // algorithm, but do it now because we won't start that until after the timer fires and the
     550    // event may have already fired by then.
     551    setShouldDelayLoadEvent(true);
    544552}
    545553
     
    575583        if (!node) {
    576584            m_loadState = WaitingForSource;
     585            setShouldDelayLoadEvent(false);
    577586
    578587            // ... set the networkState to NETWORK_EMPTY, and abort these steps
    579588            m_networkState = NETWORK_EMPTY;
    580             ASSERT(!m_delayingTheLoadEvent);
    581589            return;
    582590        }
     
    585593    }
    586594
    587     // 4
    588     m_delayingTheLoadEvent = true;
     595    // 4 - Set the media element's delaying-the-load-event flag to true (this delays the load event),
     596    // and set its networkState to NETWORK_LOADING.
     597    setShouldDelayLoadEvent(true);
    589598    m_networkState = NETWORK_LOADING;
    590599
     
    710719
    711720    // 6.18 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
    712     m_delayingTheLoadEvent = false;
     721    setShouldDelayLoadEvent(false);
    713722}
    714723
     
    733742
    734743    // 8 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
    735     m_delayingTheLoadEvent = false;
     744    setShouldDelayLoadEvent(false);
    736745
    737746    // 9 -Abort these steps. Until the load() method is invoked, the element won't attempt to load another resource.
     
    753762    m_error = err;
    754763
    755     // 3 - Queue a task to fire a progress event called error at the media element, in
    756     // the context of the fetching process started by this instance of this algorithm.
     764    // 3 - Queue a task to fire a simple event named error at the media element.
    757765    scheduleEvent(eventNames().errorEvent);
    758766
     
    763771
    764772    // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
    765     m_delayingTheLoadEvent = false;
     773    setShouldDelayLoadEvent(false);
    766774
    767775    // 6 - Abort the overall resource selection algorithm.
     
    910918        if (renderer())
    911919            renderer()->updateFromElement();
    912         m_delayingTheLoadEvent = false;
    913920        m_player->seek(0);
    914921    }
     
    916923    bool shouldUpdateDisplayState = false;
    917924
    918     // 4.8.10.7 says loadeddata is sent only when the new state *is* HAVE_CURRENT_DATA: "If the
    919     // previous ready state was HAVE_METADATA and the new ready state is HAVE_CURRENT_DATA",
    920     // but the event table at the end of the spec says it is sent when: "readyState newly
    921     // increased to HAVE_CURRENT_DATA  or greater for the first time"
    922     // We go with the later because it seems useful to count on getting this event
    923925    if (m_readyState >= HAVE_CURRENT_DATA && oldState < HAVE_CURRENT_DATA && !m_haveFiredLoadedData) {
    924926        m_haveFiredLoadedData = true;
    925927        shouldUpdateDisplayState = true;
    926928        scheduleEvent(eventNames().loadeddataEvent);
     929        setShouldDelayLoadEvent(false);
    927930    }
    928931
     
    18131816    m_error = MediaError::create(MediaError::MEDIA_ERR_ABORTED);
    18141817
    1815     // 3 - Queue a task to fire a progress event called abort at the media element, in the context
    1816     // of the fetching process started by this instance of this algorithm.
     1818    // 3 - Queue a task to fire a simple event named error at the media element.
    18171819    scheduleEvent(eventNames().abortEvent);
    18181820
    1819     // 5 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the
    1820     // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a
    1821     // simple event called emptied at the element. Otherwise, set set the element's networkState
     1821    // 4 - If the media element's readyState attribute has a value equal to HAVE_NOTHING, set the
     1822    // element's networkState attribute to the NETWORK_EMPTY value and queue a task to fire a 
     1823    // simple event named emptied at the element. Otherwise, set the element's networkState
    18221824    // attribute to the NETWORK_IDLE value.
    18231825    if (m_readyState == HAVE_NOTHING) {
     
    18281830        m_networkState = NETWORK_IDLE;
    18291831
    1830     // 6 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
    1831     m_delayingTheLoadEvent = false;
    1832 
    1833     // 7 - Abort the overall resource selection algorithm.
     1832    // 5 - Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
     1833    setShouldDelayLoadEvent(false);
     1834
     1835    // 6 - Abort the overall resource selection algorithm.
    18341836    m_currentSourceNode = 0;
    18351837
     
    20822084}
    20832085
     2086void HTMLMediaElement::setShouldDelayLoadEvent(bool delay)
     2087{
     2088    if (m_shouldDelayLoadEvent == delay)
     2089        return;
     2090
     2091    m_shouldDelayLoadEvent = delay;
     2092    if (delay)
     2093        document()->incrementLoadEventDelayCount();
     2094    else
     2095        document()->decrementLoadEventDelayCount();
     2096}
     2097   
    20842098}
    20852099
  • trunk/WebCore/html/HTMLMediaElement.h

    r65986 r66110  
    281281    virtual void mediaCanStart();
    282282
     283    void setShouldDelayLoadEvent(bool);
     284
    283285    // Restrictions to change default behaviors. This is effectively a compile time choice at the moment
    284286    // because there are no accessor functions.
     
    340342    bool m_playing : 1;
    341343    bool m_isWaitingUntilMediaCanStart : 1;
    342     bool m_delayingTheLoadEvent : 1;
     344    bool m_shouldDelayLoadEvent : 1;
    343345    bool m_haveFiredLoadedData : 1;
    344346    bool m_inActiveDocument : 1;
  • trunk/WebCore/loader/FrameLoader.cpp

    r65573 r66110  
    832832        return;
    833833
     834    // Still waiting for elements that don't go through a FrameLoader?
     835    if (m_frame->document()->isDelayingLoadEvent())
     836        return;
     837
    834838    // OK, completed.
    835839    m_isComplete = true;
     
    880884void FrameLoader::checkCallImplicitClose()
    881885{
    882     if (m_didCallImplicitClose || m_frame->document()->parsing())
     886    if (m_didCallImplicitClose || m_frame->document()->parsing() || m_frame->document()->isDelayingLoadEvent())
    883887        return;
    884888
Note: See TracChangeset for help on using the changeset viewer.