Title: [159610] trunk
Revision
159610
Author
[email protected]
Date
2013-11-20 23:00:09 -0800 (Wed, 20 Nov 2013)

Log Message

Hoist <template> to head when found between </head> and <body> for consistency with <script>
https://bugs.webkit.org/show_bug.cgi?id=123949

Reviewed by Antti Koivisto.

Source/WebCore:

Merge https://chromium.googlesource.com/chromium/blink/+/835fb468fd211054a920fb7612a6dc5043662495

Move template elements between head and body elements into the head to be consistent with script elements.
The HTML5 specification was changed in http://html5.org/tools/web-apps-tracker?from=8217&to=8218.

Inline comments below are cited from https://www.w3.org/Bugs/Public/show_bug.cgi?id=23002
and https://codereview.chromium.org/25900003 for clarity.

* html/parser/HTMLTreeBuilder.cpp:
(WebCore::HTMLTreeBuilder::processStartTag): Add the template element to the list of elements to be hoisted into
the head element.
(WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately):

Replace the assertion that isParsingFragment is true when item->node() == m_tree.openElements()->rootNode() since,
with this change, we can now invoke resetInsertionMode when parsing a normal document (not fragment) and there is
only the html element on the stack of open elements.

For the second change, consider: <head></head><template>

This example breaks in the old HTML parser because the template element is handled by "after head" state which
pushes the head element back on, processes the template element for "in head", then pops the head element off.
EOF is reached, which processes a fake close tag for the template element, which pops the template element off
and resets the insertion mode appropriately

The problem here is that "reset the insertion mode" is going to inspect the bottom-most element on the stack which
is now the html element and it will set the mode to "before head". Nothing good happens after this.

We fix this problem by having the reset algorithm check if the head element pointer is set, and if so, go to after
head instead of before head.

LayoutTests:

Merge https://chromium.googlesource.com/chromium/blink/+/835fb468fd211054a920fb7612a6dc5043662495
and added two more test cases discussed in https://www.w3.org/Bugs/Public/show_bug.cgi?id=23002.

* html5lib/resources/template.dat:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (159609 => 159610)


--- trunk/LayoutTests/ChangeLog	2013-11-21 06:57:19 UTC (rev 159609)
+++ trunk/LayoutTests/ChangeLog	2013-11-21 07:00:09 UTC (rev 159610)
@@ -1,3 +1,15 @@
+2013-11-20  Ryosuke Niwa  <[email protected]>
+
+        Hoist <template> to head when found between </head> and <body> for consistency with <script>
+        https://bugs.webkit.org/show_bug.cgi?id=123949
+
+        Reviewed by Antti Koivisto.
+
+        Merge https://chromium.googlesource.com/chromium/blink/+/835fb468fd211054a920fb7612a6dc5043662495
+        and added two more test cases discussed in https://www.w3.org/Bugs/Public/show_bug.cgi?id=23002.
+
+        * html5lib/resources/template.dat:
+
 2013-11-20  Radu Stavila  <[email protected]>
 
         [CSS Regions] Implement visual overflow for first & last regions

Modified: trunk/LayoutTests/html5lib/resources/template.dat (159609 => 159610)


--- trunk/LayoutTests/html5lib/resources/template.dat	2013-11-21 06:57:19 UTC (rev 159609)
+++ trunk/LayoutTests/html5lib/resources/template.dat	2013-11-21 07:00:09 UTC (rev 159610)
@@ -1298,3 +1298,44 @@
 |   <body>
 |     <template>
 |       content
+
+#data
+<head></head><template>
+#errors
+#document
+| <html>
+|   <head>
+|     <template>
+|       content
+|   <body>
+
+#data
+<head></head><template>Foo</template>
+#errors
+#document
+| <html>
+|   <head>
+|     <template>
+|       content
+|         "Foo"
+|   <body>
+
+#data
+<html><head></head><template></template><head>
+#errors
+#document
+| <html>
+|   <head>
+|     <template>
+|       content
+|   <body>
+
+#data
+<body></body><template>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <template>
+|       content

Modified: trunk/Source/WebCore/ChangeLog (159609 => 159610)


--- trunk/Source/WebCore/ChangeLog	2013-11-21 06:57:19 UTC (rev 159609)
+++ trunk/Source/WebCore/ChangeLog	2013-11-21 07:00:09 UTC (rev 159610)
@@ -1,3 +1,40 @@
+2013-11-20  Ryosuke Niwa  <[email protected]>
+
+        Hoist <template> to head when found between </head> and <body> for consistency with <script>
+        https://bugs.webkit.org/show_bug.cgi?id=123949
+
+        Reviewed by Antti Koivisto.
+
+        Merge https://chromium.googlesource.com/chromium/blink/+/835fb468fd211054a920fb7612a6dc5043662495
+
+        Move template elements between head and body elements into the head to be consistent with script elements.
+        The HTML5 specification was changed in http://html5.org/tools/web-apps-tracker?from=8217&to=8218.
+
+        Inline comments below are cited from https://www.w3.org/Bugs/Public/show_bug.cgi?id=23002
+        and https://codereview.chromium.org/25900003 for clarity.
+
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::processStartTag): Add the template element to the list of elements to be hoisted into
+        the head element.
+        (WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately):
+
+        Replace the assertion that isParsingFragment is true when item->node() == m_tree.openElements()->rootNode() since,
+        with this change, we can now invoke resetInsertionMode when parsing a normal document (not fragment) and there is
+        only the html element on the stack of open elements.
+
+        For the second change, consider: <head></head><template>
+
+        This example breaks in the old HTML parser because the template element is handled by "after head" state which
+        pushes the head element back on, processes the template element for "in head", then pops the head element off.
+        EOF is reached, which processes a fake close tag for the template element, which pops the template element off
+        and resets the insertion mode appropriately
+
+        The problem here is that "reset the insertion mode" is going to inspect the bottom-most element on the stack which
+        is now the html element and it will set the mode to "before head". Nothing good happens after this.
+
+        We fix this problem by having the reset algorithm check if the head element pointer is set, and if so, go to after
+        head instead of before head.
+
 2013-11-20  Radu Stavila  <[email protected]>
 
         [CSS Regions] Implement visual overflow for first & last regions

Modified: trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp (159609 => 159610)


--- trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2013-11-21 06:57:19 UTC (rev 159609)
+++ trunk/Source/WebCore/html/parser/HTMLTreeBuilder.cpp	2013-11-21 07:00:09 UTC (rev 159610)
@@ -1129,6 +1129,9 @@
             || token->name() == noframesTag
             || token->name() == scriptTag
             || token->name() == styleTag
+#if ENABLE(TEMPLATE_ELEMENT)
+            || token->name() == templateTag
+#endif
             || token->name() == titleTag) {
             parseError(token);
             ASSERT(m_tree.head());
@@ -1632,9 +1635,15 @@
     while (1) {
         RefPtr<HTMLStackItem> item = nodeRecord->stackItem();
         if (item->node() == m_tree.openElements()->rootNode()) {
+            last = true;
+#if ENABLE(TEMPLATE_ELEMENT)
+            bool shouldCreateItem = isParsingFragment();
+#else
             ASSERT(isParsingFragment());
-            last = true;
-            item = HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLStackItem::ItemForContextElement);
+            bool shouldCreateItem = true;
+#endif
+            if (shouldCreateItem)
+                item = HTMLStackItem::create(m_fragmentContext.contextElement(), HTMLStackItem::ItemForContextElement);
         }
 #if ENABLE(TEMPLATE_ELEMENT)
         if (item->hasTagName(templateTag))
@@ -1679,6 +1688,8 @@
             return setInsertionMode(InFramesetMode);
         }
         if (item->hasTagName(htmlTag)) {
+            if (m_tree.headStackItem())
+                return setInsertionMode(AfterHeadMode);
             ASSERT(isParsingFragment());
             return setInsertionMode(BeforeHeadMode);
         }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to