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 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 |
(...skipping 16 matching lines...) Expand all Loading... |
27 #include "config.h" | 27 #include "config.h" |
28 #include "core/html/parser/HTMLConstructionSite.h" | 28 #include "core/html/parser/HTMLConstructionSite.h" |
29 | 29 |
30 #include "core/HTMLElementFactory.h" | 30 #include "core/HTMLElementFactory.h" |
31 #include "core/HTMLNames.h" | 31 #include "core/HTMLNames.h" |
32 #include "core/dom/Comment.h" | 32 #include "core/dom/Comment.h" |
33 #include "core/dom/DocumentFragment.h" | 33 #include "core/dom/DocumentFragment.h" |
34 #include "core/dom/DocumentType.h" | 34 #include "core/dom/DocumentType.h" |
35 #include "core/dom/Element.h" | 35 #include "core/dom/Element.h" |
36 #include "core/dom/ScriptLoader.h" | 36 #include "core/dom/ScriptLoader.h" |
| 37 #include "core/dom/TemplateContentDocumentFragment.h" |
37 #include "core/dom/Text.h" | 38 #include "core/dom/Text.h" |
38 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
39 #include "core/html/HTMLFormElement.h" | 40 #include "core/html/HTMLFormElement.h" |
40 #include "core/html/HTMLHtmlElement.h" | 41 #include "core/html/HTMLHtmlElement.h" |
41 #include "core/html/HTMLPlugInElement.h" | 42 #include "core/html/HTMLPlugInElement.h" |
42 #include "core/html/HTMLScriptElement.h" | 43 #include "core/html/HTMLScriptElement.h" |
43 #include "core/html/HTMLTemplateElement.h" | 44 #include "core/html/HTMLTemplateElement.h" |
44 #include "core/html/parser/AtomicHTMLToken.h" | 45 #include "core/html/parser/AtomicHTMLToken.h" |
45 #include "core/html/parser/HTMLParserIdioms.h" | 46 #include "core/html/parser/HTMLParserIdioms.h" |
46 #include "core/html/parser/HTMLStackItem.h" | 47 #include "core/html/parser/HTMLStackItem.h" |
(...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
819 { | 820 { |
820 while (hasImpliedEndTag(currentStackItem())) | 821 while (hasImpliedEndTag(currentStackItem())) |
821 m_openElements.pop(); | 822 m_openElements.pop(); |
822 } | 823 } |
823 | 824 |
824 bool HTMLConstructionSite::inQuirksMode() | 825 bool HTMLConstructionSite::inQuirksMode() |
825 { | 826 { |
826 return m_inQuirksMode; | 827 return m_inQuirksMode; |
827 } | 828 } |
828 | 829 |
| 830 |
| 831 // Adjusts |task| to match the "adjusted insertion location" determined by the f
oster parenting algorithm, |
| 832 // laid out as the substeps of step 2 of https://html.spec.whatwg.org/#appropria
te-place-for-inserting-a-node |
829 void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task) | 833 void HTMLConstructionSite::findFosterSite(HTMLConstructionSiteTask& task) |
830 { | 834 { |
831 // When a node is to be foster parented, the last template element with no t
able element is below it in the stack of open elements is the foster parent elem
ent (NOT the template's parent!) | 835 // 2.1 |
832 HTMLElementStack::ElementRecord* lastTemplateElement = m_openElements.topmos
t(templateTag.localName()); | 836 HTMLElementStack::ElementRecord* lastTemplate = m_openElements.topmost(templ
ateTag.localName()); |
833 if (lastTemplateElement && !m_openElements.inTableScope(tableTag)) { | 837 |
834 task.parent = lastTemplateElement->element(); | 838 // 2.2 |
| 839 HTMLElementStack::ElementRecord* lastTable = m_openElements.topmost(tableTag
.localName()); |
| 840 |
| 841 // 2.3 |
| 842 if (lastTemplate && (!lastTable || lastTemplate->isAbove(lastTable))) { |
| 843 task.parent = lastTemplate->element(); |
835 return; | 844 return; |
836 } | 845 } |
837 | 846 |
838 HTMLElementStack::ElementRecord* lastTableElementRecord = m_openElements.top
most(tableTag.localName()); | 847 // 2.4 |
839 if (lastTableElementRecord) { | 848 if (!lastTable) { |
840 Element* lastTableElement = lastTableElementRecord->element(); | 849 // Fragment case |
841 ContainerNode* parent; | 850 task.parent = m_openElements.rootNode(); // DocumentFragment |
842 if (lastTableElementRecord->next()->stackItem()->hasTagName(templateTag)
) | |
843 parent = lastTableElementRecord->next()->element(); | |
844 else | |
845 parent = lastTableElement->parentNode(); | |
846 | |
847 // When parsing HTML fragments, we skip step 4.2 ("Let root be a new htm
l element with no attributes") for efficiency, | |
848 // and instead use the DocumentFragment as a root node. So we must treat
the root node (DocumentFragment) as if it is a html element here. | |
849 if (parent && (parent->isElementNode() || (m_isParsingFragment && parent
== m_openElements.rootNode()))) { | |
850 task.parent = parent; | |
851 task.nextChild = lastTableElement; | |
852 return; | |
853 } | |
854 task.parent = lastTableElementRecord->next()->element(); | |
855 return; | 851 return; |
856 } | 852 } |
857 // Fragment case | 853 |
858 task.parent = m_openElements.rootNode(); // DocumentFragment | 854 // 2.5 |
| 855 if (ContainerNode* parent = lastTable->element()->parentNode()) { |
| 856 task.parent = parent; |
| 857 task.nextChild = lastTable->element(); |
| 858 return; |
| 859 } |
| 860 |
| 861 // 2.6, 2.7 |
| 862 task.parent = lastTable->next()->element(); |
859 } | 863 } |
860 | 864 |
861 bool HTMLConstructionSite::shouldFosterParent() const | 865 bool HTMLConstructionSite::shouldFosterParent() const |
862 { | 866 { |
863 return m_redirectAttachToFosterParent | 867 return m_redirectAttachToFosterParent |
864 && currentStackItem()->isElementNode() | 868 && currentStackItem()->isElementNode() |
865 && currentStackItem()->causesFosterParenting(); | 869 && currentStackItem()->causesFosterParenting(); |
866 } | 870 } |
867 | 871 |
868 void HTMLConstructionSite::fosterParent(PassRefPtrWillBeRawPtr<Node> node) | 872 void HTMLConstructionSite::fosterParent(PassRefPtrWillBeRawPtr<Node> node) |
869 { | 873 { |
870 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); | 874 HTMLConstructionSiteTask task(HTMLConstructionSiteTask::Insert); |
871 findFosterSite(task); | 875 findFosterSite(task); |
872 task.child = node; | 876 task.child = node; |
873 ASSERT(task.parent); | 877 ASSERT(task.parent); |
874 queueTask(task); | 878 queueTask(task); |
875 } | 879 } |
876 | 880 |
877 void HTMLConstructionSite::PendingText::trace(Visitor* visitor) | 881 void HTMLConstructionSite::PendingText::trace(Visitor* visitor) |
878 { | 882 { |
879 visitor->trace(parent); | 883 visitor->trace(parent); |
880 visitor->trace(nextChild); | 884 visitor->trace(nextChild); |
881 } | 885 } |
882 | 886 |
883 | 887 |
884 } | 888 } |
OLD | NEW |