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

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: Rebase. 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 16 matching lines...) Expand all
345 // Depending on why we're being destroyed it might be OK 355 // Depending on why we're being destroyed it might be OK
346 // to forget queued tasks, but currently we don't expect to. 356 // to forget queued tasks, but currently we don't expect to.
347 ASSERT(m_taskQueue.isEmpty()); 357 ASSERT(m_taskQueue.isEmpty());
348 // Currently we assume that text will never be the last token in the 358 // Currently we assume that text will never be the last token in the
349 // document and that we'll always queue some additional task to cause it to flush. 359 // document and that we'll always queue some additional task to cause it to flush.
350 ASSERT(m_pendingText.isEmpty()); 360 ASSERT(m_pendingText.isEmpty());
351 } 361 }
352 362
353 DEFINE_TRACE(HTMLConstructionSite) 363 DEFINE_TRACE(HTMLConstructionSite)
354 { 364 {
365 visitor->trace(m_reentryPermit);
355 visitor->trace(m_document); 366 visitor->trace(m_document);
356 visitor->trace(m_attachmentRoot); 367 visitor->trace(m_attachmentRoot);
357 visitor->trace(m_head); 368 visitor->trace(m_head);
358 visitor->trace(m_form); 369 visitor->trace(m_form);
359 visitor->trace(m_openElements); 370 visitor->trace(m_openElements);
360 visitor->trace(m_activeFormattingElements); 371 visitor->trace(m_activeFormattingElements);
361 visitor->trace(m_taskQueue); 372 visitor->trace(m_taskQueue);
362 visitor->trace(m_pendingText); 373 visitor->trace(m_pendingText);
363 } 374 }
364 375
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 return element; 751 return element;
741 } 752 }
742 753
743 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() 754 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
744 { 755 {
745 if (isHTMLTemplateElement(*currentNode())) 756 if (isHTMLTemplateElement(*currentNode()))
746 return toHTMLTemplateElement(currentElement())->content()->document(); 757 return toHTMLTemplateElement(currentElement())->content()->document();
747 return currentNode()->document(); 758 return currentNode()->document();
748 } 759 }
749 760
761 // "look up a custom element definition" for a token
762 // https://html.spec.whatwg.org/#look-up-a-custom-element-definition
763 CustomElementDefinition* HTMLConstructionSite::lookUpCustomElementDefinition(Doc ument& document, AtomicHTMLToken* token)
764 {
765 // TODO(dominicc): Add a namespace parameter and check when foreign
766 // and HTML element creation is unified.
kouhei (in TOK) 2016/08/15 02:10:31 mention in a TODO about step 1?
767
768 // "2. If document does not have a browsing context, return null."
769 LocalDOMWindow* window = document.domWindow();
770 if (!window)
771 return nullptr;
772
773 // "3. Let registry be document's browsing context's Window's
774 // CustomElementsRegistry object."
775 CustomElementsRegistry* registry = window->maybeCustomElements();
776 if (!registry)
777 return nullptr;
778
779 const AtomicString& localName = token->name();
780 const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr);
781 const AtomicString& name = isAttribute ? isAttribute->value() : localName;
782 CustomElementDescriptor descriptor(name, localName);
783
784 // 4.-6.
785 return registry->definitionFor(descriptor);
786 }
787
788 // "create an element for a token"
789 // https://html.spec.whatwg.org/#create-an-element-for-the-token
790 // TODO(dominicc): When form association is separate from creation, unify
791 // this with foreign element creation.
750 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) 792 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
751 { 793 {
794 // "1. Let document be intended parent's node document."
752 Document& document = ownerDocumentForCurrentNode(); 795 Document& document = ownerDocumentForCurrentNode();
796
753 // Only associate the element with the current form if we're creating the ne w element 797 // 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 ). 798 // in a document with a browsing context (rather than in <template> contents ).
799 // TODO(dominicc): Change form to happen after element creation when
800 // implementing customized built-in elements.
755 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr; 801 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr;
756 // FIXME: This can't use HTMLConstructionSite::createElement because we 802
757 // have to pass the current form element. We should rework form association 803 // "2. Let local name be the tag name of the token."
758 // to occur after construction to allow better code sharing here. 804 // "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()); 805 // "4. Let definition be the result of looking up a custom element ..." etc.
760 setAttributes(element, token, m_parserContentPolicy); 806 CustomElementDefinition* definition = m_isParsingFragment ? nullptr : lookUp CustomElementDefinition(document, token);
807 // "5. If definition is non-null and the parser was not originally created
808 // for the HTML fragment parsing algorithm, then let will execute script
809 // be true."
810 bool willExecuteScript = definition && !m_isParsingFragment;
811
812 HTMLElement* element;
813
814 if (willExecuteScript) {
815 // "6.1 Increment the parser's script nesting level."
816 HTMLParserReentryPermit::ScriptNestingLevelIncrementer incrementScriptNe stingLevel = m_reentryPermit->incrementScriptNestingLevel();
817
818 // "6.2 Set the parser pause flag to true."
819 m_reentryPermit->pause();
820
821 // TODO(dominicc): Change this once resolved:
822 // https://github.com/whatwg/html/issues/1630
823 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWrites(
824 &document);
825
826 // "6.3 If the JavaScript execution context stack is empty,
827 // then perform a microtask checkpoint."
828
829 // TODO(dominicc): This is the way the Blink HTML parser
830 // performs checkpoints, but note the spec is different--it
831 // talks about the JavaScript stack, not the script nesting
832 // level.
833 if (1u == m_reentryPermit->scriptNestingLevel())
834 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate());
835
836 // "6.4 Push a new element queue onto the custom element
837 // reactions stack."
838 CEReactionsScope reactions;
839
840 // 7.
841 QualifiedName elementQName(nullAtom, token->name(), HTMLNames::xhtmlName spaceURI);
842 element = definition->createElementSync(document, elementQName);
843
844 // "8. Append each attribute in the given token to element."
845 // We don't use setAttributes here because the custom element
846 // constructor may have manipulated attributes.
847 for (const auto& attribute : token->attributes()) {
848 element->setAttribute(attribute.name(), attribute.value());
849 }
850
851 // "9. If will execute script is true, then ..." etc. The
852 // CEReactionsScope and ScriptNestingLevelIncrementer
853 // destructors implement steps 9.1-4.
854 } else {
855 // FIXME: This can't use
856 // HTMLConstructionSite::createElement because we have to
857 // pass the current form element. We should rework form
858 // association to occur after construction to allow better
859 // code sharing here.
860 element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags());
861
862 // "8. Append each attribute in the given token to element."
863 setAttributes(element, token, m_parserContentPolicy);
864 }
865
866 // TODO(dominicc): Implement steps 10-12 when customized built-in
867 // elements are implemented.
868
761 return element; 869 return element;
762 } 870 }
763 871
764 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item) 872 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
765 { 873 {
766 Element* element; 874 Element* element;
767 // NOTE: Moving from item -> token -> item copies the Attribute vector twice ! 875 // NOTE: Moving from item -> token -> item copies the Attribute vector twice !
768 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes()); 876 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes());
769 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI) 877 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
770 element = createHTMLElement(&fakeToken); 878 element = createHTMLElement(&fakeToken);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 queueTask(task); 983 queueTask(task);
876 } 984 }
877 985
878 DEFINE_TRACE(HTMLConstructionSite::PendingText) 986 DEFINE_TRACE(HTMLConstructionSite::PendingText)
879 { 987 {
880 visitor->trace(parent); 988 visitor->trace(parent);
881 visitor->trace(nextChild); 989 visitor->trace(nextChild);
882 } 990 }
883 991
884 } // namespace blink 992 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698