diff options
Diffstat (limited to 'Source/WebCore/html/parser/HTMLTreeBuilder.h')
-rw-r--r-- | Source/WebCore/html/parser/HTMLTreeBuilder.h | 237 |
1 files changed, 124 insertions, 113 deletions
diff --git a/Source/WebCore/html/parser/HTMLTreeBuilder.h b/Source/WebCore/html/parser/HTMLTreeBuilder.h index 37353f2d7..aeccab45d 100644 --- a/Source/WebCore/html/parser/HTMLTreeBuilder.h +++ b/Source/WebCore/html/parser/HTMLTreeBuilder.h @@ -1,6 +1,6 @@ /* * Copyright (C) 2010 Google, Inc. All Rights Reserved. - * Copyright (C) 2011 Apple Inc. All rights reserved. + * Copyright (C) 2011-2017 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,68 +24,56 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef HTMLTreeBuilder_h -#define HTMLTreeBuilder_h +#pragma once -#include "FragmentScriptingPermission.h" #include "HTMLConstructionSite.h" -#include "HTMLElementStack.h" -#include "HTMLFormattingElementList.h" #include "HTMLParserOptions.h" -#include "HTMLTokenizer.h" -#include <wtf/Noncopyable.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> #include <wtf/text/StringBuilder.h> #include <wtf/text/TextPosition.h> namespace WebCore { -class AtomicHTMLToken; -class Document; -class DocumentFragment; -class Element; -class Frame; -class HTMLToken; -class HTMLDocument; -class Node; +class JSCustomElementInterface; class HTMLDocumentParser; +class ScriptElement; + +struct CustomElementConstructionData { + CustomElementConstructionData(Ref<JSCustomElementInterface>&&, const AtomicString& name, Vector<Attribute>&&); + ~CustomElementConstructionData(); + + Ref<JSCustomElementInterface> elementInterface; + AtomicString name; + Vector<Attribute> attributes; +}; class HTMLTreeBuilder { - WTF_MAKE_NONCOPYABLE(HTMLTreeBuilder); WTF_MAKE_FAST_ALLOCATED; + WTF_MAKE_FAST_ALLOCATED; public: HTMLTreeBuilder(HTMLDocumentParser&, HTMLDocument&, ParserContentPolicy, const HTMLParserOptions&); - HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element* contextElement, ParserContentPolicy, const HTMLParserOptions&); - ~HTMLTreeBuilder(); + HTMLTreeBuilder(HTMLDocumentParser&, DocumentFragment&, Element& contextElement, ParserContentPolicy, const HTMLParserOptions&); + void setShouldSkipLeadingNewline(bool); - const HTMLElementStack* openElements() const { return m_tree.openElements(); } + ~HTMLTreeBuilder(); - bool isParsingFragment() const { return !!m_fragmentContext.fragment(); } -#if ENABLE(TEMPLATE_ELEMENT) - bool isParsingTemplateContents() const { return m_tree.openElements()->hasTemplateInHTMLScope(); } -#else - bool isParsingTemplateContents() const { return false; } -#endif - bool isParsingFragmentOrTemplateContents() const { return isParsingFragment() || isParsingTemplateContents(); } + bool isParsingFragment() const; - void detach(); + void constructTree(AtomicHTMLToken&&); - void constructTree(AtomicHTMLToken*); + bool isParsingTemplateContents() const; + bool hasParserBlockingScriptWork() const; - bool hasParserBlockingScript() const { return !!m_scriptToProcess; } // Must be called to take the parser-blocking script before calling the parser again. - PassRefPtr<Element> takeScriptToProcess(TextPosition& scriptStartPosition); + RefPtr<ScriptElement> takeScriptToProcess(TextPosition& scriptStartPosition); + + std::unique_ptr<CustomElementConstructionData> takeCustomElementConstructionData() { return WTFMove(m_customElementToConstruct); } + void didCreateCustomOrCallbackElement(Ref<Element>&&, CustomElementConstructionData&); // Done, close any open tags, etc. void finished(); - void setShouldSkipLeadingNewline(bool shouldSkip) { m_shouldSkipLeadingNewline = shouldSkip; } - private: class ExternalCharacterTokenBuffer; + // Represents HTML5 "insertion mode" // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode enum class InsertionMode { @@ -114,52 +102,52 @@ private: AfterAfterFrameset, }; -#if PLATFORM(IOS) + bool isParsingFragmentOrTemplateContents() const; + +#if ENABLE(TELEPHONE_NUMBER_DETECTION) && PLATFORM(IOS) void insertPhoneNumberLink(const String&); void linkifyPhoneNumbers(const String&); #endif - void processToken(AtomicHTMLToken*); - - void processDoctypeToken(AtomicHTMLToken*); - void processStartTag(AtomicHTMLToken*); - void processEndTag(AtomicHTMLToken*); - void processComment(AtomicHTMLToken*); - void processCharacter(AtomicHTMLToken*); - void processEndOfFile(AtomicHTMLToken*); - - bool processStartTagForInHead(AtomicHTMLToken*); - void processStartTagForInBody(AtomicHTMLToken*); - void processStartTagForInTable(AtomicHTMLToken*); - void processEndTagForInBody(AtomicHTMLToken*); - void processEndTagForInTable(AtomicHTMLToken*); - void processEndTagForInTableBody(AtomicHTMLToken*); - void processEndTagForInRow(AtomicHTMLToken*); - void processEndTagForInCell(AtomicHTMLToken*); - - void processIsindexStartTagForInBody(AtomicHTMLToken*); - void processHtmlStartTagForInBody(AtomicHTMLToken*); - bool processBodyEndTagForInBody(AtomicHTMLToken*); + void processToken(AtomicHTMLToken&&); + + void processDoctypeToken(AtomicHTMLToken&&); + void processStartTag(AtomicHTMLToken&&); + void processEndTag(AtomicHTMLToken&&); + void processComment(AtomicHTMLToken&&); + void processCharacter(AtomicHTMLToken&&); + void processEndOfFile(AtomicHTMLToken&&); + + bool processStartTagForInHead(AtomicHTMLToken&&); + void processStartTagForInBody(AtomicHTMLToken&&); + void processStartTagForInTable(AtomicHTMLToken&&); + void processEndTagForInBody(AtomicHTMLToken&&); + void processEndTagForInTable(AtomicHTMLToken&&); + void processEndTagForInTableBody(AtomicHTMLToken&&); + void processEndTagForInRow(AtomicHTMLToken&&); + void processEndTagForInCell(AtomicHTMLToken&&); + + void processHtmlStartTagForInBody(AtomicHTMLToken&&); + bool processBodyEndTagForInBody(AtomicHTMLToken&&); bool processTableEndTagForInTable(); bool processCaptionEndTagForInCaption(); bool processColgroupEndTagForInColumnGroup(); bool processTrEndTagForInRow(); - // FIXME: This function should be inlined into its one call site or it - // needs to assert which tokens it can be called with. - void processAnyOtherEndTagForInBody(AtomicHTMLToken*); + + void processAnyOtherEndTagForInBody(AtomicHTMLToken&&); void processCharacterBuffer(ExternalCharacterTokenBuffer&); inline void processCharacterBufferForInBody(ExternalCharacterTokenBuffer&); - void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>()); + void processFakeStartTag(const QualifiedName&, Vector<Attribute>&& attributes = Vector<Attribute>()); void processFakeEndTag(const QualifiedName&); void processFakeEndTag(const AtomicString&); void processFakeCharacters(const String&); void processFakePEndTagIfPInButtonScope(); - void processGenericRCDATAStartTag(AtomicHTMLToken*); - void processGenericRawTextStartTag(AtomicHTMLToken*); - void processScriptStartTag(AtomicHTMLToken*); + void processGenericRCDATAStartTag(AtomicHTMLToken&&); + void processGenericRawTextStartTag(AtomicHTMLToken&&); + void processScriptStartTag(AtomicHTMLToken&&); // Default processing for the different insertion modes. void defaultForInitial(); @@ -170,78 +158,101 @@ private: void defaultForAfterHead(); void defaultForInTableText(); - inline bool shouldProcessTokenInForeignContent(AtomicHTMLToken*); - void processTokenInForeignContent(AtomicHTMLToken*); - - Vector<Attribute> attributesForIsindexInput(AtomicHTMLToken*); + bool shouldProcessTokenInForeignContent(const AtomicHTMLToken&); + void processTokenInForeignContent(AtomicHTMLToken&&); + + HTMLStackItem& adjustedCurrentStackItem() const; - void callTheAdoptionAgency(AtomicHTMLToken*); + void callTheAdoptionAgency(AtomicHTMLToken&); void closeTheCell(); - template <bool shouldClose(const HTMLStackItem*)> - void processCloseWhenNestedTag(AtomicHTMLToken*); - - void parseError(AtomicHTMLToken*); + template <bool shouldClose(const HTMLStackItem&)> void processCloseWhenNestedTag(AtomicHTMLToken&&); - InsertionMode insertionMode() const { return m_insertionMode; } - void setInsertionMode(InsertionMode mode) { m_insertionMode = mode; } + void parseError(const AtomicHTMLToken&); void resetInsertionModeAppropriately(); -#if ENABLE(TEMPLATE_ELEMENT) - void processTemplateStartTag(AtomicHTMLToken*); - bool processTemplateEndTag(AtomicHTMLToken*); - bool processEndOfFileForInTemplateContents(AtomicHTMLToken*); -#endif + void insertGenericHTMLElement(AtomicHTMLToken&&); + + void processTemplateStartTag(AtomicHTMLToken&&); + bool processTemplateEndTag(AtomicHTMLToken&&); + bool processEndOfFileForInTemplateContents(AtomicHTMLToken&&); class FragmentParsingContext { - WTF_MAKE_NONCOPYABLE(FragmentParsingContext); public: FragmentParsingContext(); - FragmentParsingContext(DocumentFragment&, Element* contextElement); - ~FragmentParsingContext(); + FragmentParsingContext(DocumentFragment&, Element& contextElement); - DocumentFragment* fragment() const { return m_fragment; } - Element* contextElement() const { ASSERT(m_fragment); return m_contextElement; } + DocumentFragment* fragment() const; + Element& contextElement() const; + HTMLStackItem& contextElementStackItem() const; private: - DocumentFragment* m_fragment; - Element* m_contextElement; + DocumentFragment* m_fragment { nullptr }; + RefPtr<HTMLStackItem> m_contextElementStackItem; }; - bool m_framesetOk; -#ifndef NDEBUG - bool m_isAttached; -#endif - FragmentParsingContext m_fragmentContext; - HTMLConstructionSite m_tree; - - // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode - InsertionMode m_insertionMode; + HTMLDocumentParser& m_parser; + const HTMLParserOptions m_options; + const FragmentParsingContext m_fragmentContext; - // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#original-insertion-mode - InsertionMode m_originalInsertionMode; + HTMLConstructionSite m_tree; -#if ENABLE(TEMPLATE_ELEMENT) - Vector<InsertionMode> m_templateInsertionModes; -#endif + // https://html.spec.whatwg.org/multipage/syntax.html#the-insertion-mode + InsertionMode m_insertionMode { InsertionMode::Initial }; + InsertionMode m_originalInsertionMode { InsertionMode::Initial }; + Vector<InsertionMode, 1> m_templateInsertionModes; - // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens + // https://html.spec.whatwg.org/multipage/syntax.html#concept-pending-table-char-tokens StringBuilder m_pendingTableCharacters; - bool m_shouldSkipLeadingNewline; + RefPtr<ScriptElement> m_scriptToProcess; // <script> tag which needs processing before resuming the parser. + TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing. - // We access parser because HTML5 spec requires that we be able to change the state of the tokenizer - // from within parser actions. We also need it to track the current position. - HTMLDocumentParser& m_parser; + std::unique_ptr<CustomElementConstructionData> m_customElementToConstruct; - RefPtr<Element> m_scriptToProcess; // <script> tag which needs processing before resuming the parser. - TextPosition m_scriptToProcessStartPosition; // Starting line number of the script tag needing processing. + bool m_shouldSkipLeadingNewline { false }; + + bool m_framesetOk { true }; - HTMLParserOptions m_options; +#if !ASSERT_DISABLED + bool m_destroyed { false }; + bool m_destructionProhibited { true }; +#endif }; +inline HTMLTreeBuilder::~HTMLTreeBuilder() +{ +#if !ASSERT_DISABLED + ASSERT(!m_destroyed); + ASSERT(!m_destructionProhibited); + m_destroyed = true; +#endif +} + +inline void HTMLTreeBuilder::setShouldSkipLeadingNewline(bool shouldSkip) +{ + ASSERT(!m_destroyed); + m_shouldSkipLeadingNewline = shouldSkip; } -#endif +inline bool HTMLTreeBuilder::isParsingFragment() const +{ + ASSERT(!m_destroyed); + return !!m_fragmentContext.fragment(); +} + +inline bool HTMLTreeBuilder::hasParserBlockingScriptWork() const +{ + ASSERT(!m_destroyed); + ASSERT(!(m_scriptToProcess && m_customElementToConstruct)); + return m_scriptToProcess || m_customElementToConstruct; +} + +inline DocumentFragment* HTMLTreeBuilder::FragmentParsingContext::fragment() const +{ + return m_fragment; +} + +} // namespace WebCore |