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

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: Bring patch to head. 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"
53 #include "core/html/HTMLUnknownElement.h"
45 #include "core/html/parser/AtomicHTMLToken.h" 54 #include "core/html/parser/AtomicHTMLToken.h"
46 #include "core/html/parser/HTMLParserIdioms.h" 55 #include "core/html/parser/HTMLParserIdioms.h"
56 #include "core/html/parser/HTMLParserReentryPermit.h"
47 #include "core/html/parser/HTMLStackItem.h" 57 #include "core/html/parser/HTMLStackItem.h"
48 #include "core/html/parser/HTMLToken.h" 58 #include "core/html/parser/HTMLToken.h"
49 #include "core/loader/FrameLoader.h" 59 #include "core/loader/FrameLoader.h"
50 #include "core/loader/FrameLoaderClient.h" 60 #include "core/loader/FrameLoaderClient.h"
51 #include "core/svg/SVGScriptElement.h" 61 #include "core/svg/SVGScriptElement.h"
52 #include "platform/text/TextBreakIterator.h" 62 #include "platform/text/TextBreakIterator.h"
53 #include <limits> 63 #include <limits>
54 64
55 namespace blink { 65 namespace blink {
56 66
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // re-enters the parser. 317 // re-enters the parser.
308 TaskQueue queue; 318 TaskQueue queue;
309 queue.swap(m_taskQueue); 319 queue.swap(m_taskQueue);
310 320
311 for (size_t i = 0; i < size; ++i) 321 for (size_t i = 0; i < size; ++i)
312 executeTask(queue[i]); 322 executeTask(queue[i]);
313 323
314 // We might be detached now. 324 // We might be detached now.
315 } 325 }
316 326
317 HTMLConstructionSite::HTMLConstructionSite(Document& document, ParserContentPoli cy parserContentPolicy) 327 HTMLConstructionSite::HTMLConstructionSite(HTMLParserReentryPermit* reentryPermi t, Document& document, ParserContentPolicy parserContentPolicy)
318 : m_document(&document) 328 : m_reentryPermit(reentryPermit)
329 , m_document(&document)
319 , m_attachmentRoot(document) 330 , m_attachmentRoot(document)
320 , m_parserContentPolicy(parserContentPolicy) 331 , m_parserContentPolicy(parserContentPolicy)
321 , m_isParsingFragment(false) 332 , m_isParsingFragment(false)
322 , m_redirectAttachToFosterParent(false) 333 , m_redirectAttachToFosterParent(false)
323 , m_inQuirksMode(document.inQuirksMode()) 334 , m_inQuirksMode(document.inQuirksMode())
324 { 335 {
325 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument()); 336 ASSERT(m_document->isHTMLDocument() || m_document->isXHTMLDocument());
326 } 337 }
327 338
328 void HTMLConstructionSite::initFragmentParsing(DocumentFragment* fragment, Eleme nt* contextElement) 339 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 356 // Depending on why we're being destroyed it might be OK
346 // to forget queued tasks, but currently we don't expect to. 357 // to forget queued tasks, but currently we don't expect to.
347 ASSERT(m_taskQueue.isEmpty()); 358 ASSERT(m_taskQueue.isEmpty());
348 // Currently we assume that text will never be the last token in the 359 // 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. 360 // document and that we'll always queue some additional task to cause it to flush.
350 ASSERT(m_pendingText.isEmpty()); 361 ASSERT(m_pendingText.isEmpty());
351 } 362 }
352 363
353 DEFINE_TRACE(HTMLConstructionSite) 364 DEFINE_TRACE(HTMLConstructionSite)
354 { 365 {
366 visitor->trace(m_reentryPermit);
355 visitor->trace(m_document); 367 visitor->trace(m_document);
356 visitor->trace(m_attachmentRoot); 368 visitor->trace(m_attachmentRoot);
357 visitor->trace(m_head); 369 visitor->trace(m_head);
358 visitor->trace(m_form); 370 visitor->trace(m_form);
359 visitor->trace(m_openElements); 371 visitor->trace(m_openElements);
360 visitor->trace(m_activeFormattingElements); 372 visitor->trace(m_activeFormattingElements);
361 visitor->trace(m_taskQueue); 373 visitor->trace(m_taskQueue);
362 visitor->trace(m_pendingText); 374 visitor->trace(m_pendingText);
363 } 375 }
364 376
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 return element; 752 return element;
741 } 753 }
742 754
743 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode() 755 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
744 { 756 {
745 if (isHTMLTemplateElement(*currentNode())) 757 if (isHTMLTemplateElement(*currentNode()))
746 return toHTMLTemplateElement(currentElement())->content()->document(); 758 return toHTMLTemplateElement(currentElement())->content()->document();
747 return currentNode()->document(); 759 return currentNode()->document();
748 } 760 }
749 761
762 // "look up a custom element definition" for a token
763 // https://html.spec.whatwg.org/#look-up-a-custom-element-definition
764 CustomElementDefinition* HTMLConstructionSite::lookUpCustomElementDefinition(Doc ument& document, AtomicHTMLToken* token)
765 {
766 // TODO(dominicc): Add a namespace parameter and check when foreign
767 // and HTML element creation is unified.
768
769 // "2. If document does not have a browsing context, return null."
770 LocalDOMWindow* window = document.domWindow();
771 if (!window)
772 return nullptr;
773
774 // "3. Let registry be document's browsing context's Window's
775 // CustomElementsRegistry object."
776 CustomElementsRegistry* registry = window->maybeCustomElements();
777 if (!registry)
778 return nullptr;
779
780 const AtomicString& localName = token->name();
781 const Attribute* isAttribute = token->getAttributeItem(HTMLNames::isAttr);
782 const AtomicString& name = isAttribute ? isAttribute->value() : localName;
783 CustomElementDescriptor descriptor(name, localName);
784
785 // 4.-6.
786 return registry->definitionFor(descriptor);
787 }
788
789 // "create an element for a token"
790 // https://html.spec.whatwg.org/#create-an-element-for-the-token
791 // TODO(dominicc): When form association is separate from creation, unify
792 // this with foreign element creation.
750 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token) 793 HTMLElement* HTMLConstructionSite::createHTMLElement(AtomicHTMLToken* token)
751 { 794 {
795 // "1. Let document be intended parent's node document."
752 Document& document = ownerDocumentForCurrentNode(); 796 Document& document = ownerDocumentForCurrentNode();
797
753 // Only associate the element with the current form if we're creating the ne w element 798 // 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 ). 799 // in a document with a browsing context (rather than in <template> contents ).
800 // TODO(dominicc): Change form to happen after element creation when
801 // implementing customized built-in elements.
755 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr; 802 HTMLFormElement* form = document.frame() ? m_form.get() : nullptr;
756 // FIXME: This can't use HTMLConstructionSite::createElement because we 803
757 // have to pass the current form element. We should rework form association 804 // "2. Let local name be the tag name of the token."
758 // to occur after construction to allow better code sharing here. 805 // "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()); 806 // "4. Let definition be the result of looking up a custom element ..." etc.
760 setAttributes(element, token, m_parserContentPolicy); 807 CustomElementDefinition* definition = m_isParsingFragment ? nullptr : lookUp CustomElementDefinition(document, token);
808 // "5. If definition is non-null and the parser was not originally created
809 // for the HTML fragment parsing algorithm, then let will execute script
810 // be true."
811 bool willExecuteScript = definition && !m_isParsingFragment;
812
813 HTMLElement* element;
814
815 if (willExecuteScript) {
816 // "6.1 Increment the parser's script nesting level."
817 HTMLParserReentryPermit::ScriptNestingLevelIncrementer incrementScriptNe stingLevel = m_reentryPermit->incrementScriptNestingLevel();
818
819 // "6.2 Set the parser pause flag to true."
820 m_reentryPermit->pause();
821
822 // TODO(dominicc): Change this once resolved:
823 // https://github.com/whatwg/html/issues/1630
824 IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWrites(
825 &document);
826
827 // "6.3 If the JavaScript execution context stack is empty,
828 // then perform a microtask checkpoint."
829
830 // TODO(dominicc): This is the way the Blink HTML parser
831 // performs checkpoints, but note the spec is different--it
832 // talks about the JavaScript stack, not the script nesting
833 // level.
834 if (1u == m_reentryPermit->scriptNestingLevel())
835 Microtask::performCheckpoint(V8PerIsolateData::mainThreadIsolate());
836
837 // "6.4 Push a new element queue onto the custom element
838 // reactions stack."
839 CEReactionsScope reactions;
840
841 QualifiedName elementQName(nullAtom, token->name(), HTMLNames::xhtmlName spaceURI);
842 element = definition->createElementSync(document, elementQName);
843
844 // TODO(dominicc): When ScriptCustomElementDefinition reports
845 // exceptions from runConstructor, add a test that an
846 // exception is reported here.
847 if (!element) {
kojii 2016/08/08 07:47:30 ScriptCustomElementDefinition::createElementSync,
dominicc (has gone to gerrit) 2016/08/15 01:33:15 Good point! Done.
848 // "7. (cont'd) ... let element be instead a new element
849 // that implements HTMLUnknownElement, with no attributes,
850 // namespace set to given namespace, namespace prefix set
851 // to null, custom element state set to failed, custom
852 // element definition set to null, and node document set
853 // to document."
854 element = HTMLUnknownElement::create(elementQName, document);
855 element->setCustomElementState(CustomElementState::Failed);
856 }
857
858 // "8. Append each attribute in the given token to element."
859 // We don't use setAttributes here because the custom element
860 // constructor may have manipulated attributes.
861 for (const auto& attribute : token->attributes()) {
862 element->setAttribute(attribute.name(), attribute.value());
863 }
864
865 // "9. If will execute script is true, then ..." etc. The
866 // CEReactionsScope and ScriptNestingLevelIncrementer
867 // destructors implement steps 9.1-4.
868 } else {
869 // FIXME: This can't use
870 // HTMLConstructionSite::createElement because we have to
871 // pass the current form element. We should rework form
872 // association to occur after construction to allow better
873 // code sharing here.
874 element = HTMLElementFactory::createHTMLElement(token->name(), document, form, getCreateElementFlags());
875
876 // "8. Append each attribute in the given token to element."
877 setAttributes(element, token, m_parserContentPolicy);
878 }
879
880 // TODO(dominicc): Implement steps 10-12 when customized built-in
881 // elements are implemented.
882
761 return element; 883 return element;
762 } 884 }
763 885
764 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item) 886 HTMLStackItem* HTMLConstructionSite::createElementFromSavedToken(HTMLStackItem* item)
765 { 887 {
766 Element* element; 888 Element* element;
767 // NOTE: Moving from item -> token -> item copies the Attribute vector twice ! 889 // NOTE: Moving from item -> token -> item copies the Attribute vector twice !
768 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes()); 890 AtomicHTMLToken fakeToken(HTMLToken::StartTag, item->localName(), item->attr ibutes());
769 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI) 891 if (item->namespaceURI() == HTMLNames::xhtmlNamespaceURI)
770 element = createHTMLElement(&fakeToken); 892 element = createHTMLElement(&fakeToken);
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 queueTask(task); 997 queueTask(task);
876 } 998 }
877 999
878 DEFINE_TRACE(HTMLConstructionSite::PendingText) 1000 DEFINE_TRACE(HTMLConstructionSite::PendingText)
879 { 1001 {
880 visitor->trace(parent); 1002 visitor->trace(parent);
881 visitor->trace(nextChild); 1003 visitor->trace(nextChild);
882 } 1004 }
883 1005
884 } // namespace blink 1006 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698