Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(270)

Side by Side Diff: third_party/WebKit/Source/core/html/parser/HTMLConstructionSite.cpp

Issue 2200613002: The HTML parser synchronously creates custom elements (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Eliminate redundant TODOs. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2010 Google, Inc. All Rights Reserved. 2 * Copyright (C) 2010 Google, Inc. All Rights Reserved.
3 * Copyright (C) 2011 Apple Inc. All rights reserved. 3 * Copyright (C) 2011 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
11 * notice, this list of conditions and the following disclaimer in the 11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution. 12 * documentation and/or other materials provided with the distribution.
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY 14 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */ 25 */
26 26
27 #include "core/html/parser/HTMLConstructionSite.h" 27 #include "core/html/parser/HTMLConstructionSite.h"
28 28
29 #include "bindings/core/v8/Microtask.h"
30 #include "bindings/core/v8/V8PerIsolateData.h"
29 #include "core/HTMLElementFactory.h" 31 #include "core/HTMLElementFactory.h"
30 #include "core/HTMLNames.h" 32 #include "core/HTMLNames.h"
31 #include "core/dom/Comment.h" 33 #include "core/dom/Comment.h"
32 #include "core/dom/DocumentFragment.h" 34 #include "core/dom/DocumentFragment.h"
33 #include "core/dom/DocumentType.h" 35 #include "core/dom/DocumentType.h"
34 #include "core/dom/Element.h" 36 #include "core/dom/Element.h"
35 #include "core/dom/ElementTraversal.h" 37 #include "core/dom/ElementTraversal.h"
38 #include "core/dom/IgnoreDestructiveWriteCountIncrementer.h"
36 #include "core/dom/ScriptLoader.h" 39 #include "core/dom/ScriptLoader.h"
37 #include "core/dom/TemplateContentDocumentFragment.h" 40 #include "core/dom/TemplateContentDocumentFragment.h"
38 #include "core/dom/Text.h" 41 #include "core/dom/Text.h"
42 #include "core/dom/custom/CEReactionsScope.h"
43 #include "core/dom/custom/CustomElementDefinition.h"
44 #include "core/dom/custom/CustomElementDescriptor.h"
45 #include "core/dom/custom/CustomElementsRegistry.h"
46 #include "core/frame/LocalDOMWindow.h"
39 #include "core/frame/LocalFrame.h" 47 #include "core/frame/LocalFrame.h"
40 #include "core/html/HTMLFormElement.h" 48 #include "core/html/HTMLFormElement.h"
41 #include "core/html/HTMLHtmlElement.h" 49 #include "core/html/HTMLHtmlElement.h"
42 #include "core/html/HTMLPlugInElement.h" 50 #include "core/html/HTMLPlugInElement.h"
43 #include "core/html/HTMLScriptElement.h" 51 #include "core/html/HTMLScriptElement.h"
44 #include "core/html/HTMLTemplateElement.h" 52 #include "core/html/HTMLTemplateElement.h"
45 #include "core/html/parser/AtomicHTMLToken.h" 53 #include "core/html/parser/AtomicHTMLToken.h"
46 #include "core/html/parser/HTMLParserIdioms.h" 54 #include "core/html/parser/HTMLParserIdioms.h"
55 #include "core/html/parser/HTMLParserReentryPermit.h"
47 #include "core/html/parser/HTMLStackItem.h" 56 #include "core/html/parser/HTMLStackItem.h"
48 #include "core/html/parser/HTMLToken.h" 57 #include "core/html/parser/HTMLToken.h"
49 #include "core/loader/FrameLoader.h" 58 #include "core/loader/FrameLoader.h"
50 #include "core/loader/FrameLoaderClient.h" 59 #include "core/loader/FrameLoaderClient.h"
51 #include "core/svg/SVGScriptElement.h" 60 #include "core/svg/SVGScriptElement.h"
52 #include "platform/text/TextBreakIterator.h" 61 #include "platform/text/TextBreakIterator.h"
53 #include <limits> 62 #include <limits>
54 63
55 namespace blink { 64 namespace blink {
56 65
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // re-enters the parser. 316 // re-enters the parser.
308 TaskQueue queue; 317 TaskQueue queue;
309 queue.swap(m_taskQueue); 318 queue.swap(m_taskQueue);
310 319
311 for (size_t i = 0; i < size; ++i) 320 for (size_t i = 0; i < size; ++i)
312 executeTask(queue[i]); 321 executeTask(queue[i]);
313 322
314 // We might be detached now. 323 // We might be detached now.
315 } 324 }
316 325
317 HTMLConstructionSite::HTMLConstructionSite(Document& document, ParserContentPoli cy parserContentPolicy) 326 HTMLConstructionSite::HTMLConstructionSite(HTMLParserReentryPermit* reentryPermi t, Document& document, ParserContentPolicy parserContentPolicy)
318 : m_document(&document) 327 : m_reentryPermit(reentryPermit)
328 , m_document(&document)
319 , m_attachmentRoot(document) 329 , m_attachmentRoot(document)
320 , m_parserContentPolicy(parserContentPolicy) 330 , m_parserContentPolicy(parserContentPolicy)
321 , m_isParsingFragment(false) 331 , m_isParsingFragment(false)
322 , m_redirectAttachToFosterParent(false) 332 , m_redirectAttachToFosterParent(false)
323 , m_inQuirksMode(document.inQuirksMode()) 333 , m_inQuirksMode(document.inQuirksMode())
324 { 334 {
325 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); 335 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument());
326 } 336 }
327 337
328 void HTMLConstructionSite::initFragmentParsing(DocumentFragment* fragment, Eleme nt* contextElement) 338 void HTMLConstructionSite::initFragmentParsing(DocumentFragment* fragment, Eleme nt* contextElement)
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 return element; 750 return element;
741 } 751 }
742 752
743 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() 753 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
744 { 754 {
745 if (isHTMLTemplateElement(*currentNode())) 755 if (isHTMLTemplateElement(*currentNode()))
746 return toHTMLTemplateElement(currentElement())->content()->document(); 756 return toHTMLTemplateElement(currentElement())->content()->document();
747 return currentNode()->document(); 757 return currentNode()->document();
748 } 758 }
749 759
760 // "look up a custom element definition" for a token
761 // https://html.spec.whatwg.org/#look-up-a-custom-element-definition
762 CustomElementDefinition* HTMLConstructionSite::lookUpCustomElementDefinition(Doc ument& document, AtomicHTMLToken* token)
763 {
764 // "2. If document does not have a browsing context, return null."
765 LocalDOMWindow* window = document.domWindow();
766 if (!window)
767 return nullptr;
768
769 // "3. Let registry be document's browsing context's Window's
770 // CustomElementsRegistry object."
771 CustomElementsRegistry* registry = window->maybeCustomElements();
772 if (!registry)
773 return nullptr;
774
775 const AtomicString& localName = token->name();
776 const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr);
777 const AtomicString& name = isAttribute ? isAttribute->value() : localName;
778 CustomElementDescriptor descriptor(name, localName);
779
780 // 4.-6.
781 return registry->definitionFor(descriptor);
782 }
783
784 // "create an element for a token"
785 // https://html.spec.whatwg.org/#create-an-element-for-the-token
786 // TODO(dominicc): When form association is separate from creation,
787 // unify this with foreign element creation. Add a namespace parameter
788 // and check for HTML namespace to lookupCustomElementDefinition.
750 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) 789 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
751 { 790 {
791 // "1. Let document be intended parent's node document."
752 Document& document = ownerDocumentForCurrentNode(); 792 Document& document = ownerDocumentForCurrentNode();
793
753 // Only associate the element with the current form if we're creating the ne w element 794 // Only associate the element with the current form if we're creating the ne w element
754 // in a document with a browsing context (rather than in <template> contents ). 795 // in a document with a browsing context (rather than in <template> contents ).
796 // TODO(dominicc): Change form to happen after element creation when
797 // implementing customized built-in elements.
755 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr; 798 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr;
756 // FIXME: This can't use HTMLConstructionSite::createElement because we 799
757 // have to pass the current form element. We should rework form association 800 // "2. Let local name be the tag name of the token."
758 // to occur after construction to allow better code sharing here. 801 // "3. Let is be the value of the "is" attribute in the giev token ..." etc.
759 HTMLElement* element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags()); 802 // "4. Let definition be the result of looking up a custom element ..." etc.
760 setAttributes(element, token, m_parserContentPolicy); 803 CustomElementDefinition* definition = m_isParsingFragment ? nullptr : lookUp CustomElementDefinition(document, token);
804 // "5. If definition is non-null and the parser was not originally created
805 // for the HTML fragment parsing algorithm, then let will execute script
806 // be true."
807 bool willExecuteScript = definition && !m_isParsingFragment;
808
809 HTMLElement* element;
810
811 if (willExecuteScript) {
812 // "6.1 Increment the parser's script nesting level."
813 HTMLParserReentryPermit::ScriptNestingLevelIncrementer incrementScriptNe stingLevel = m_reentryPermit->incrementScriptNestingLevel();
814
815 // "6.2 Set the parser pause flag to true."
816 m_reentryPermit->pause();
817
818 // TODO(dominicc): Change this once resolved:
819 // https://github.com/whatwg/html/issues/1630
820 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWrites(
821 &document);
822
823 // "6.3 If the JavaScript execution context stack is empty,
824 // then perform a microtask checkpoint."
825
826 // TODO(dominicc): This is the way the Blink HTML parser
827 // performs checkpoints, but note the spec is different--it
828 // talks about the JavaScript stack, not the script nesting
829 // level.
830 if (1u == m_reentryPermit->scriptNestingLevel())
831 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate());
832
833 // "6.4 Push a new element queue onto the custom element
834 // reactions stack."
835 CEReactionsScope reactions;
836
837 // 7.
838 QualifiedName elementQName(nullAtom, token->name(), HTMLNames::xhtmlName spaceURI);
839 element = definition->createElementSync(document, elementQName);
840
841 // "8. Append each attribute in the given token to element."
842 // We don't use setAttributes here because the custom element
843 // constructor may have manipulated attributes.
844 for (const auto& attribute : token->attributes())
845 element->setAttribute(attribute.name(), attribute.value());
846
847 // "9. If will execute script is true, then ..." etc. The
848 // CEReactionsScope and ScriptNestingLevelIncrementer
849 // destructors implement steps 9.1-4.
850 } else {
851 // FIXME: This can't use
852 // HTMLConstructionSite::createElement because we have to
853 // pass the current form element. We should rework form
854 // association to occur after construction to allow better
855 // code sharing here.
856 element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags());
857
858 // "8. Append each attribute in the given token to element."
859 setAttributes(element, token, m_parserContentPolicy);
860 }
861
862 // TODO(dominicc): Implement steps 10-12 when customized built-in
863 // elements are implemented.
864
761 return element; 865 return element;
762 } 866 }
763 867
764 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item) 868 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
765 { 869 {
766 Element* element; 870 Element* element;
767 // NOTE: Moving from item -> token -> item copies the Attribute vector twice ! 871 // NOTE: Moving from item -> token -> item copies the Attribute vector twice !
768 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes()); 872 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes());
769 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI) 873 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
770 element = createHTMLElement(&fakeToken); 874 element = createHTMLElement(&fakeToken);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 queueTask(task); 979 queueTask(task);
876 } 980 }
877 981
878 DEFINE_TRACE(HTMLConstructionSite::PendingText) 982 DEFINE_TRACE(HTMLConstructionSite::PendingText)
879 { 983 {
880 visitor->trace(parent); 984 visitor->trace(parent);
881 visitor->trace(nextChild); 985 visitor->trace(nextChild);
882 } 986 }
883 987
884 } // namespace blink 988 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698