| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. | 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. |
| 3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. | 3 * Copyright (C) 2011, 2014 Apple Inc. All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
| 7 * are met: | 7 * are met: |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "core/MathMLNames.h" | 31 #include "core/MathMLNames.h" |
| 32 #include "core/SVGNames.h" | 32 #include "core/SVGNames.h" |
| 33 #include "core/XLinkNames.h" | 33 #include "core/XLinkNames.h" |
| 34 #include "core/XMLNSNames.h" | 34 #include "core/XMLNSNames.h" |
| 35 #include "core/XMLNames.h" | 35 #include "core/XMLNames.h" |
| 36 #include "core/dom/DocumentFragment.h" | 36 #include "core/dom/DocumentFragment.h" |
| 37 #include "core/dom/ElementTraversal.h" | 37 #include "core/dom/ElementTraversal.h" |
| 38 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 39 #include "core/html/HTMLDocument.h" | 39 #include "core/html/HTMLDocument.h" |
| 40 #include "core/html/HTMLFormElement.h" | 40 #include "core/html/HTMLFormElement.h" |
| 41 #include "core/html/HTMLTemplateElement.h" |
| 41 #include "core/html/parser/AtomicHTMLToken.h" | 42 #include "core/html/parser/AtomicHTMLToken.h" |
| 42 #include "core/html/parser/HTMLDocumentParser.h" | 43 #include "core/html/parser/HTMLDocumentParser.h" |
| 43 #include "core/html/parser/HTMLParserIdioms.h" | 44 #include "core/html/parser/HTMLParserIdioms.h" |
| 44 #include "core/html/parser/HTMLStackItem.h" | 45 #include "core/html/parser/HTMLStackItem.h" |
| 45 #include "core/html/parser/HTMLToken.h" | 46 #include "core/html/parser/HTMLToken.h" |
| 46 #include "core/html/parser/HTMLTokenizer.h" | 47 #include "core/html/parser/HTMLTokenizer.h" |
| 47 #include "platform/text/PlatformLocale.h" | 48 #include "platform/text/PlatformLocale.h" |
| 48 #include "wtf/text/CharacterNames.h" | 49 #include "wtf/text/CharacterNames.h" |
| 49 #include <memory> | 50 #include <memory> |
| 50 | 51 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 return tagName == nobrTag | 127 return tagName == nobrTag |
| 127 || isNonAnchorNonNobrFormattingTag(tagName); | 128 || isNonAnchorNonNobrFormattingTag(tagName); |
| 128 } | 129 } |
| 129 | 130 |
| 130 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#form
atting | 131 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#form
atting |
| 131 static bool isFormattingTag(const AtomicString& tagName) | 132 static bool isFormattingTag(const AtomicString& tagName) |
| 132 { | 133 { |
| 133 return tagName == aTag || isNonAnchorFormattingTag(tagName); | 134 return tagName == aTag || isNonAnchorFormattingTag(tagName); |
| 134 } | 135 } |
| 135 | 136 |
| 136 static HTMLFormElement* closestFormAncestor(Element& element) | |
| 137 { | |
| 138 ASSERT(isMainThread()); | |
| 139 return Traversal<HTMLFormElement>::firstAncestorOrSelf(element); | |
| 140 } | |
| 141 | |
| 142 class HTMLTreeBuilder::CharacterTokenBuffer { | 137 class HTMLTreeBuilder::CharacterTokenBuffer { |
| 143 WTF_MAKE_NONCOPYABLE(CharacterTokenBuffer); | 138 WTF_MAKE_NONCOPYABLE(CharacterTokenBuffer); |
| 144 public: | 139 public: |
| 145 explicit CharacterTokenBuffer(AtomicHTMLToken* token) | 140 explicit CharacterTokenBuffer(AtomicHTMLToken* token) |
| 146 : m_characters(token->characters().impl()) | 141 : m_characters(token->characters().impl()) |
| 147 , m_current(0) | 142 , m_current(0) |
| 148 , m_end(token->characters().length()) | 143 , m_end(token->characters().length()) |
| 149 { | 144 { |
| 150 ASSERT(!isEmpty()); | 145 ASSERT(!isEmpty()); |
| 151 } | 146 } |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) | 275 , m_scriptToProcessStartPosition(uninitializedPositionValue1()) |
| 281 , m_options(options) | 276 , m_options(options) |
| 282 { | 277 { |
| 283 } | 278 } |
| 284 | 279 |
| 285 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) | 280 HTMLTreeBuilder::HTMLTreeBuilder(HTMLDocumentParser* parser, DocumentFragment* f
ragment, Element* contextElement, ParserContentPolicy parserContentPolicy, const
HTMLParserOptions& options) |
| 286 : HTMLTreeBuilder(parser, fragment->document(), parserContentPolicy, options
) | 281 : HTMLTreeBuilder(parser, fragment->document(), parserContentPolicy, options
) |
| 287 { | 282 { |
| 288 ASSERT(isMainThread()); | 283 ASSERT(isMainThread()); |
| 289 ASSERT(contextElement); | 284 ASSERT(contextElement); |
| 290 m_tree.initFragmentParsing(fragment); | 285 m_tree.initFragmentParsing(fragment, contextElement); |
| 291 m_fragmentContext.init(fragment, contextElement); | 286 m_fragmentContext.init(fragment, contextElement); |
| 292 | 287 |
| 293 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: | 288 // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm: |
| 294 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case | 289 // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#
fragment-case |
| 295 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") | 290 // For efficiency, we skip step 4.2 ("Let root be a new html element with no
attributes") |
| 296 // and instead use the DocumentFragment as a root node. | 291 // and instead use the DocumentFragment as a root node. |
| 297 m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStac
kItem::ItemForDocumentFragmentNode)); | 292 m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStac
kItem::ItemForDocumentFragmentNode)); |
| 298 | 293 |
| 299 if (isHTMLTemplateElement(*contextElement)) | 294 if (isHTMLTemplateElement(*contextElement)) |
| 300 m_templateInsertionModes.append(TemplateContentsMode); | 295 m_templateInsertionModes.append(TemplateContentsMode); |
| 301 | 296 |
| 302 resetInsertionModeAppropriately(); | 297 resetInsertionModeAppropriately(); |
| 303 m_tree.setForm(closestFormAncestor(*contextElement)); | |
| 304 } | 298 } |
| 305 | 299 |
| 306 HTMLTreeBuilder::~HTMLTreeBuilder() | 300 HTMLTreeBuilder::~HTMLTreeBuilder() |
| 307 { | 301 { |
| 308 } | 302 } |
| 309 | 303 |
| 310 void HTMLTreeBuilder::FragmentParsingContext::init(DocumentFragment* fragment, E
lement* contextElement) | 304 void HTMLTreeBuilder::FragmentParsingContext::init(DocumentFragment* fragment, E
lement* contextElement) |
| 311 { | 305 { |
| 312 DCHECK(fragment); | 306 DCHECK(fragment); |
| 313 DCHECK(!fragment->hasChildren()); | 307 DCHECK(!fragment->hasChildren()); |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 return; | 661 return; |
| 668 } | 662 } |
| 669 if (token->name() == preTag || token->name() == listingTag) { | 663 if (token->name() == preTag || token->name() == listingTag) { |
| 670 processFakePEndTagIfPInButtonScope(); | 664 processFakePEndTagIfPInButtonScope(); |
| 671 m_tree.insertHTMLElement(token); | 665 m_tree.insertHTMLElement(token); |
| 672 m_shouldSkipLeadingNewline = true; | 666 m_shouldSkipLeadingNewline = true; |
| 673 m_framesetOk = false; | 667 m_framesetOk = false; |
| 674 return; | 668 return; |
| 675 } | 669 } |
| 676 if (token->name() == formTag) { | 670 if (token->name() == formTag) { |
| 677 if (m_tree.form()) { | 671 if (m_tree.isFormElementPointerNonNull() && !isParsingTemplateContents()
) { |
| 678 parseError(token); | 672 parseError(token); |
| 679 return; | 673 return; |
| 680 } | 674 } |
| 681 processFakePEndTagIfPInButtonScope(); | 675 processFakePEndTagIfPInButtonScope(); |
| 682 m_tree.insertHTMLFormElement(token); | 676 m_tree.insertHTMLFormElement(token); |
| 683 return; | 677 return; |
| 684 } | 678 } |
| 685 if (token->name() == liTag) { | 679 if (token->name() == liTag) { |
| 686 processCloseWhenNestedTag<isLi>(token); | 680 processCloseWhenNestedTag<isLi>(token); |
| 687 return; | 681 return; |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1032 Attribute* typeAttribute = token->getAttributeItem(typeAttr); | 1026 Attribute* typeAttribute = token->getAttributeItem(typeAttr); |
| 1033 if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")
) { | 1027 if (typeAttribute && equalIgnoringCase(typeAttribute->value(), "hidden")
) { |
| 1034 parseError(token); | 1028 parseError(token); |
| 1035 m_tree.insertSelfClosingHTMLElementDestroyingToken(token); | 1029 m_tree.insertSelfClosingHTMLElementDestroyingToken(token); |
| 1036 return; | 1030 return; |
| 1037 } | 1031 } |
| 1038 // Fall through to "anything else" case. | 1032 // Fall through to "anything else" case. |
| 1039 } | 1033 } |
| 1040 if (token->name() == formTag) { | 1034 if (token->name() == formTag) { |
| 1041 parseError(token); | 1035 parseError(token); |
| 1042 if (m_tree.form()) | 1036 if (m_tree.isFormElementPointerNonNull() && !isParsingTemplateContents()
) |
| 1043 return; | 1037 return; |
| 1044 m_tree.insertHTMLFormElement(token, true); | 1038 m_tree.insertHTMLFormElement(token, true); |
| 1045 m_tree.openElements()->pop(); | 1039 m_tree.openElements()->pop(); |
| 1046 return; | 1040 return; |
| 1047 } | 1041 } |
| 1048 if (token->name() == templateTag) { | 1042 if (token->name() == templateTag) { |
| 1049 processTemplateStartTag(token); | 1043 processTemplateStartTag(token); |
| 1050 return; | 1044 return; |
| 1051 } | 1045 } |
| 1052 parseError(token); | 1046 parseError(token); |
| (...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 if (!m_tree.openElements()->inScope(token->name())) { | 1778 if (!m_tree.openElements()->inScope(token->name())) { |
| 1785 parseError(token); | 1779 parseError(token); |
| 1786 return; | 1780 return; |
| 1787 } | 1781 } |
| 1788 m_tree.generateImpliedEndTags(); | 1782 m_tree.generateImpliedEndTags(); |
| 1789 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) | 1783 if (!m_tree.currentStackItem()->matchesHTMLTag(token->name())) |
| 1790 parseError(token); | 1784 parseError(token); |
| 1791 m_tree.openElements()->popUntilPopped(token->name()); | 1785 m_tree.openElements()->popUntilPopped(token->name()); |
| 1792 return; | 1786 return; |
| 1793 } | 1787 } |
| 1794 if (token->name() == formTag) { | 1788 if (token->name() == formTag && !isParsingTemplateContents()) { |
| 1795 Element* node = m_tree.takeForm(); | 1789 Element* node = m_tree.takeForm(); |
| 1796 if (!node || !m_tree.openElements()->inScope(node)) { | 1790 if (!node || !m_tree.openElements()->inScope(node)) { |
| 1797 parseError(token); | 1791 parseError(token); |
| 1798 return; | 1792 return; |
| 1799 } | 1793 } |
| 1800 m_tree.generateImpliedEndTags(); | 1794 m_tree.generateImpliedEndTags(); |
| 1801 if (m_tree.currentElement() != node) | 1795 if (m_tree.currentElement() != node) |
| 1802 parseError(token); | 1796 parseError(token); |
| 1803 m_tree.openElements()->remove(node); | 1797 m_tree.openElements()->remove(node); |
| 1804 } | 1798 } |
| (...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2802 ASSERT(m_isAttached); | 2796 ASSERT(m_isAttached); |
| 2803 // Warning, this may detach the parser. Do not do anything else after this. | 2797 // Warning, this may detach the parser. Do not do anything else after this. |
| 2804 m_tree.finishedParsing(); | 2798 m_tree.finishedParsing(); |
| 2805 } | 2799 } |
| 2806 | 2800 |
| 2807 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) | 2801 void HTMLTreeBuilder::parseError(AtomicHTMLToken*) |
| 2808 { | 2802 { |
| 2809 } | 2803 } |
| 2810 | 2804 |
| 2811 } // namespace blink | 2805 } // namespace blink |
| OLD | NEW |