Changeset 66841 in webkit


Ignore:
Timestamp:
Sep 6, 2010 11:32:48 AM (14 years ago)
Author:
tonyg@chromium.org
Message:

2010-09-06 Tony Gentilcore <tonyg@chromium.org>

Reviewed by Adam Barth.

Implement HTML5 definition of document.readyState
https://bugs.webkit.org/show_bug.cgi?id=45119

  • fast/dom/Document/readystate-expected.txt: Added.
  • fast/dom/Document/readystate.html: Added. Reads readyState inline script, external script, deferred script, DOMContentLoaded, onload, and dynamic post-onload script.

2010-09-06 Tony Gentilcore <tonyg@chromium.org>

Reviewed by Adam Barth.

Implement HTML5 definition of document.readyState
https://bugs.webkit.org/show_bug.cgi?id=45119

The legacy behavior was "loading" -> "loaded" -> "complete". The new
HTML5 behavior is "loading" -> "interactive" -> "complete". There is
some potential for this to cause compat problems if for instance a
page expects readyState to be "loaded" during the DOMContentLoaded event.

Test: fast/dom/Document/readystate.html

  • dom/Document.cpp: (WebCore::Document::Document): Initial value is Complete because according to http://www.whatwg.org/specs/web-apps/current-work/#dom-document-readystate, when a Document is created the initial value is "complete" unless it has a parser associated with it, in which case it is "loading". So the ctor starts it Complete, and when the parser is created it is flipped to Loading. (WebCore::Document::readyState): (WebCore::Document::setReadyState): (WebCore::Document::implicitOpen): (WebCore::Document::finishedParsing): Ensure that XML and HTML parser have transition to Stopping state.
  • dom/Document.h:
  • dom/DocumentParser.cpp: (WebCore::DocumentParser::prepareToStopParsing): Previously this was being called when parsing had stopped. It is better to ensure it is only called while parsing.
  • dom/XMLDocumentParser.cpp: (WebCore::XMLDocumentParser::end): Transition to stopping before calling document finishedParsiong().
  • html/parser/HTMLDocumentParser.cpp: (WebCore::HTMLDocumentParser::prepareToStopParsing): Set state to interactive before running deferred scripts. This method is also called when parsing fragments, so we need to ensure it isn't done in that case. (WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd): Added. Break out this part s that notifyFinished doesn't go through the additional steps of pumping tokenizer, setting the state, etc. (WebCore::HTMLDocumentParser::notifyFinished): Now that prepareToStopParsing is split up, we must protect. It also makes sense to add a couple of ASSERTs.
  • loader/FrameLoader.cpp: (WebCore::FrameLoader::stopLoading): It looks like an aborted load should never transition to "complete" according the HTML5. I've left the legacy behavior for now though. (WebCore::FrameLoader::checkCompleted): The FrameLoader now sets the state on the Document instead of the Document polling the FrameLoader.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r66836 r66841  
     12010-09-06  Tony Gentilcore  <tonyg@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        Implement HTML5 definition of document.readyState
     6        https://bugs.webkit.org/show_bug.cgi?id=45119
     7
     8        * fast/dom/Document/readystate-expected.txt: Added.
     9        * fast/dom/Document/readystate.html: Added. Reads readyState inline script, external script, deferred script, DOMContentLoaded, onload, and dynamic post-onload script.
     10
    1112010-09-06  Shane Stephens  <shanestephens@google.com>
    212
  • trunk/WebCore/ChangeLog

    r66840 r66841  
     12010-09-06  Tony Gentilcore  <tonyg@chromium.org>
     2
     3        Reviewed by Adam Barth.
     4
     5        Implement HTML5 definition of document.readyState
     6        https://bugs.webkit.org/show_bug.cgi?id=45119
     7
     8        The legacy behavior was "loading" -> "loaded" -> "complete". The new
     9        HTML5 behavior is "loading" -> "interactive" -> "complete". There is
     10        some potential for this to cause compat problems if for instance a
     11        page expects readyState to be "loaded" during the DOMContentLoaded event.
     12
     13        Test: fast/dom/Document/readystate.html
     14
     15        * dom/Document.cpp:
     16        (WebCore::Document::Document): Initial value is Complete because according to http://www.whatwg.org/specs/web-apps/current-work/#dom-document-readystate,
     17        when a Document is created the initial value is "complete" unless it has a parser associated with it, in which case it is "loading".
     18        So the ctor starts it Complete, and when the parser is created it is flipped to Loading.
     19        (WebCore::Document::readyState):
     20        (WebCore::Document::setReadyState):
     21        (WebCore::Document::implicitOpen):
     22        (WebCore::Document::finishedParsing): Ensure that XML and HTML parser have transition to Stopping state.
     23        * dom/Document.h:
     24        * dom/DocumentParser.cpp:
     25        (WebCore::DocumentParser::prepareToStopParsing): Previously this was being called when parsing had stopped.
     26        It is better to ensure it is only called while parsing.
     27        * dom/XMLDocumentParser.cpp:
     28        (WebCore::XMLDocumentParser::end): Transition to stopping before calling document finishedParsiong().
     29        * html/parser/HTMLDocumentParser.cpp:
     30        (WebCore::HTMLDocumentParser::prepareToStopParsing): Set state to interactive before running deferred scripts.
     31        This method is also called when parsing fragments, so we need to ensure it isn't done in that case.
     32        (WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd): Added. Break out this part s that notifyFinished doesn't go through
     33        the additional steps of pumping tokenizer, setting the state, etc.
     34        (WebCore::HTMLDocumentParser::notifyFinished): Now that prepareToStopParsing is split up, we must protect. It also makes sense to add a couple of ASSERTs.
     35        * loader/FrameLoader.cpp:
     36        (WebCore::FrameLoader::stopLoading): It looks like an aborted load should never transition to "complete" according the HTML5. I've left the legacy behavior for now though.
     37        (WebCore::FrameLoader::checkCompleted): The FrameLoader now sets the state on the Document instead of the Document polling the FrameLoader.
     38
    1392010-09-06  Anton Muhin  <antonm@chromium.org>
    240
  • trunk/WebCore/dom/Document.cpp

    r66677 r66841  
    358358    , m_domTreeVersion(0)
    359359    , m_styleSheets(StyleSheetList::create(this))
     360    , m_readyState(Complete)
    360361    , m_styleRecalcTimer(this, &Document::styleRecalcTimerFired)
    361362    , m_pendingStyleRecalcShouldForce(false)
     
    953954String Document::readyState() const
    954955{
    955     if (Frame* f = frame()) {
    956         if (f->loader()->isComplete())
    957             return "complete";
    958         if (parsing())
    959             return "loading";
    960         return "loaded";
    961         // FIXME: What does "interactive" mean?
    962         // FIXME: Missing support for "uninitialized".
    963     }
     956    DEFINE_STATIC_LOCAL(const String, loading, ("loading"));
     957    DEFINE_STATIC_LOCAL(const String, interactive, ("interactive"));
     958    DEFINE_STATIC_LOCAL(const String, complete, ("complete"));
     959
     960    switch (m_readyState) {
     961    case Loading:
     962        return loading;
     963    case Interactive:
     964        return interactive;
     965    case Complete:
     966        return complete;
     967    }
     968
     969    ASSERT_NOT_REACHED();
    964970    return String();
     971}
     972
     973void Document::setReadyState(ReadyState readyState)
     974{
     975    // FIXME: Fire the readystatechange event on this Document.
     976    m_readyState = readyState;
    965977}
    966978
     
    18701882    m_parser = createParser();
    18711883    setParsing(true);
     1884    setReadyState(Loading);
    18721885
    18731886    ScriptableDocumentParser* parser = scriptableDocumentParser();
     
    41044117void Document::finishedParsing()
    41054118{
     4119    ASSERT(!scriptableDocumentParser() || !m_parser->isParsing());
     4120    ASSERT(!scriptableDocumentParser() || m_readyState != Loading);
    41064121    setParsing(false);
    41074122    dispatchEvent(Event::create(eventNames().DOMContentLoadedEvent, true, false));
  • trunk/WebCore/dom/Document.h

    r66628 r66841  
    583583    bool inLimitedQuirksMode() const { return m_compatibilityMode == LimitedQuirksMode; }
    584584    bool inNoQuirksMode() const { return m_compatibilityMode == NoQuirksMode; }
    585    
     585
     586    enum ReadyState {
     587        Loading,
     588        Interactive,
     589        Complete
     590    };
     591    void setReadyState(ReadyState);
    586592    void setParsing(bool);
    587593    bool parsing() const { return m_bParsing; }
     
    11551161    bool m_loadingSheet;
    11561162    bool m_visuallyOrdered;
     1163    ReadyState m_readyState;
    11571164    bool m_bParsing;
    11581165   
  • trunk/WebCore/dom/DocumentParser.cpp

    r66670 r66841  
    5353void DocumentParser::prepareToStopParsing()
    5454{
    55     if (m_state == ParsingState)
    56         m_state = StoppingState;
     55    ASSERT(m_state == ParsingState);
     56    m_state = StoppingState;
    5757}
    5858
  • trunk/WebCore/dom/XMLDocumentParser.cpp

    r66670 r66841  
    235235    }
    236236
     237    if (isParsing())
     238        prepareToStopParsing();
     239    document()->setReadyState(Document::Interactive);
    237240    clearCurrentNodeStack();
    238241    document()->finishedParsing();
  • trunk/WebCore/html/parser/HTMLDocumentParser.cpp

    r66670 r66841  
    153153    RefPtr<HTMLDocumentParser> protect(this);
    154154
    155     // FIXME: Set the current document readiness to "interactive".
    156 
    157155    // NOTE: This pump should only ever emit buffered character tokens,
    158156    // so ForceSynchronous vs. AllowYield should be meaningless.
    159157    pumpTokenizerIfPossible(ForceSynchronous);
     158   
     159    if (isStopped())
     160        return;
    160161
    161162    DocumentParser::prepareToStopParsing();
    162     if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
    163         return;
    164     end();
     163
     164    // We will not have a scriptRunner when parsing a DocumentFragment.
     165    if (m_scriptRunner)
     166        document()->setReadyState(Document::Interactive);
     167
     168    attemptToRunDeferredScriptsAndEnd();
    165169}
    166170
     
    354358}
    355359
     360void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
     361{
     362    ASSERT(isStopping());
     363    ASSERT(!hasInsertionPoint());
     364    if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
     365        return;
     366    end();
     367}
     368
    356369void HTMLDocumentParser::attemptToEnd()
    357370{
     
    461474void HTMLDocumentParser::notifyFinished(CachedResource* cachedResource)
    462475{
    463     if (isStopping()) {
    464         prepareToStopParsing();
    465         return;
    466     }
    467 
    468476    // pumpTokenizer can cause this parser to be detached from the Document,
    469477    // but we need to ensure it isn't deleted yet.
     
    472480    ASSERT(m_scriptRunner);
    473481    ASSERT(!inScriptExecution());
     482    if (isStopping()) {
     483        attemptToRunDeferredScriptsAndEnd();
     484        return;
     485    }
     486
    474487    ASSERT(m_treeBuilder->isPaused());
    475488    // Note: We only ever wait on one script at a time, so we always know this
  • trunk/WebCore/html/parser/HTMLDocumentParser.h

    r66670 r66841  
    115115    void attemptToEnd();
    116116    void endIfDelayed();
     117    void attemptToRunDeferredScriptsAndEnd();
    117118    void end();
    118119
  • trunk/WebCore/loader/FrameLoader.cpp

    r66815 r66841  
    426426
    427427    if (Document* doc = m_frame->document()) {
     428        // FIXME: HTML5 doesn't tell us to set the state to complete when aborting, but we do anyway to match legacy behavior.
     429        // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10537
     430        doc->setReadyState(Document::Complete);
     431
    428432        if (DocLoader* docLoader = doc->docLoader())
    429433            cache()->loader()->cancelRequests(docLoader);
     
    839843    // OK, completed.
    840844    m_isComplete = true;
     845    m_frame->document()->setReadyState(Document::Complete);
    841846
    842847    RefPtr<Frame> protect(m_frame);
Note: See TracChangeset for help on using the changeset viewer.