2010-10-21 James Simonsen <simonjam@chromium.org>
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Oct 2010 05:49:12 +0000 (05:49 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Oct 2010 05:49:12 +0000 (05:49 +0000)
        Reviewed by Adam Barth.

        HTMLTreeBuilder's InForeignContent code needs a re-write

        Foreign Content mode was changed significantly by:
        http://www.w3.org/Bugs/Public/show_bug.cgi?id=10314

        The differences can be seen here:
        http://html5.org/tools/web-apps-tracker?from=5520&to=5522

        This bug addresses all spec changes in the diff except the select scope
        changes, which have already been fixed in a separate bug.

        https://bugs.webkit.org/show_bug.cgi?id=46676

        * html5lib/resources/webkit01.dat: Added the demo case for the new code. Added a case that exposes crash when not using hasTagName().
        * html5lib/runner-expected.txt: Since the behavior of InForeignContentMode has changed, the expectations need to be updated. These have been manually verified.
        * platform/chromium/html5lib/runner-expected.txt: Ditto.
        * platform/win/html5lib/runner-expected.txt: Ditto.
2010-10-21  James Simonsen  <simonjam@chromium.org>

        Reviewed by Adam Barth.

        HTMLTreeBuilder's InForeignContent code needs a re-write

        Foreign Content mode was changed significantly by:
        http://www.w3.org/Bugs/Public/show_bug.cgi?id=10314

        The differences can be seen here:
        http://html5.org/tools/web-apps-tracker?from=5520&to=5522

        This bug addresses all spec changes in the diff except the select scope
        changes, which have already been fixed in a separate bug.

        https://bugs.webkit.org/show_bug.cgi?id=46676

        * html/parser/HTMLElementStack.cpp:
        (WebCore::HTMLNames::isScopeMarker): Add foreign elements to list.
        * html/parser/HTMLTreeBuilder.cpp:
        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
        (WebCore::HTMLTreeBuilder::processDoctypeToken): Switch mode before reprocessing any tokens.
        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto. Remove secondary insertion mode.
        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Switch mode before reprocessing any tokens.
        (WebCore::HTMLTreeBuilder::processStartTag): Ditto. Remove secondary insertion mode.
        (WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Remove foreign var. Use hasTagName() instead of == localName() to fix bug with foreign elements.
        (WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Switch mode before reprocessing any tokens.
        (WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
        (WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
        (WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
        (WebCore::HTMLTreeBuilder::processEndTag): Ditto.
        (WebCore::HTMLTreeBuilder::prepareToReprocessToken): Added.
        (WebCore::HTMLTreeBuilder::reprocessStartTag): Added.
        (WebCore::HTMLTreeBuilder::reprocessEndTag): Added.
        (WebCore::HTMLTreeBuilder::processForeignContentUsingInBodyModeAndResetMode): Added.
        (WebCore::HTMLTreeBuilder::resetForeignInsertionMode): Added.
        (WebCore::HTMLTreeBuilder::processComment): Switch mode before reprocessing any tokens.
        (WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
        (WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
        * html/parser/HTMLTreeBuilder.h: Functions and member for tracking potential switch from InForeignContentMode.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@70293 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/html5lib/resources/webkit01.dat
LayoutTests/html5lib/runner-expected.txt
LayoutTests/platform/chromium/html5lib/runner-expected.txt
LayoutTests/platform/win/html5lib/runner-expected.txt
WebCore/ChangeLog
WebCore/html/parser/HTMLElementStack.cpp
WebCore/html/parser/HTMLTreeBuilder.cpp
WebCore/html/parser/HTMLTreeBuilder.h

index 312776f43e4ffe9d416984902d2a05404e20cee7..a6d243131efb83c0c3d6f9fd0d5b8ff86d83566f 100644 (file)
@@ -1,3 +1,25 @@
+2010-10-21  James Simonsen  <simonjam@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        HTMLTreeBuilder's InForeignContent code needs a re-write
+
+        Foreign Content mode was changed significantly by:
+        http://www.w3.org/Bugs/Public/show_bug.cgi?id=10314
+
+        The differences can be seen here:
+        http://html5.org/tools/web-apps-tracker?from=5520&to=5522
+
+        This bug addresses all spec changes in the diff except the select scope
+        changes, which have already been fixed in a separate bug.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46676
+
+        * html5lib/resources/webkit01.dat: Added the demo case for the new code. Added a case that exposes crash when not using hasTagName().
+        * html5lib/runner-expected.txt: Since the behavior of InForeignContentMode has changed, the expectations need to be updated. These have been manually verified.
+        * platform/chromium/html5lib/runner-expected.txt: Ditto.
+        * platform/win/html5lib/runner-expected.txt: Ditto.
+
 2010-10-21  Ryosuke Niwa  <rniwa@webkit.org>
 
         Unreviewed; rebaseline for r70240.
index cf18925aa71315db2748cf4f6bcf0c7ba51ed5f9..9869454e7de6b87c0e302ef742a4168e84546420 100644 (file)
@@ -535,3 +535,40 @@ console.log("FOO<span>BAR</span>BAZ");
 |         "B"
 |         <div>
 |           "C"
+
+#data
+<svg><em><desc></em>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|     <em>
+|       <desc>
+
+#data
+<table><tr><td><svg><desc><td></desc><circle>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <tbody>
+|         <tr>
+|           <td>
+|             <svg svg>
+|               <svg desc>
+|               <svg circle>
+
+#data
+<svg><tfoot></mi><td>
+#errors
+#document
+| <html>
+|   <head>
+|   <body>
+|     <svg svg>
+|       <svg tfoot>
+|         <svg td>
index b24c3adbfec4a8f546376e9fe50102dacc37a9f7..1dd95a1f4009c84390d8f53f59c0e2f081890c22 100644 (file)
@@ -52,13 +52,106 @@ Expected:
 |     <keygen>
 resources/tests8.dat: PASS
 
-resources/tests9.dat: PASS
+resources/tests9.dat:
+16
 
+Test 16 of 27 in resources/tests9.dat failed. Input:
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
 resources/tests10.dat:
+15
+36
 38
 51
 52
 
+Test 15 of 52 in resources/tests10.dat failed. Input:
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
+
+Test 36 of 52 in resources/tests10.dat failed. Input:
+<math><mi><div><object><div><span></span></div></object></div></mi><mi>
+Got:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <math mi>
+Expected:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <mi>
+
 Test 38 of 52 in resources/tests10.dat failed. Input:
 <svg><script></script><path>
 Got:
@@ -154,7 +247,56 @@ resources/tests17.dat: PASS
 resources/tests18.dat: PASS
 
 resources/tests19.dat:
+31
+32
 63
+78
+
+Test 31 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mi><p><h1>
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|           <p>
+|           <h1>
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|     <p>
+|     <h1>
+
+Test 32 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mi><p><h1>
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|           <p>
+|           <h1>
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|     <p>
+|     <h1>
 
 Test 63 of 97 in resources/tests19.dat failed. Input:
 <!doctype html><keygen><frameset>
@@ -176,6 +318,30 @@ Expected:
 |   <head>
 |   <body>
 |     <keygen>
+
+Test 78 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mn><span></p>a
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <span>
+|             <p>
+|             "a"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <span>
+|     "a"
 resources/tests20.dat: PASS
 
 resources/tests21.dat: PASS
index ae08bbed31e46da2fee37324e2bc253defc3f1b2..f24b790a2bccb1fed4d1f65a3b671eadf11c19da 100755 (executable)
@@ -50,13 +50,106 @@ Expected:
 |     <keygen>
 resources/tests8.dat: PASS
 
-resources/tests9.dat: PASS
+resources/tests9.dat:
+16
 
+Test 16 of 27 in resources/tests9.dat failed. Input:
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
 resources/tests10.dat:
+15
+36
 38
 51
 52
 
+Test 15 of 52 in resources/tests10.dat failed. Input:
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
+
+Test 36 of 52 in resources/tests10.dat failed. Input:
+<math><mi><div><object><div><span></span></div></object></div></mi><mi>
+Got:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <math mi>
+Expected:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <mi>
+
 Test 38 of 52 in resources/tests10.dat failed. Input:
 <svg><script></script><path>
 Got:
@@ -152,7 +245,56 @@ resources/tests17.dat: PASS
 resources/tests18.dat: PASS
 
 resources/tests19.dat:
+31
+32
 63
+78
+
+Test 31 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mi><p><h1>
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|           <p>
+|           <h1>
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|     <p>
+|     <h1>
+
+Test 32 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mi><p><h1>
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|           <p>
+|           <h1>
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mi>
+|     <p>
+|     <h1>
 
 Test 63 of 97 in resources/tests19.dat failed. Input:
 <!doctype html><keygen><frameset>
@@ -172,6 +314,30 @@ Expected:
 |   <head>
 |   <body>
 |     <keygen>
+
+Test 78 of 97 in resources/tests19.dat failed. Input:
+<!doctype html><p><math><mn><span></p>a
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <span>
+|             <p>
+|             "a"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <p>
+|       <math math>
+|         <math mn>
+|           <span>
+|     "a"
 resources/tests20.dat: PASS
 
 resources/tests21.dat: PASS
index e6259c8e2a5454bc42284cb667a9c8257cb422b8..a7232ae441d70b0002318a85a20751083abbe30c 100644 (file)
@@ -31,13 +31,106 @@ resources/tests7.dat: PASS
 
 resources/tests8.dat: PASS
 
-resources/tests9.dat: PASS
+resources/tests9.dat:
+16
 
+Test 16 of 27 in resources/tests9.dat failed. Input:
+<!DOCTYPE html><body><table><caption><math><mi>foo</mi><mi>bar</mi>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <math math>
+|           <math mi>
+|             "foo"
+|           <math mi>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
 resources/tests10.dat:
+15
+36
 38
 51
 52
 
+Test 15 of 52 in resources/tests10.dat failed. Input:
+<!DOCTYPE html><body><table><caption><svg><g>foo</g><g>bar</g>baz</table><p>quux
+Got:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|         <p>
+|           "quux"
+Expected:
+| <!DOCTYPE html>
+| <html>
+|   <head>
+|   <body>
+|     <table>
+|       <caption>
+|         <svg svg>
+|           <svg g>
+|             "foo"
+|           <svg g>
+|             "bar"
+|           "baz"
+|     <p>
+|       "quux"
+
+Test 36 of 52 in resources/tests10.dat failed. Input:
+<math><mi><div><object><div><span></span></div></object></div></mi><mi>
+Got:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <math mi>
+Expected:
+| <html>
+|   <head>
+|   <body>
+|     <math math>
+|       <math mi>
+|         <div>
+|           <object>
+|             <div>
+|               <span>
+|       <mi>
+
 Test 38 of 52 in resources/tests10.dat failed. Input:
 <svg><script></script><path>
 Got:
index 4d8a921a78058030898b82bc10ac4828acee2535..6b96ae7a0516ebbee72a1e3365e9dc4f7d765c03 100644 (file)
@@ -1,3 +1,44 @@
+2010-10-21  James Simonsen  <simonjam@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        HTMLTreeBuilder's InForeignContent code needs a re-write
+
+        Foreign Content mode was changed significantly by:
+        http://www.w3.org/Bugs/Public/show_bug.cgi?id=10314
+
+        The differences can be seen here:
+        http://html5.org/tools/web-apps-tracker?from=5520&to=5522
+
+        This bug addresses all spec changes in the diff except the select scope
+        changes, which have already been fixed in a separate bug.
+
+        https://bugs.webkit.org/show_bug.cgi?id=46676
+
+        * html/parser/HTMLElementStack.cpp:
+        (WebCore::HTMLNames::isScopeMarker): Add foreign elements to list.
+        * html/parser/HTMLTreeBuilder.cpp:
+        (WebCore::HTMLTreeBuilder::HTMLTreeBuilder):
+        (WebCore::HTMLTreeBuilder::processDoctypeToken): Switch mode before reprocessing any tokens.
+        (WebCore::HTMLTreeBuilder::processStartTagForInBody): Ditto. Remove secondary insertion mode.
+        (WebCore::HTMLTreeBuilder::processStartTagForInTable): Switch mode before reprocessing any tokens.
+        (WebCore::HTMLTreeBuilder::processStartTag): Ditto. Remove secondary insertion mode.
+        (WebCore::HTMLTreeBuilder::resetInsertionModeAppropriately): Remove foreign var. Use hasTagName() instead of == localName() to fix bug with foreign elements.
+        (WebCore::HTMLTreeBuilder::processEndTagForInTableBody): Switch mode before reprocessing any tokens.
+        (WebCore::HTMLTreeBuilder::processEndTagForInRow): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInCell): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTagForInBody): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndTag): Ditto.
+        (WebCore::HTMLTreeBuilder::prepareToReprocessToken): Added.
+        (WebCore::HTMLTreeBuilder::reprocessStartTag): Added.
+        (WebCore::HTMLTreeBuilder::reprocessEndTag): Added.
+        (WebCore::HTMLTreeBuilder::processForeignContentUsingInBodyModeAndResetMode): Added.
+        (WebCore::HTMLTreeBuilder::resetForeignInsertionMode): Added.
+        (WebCore::HTMLTreeBuilder::processComment): Switch mode before reprocessing any tokens.
+        (WebCore::HTMLTreeBuilder::processCharacterBuffer): Ditto.
+        (WebCore::HTMLTreeBuilder::processEndOfFile): Ditto.
+        * html/parser/HTMLTreeBuilder.h: Functions and member for tracking potential switch from InForeignContentMode.
+
 2010-10-21  Adam Barth  <abarth@webkit.org>
 
         Reviewed by David Levin.
index 6b96291dc299aa2659bf050a40cde909659330eb..6aab0f7c37fbbfc73fe4b2864e20bd631ef9c20f 100644 (file)
 #include "SVGNames.h"
 #include <wtf/PassOwnPtr.h>
 
-#if ENABLE(SVG)
-#include "SVGNames.h"
-#endif
-
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -56,15 +52,21 @@ inline bool isScopeMarker(Element* element)
 {
     return element->hasTagName(appletTag)
         || element->hasTagName(captionTag)
-#if ENABLE(SVG_FOREIGN_OBJECT)
-        || element->hasTagName(SVGNames::foreignObjectTag)
-#endif
         || element->hasTagName(htmlTag)
         || element->hasTagName(marqueeTag)
         || element->hasTagName(objectTag)
         || element->hasTagName(tableTag)
         || element->hasTagName(tdTag)
-        || element->hasTagName(thTag);
+        || element->hasTagName(thTag)
+        || element->hasTagName(MathMLNames::miTag)
+        || element->hasTagName(MathMLNames::moTag)
+        || element->hasTagName(MathMLNames::mnTag)
+        || element->hasTagName(MathMLNames::msTag)
+        || element->hasTagName(MathMLNames::mtextTag)
+        || element->hasTagName(MathMLNames::annotation_xmlTag)
+        || element->hasTagName(SVGNames::foreignObjectTag)
+        || element->hasTagName(SVGNames::descTag)
+        || element->hasTagName(SVGNames::titleTag);
 }
 
 inline bool isListItemScopeMarker(Element* element)
index 5f90285d5a7d07434c81b47bcef7574fc07f6e0a..310ff601213aa00a1c409e4da94df2918020a810 100644 (file)
@@ -105,7 +105,15 @@ bool isTableBodyContextTag(const AtomicString& tagName)
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#special
 bool isSpecialNode(Node* node)
 {
-    if (node->hasTagName(SVGNames::foreignObjectTag))
+    if (node->hasTagName(MathMLNames::miTag)
+        || node->hasTagName(MathMLNames::moTag)
+        || node->hasTagName(MathMLNames::mnTag)
+        || node->hasTagName(MathMLNames::msTag)
+        || node->hasTagName(MathMLNames::mtextTag)
+        || node->hasTagName(MathMLNames::annotation_xmlTag)
+        || node->hasTagName(SVGNames::foreignObjectTag)
+        || node->hasTagName(SVGNames::descTag)
+        || node->hasTagName(SVGNames::titleTag))
         return true;
     if (node->namespaceURI() != xhtmlNamespaceURI)
         return false;
@@ -331,11 +339,11 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* documen
     , m_isPaused(false)
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
-    , m_secondaryInsertionMode(InitialMode)
     , m_tokenizer(tokenizer)
     , m_scriptToProcessStartLine(uninitializedLineNumberValue)
     , m_lastScriptElementStartLine(uninitializedLineNumberValue)
     , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
+    , m_hasPendingForeignInsertionModeSteps(false)
 {
 }
 
@@ -350,11 +358,11 @@ HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, DocumentFragment* fra
     , m_isPaused(false)
     , m_insertionMode(InitialMode)
     , m_originalInsertionMode(InitialMode)
-    , m_secondaryInsertionMode(InitialMode)
     , m_tokenizer(tokenizer)
     , m_scriptToProcessStartLine(uninitializedLineNumberValue)
     , m_lastScriptElementStartLine(uninitializedLineNumberValue)
     , m_usePreHTML5ParserQuirks(usePreHTML5ParserQuirks)
+    , m_hasPendingForeignInsertionModeSteps(false)
 {
     if (contextElement) {
         // Steps 4.2-4.6 of the HTML5 Fragment Case parsing algorithm:
@@ -815,7 +823,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         if (m_tree.openElements()->inScope(buttonTag)) {
             parseError(token);
             processFakeEndTag(buttonTag);
-            processStartTag(token); // FIXME: Could we just fall through here?
+            reprocessStartTag(token); // FIXME: Could we just fall through here?
             return;
         }
         m_tree.reconstructTheActiveFormattingElements();
@@ -872,6 +880,7 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         parseError(token);
         // Apparently we're not supposed to ask.
         token.setName(imgTag.localName());
+        prepareToReprocessToken();
         // Note the fall through to the imgTag handling below!
     }
     if (token.name() == areaTag
@@ -971,10 +980,8 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         adjustMathMLAttributes(token);
         adjustForeignAttributes(token);
         m_tree.insertForeignElement(token, MathMLNames::mathmlNamespaceURI);
-        if (m_insertionMode != InForeignContentMode) {
-            setSecondaryInsertionMode(m_insertionMode);
+        if (m_insertionMode != InForeignContentMode)
             setInsertionMode(InForeignContentMode);
-        }
         return;
     }
     if (token.name() == SVGNames::svgTag.localName()) {
@@ -982,10 +989,8 @@ void HTMLTreeBuilder::processStartTagForInBody(AtomicHTMLToken& token)
         adjustSVGAttributes(token);
         adjustForeignAttributes(token);
         m_tree.insertForeignElement(token, SVGNames::svgNamespaceURI);
-        if (m_insertionMode != InForeignContentMode) {
-            setSecondaryInsertionMode(m_insertionMode);
+        if (m_insertionMode != InForeignContentMode)
             setInsertionMode(InForeignContentMode);
-        }
         return;
     }
     if (isCaptionColOrColgroupTag(token.name())
@@ -1046,7 +1051,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
     if (token.name() == colTag) {
         processFakeStartTag(colgroupTag);
         ASSERT(InColumnGroupMode);
-        processStartTag(token);
+        reprocessStartTag(token);
         return;
     }
     if (isTableBodyContextTag(token.name())) {
@@ -1059,7 +1064,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
         || token.name() == trTag) {
         processFakeStartTag(tbodyTag);
         ASSERT(insertionMode() == InTableBodyMode);
-        processStartTag(token);
+        reprocessStartTag(token);
         return;
     }
     if (token.name() == tableTag) {
@@ -1068,7 +1073,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
             ASSERT(isParsingFragment());
             return;
         }
-        processStartTag(token);
+        reprocessStartTag(token);
         return;
     }
     if (token.name() == styleTag || token.name() == scriptTag) {
@@ -1099,7 +1104,7 @@ void HTMLTreeBuilder::processStartTagForInTable(AtomicHTMLToken& token)
 
 namespace {
 
-bool shouldProcessUsingSecondaryInsertionMode(AtomicHTMLToken& token, Element* currentElement)
+bool shouldProcessForeignContentUsingInBodyInsertionMode(AtomicHTMLToken& token, Element* currentElement)
 {
     ASSERT(token.type() == HTMLToken::StartTag);
     if (currentElement->hasTagName(MathMLNames::miTag)
@@ -1215,7 +1220,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
                 ASSERT(isParsingFragment());
                 return;
             }
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         processStartTagForInBody(token);
@@ -1234,7 +1239,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             ASSERT(isParsingFragment());
             return;
         }
-        processStartTag(token);
+        reprocessStartTag(token);
         break;
     case InTableBodyMode:
         ASSERT(insertionMode() == InTableBodyMode);
@@ -1248,7 +1253,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             parseError(token);
             processFakeStartTag(trTag);
             ASSERT(insertionMode() == InRowMode);
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         if (isCaptionColOrColgroupTag(token.name()) || isTableBodyContextTag(token.name())) {
@@ -1261,7 +1266,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             m_tree.openElements()->popUntilTableBodyScopeMarker();
             ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
             processFakeEndTag(m_tree.currentElement()->tagQName());
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         processStartTagForInTable(token);
@@ -1283,7 +1288,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
                 return;
             }
             ASSERT(insertionMode() == InTableBodyMode);
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         processStartTagForInTable(token);
@@ -1301,7 +1306,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
                 return;
             }
             closeTheCell();
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         processStartTagForInBody(token);
@@ -1314,7 +1319,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             return;
         }
         setInsertionMode(InBodyMode);
-        processStartTag(token);
+        reprocessStartTag(token);
         break;
     case InHeadNoscriptMode:
         ASSERT(insertionMode() == InHeadNoscriptMode);
@@ -1382,7 +1387,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             parseError(token);
             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
             processEndTag(endSelect);
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         // Fall through
@@ -1428,7 +1433,7 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             }
             AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
             processEndTag(endSelect);
-            processStartTag(token);
+            reprocessStartTag(token);
             return;
         }
         if (token.name() == scriptTag) {
@@ -1442,8 +1447,8 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
         processStartTag(token);
         break;
     case InForeignContentMode: {
-        if (shouldProcessUsingSecondaryInsertionMode(token, m_tree.currentElement())) {
-            processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
+        if (shouldProcessForeignContentUsingInBodyInsertionMode(token, m_tree.currentElement())) {
+            processForeignContentUsingInBodyModeAndResetMode(token);
             return;
         }
         if (token.name() == bTag
@@ -1488,15 +1493,14 @@ void HTMLTreeBuilder::processStartTag(AtomicHTMLToken& token)
             || (token.name() == fontTag && (token.getAttributeItem(colorAttr) || token.getAttributeItem(faceAttr) || token.getAttributeItem(sizeAttr)))) {
             parseError(token);
             m_tree.openElements()->popUntilForeignContentScopeMarker();
-            if (insertionMode() == InForeignContentMode && m_tree.openElements()->hasOnlyHTMLElementsInScope())
-                setInsertionMode(m_secondaryInsertionMode);
-            processStartTag(token);
+            resetInsertionModeAppropriately();
+            reprocessStartTag(token);
             return;
         }
         const AtomicString& currentNamespace = m_tree.currentElement()->namespaceURI();
         if (currentNamespace == MathMLNames::mathmlNamespaceURI)
             adjustMathMLAttributes(token);
-         if (currentNamespace == SVGNames::svgNamespaceURI) {
+        if (currentNamespace == SVGNames::svgNamespaceURI) {
             adjustSVGTagNameCase(token);
             adjustSVGAttributes(token);
         }
@@ -1679,26 +1683,10 @@ void HTMLTreeBuilder::callTheAdoptionAgency(AtomicHTMLToken& token)
     }
 }
 
-void HTMLTreeBuilder::setSecondaryInsertionMode(InsertionMode mode)
-{
-    ASSERT(mode != InForeignContentMode);
-    m_secondaryInsertionMode = mode;
-}
-
-void HTMLTreeBuilder::setInsertionModeAndEnd(InsertionMode newInsertionMode, bool foreign)
-{
-    setInsertionMode(newInsertionMode);
-    if (foreign) {
-        setSecondaryInsertionMode(m_insertionMode);
-        setInsertionMode(InForeignContentMode);
-    }
-}
-
 void HTMLTreeBuilder::resetInsertionModeAppropriately()
 {
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#reset-the-insertion-mode-appropriately
     bool last = false;
-    bool foreign = false;
     HTMLElementStack::ElementRecord* nodeRecord = m_tree.openElements()->topRecord();
     while (1) {
         Element* node = nodeRecord->element();
@@ -1709,42 +1697,42 @@ void HTMLTreeBuilder::resetInsertionModeAppropriately()
         }
         if (node->hasTagName(selectTag)) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(InSelectMode, foreign);
+            return setInsertionMode(InSelectMode);
         }
         if (node->hasTagName(tdTag) || node->hasTagName(thTag))
-            return setInsertionModeAndEnd(InCellMode, foreign);
+            return setInsertionMode(InCellMode);
         if (node->hasTagName(trTag))
-            return setInsertionModeAndEnd(InRowMode, foreign);
-        if (isTableBodyContextTag(node->localName()))
-            return setInsertionModeAndEnd(InTableBodyMode, foreign);
+            return setInsertionMode(InRowMode);
+        if (node->hasTagName(tbodyTag) || node->hasTagName(theadTag) || node->hasTagName(tfootTag))
+            return setInsertionMode(InTableBodyMode);
         if (node->hasTagName(captionTag))
-            return setInsertionModeAndEnd(InCaptionMode, foreign);
+            return setInsertionMode(InCaptionMode);
         if (node->hasTagName(colgroupTag)) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(InColumnGroupMode, foreign);
+            return setInsertionMode(InColumnGroupMode);
         }
         if (node->hasTagName(tableTag))
-            return setInsertionModeAndEnd(InTableMode, foreign);
+            return setInsertionMode(InTableMode);
         if (node->hasTagName(headTag)) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(InBodyMode, foreign);
+            return setInsertionMode(InBodyMode);
         }
         if (node->hasTagName(bodyTag))
-            return setInsertionModeAndEnd(InBodyMode, foreign);
+            return setInsertionMode(InBodyMode);
         if (node->hasTagName(framesetTag)) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(InFramesetMode, foreign);
+            return setInsertionMode(InFramesetMode);
         }
         if (node->hasTagName(htmlTag)) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(BeforeHeadMode, foreign);
+            return setInsertionMode(BeforeHeadMode);
         }
         if (node->namespaceURI() == SVGNames::svgNamespaceURI
             || node->namespaceURI() == MathMLNames::mathmlNamespaceURI)
-            foreign = true;
+            return setInsertionMode(InForeignContentMode);
         if (last) {
             ASSERT(isParsingFragment());
-            return setInsertionModeAndEnd(InBodyMode, foreign);
+            return setInsertionMode(InBodyMode);
         }
         nodeRecord = nodeRecord->next();
     }
@@ -1773,7 +1761,7 @@ void HTMLTreeBuilder::processEndTagForInTableBody(AtomicHTMLToken& token)
         m_tree.openElements()->popUntilTableBodyScopeMarker();
         ASSERT(isTableBodyContextTag(m_tree.currentElement()->localName()));
         processFakeEndTag(m_tree.currentElement()->tagQName());
-        processEndTag(token);
+        reprocessEndTag(token);
         return;
     }
     if (token.name() == bodyTag
@@ -1800,7 +1788,7 @@ void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
             return;
         }
         ASSERT(insertionMode() == InTableBodyMode);
-        processEndTag(token);
+        reprocessEndTag(token);
         return;
     }
     if (isTableBodyContextTag(token.name())) {
@@ -1810,7 +1798,7 @@ void HTMLTreeBuilder::processEndTagForInRow(AtomicHTMLToken& token)
         }
         processFakeEndTag(trTag);
         ASSERT(insertionMode() == InTableBodyMode);
-        processEndTag(token);
+        reprocessEndTag(token);
         return;
     }
     if (token.name() == bodyTag
@@ -1854,7 +1842,7 @@ void HTMLTreeBuilder::processEndTagForInCell(AtomicHTMLToken& token)
             return;
         }
         closeTheCell();
-        processEndTag(token);
+        reprocessEndTag(token);
         return;
     }
     processEndTagForInBody(token);
@@ -1870,7 +1858,7 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
     if (token.name() == htmlTag) {
         AtomicHTMLToken endBody(HTMLToken::EndTag, bodyTag.localName());
         if (processBodyEndTagForInBody(endBody))
-            processEndTag(token);
+            reprocessEndTag(token);
         return;
     }
     if (token.name() == addressTag
@@ -1923,7 +1911,7 @@ void HTMLTreeBuilder::processEndTagForInBody(AtomicHTMLToken& token)
             parseError(token);
             processFakeStartTag(pTag);
             ASSERT(m_tree.openElements()->inScope(token.name()));
-            processEndTag(token);
+            reprocessEndTag(token);
             return;
         }
         m_tree.generateImpliedEndTagsWithExclusion(token.name());
@@ -2119,7 +2107,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
                 ASSERT(isParsingFragment());
                 return;
             }
-            processEndTag(token);
+            reprocessEndTag(token);
             return;
         }
         if (token.name() == bodyTag
@@ -2148,7 +2136,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             ASSERT(isParsingFragment());
             return;
         }
-        processEndTag(token);
+        reprocessEndTag(token);
         break;
     case InRowMode:
         ASSERT(insertionMode() == InRowMode);
@@ -2172,12 +2160,13 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             setInsertionMode(AfterAfterBodyMode);
             return;
         }
+        prepareToReprocessToken();
         // Fall through.
     case AfterAfterBodyMode:
         ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
         parseError(token);
         setInsertionMode(InBodyMode);
-        processEndTag(token);
+        reprocessEndTag(token);
         break;
     case InHeadNoscriptMode:
         ASSERT(insertionMode() == InHeadNoscriptMode);
@@ -2253,7 +2242,7 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             if (m_tree.openElements()->inTableScope(token.name())) {
                 AtomicHTMLToken endSelect(HTMLToken::EndTag, selectTag.localName());
                 processEndTag(endSelect);
-                processEndTag(token);
+                reprocessEndTag(token);
             }
             return;
         }
@@ -2314,11 +2303,31 @@ void HTMLTreeBuilder::processEndTag(AtomicHTMLToken& token)
             }
         }
         // Any other end tag (also the last two steps of "An end tag, if the current node is not an element in the HTML namespace."
-        processUsingSecondaryInsertionModeAndAdjustInsertionMode(token);
+        processForeignContentUsingInBodyModeAndResetMode(token);
         break;
     }
 }
 
+void HTMLTreeBuilder::prepareToReprocessToken()
+{
+    if (m_hasPendingForeignInsertionModeSteps) {
+        resetForeignInsertionMode();
+        m_hasPendingForeignInsertionModeSteps = false;
+    }
+}
+
+void HTMLTreeBuilder::reprocessStartTag(AtomicHTMLToken& token)
+{
+    prepareToReprocessToken();
+    processStartTag(token);
+}
+
+void HTMLTreeBuilder::reprocessEndTag(AtomicHTMLToken& token)
+{
+    prepareToReprocessToken();
+    processEndTag(token);
+}
+
 class HTMLTreeBuilder::FakeInsertionMode : public Noncopyable {
 public:
     FakeInsertionMode(HTMLTreeBuilder* treeBuilder, InsertionMode mode)
@@ -2339,18 +2348,21 @@ private:
     InsertionMode m_originalMode;
 };
 
-// This handles both secondary insertion mode processing, as well as updating
-// the insertion mode.  These are separate steps in the spec, but always occur
-// right after one another.
-void HTMLTreeBuilder::processUsingSecondaryInsertionModeAndAdjustInsertionMode(AtomicHTMLToken& token)
+void HTMLTreeBuilder::processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token)
 {
-    ASSERT(token.type() == HTMLToken::StartTag || token.type() == HTMLToken::EndTag);
+    m_hasPendingForeignInsertionModeSteps = true;
     {
-        FakeInsertionMode fakeMode(this, m_secondaryInsertionMode);
+        FakeInsertionMode fakeMode(this, InBodyMode);
         processToken(token);
     }
-    if (insertionMode() == InForeignContentMode && m_tree.openElements()->hasOnlyHTMLElementsInScope())
-        setInsertionMode(m_secondaryInsertionMode);
+    if (m_hasPendingForeignInsertionModeSteps)
+        resetForeignInsertionMode();
+}
+
+void HTMLTreeBuilder::resetForeignInsertionMode()
+{
+    if (insertionMode() == InForeignContentMode)
+        resetInsertionModeAppropriately();
 }
 
 void HTMLTreeBuilder::processComment(AtomicHTMLToken& token)
@@ -2448,6 +2460,7 @@ ReprocessBuffer:
         ASSERT(m_pendingTableCharacters.isEmpty());
         m_originalInsertionMode = m_insertionMode;
         setInsertionMode(InTableTextMode);
+        prepareToReprocessToken();
         // Fall through.
     }
     case InTableTextMode: {
@@ -2468,6 +2481,7 @@ ReprocessBuffer:
             if (buffer.isEmpty())
                 return;
         }
+        prepareToReprocessToken();
         goto ReprocessBuffer;
     }
     case AfterBodyMode:
@@ -2475,6 +2489,7 @@ ReprocessBuffer:
         ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
         // FIXME: parse error
         setInsertionMode(InBodyMode);
+        prepareToReprocessToken();
         goto ReprocessBuffer;
         break;
     }
@@ -2593,16 +2608,11 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
             ASSERT(isParsingFragment());
             return;
         }
+        prepareToReprocessToken();
         processEndOfFile(token);
         return;
     case InForeignContentMode:
-        parseError(token);
-        m_tree.openElements()->popUntilForeignContentScopeMarker();
-        // FIXME: The spec adds the following condition before setting the
-        //        insertion mode.  However, this condition causes an infinite loop.
-        //        See http://www.w3.org/Bugs/Public/show_bug.cgi?id=10621
-        //        if (insertionMode() == InForeignContentMode && m_tree.openElements()->hasOnlyHTMLElementsInScope())
-        setInsertionMode(m_secondaryInsertionMode);
+        setInsertionMode(InBodyMode);
         processEndOfFile(token);
         return;
     case InTableTextMode:
@@ -2615,6 +2625,7 @@ void HTMLTreeBuilder::processEndOfFile(AtomicHTMLToken& token)
             notImplemented(); // mark the script element as "already started".
         m_tree.openElements()->pop();
         setInsertionMode(m_originalInsertionMode);
+        prepareToReprocessToken();
         processEndOfFile(token);
         return;
     }
@@ -2629,6 +2640,7 @@ void HTMLTreeBuilder::defaultForInitial()
         m_document->setCompatibilityMode(Document::QuirksMode);
     // FIXME: parse error
     setInsertionMode(BeforeHTMLMode);
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForBeforeHTML()
@@ -2636,24 +2648,28 @@ void HTMLTreeBuilder::defaultForBeforeHTML()
     AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
     m_tree.insertHTMLHtmlStartTagBeforeHTML(startHTML);
     setInsertionMode(BeforeHeadMode);
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForBeforeHead()
 {
     AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
     processStartTag(startHead);
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForInHead()
 {
     AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
     processEndTag(endHead);
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForInHeadNoscript()
 {
     AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
     processEndTag(endNoscript);
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForAfterHead()
@@ -2661,6 +2677,7 @@ void HTMLTreeBuilder::defaultForAfterHead()
     AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
     processStartTag(startBody);
     m_framesetOk = true;
+    prepareToReprocessToken();
 }
 
 void HTMLTreeBuilder::defaultForInTableText()
@@ -2673,10 +2690,12 @@ void HTMLTreeBuilder::defaultForInTableText()
         m_tree.insertTextNode(characters);
         m_framesetOk = false;
         setInsertionMode(m_originalInsertionMode);
+        prepareToReprocessToken();
         return;
     }
     m_tree.insertTextNode(characters);
     setInsertionMode(m_originalInsertionMode);
+    prepareToReprocessToken();
 }
 
 bool HTMLTreeBuilder::processStartTagForInHead(AtomicHTMLToken& token)
index e61fe73466da178d3311d27620e46b8281c1e455..c6fcdfd98be36c28a62cda04d2e3008d98bbc713 100644 (file)
@@ -163,7 +163,10 @@ private:
     void defaultForAfterHead();
     void defaultForInTableText();
 
-    void processUsingSecondaryInsertionModeAndAdjustInsertionMode(AtomicHTMLToken&);
+    void prepareToReprocessToken();
+
+    void reprocessStartTag(AtomicHTMLToken&);
+    void reprocessEndTag(AtomicHTMLToken&);
 
     PassRefPtr<NamedNodeMap> attributesForIsindexInput(AtomicHTMLToken&);
 
@@ -194,11 +197,11 @@ private:
         m_isFakeInsertionMode = true;
     }
 
-    void setSecondaryInsertionMode(InsertionMode);
-
-    void setInsertionModeAndEnd(InsertionMode, bool foreign); // Helper for resetInsertionModeAppropriately
     void resetInsertionModeAppropriately();
 
+    void processForeignContentUsingInBodyModeAndResetMode(AtomicHTMLToken& token);
+    void resetForeignInsertionMode();
+
     class FragmentParsingContext : public Noncopyable {
     public:
         FragmentParsingContext();
@@ -236,7 +239,6 @@ private:
     // setInsertionMode and never set m_insertionMode directly.
     InsertionMode m_insertionMode;
     InsertionMode m_originalInsertionMode;
-    InsertionMode m_secondaryInsertionMode;
 
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#pending-table-character-tokens
     Vector<UChar> m_pendingTableCharacters;
@@ -252,8 +254,10 @@ private:
     // created to service the legacy tree builder, but it seems to be used for
     // some other things now.
     int m_lastScriptElementStartLine;
-    
+
     bool m_usePreHTML5ParserQuirks;
+
+    bool m_hasPendingForeignInsertionModeSteps;
 };
 
 }