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 |