summaryrefslogtreecommitdiff
path: root/Source/WebCore/html/parser/HTMLTreeBuilder.h
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/html/parser/HTMLTreeBuilder.h')
-rw-r--r--Source/WebCore/html/parser/HTMLTreeBuilder.h237
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