Modernize and tighten up HTMLDocumentParser
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 02:24:31 +0000 (02:24 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 5 Jan 2015 02:24:31 +0000 (02:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=140041

Reviewed by Sam Weinig.

* dom/DocumentFragment.cpp:
(WebCore::DocumentFragment::parseHTML): Pass a reference instead of
a pointer for the context element.

* html/FTPDirectoryDocument.cpp: Removed unneeded includes, made more
things in FTPDirectoryDocumentParser private. Use Ref instead of RefPtr
in a could places. Initialize in class instead of in constructor.
(WebCore::FTPDirectoryDocumentParser::FTPDirectoryDocumentParser):
Less initialization here.
(WebCore::FTPDirectoryDocumentParser::createTDForFilename): More Ref here.
(WebCore::createTemplateDocumentData): Removed unneeded initialization
of RefPtr, which is initialized without explicitly asking for it.
(WebCore::FTPDirectoryDocumentParser::loadDocumentTemplate): Reworded
comment slightly.

* html/parser/HTMLDocumentParser.cpp: Cut down on includes.
(WebCore::tokenizerStateForContextElement): Fixed URL. Changed argument
to be a reference rather than a pointer.
(WebCore::HTMLDocumentParser::inPumpSession):
(WebCore::HTMLDocumentParser::shouldDelayEnd):
(WebCore::HTMLDocumentParser::HTMLDocumentParser): Marked constructors
inline. Updated for data members that are now objects instead of pointers.
Removed explicit initialization for scalars that are now initialized in
the class definition.
(WebCore::HTMLDocumentParser::create): Moved the private creation
functions in here, out of the header file.
(WebCore::HTMLDocumentParser::~HTMLDocumentParser): Removed unused
m_haveBackgroundParser.
(WebCore::HTMLDocumentParser::prepareToStopParsing): Updated URL and
removed m_haveBackgroundParser reference.
(WebCore::HTMLDocumentParser::processingData): Removed a check of
m_haveBackgroundParser.
(WebCore::HTMLDocumentParser::resumeParsingAfterYield): Tweak comment.
(WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Added
a null check of the result of takeScriptToProcess, since there really
is no guarantee it's non-null.
(WebCore::HTMLDocumentParser::canTakeNextToken): Removed assertion
that was for m_haveBackgroundParser cases only. Rewrapped comment.
(WebCore::HTMLDocumentParser::contextForParsingSession): Use nullptr.
(WebCore::HTMLDocumentParser::pumpTokenizer): Rework comments,
remove assertions that no longer make sense, use auto instead of
repeating a long type name, update to use m_token and m_tokenizer.
(WebCore::HTMLDocumentParser::hasInsertionPoint): Rewrapped comment.
(WebCore::HTMLDocumentParser::insert): Got rid of braces around a
single-line if body.
(WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd):
Removed comment about incorrect m_haveBackgroundParser assertion.
(WebCore::HTMLDocumentParser::isExecutingScript): Use && style instead
of early exit for a null check.
(WebCore::HTMLDocumentParser::textPosition): Tightened up code a little.
(WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution): Added
a Ref to protect the parser, as is already done in every other function
that calls pumpTokenizerIfPossible.
(WebCore::HTMLDocumentParser::parseDocumentFragment): Take a reference
instead of a pointer. Also use auto so we get a Ref instead of a RefPtr.

* html/parser/HTMLDocumentParser.h: Removed unneeded includes.
Made private inheritance explicit instead of just omitting public.
Moved function bodies out of the class, and in some cases, out of the
header entirely. Return a reference from tokenizer(). Marked most
virtual functions final. Made DocumentFragment version of the
constructor private rather than protected. Made the functions
suspendScheduledTasks() and resumeScheduledTasks() private, since
they are always called through a base class. Removed the private
token function since it is better to get at m_token directly.
Removed m_haveBackgroundParser, since we don't have that any more
and it's always false. Also removed forcePlaintextForTextDocument
since the tokenizer is exposed and can be used directly to do that.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Made the parser non-const.
It could only be const before because HTMLDocumentParser::tokenizer
took a const parser and returned a non-const tokenizer, but that doesn't
really make sense.
(WebCore::HTMLTreeBuilder::constructTree): Removed null check for
tokenizer, which was never null. Updated since tokenizer is a reference.
(WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
(WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
(WebCore::HTMLTreeBuilder::processEndTag): Ditto. Also fixed and removed
some assertions like the ones I did recently in the rest of this file.
(WebCore::HTMLTreeBuilder::processGenericRCDATAStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processGenericRawTextStartTag): Ditto.
(WebCore::HTMLTreeBuilder::processScriptStartTag): Ditto.

* html/parser/HTMLTreeBuilder.h: Made HTMLDocumentParser& non-const.

* html/parser/TextDocumentParser.cpp: Removed unneeded include and
unneeded explicit destructor.
(WebCore::TextDocumentParser::TextDocumentParser): Updated since
treeBuilder() returns a reference now, and set the tokenizer state
directly since tokenizer() is exposed.

* html/parser/TextDocumentParser.h: Moved initialization of the
data member here instead of the constructor. Also removed unneeded
explicitly defined destructor.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@177883 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/DocumentFragment.cpp
Source/WebCore/html/FTPDirectoryDocument.cpp
Source/WebCore/html/parser/HTMLDocumentParser.cpp
Source/WebCore/html/parser/HTMLDocumentParser.h
Source/WebCore/html/parser/HTMLTreeBuilder.cpp
Source/WebCore/html/parser/HTMLTreeBuilder.h
Source/WebCore/html/parser/TextDocumentParser.cpp
Source/WebCore/html/parser/TextDocumentParser.h

index 4d586b7aa2879d26ac7751d34ac5d2eb5547bfda..17ee70428db688ac1cd2c101a817995068da4a92 100644 (file)
@@ -1,3 +1,106 @@
+2015-01-04  Darin Adler  <darin@apple.com>
+
+        Modernize and tighten up HTMLDocumentParser
+        https://bugs.webkit.org/show_bug.cgi?id=140041
+
+        Reviewed by Sam Weinig.
+
+        * dom/DocumentFragment.cpp:
+        (WebCore::DocumentFragment::parseHTML): Pass a reference instead of
+        a pointer for the context element.
+
+        * html/FTPDirectoryDocument.cpp: Removed unneeded includes, made more
+        things in FTPDirectoryDocumentParser private. Use Ref instead of RefPtr
+        in a could places. Initialize in class instead of in constructor.
+        (WebCore::FTPDirectoryDocumentParser::FTPDirectoryDocumentParser):
+        Less initialization here.
+        (WebCore::FTPDirectoryDocumentParser::createTDForFilename): More Ref here.
+        (WebCore::createTemplateDocumentData): Removed unneeded initialization
+        of RefPtr, which is initialized without explicitly asking for it.
+        (WebCore::FTPDirectoryDocumentParser::loadDocumentTemplate): Reworded
+        comment slightly.
+
+        * html/parser/HTMLDocumentParser.cpp: Cut down on includes.
+        (WebCore::tokenizerStateForContextElement): Fixed URL. Changed argument
+        to be a reference rather than a pointer.
+        (WebCore::HTMLDocumentParser::inPumpSession):
+        (WebCore::HTMLDocumentParser::shouldDelayEnd):
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser): Marked constructors
+        inline. Updated for data members that are now objects instead of pointers.
+        Removed explicit initialization for scalars that are now initialized in
+        the class definition.
+        (WebCore::HTMLDocumentParser::create): Moved the private creation
+        functions in here, out of the header file.
+        (WebCore::HTMLDocumentParser::~HTMLDocumentParser): Removed unused
+        m_haveBackgroundParser.
+        (WebCore::HTMLDocumentParser::prepareToStopParsing): Updated URL and
+        removed m_haveBackgroundParser reference.
+        (WebCore::HTMLDocumentParser::processingData): Removed a check of
+        m_haveBackgroundParser.
+        (WebCore::HTMLDocumentParser::resumeParsingAfterYield): Tweak comment.
+        (WebCore::HTMLDocumentParser::runScriptsForPausedTreeBuilder): Added
+        a null check of the result of takeScriptToProcess, since there really
+        is no guarantee it's non-null.
+        (WebCore::HTMLDocumentParser::canTakeNextToken): Removed assertion
+        that was for m_haveBackgroundParser cases only. Rewrapped comment.
+        (WebCore::HTMLDocumentParser::contextForParsingSession): Use nullptr.
+        (WebCore::HTMLDocumentParser::pumpTokenizer): Rework comments,
+        remove assertions that no longer make sense, use auto instead of
+        repeating a long type name, update to use m_token and m_tokenizer.
+        (WebCore::HTMLDocumentParser::hasInsertionPoint): Rewrapped comment.
+        (WebCore::HTMLDocumentParser::insert): Got rid of braces around a
+        single-line if body.
+        (WebCore::HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd):
+        Removed comment about incorrect m_haveBackgroundParser assertion.
+        (WebCore::HTMLDocumentParser::isExecutingScript): Use && style instead
+        of early exit for a null check.
+        (WebCore::HTMLDocumentParser::textPosition): Tightened up code a little.
+        (WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution): Added
+        a Ref to protect the parser, as is already done in every other function
+        that calls pumpTokenizerIfPossible.
+        (WebCore::HTMLDocumentParser::parseDocumentFragment): Take a reference
+        instead of a pointer. Also use auto so we get a Ref instead of a RefPtr.
+
+        * html/parser/HTMLDocumentParser.h: Removed unneeded includes.
+        Made private inheritance explicit instead of just omitting public.
+        Moved function bodies out of the class, and in some cases, out of the
+        header entirely. Return a reference from tokenizer(). Marked most
+        virtual functions final. Made DocumentFragment version of the
+        constructor private rather than protected. Made the functions
+        suspendScheduledTasks() and resumeScheduledTasks() private, since
+        they are always called through a base class. Removed the private
+        token function since it is better to get at m_token directly.
+        Removed m_haveBackgroundParser, since we don't have that any more
+        and it's always false. Also removed forcePlaintextForTextDocument
+        since the tokenizer is exposed and can be used directly to do that.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder): Made the parser non-const.
+        It could only be const before because HTMLDocumentParser::tokenizer
+        took a const parser and returned a non-const tokenizer, but that doesn't
+        really make sense.
+        (WebCore::HTMLTreeBuilder::constructTree): Removed null check for
+        tokenizer, which was never null. Updated since tokenizer is a reference.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTag): Ditto. Also fixed and removed
+        some assertions like the ones I did recently in the rest of this file.
+        (WebCore::HTMLTreeBuilder::processGenericRCDATAStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processGenericRawTextStartTag): Ditto.
+        (WebCore::HTMLTreeBuilder::processScriptStartTag): Ditto.
+
+        * html/parser/HTMLTreeBuilder.h: Made HTMLDocumentParser& non-const.
+
+        * html/parser/TextDocumentParser.cpp: Removed unneeded include and
+        unneeded explicit destructor.
+        (WebCore::TextDocumentParser::TextDocumentParser): Updated since
+        treeBuilder() returns a reference now, and set the tokenizer state
+        directly since tokenizer() is exposed.
+
+        * html/parser/TextDocumentParser.h: Moved initialization of the
+        data member here instead of the constructor. Also removed unneeded
+        explicitly defined destructor.
+
 2015-01-04  Antti Koivisto  <antti@apple.com>
 
         Remove GlyphPageTree
index d600812cefe717e3f6ea6f87a07855097d0b04e5..479022b19b5ca3380ce43178d1afa3f6a98cd337 100644 (file)
@@ -82,11 +82,13 @@ RefPtr<Node> DocumentFragment::cloneNodeInternal(Document& targetDocument, Cloni
 
 void DocumentFragment::parseHTML(const String& source, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
-    HTMLDocumentParser::parseDocumentFragment(source, *this, contextElement, parserContentPolicy);
+    ASSERT(contextElement);
+    HTMLDocumentParser::parseDocumentFragment(source, *this, *contextElement, parserContentPolicy);
 }
 
 bool DocumentFragment::parseXML(const String& source, Element* contextElement, ParserContentPolicy parserContentPolicy)
 {
+    ASSERT(contextElement);
     return XMLDocumentParser::parseDocumentFragment(source, *this, contextElement, parserContentPolicy);
 }
 
index 6661fae7b29e65dde6c7d43cb1895e99ee4d9db4..27b729f17c59e4aef1530c6262698fb7e4be26be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2008, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2008, 2014-2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -26,9 +26,7 @@
 #if ENABLE(FTPDIR)
 #include "FTPDirectoryDocument.h"
 
-#include "ExceptionCodePlaceholder.h"
 #include "HTMLDocumentParser.h"
-#include "HTMLNames.h"
 #include "HTMLTableElement.h"
 #include "LocalizedStrings.h"
 #include "Logging.h"
 #include "Settings.h"
 #include "SharedBuffer.h"
 #include "Text.h"
-#include <wtf/CurrentTime.h>
-#include <wtf/GregorianDateTime.h>
 #include <wtf/StdLibExtras.h>
-#include <wtf/text/CString.h>
 #include <wtf/unicode/CharacterNames.h>
 
 namespace WebCore {
@@ -53,12 +48,14 @@ public:
         return adoptRef(*new FTPDirectoryDocumentParser(document));
     }
 
+private:
     virtual void append(PassRefPtr<StringImpl>) override;
     virtual void finish() override;
 
+    // FIXME: Why do we need this?
     virtual bool isWaitingForScripts() const override { return false; }
 
-    inline void checkBuffer(int len = 10)
+    void checkBuffer(int len = 10)
     {
         if ((m_dest - m_buffer) > m_size - len) {
             // Enlarge buffer
@@ -69,8 +66,7 @@ public:
             m_size = newSize;
         }
     }
-        
-private:
+
     FTPDirectoryDocumentParser(HTMLDocument&);
 
     // The parser will attempt to load the document template specified via the preference
@@ -81,13 +77,13 @@ private:
 
     void parseAndAppendOneLine(const String&);
     void appendEntry(const String& name, const String& size, const String& date, bool isDirectory);    
-    RefPtr<Element> createTDForFilename(const String&);
+    Ref<Element> createTDForFilename(const String&);
 
     RefPtr<HTMLTableElement> m_tableElement;
 
-    bool m_skipLF;
+    bool m_skipLF { false };
     
-    int m_size;
+    int m_size { 254 };
     UChar* m_buffer;
     UChar* m_dest;
     String m_carryOver;
@@ -97,8 +93,6 @@ private:
 
 FTPDirectoryDocumentParser::FTPDirectoryDocumentParser(HTMLDocument& document)
     : HTMLDocumentParser(document)
-    , m_skipLF(false)
-    , m_size(254)
     , m_buffer(static_cast<UChar*>(fastMalloc(sizeof(UChar) * m_size)))
     , m_dest(m_buffer)
 {
@@ -132,7 +126,7 @@ void FTPDirectoryDocumentParser::appendEntry(const String& filename, const Strin
     rowElement->appendChild(element, IGNORE_EXCEPTION);
 }
 
-RefPtr<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& filename)
+Ref<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& filename)
 {
     String fullURL = document()->baseURL().string();
     if (fullURL.endsWith('/'))
@@ -144,10 +138,10 @@ RefPtr<Element> FTPDirectoryDocumentParser::createTDForFilename(const String& fi
     anchorElement->setAttribute(HTMLNames::hrefAttr, fullURL);
     anchorElement->appendChild(Text::create(*document(), filename), IGNORE_EXCEPTION);
 
-    RefPtr<Element> tdElement = document()->createElement(tdTag, false);
+    Ref<Element> tdElement = document()->createElement(tdTag, false);
     tdElement->appendChild(anchorElement, IGNORE_EXCEPTION);
 
-    return tdElement.release();
+    return tdElement;
 }
 
 static String processFilesizeString(const String& size, bool isDirectory)
@@ -275,7 +269,7 @@ void FTPDirectoryDocumentParser::parseAndAppendOneLine(const String& inputLine)
 
 static inline RefPtr<SharedBuffer> createTemplateDocumentData(Settings* settings)
 {
-    RefPtr<SharedBuffer> buffer = 0;
+    RefPtr<SharedBuffer> buffer;
     if (settings)
         buffer = SharedBuffer::createWithContentsOfFile(settings->ftpDirectoryTemplatePath());
     if (buffer)
@@ -286,9 +280,8 @@ static inline RefPtr<SharedBuffer> createTemplateDocumentData(Settings* settings
 bool FTPDirectoryDocumentParser::loadDocumentTemplate()
 {
     static SharedBuffer* templateDocumentData = createTemplateDocumentData(document()->settings()).release().leakRef();
-    // FIXME: Instead of storing the data, we'd rather actually parse the template data into the template Document once,
-    // store that document, then "copy" it whenever we get an FTP directory listing.  There are complexities with this 
-    // approach that make it worth putting this off.
+    // FIXME: Instead of storing the data, it would be more efficient if we could parse the template data into the
+    // template Document once, store that document, then "copy" it whenever we get an FTP directory listing.
     
     if (!templateDocumentData) {
         LOG_ERROR("Could not load templateData");
index 20cff5c0fd7ea89115a06cf494856b845557efdd..0915350945d77b3420523df5848f4a6b02cdecff 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "HTMLDocumentParser.h"
 
-#include "ContentSecurityPolicy.h"
 #include "DocumentFragment.h"
-#include "DocumentLoader.h"
-#include "Frame.h"
 #include "HTMLParserScheduler.h"
+#include "HTMLPreloadScanner.h"
 #include "HTMLScriptRunner.h"
 #include "HTMLTreeBuilder.h"
 #include "HTMLDocument.h"
 #include "InspectorInstrumentation.h"
-#include "Settings.h"
-#include <wtf/Ref.h>
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
 // This is a direct transcription of step 4 from:
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#fragment-case
-static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElement, bool reportErrors, const HTMLParserOptions& options)
+// https://html.spec.whatwg.org/multipage/syntax.html#parsing-html-fragments
+static HTMLTokenizer::State tokenizerStateForContextElement(Element& contextElement, bool reportErrors, const HTMLParserOptions& options)
 {
-    if (!contextElement)
-        return HTMLTokenizer::DataState;
-
-    const QualifiedName& contextTag = contextElement->tagQName();
+    const QualifiedName& contextTag = contextElement.tagQName();
 
     if (contextTag.matches(titleTag) || contextTag.matches(textareaTag))
         return HTMLTokenizer::RCDATAState;
@@ -70,46 +64,43 @@ static HTMLTokenizer::State tokenizerStateForContextElement(Element* contextElem
 HTMLDocumentParser::HTMLDocumentParser(HTMLDocument& document)
     : ScriptableDocumentParser(document)
     , m_options(document)
-    , m_token(std::make_unique<HTMLToken>())
-    , m_tokenizer(std::make_unique<HTMLTokenizer>(m_options))
+    , m_tokenizer(m_options)
     , m_scriptRunner(std::make_unique<HTMLScriptRunner>(document, static_cast<HTMLScriptRunnerHost&>(*this)))
     , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, document, parserContentPolicy(), m_options))
     , m_parserScheduler(std::make_unique<HTMLParserScheduler>(*this))
     , m_xssAuditorDelegate(document)
     , m_preloader(std::make_unique<HTMLResourcePreloader>(document))
-    , m_endWasDelayed(false)
-    , m_haveBackgroundParser(false)
-    , m_pumpSessionNestingLevel(0)
 {
-    ASSERT(m_token);
-    ASSERT(m_tokenizer);
 }
 
-// FIXME: Member variables should be grouped into self-initializing structs to
-// minimize code duplication between these constructors.
-HTMLDocumentParser::HTMLDocumentParser(DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
-    : ScriptableDocumentParser(fragment.document(), parserContentPolicy)
+Ref<HTMLDocumentParser> HTMLDocumentParser::create(HTMLDocument& document)
+{
+    return adoptRef(*new HTMLDocumentParser(document));
+}
+
+inline HTMLDocumentParser::HTMLDocumentParser(DocumentFragment& fragment, Element& contextElement, ParserContentPolicy contentPolicy)
+    : ScriptableDocumentParser(fragment.document(), contentPolicy)
     , m_options(fragment.document())
-    , m_token(std::make_unique<HTMLToken>())
-    , m_tokenizer(std::make_unique<HTMLTokenizer>(m_options))
-    , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, *contextElement, this->parserContentPolicy(), m_options))
+    , m_tokenizer(m_options)
+    , m_treeBuilder(std::make_unique<HTMLTreeBuilder>(*this, fragment, contextElement, contentPolicy, m_options))
     , m_xssAuditorDelegate(fragment.document())
-    , m_endWasDelayed(false)
-    , m_haveBackgroundParser(false)
-    , m_pumpSessionNestingLevel(0)
 {
     bool reportErrors = false; // For now document fragment parsing never reports errors.
-    m_tokenizer->setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options));
+    m_tokenizer.setState(tokenizerStateForContextElement(contextElement, reportErrors, m_options));
     m_xssAuditor.initForFragment();
 }
 
+inline Ref<HTMLDocumentParser> HTMLDocumentParser::create(DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy)
+{
+    return adoptRef(*new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
+}
+
 HTMLDocumentParser::~HTMLDocumentParser()
 {
     ASSERT(!m_parserScheduler);
     ASSERT(!m_pumpSessionNestingLevel);
     ASSERT(!m_preloadScanner);
     ASSERT(!m_insertionPreloadScanner);
-    ASSERT(!m_haveBackgroundParser);
 }
 
 void HTMLDocumentParser::detach()
@@ -132,12 +123,10 @@ void HTMLDocumentParser::stopParsing()
 }
 
 // This kicks off "Once the user agent stops parsing" as described by:
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
+// https://html.spec.whatwg.org/multipage/syntax.html#the-end
 void HTMLDocumentParser::prepareToStopParsing()
 {
-    // FIXME: It may not be correct to disable this for the background parser.
-    // That means hasInsertionPoint() may not be correct in some cases.
-    ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
+    ASSERT(!hasInsertionPoint());
 
     // pumpTokenizer can cause this parser to be detached from the Document,
     // but we need to ensure it isn't deleted yet.
@@ -164,6 +153,16 @@ void HTMLDocumentParser::prepareToStopParsing()
     attemptToRunDeferredScriptsAndEnd();
 }
 
+inline bool HTMLDocumentParser::inPumpSession() const
+{
+    return m_pumpSessionNestingLevel > 0;
+}
+
+inline bool HTMLDocumentParser::shouldDelayEnd() const
+{
+    return inPumpSession() || isWaitingForScripts() || isScheduledForResume() || isExecutingScript();
+}
+
 bool HTMLDocumentParser::isParsingFragment() const
 {
     return m_treeBuilder->isParsingFragment();
@@ -171,7 +170,7 @@ bool HTMLDocumentParser::isParsingFragment() const
 
 bool HTMLDocumentParser::processingData() const
 {
-    return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
+    return isScheduledForResume() || inPumpSession();
 }
 
 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
@@ -200,8 +199,8 @@ void HTMLDocumentParser::resumeParsingAfterYield()
     // but we need to ensure it isn't deleted yet.
     Ref<HTMLDocumentParser> protect(*this);
 
-    // We should never be here unless we can pump immediately.  Call pumpTokenizer()
-    // directly so that ASSERTS will fire if we're wrong.
+    // We should never be here unless we can pump immediately.
+    // Call pumpTokenizer() directly so that ASSERTS will fire if we're wrong.
     pumpTokenizer(AllowYield);
     endIfDelayed();
 }
@@ -211,10 +210,11 @@ void HTMLDocumentParser::runScriptsForPausedTreeBuilder()
     ASSERT(scriptingContentIsAllowed(parserContentPolicy()));
 
     TextPosition scriptStartPosition = TextPosition::belowRangePosition();
-    RefPtr<Element> scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition);
-    // We will not have a scriptRunner when parsing a DocumentFragment.
-    if (m_scriptRunner)
-        m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
+    if (auto scriptElement = m_treeBuilder->takeScriptToProcess(scriptStartPosition)) {
+        // We will not have a scriptRunner when parsing a DocumentFragment.
+        if (m_scriptRunner)
+            m_scriptRunner->execute(scriptElement.release(), scriptStartPosition);
+    }
 }
 
 bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& session)
@@ -222,8 +222,6 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
     if (isStopped())
         return false;
 
-    ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
-
     if (isWaitingForScripts()) {
         if (mode == AllowYield)
             m_parserScheduler->checkForYieldBeforeScript(session);
@@ -238,14 +236,11 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
             return false;
     }
 
-    // FIXME: It's wrong for the HTMLDocumentParser to reach back to the
-    //        Frame, but this approach is how the old parser handled
-    //        stopping when the page assigns window.location.  What really
-    //        should happen is that assigning window.location causes the
-    //        parser to stop parsing cleanly.  The problem is we're not
-    //        perpared to do that at every point where we run JavaScript.
-    if (!isParsingFragment()
-        && document()->frame() && document()->frame()->navigationScheduler().locationChangePending())
+    // FIXME: It's wrong for the HTMLDocumentParser to reach back to the Frame, but this approach is
+    // how the parser has always handled stopping when the page assigns window.location. What should
+    // happen instead  is that assigning window.location causes the parser to stop parsing cleanly.
+    // The problem is we're not prepared to do that at every point where we run JavaScript.
+    if (!isParsingFragment() && document()->frame() && document()->frame()->navigationScheduler().locationChangePending())
         return false;
 
     if (mode == AllowYield)
@@ -254,17 +249,12 @@ bool HTMLDocumentParser::canTakeNextToken(SynchronousMode mode, PumpSession& ses
     return true;
 }
 
-void HTMLDocumentParser::forcePlaintextForTextDocument()
-{
-    m_tokenizer->setState(HTMLTokenizer::PLAINTEXTState);
-}
-
 Document* HTMLDocumentParser::contextForParsingSession()
 {
     // The parsing session should interact with the document only when parsing
     // non-fragments. Otherwise, we might delay the load event mistakenly.
     if (isParsingFragment())
-        return 0;
+        return nullptr;
     return document();
 }
 
@@ -272,11 +262,9 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
 {
     ASSERT(!isStopped());
     ASSERT(!isScheduledForResume());
-    // ASSERT that this object is both attached to the Document and protected.
+
+    // This is an attempt to check that this object is both attached to the Document and protected by something.
     ASSERT(refCount() >= 2);
-    ASSERT(m_tokenizer);
-    ASSERT(m_token);
-    ASSERT(!m_haveBackgroundParser || mode == ForceSynchronous);
 
     PumpSession session(m_pumpSessionNestingLevel, contextForParsingSession());
 
@@ -285,28 +273,28 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
     // FIXME: m_input.current().length() is only accurate if we
     // end up parsing the whole buffer in this pump.  We should pass how
     // much we parsed as part of didWriteHTML instead of willWriteHTML.
-    InspectorInstrumentationCookie cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
+    auto cookie = InspectorInstrumentation::willWriteHTML(document(), m_input.current().currentLine().zeroBasedInt());
 
     m_xssAuditor.init(document(), &m_xssAuditorDelegate);
 
     while (canTakeNextToken(mode, session) && !session.needsYield) {
         if (!isParsingFragment())
-            m_sourceTracker.start(m_input.current(), m_tokenizer.get(), token());
+            m_sourceTracker.start(m_input.current(), &m_tokenizer, m_token);
 
-        if (!m_tokenizer->nextToken(m_input.current(), token()))
+        if (!m_tokenizer.nextToken(m_input.current(), m_token))
             break;
 
         if (!isParsingFragment()) {
-            m_sourceTracker.end(m_input.current(), m_tokenizer.get(), token());
+            m_sourceTracker.end(m_input.current(), &m_tokenizer, m_token);
 
             // We do not XSS filter innerHTML, which means we (intentionally) fail
             // http/tests/security/xssAuditor/dom-write-innerHTML.html
-            if (auto xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(token(), m_sourceTracker, m_tokenizer->shouldAllowCDATA())))
+            if (auto xssInfo = m_xssAuditor.filterToken(FilterTokenRequest(m_token, m_sourceTracker, m_tokenizer.shouldAllowCDATA())))
                 m_xssAuditorDelegate.didBlockScript(*xssInfo);
         }
 
-        constructTreeFromHTMLToken(token());
-        ASSERT(token().isUninitialized());
+        constructTreeFromHTMLToken(m_token);
+        ASSERT(m_token.isUninitialized());
     }
 
     // Ensure we haven't been totally deref'ed after pumping. Any caller of this
@@ -320,7 +308,7 @@ void HTMLDocumentParser::pumpTokenizer(SynchronousMode mode)
         m_parserScheduler->scheduleForResume();
 
     if (isWaitingForScripts()) {
-        ASSERT(m_tokenizer->state() == HTMLTokenizer::DataState);
+        ASSERT(m_tokenizer.state() == HTMLTokenizer::DataState);
         if (!m_preloadScanner) {
             m_preloadScanner = std::make_unique<HTMLPreloadScanner>(m_options, document()->url(), document()->deviceScaleFactor());
             m_preloadScanner->appendToEnd(m_input.current());
@@ -359,10 +347,9 @@ void HTMLDocumentParser::constructTreeFromHTMLToken(HTMLToken& rawToken)
 bool HTMLDocumentParser::hasInsertionPoint()
 {
     // FIXME: The wasCreatedByScript() branch here might not be fully correct.
-    //        Our model of the EOF character differs slightly from the one in
-    //        the spec because our treatment is uniform between network-sourced
-    //        and script-sourced input streams whereas the spec treats them
-    //        differently.
+    // Our model of the EOF character differs slightly from the one in the spec
+    // because our treatment is uniform between network-sourced and script-sourced
+    // input streams whereas the spec treats them differently.
     return m_input.hasInsertionPoint() || (wasCreatedByScript() && !m_input.haveSeenEndOfFile());
 }
 
@@ -383,9 +370,8 @@ void HTMLDocumentParser::insert(const SegmentedString& source)
     if (isWaitingForScripts()) {
         // Check the document.write() output with a separate preload scanner as
         // the main scanner can't deal with insertions.
-        if (!m_insertionPreloadScanner) {
+        if (!m_insertionPreloadScanner)
             m_insertionPreloadScanner = std::make_unique<HTMLPreloadScanner>(m_options, document()->url(), document()->deviceScaleFactor());
-        }
         m_insertionPreloadScanner->appendToEnd(source);
         m_insertionPreloadScanner->scan(m_preloader.get(), *document());
     }
@@ -401,6 +387,7 @@ void HTMLDocumentParser::append(PassRefPtr<StringImpl> inputSource)
     // pumpTokenizer can cause this parser to be detached from the Document,
     // but we need to ensure it isn't deleted yet.
     Ref<HTMLDocumentParser> protect(*this);
+
     String source(inputSource);
 
     if (m_preloadScanner) {
@@ -441,9 +428,7 @@ void HTMLDocumentParser::end()
 void HTMLDocumentParser::attemptToRunDeferredScriptsAndEnd()
 {
     ASSERT(isStopping());
-    // FIXME: It may not be correct to disable this for the background parser.
-    // That means hasInsertionPoint() may not be correct in some cases.
-    ASSERT(!hasInsertionPoint() || m_haveBackgroundParser);
+    ASSERT(!hasInsertionPoint());
     if (m_scriptRunner && !m_scriptRunner->executeScriptsWaitingForParsing())
         return;
     end();
@@ -491,18 +476,13 @@ void HTMLDocumentParser::finish()
 
 bool HTMLDocumentParser::isExecutingScript() const
 {
-    if (!m_scriptRunner)
-        return false;
-    return m_scriptRunner->isExecutingScript();
+    return m_scriptRunner && m_scriptRunner->isExecutingScript();
 }
 
 TextPosition HTMLDocumentParser::textPosition() const
 {
-    const SegmentedString& currentString = m_input.current();
-    OrdinalNumber line = currentString.currentLine();
-    OrdinalNumber column = currentString.currentColumn();
-
-    return TextPosition(line, column);
+    auto& currentString = m_input.current();
+    return TextPosition(currentString.currentLine(), currentString.currentColumn());
 }
 
 bool HTMLDocumentParser::isWaitingForScripts() const
@@ -526,6 +506,10 @@ void HTMLDocumentParser::resumeParsingAfterScriptExecution()
     ASSERT(!isExecutingScript());
     ASSERT(!isWaitingForScripts());
 
+    // pumpTokenizer can cause this parser to be detached from the Document,
+    // but we need to ensure it isn't deleted yet.
+    Ref<HTMLDocumentParser> protect(*this);
+
     m_insertionPreloadScanner = nullptr;
     pumpTokenizerIfPossible(AllowYield);
     endIfDelayed();
@@ -589,13 +573,13 @@ void HTMLDocumentParser::executeScriptsWaitingForStylesheets()
         resumeParsingAfterScriptExecution();
 }
 
-void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
+void HTMLDocumentParser::parseDocumentFragment(const String& source, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy)
 {
-    RefPtr<HTMLDocumentParser> parser = HTMLDocumentParser::create(fragment, contextElement, parserContentPolicy);
+    auto parser = create(fragment, contextElement, parserContentPolicy);
     parser->insert(source); // Use insert() so that the parser will not yield.
     parser->finish();
-    ASSERT(!parser->processingData()); // Make sure we're done. <rdar://problem/3963151>
-    parser->detach(); // Allows ~DocumentParser to assert it was detached before destruction.
+    ASSERT(!parser->processingData());
+    parser->detach();
 }
     
 void HTMLDocumentParser::suspendScheduledTasks()
index 6cfe8dbd93338a340f5bff5fd86fb6870c07931f..44631fd22f577ceb2cc6d2a37b3e8a368a2eea16 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Google, Inc. All Rights Reserved.
+ * Copyright (C) 2015 Apple Inc. All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #define HTMLDocumentParser_h
 
 #include "CachedResourceClient.h"
-#include "FragmentScriptingPermission.h"
 #include "HTMLInputStream.h"
-#include "HTMLParserOptions.h"
-#include "HTMLPreloadScanner.h"
 #include "HTMLScriptRunnerHost.h"
 #include "HTMLSourceTracker.h"
-#include "HTMLToken.h"
 #include "HTMLTokenizer.h"
 #include "ScriptableDocumentParser.h"
-#include "SegmentedString.h"
 #include "XSSAuditor.h"
 #include "XSSAuditorDelegate.h"
-#include <wtf/Deque.h>
-#include <wtf/WeakPtr.h>
-#include <wtf/text/TextPosition.h>
 
 namespace WebCore {
 
-class BackgroundHTMLParser;
-class CompactHTMLToken;
-class Document;
 class DocumentFragment;
 class HTMLDocument;
 class HTMLParserScheduler;
+class HTMLPreloadScanner;
 class HTMLScriptRunner;
 class HTMLTreeBuilder;
 class HTMLResourcePreloader;
-class ScriptController;
-class ScriptSourceCode;
-
 class PumpSession;
 
-class HTMLDocumentParser :  public ScriptableDocumentParser, HTMLScriptRunnerHost, CachedResourceClient {
+class HTMLDocumentParser : public ScriptableDocumentParser, private HTMLScriptRunnerHost, private CachedResourceClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static Ref<HTMLDocumentParser> create(HTMLDocument& document)
-    {
-        return adoptRef(*new HTMLDocumentParser(document));
-    }
+    static Ref<HTMLDocumentParser> create(HTMLDocument&);
     virtual ~HTMLDocumentParser();
 
-    // Exposed for HTMLParserScheduler
-    void resumeParsingAfterYield();
-
-    static void parseDocumentFragment(const String&, DocumentFragment&, Element* contextElement, ParserContentPolicy = AllowScriptingContent);
+    static void parseDocumentFragment(const String&, DocumentFragment&, Element& contextElement, ParserContentPolicy = AllowScriptingContent);
 
-    HTMLTokenizer* tokenizer() const { return m_tokenizer.get(); }
-
-    virtual TextPosition textPosition() const override;
+    // For HTMLParserScheduler.
+    void resumeParsingAfterYield();
 
-    virtual void suspendScheduledTasks() override;
-    virtual void resumeScheduledTasks() override;
+    // For HTMLTreeBuilder.
+    HTMLTokenizer& tokenizer();
+    virtual TextPosition textPosition() const override final;
 
 protected:
-    virtual void insert(const SegmentedString&) override;
-    virtual void append(PassRefPtr<StringImpl>) override;
-    virtual void finish() override;
-
     explicit HTMLDocumentParser(HTMLDocument&);
-    HTMLDocumentParser(DocumentFragment&, Element* contextElement, ParserContentPolicy);
 
-    HTMLTreeBuilder* treeBuilder() const { return m_treeBuilder.get(); }
+    virtual void insert(const SegmentedString&) override final;
+    virtual void append(PassRefPtr<StringImpl>) override;
+    virtual void finish() override;
 
-    void forcePlaintextForTextDocument();
+    HTMLTreeBuilder& treeBuilder();
 
 private:
-    static Ref<HTMLDocumentParser> create(DocumentFragment& fragment, Element* contextElement, ParserContentPolicy parserContentPolicy)
-    {
-        return adoptRef(*new HTMLDocumentParser(fragment, contextElement, parserContentPolicy));
-    }
+    HTMLDocumentParser(DocumentFragment&, Element& contextElement, ParserContentPolicy);
+    static Ref<HTMLDocumentParser> create(DocumentFragment&, Element& contextElement, ParserContentPolicy);
 
     // DocumentParser
-    virtual void detach() override;
-    virtual bool hasInsertionPoint() override;
-    virtual bool processingData() const override;
-    virtual void prepareToStopParsing() override;
-    virtual void stopParsing() override;
+    virtual void detach() override final;
+    virtual bool hasInsertionPoint() override final;
+    virtual bool processingData() const override final;
+    virtual void prepareToStopParsing() override final;
+    virtual void stopParsing() override final;
     virtual bool isWaitingForScripts() const override;
-    virtual bool isExecutingScript() const override;
-    virtual void executeScriptsWaitingForStylesheets() override;
+    virtual bool isExecutingScript() const override final;
+    virtual void executeScriptsWaitingForStylesheets() override final;
+    virtual void suspendScheduledTasks() override final;
+    virtual void resumeScheduledTasks() override final;
 
     // HTMLScriptRunnerHost
-    virtual void watchForLoad(CachedResource*) override;
-    virtual void stopWatchingForLoad(CachedResource*) override;
-    virtual HTMLInputStream& inputStream() override { return m_input; }
-    virtual bool hasPreloadScanner() const override { return m_preloadScanner.get(); }
-    virtual void appendCurrentInputStreamToPreloadScannerAndScan() override;
+    virtual void watchForLoad(CachedResource*) override final;
+    virtual void stopWatchingForLoad(CachedResource*) override final;
+    virtual HTMLInputStream& inputStream() override final;
+    virtual bool hasPreloadScanner() const override final;
+    virtual void appendCurrentInputStreamToPreloadScannerAndScan() override final;
 
     // CachedResourceClient
-    virtual void notifyFinished(CachedResource*) override;
+    virtual void notifyFinished(CachedResource*) override final;
 
     Document* contextForParsingSession();
 
-    enum SynchronousMode {
-        AllowYield,
-        ForceSynchronous,
-    };
+    enum SynchronousMode { AllowYield, ForceSynchronous };
     bool canTakeNextToken(SynchronousMode, PumpSession&);
     void pumpTokenizer(SynchronousMode);
     void pumpTokenizerIfPossible(SynchronousMode);
@@ -139,16 +115,14 @@ private:
 
     bool isParsingFragment() const;
     bool isScheduledForResume() const;
-    bool inPumpSession() const { return m_pumpSessionNestingLevel > 0; }
-    bool shouldDelayEnd() const { return inPumpSession() || isWaitingForScripts() || isScheduledForResume() || isExecutingScript(); }
-
-    HTMLToken& token() { return *m_token.get(); }
+    bool inPumpSession() const;
+    bool shouldDelayEnd() const;
 
     HTMLParserOptions m_options;
     HTMLInputStream m_input;
 
-    std::unique_ptr<HTMLToken> m_token;
-    std::unique_ptr<HTMLTokenizer> m_tokenizer;
+    HTMLToken m_token;
+    HTMLTokenizer m_tokenizer;
     std::unique_ptr<HTMLScriptRunner> m_scriptRunner;
     std::unique_ptr<HTMLTreeBuilder> m_treeBuilder;
     std::unique_ptr<HTMLPreloadScanner> m_preloadScanner;
@@ -161,11 +135,31 @@ private:
 
     std::unique_ptr<HTMLResourcePreloader> m_preloader;
 
-    bool m_endWasDelayed;
-    bool m_haveBackgroundParser;
-    unsigned m_pumpSessionNestingLevel;
+    bool m_endWasDelayed { false };
+    unsigned m_pumpSessionNestingLevel { 0 };
 };
 
+inline HTMLTokenizer& HTMLDocumentParser::tokenizer()
+{
+    return m_tokenizer;
+}
+
+inline HTMLInputStream& HTMLDocumentParser::inputStream()
+{
+    return m_input;
+}
+
+inline bool HTMLDocumentParser::hasPreloadScanner() const
+{
+    return m_preloadScanner.get();
+}
+
+inline HTMLTreeBuilder& HTMLDocumentParser::treeBuilder()
+{
+    ASSERT(m_treeBuilder);
+    return *m_treeBuilder;
+}
+
 }
 
 #endif
index bf03bba6a4ed63e7da3cc334043fa90e3c33f42e..881260cec2fc8206820342d8a658e54ab9d5716b 100644 (file)
@@ -252,7 +252,7 @@ inline bool HTMLTreeBuilder::isParsingFragmentOrTemplateContents() const
     return isParsingFragment() || isParsingTemplateContents();
 }
 
-HTMLTreeBuilder::HTMLTreeBuilder(const HTMLDocumentParser& parser, HTMLDocument& document, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, HTMLDocument& document, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
     : m_parser(parser)
     , m_options(options)
     , m_tree(document, parserContentPolicy, options.maximumDOMTreeDepth)
@@ -263,7 +263,7 @@ HTMLTreeBuilder::HTMLTreeBuilder(const HTMLDocumentParser& parser, HTMLDocument&
 #endif
 }
 
-HTMLTreeBuilder::HTMLTreeBuilder(const HTMLDocumentParser& parser, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
+HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser& parser, DocumentFragment& fragment, Element& contextElement, ParserContentPolicy parserContentPolicy, const HTMLParserOptions& options)
     : m_parser(parser)
     , m_options(options)
     , m_fragmentContext(fragment, contextElement)
@@ -340,15 +340,13 @@ void HTMLTreeBuilder::constructTree(AtomicHTMLToken& token)
     else
         processToken(token);
 
-    if (m_parser.tokenizer()) {
-        bool inForeignContent = !m_tree.isEmpty()
-            && !adjustedCurrentStackItem().isInHTMLNamespace()
-            && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
-            && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
+    bool inForeignContent = !m_tree.isEmpty()
+        && !adjustedCurrentStackItem().isInHTMLNamespace()
+        && !HTMLElementStack::isHTMLIntegrationPoint(m_tree.currentStackItem())
+        && !HTMLElementStack::isMathMLTextIntegrationPoint(m_tree.currentStackItem());
 
-        m_parser.tokenizer()->setForceNullCharacterReplacement(m_insertionMode == InsertionMode::Text || inForeignContent);
-        m_parser.tokenizer()->setShouldAllowCDATA(inForeignContent);
-    }
+    m_parser.tokenizer().setForceNullCharacterReplacement(m_insertionMode == InsertionMode::Text || inForeignContent);
+    m_parser.tokenizer().setShouldAllowCDATA(inForeignContent);
 
 #if !ASSERT_DISABLED
     m_destructionProhibited = false;
@@ -699,8 +697,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     if (token.name() == plaintextTag) {
         processFakePEndTagIfPInButtonScope();
         m_tree.insertHTMLElement(&token);
-        if (m_parser.tokenizer())
-            m_parser.tokenizer()->setState(HTMLTokenizer::PLAINTEXTState);
+        m_parser.tokenizer().setState(HTMLTokenizer::PLAINTEXTState);
         return;
     }
     if (token.name() == buttonTag) {
@@ -806,8 +803,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
     if (token.name() == textareaTag) {
         m_tree.insertHTMLElement(&token);
         m_shouldSkipLeadingNewline = true;
-        if (m_parser.tokenizer())
-            m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
+        m_parser.tokenizer().setState(HTMLTokenizer::RCDATAState);
         m_originalInsertionMode = m_insertionMode;
         m_framesetOk = false;
         m_insertionMode = InsertionMode::Text;
@@ -1991,11 +1987,10 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
     ASSERT(token.type() == HTMLToken::EndTag);
     switch (m_insertionMode) {
     case InsertionMode::Initial:
-        ASSERT(m_insertionMode == InsertionMode::Initial);
         defaultForInitial();
+        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
         FALLTHROUGH;
     case InsertionMode::BeforeHTML:
-        ASSERT(m_insertionMode == InsertionMode::BeforeHTML);
         if (token.name() != headTag && token.name() != bodyTag && token.name() != htmlTag && token.name() != brTag) {
             parseError(token);
             return;
@@ -2143,14 +2138,12 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             m_tree.openElements()->pop();
             m_insertionMode = m_originalInsertionMode;
 
-            if (m_parser.tokenizer()) {
-                // This token will not have been created by the tokenizer if a
-                // self-closing script tag was encountered and pre-HTML5 parser
-                // quirks are enabled. We must set the tokenizer's state to
-                // DataState explicitly if the tokenizer didn't have a chance to.
-                ASSERT(m_parser.tokenizer()->state() == HTMLTokenizer::DataState || m_options.usePreHTML5ParserQuirks);
-                m_parser.tokenizer()->setState(HTMLTokenizer::DataState);
-            }
+            // This token will not have been created by the tokenizer if a
+            // self-closing script tag was encountered and pre-HTML5 parser
+            // quirks are enabled. We must set the tokenizer's state to
+            // DataState explicitly if the tokenizer didn't have a chance to.
+            ASSERT(m_parser.tokenizer().state() == HTMLTokenizer::DataState || m_options.usePreHTML5ParserQuirks);
+            m_parser.tokenizer().setState(HTMLTokenizer::DataState);
             return;
         }
         m_tree.openElements()->pop();
@@ -2752,8 +2745,7 @@ void HTMLTreeBuilder::processGenericRCDATAStartTag(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::StartTag);
     m_tree.insertHTMLElement(&token);
-    if (m_parser.tokenizer())
-        m_parser.tokenizer()->setState(HTMLTokenizer::RCDATAState);
+    m_parser.tokenizer().setState(HTMLTokenizer::RCDATAState);
     m_originalInsertionMode = m_insertionMode;
     m_insertionMode = InsertionMode::Text;
 }
@@ -2762,8 +2754,7 @@ void HTMLTreeBuilder::processGenericRawTextStartTag(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::StartTag);
     m_tree.insertHTMLElement(&token);
-    if (m_parser.tokenizer())
-        m_parser.tokenizer()->setState(HTMLTokenizer::RAWTEXTState);
+    m_parser.tokenizer().setState(HTMLTokenizer::RAWTEXTState);
     m_originalInsertionMode = m_insertionMode;
     m_insertionMode = InsertionMode::Text;
 }
@@ -2772,8 +2763,7 @@ void HTMLTreeBuilder::processScriptStartTag(AtomicHTMLToken& token)
 {
     ASSERT(token.type() == HTMLToken::StartTag);
     m_tree.insertScriptElement(&token);
-    if (m_parser.tokenizer())
-        m_parser.tokenizer()->setState(HTMLTokenizer::ScriptDataState);
+    m_parser.tokenizer().setState(HTMLTokenizer::ScriptDataState);
     m_originalInsertionMode = m_insertionMode;
 
     TextPosition position = m_parser.textPosition();
index 624dfa9362fa6d1c3427e432640dae0c0d315ad3..806d977261d3ff6d5c8c1e95feb3f37bc5d513f2 100644 (file)
@@ -37,8 +37,8 @@ class HTMLDocumentParser;
 class HTMLTreeBuilder {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    HTMLTreeBuilder(const HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&);
-    HTMLTreeBuilder(const HTMLDocumentParser&, DocumentFragment&, Element& contextElement, ParserContentPolicy, const HTMLParserOptions&);
+    HTMLTreeBuilder(HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&);
+    HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element& contextElement, ParserContentPolicy, const HTMLParserOptions&);
     void setShouldSkipLeadingNewline(bool);
 
     ~HTMLTreeBuilder();
@@ -183,7 +183,7 @@ private:
         RefPtr<HTMLStackItem> m_contextElementStackItem;
     };
 
-    const HTMLDocumentParser& m_parser;
+    HTMLDocumentParser& m_parser;
     const HTMLParserOptions m_options;
     const FragmentParsingContext m_fragmentContext;
 
index f6a56760c38338925be1f373a5ca6d3354706662..c1d395e79d0d525207bf450016211a235b3c8434 100644 (file)
@@ -25,7 +25,6 @@
 #include "config.h"
 #include "TextDocumentParser.h"
 
-#include "HTMLDocument.h"
 #include "HTMLTreeBuilder.h"
 
 namespace WebCore {
@@ -34,11 +33,6 @@ using namespace HTMLNames;
 
 TextDocumentParser::TextDocumentParser(HTMLDocument& document)
     : HTMLDocumentParser(document)
-    , m_haveInsertedFakePreElement(false)
-{
-}
-
-TextDocumentParser::~TextDocumentParser()
 {
 }
 
@@ -59,15 +53,15 @@ void TextDocumentParser::insertFakePreElement()
     Vector<Attribute> attributes;
     attributes.append(Attribute(styleAttr, "word-wrap: break-word; white-space: pre-wrap;"));
     AtomicHTMLToken fakePre(HTMLToken::StartTag, preTag.localName(), attributes);
-    treeBuilder()->constructTree(fakePre);
+    treeBuilder().constructTree(fakePre);
 
     // Normally we would skip the first \n after a <pre> element, but we don't
     // want to skip the first \n for text documents!
-    treeBuilder()->setShouldSkipLeadingNewline(false);
+    treeBuilder().setShouldSkipLeadingNewline(false);
 
     // Although Text Documents expose a "pre" element in their DOM, they
     // act like a <plaintext> tag, so we have to force plaintext mode.
-    forcePlaintextForTextDocument();
+    tokenizer().setState(HTMLTokenizer::PLAINTEXTState);
 
     m_haveInsertedFakePreElement = true;
 }
index 5c78eb15ea8908d9051349496bd52e1efe6f66b2..5f5a09ed2e36c73be6349ccd160bca3f3aeac7e6 100644 (file)
@@ -22,7 +22,6 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-
 #ifndef TextDocumentParser_h
 #define TextDocumentParser_h
 
@@ -36,15 +35,15 @@ public:
     {
         return adoptRef(*new TextDocumentParser(document));
     }
-    virtual ~TextDocumentParser();
 
 private:
     explicit TextDocumentParser(HTMLDocument&);
 
     virtual void append(PassRefPtr<StringImpl>) override;
+
     void insertFakePreElement();
 
-    bool m_haveInsertedFakePreElement;
+    bool m_haveInsertedFakePreElement { false };
 };
 
 }