2009-06-11 Shinichiro Hamaji <hamaji@chromium.org>
authorbfulgham@webkit.org <bfulgham@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jun 2009 18:15:05 +0000 (18:15 +0000)
committerbfulgham@webkit.org <bfulgham@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Jun 2009 18:15:05 +0000 (18:15 +0000)
        Reviewed by Adam Barth.

        https://bugs.webkit.org/show_bug.cgi?id=25512
        Handle texts after unfinished special tags (i.e., script, style, textarea,
        title, xmp, and iframe) as the text node under the tags in view-source mode.
        Before this change, all texts in unfinished special tags cannot be seen even in view-source mode.

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

12 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/dom/Window/Location/window-shadow-location-using-js-object-with-toString-expected.txt
LayoutTests/fast/dom/Window/Location/window-shadow-location-using-js-object-with-toString.html
LayoutTests/fast/dom/Window/Location/window-shadow-location-using-string-expected.txt
LayoutTests/fast/dom/Window/Location/window-shadow-location-using-string.html
LayoutTests/fast/frames/resources/viewsource-frame-unfinished-script.html [new file with mode: 0644]
LayoutTests/fast/frames/resources/viewsource-frame-unfinished-textarea.html [new file with mode: 0644]
LayoutTests/fast/frames/viewsource-unfinished-tags-expected.txt [new file with mode: 0644]
LayoutTests/fast/frames/viewsource-unfinished-tags.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/html/HTMLTokenizer.cpp
WebCore/html/HTMLTokenizer.h

index 350bf06..52d9672 100644 (file)
@@ -1,3 +1,25 @@
+2009-06-11  Shinichiro Hamaji  <hamaji@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=25512
+        Handle texts after unfinished special tags (i.e., script, style, textarea,
+        title, xmp, and iframe) as the text node under the tags in view-source mode.
+        Before this change, all texts in unfinished special tags cannot be seen even in view-source mode.
+
+        This was already done only for title. This change allows other special tags to be handled as well.
+
+        The test case verifies if the texts in the unfinished special tags are visible in view-source mode. Also, fixed window-shadow-location-using-* tests so that they don't use unfinished iframe anymore.
+
+        * fast/dom/Window/Location/window-shadow-location-using-js-object-with-toString-expected.txt:
+        * fast/dom/Window/Location/window-shadow-location-using-js-object-with-toString.html:
+        * fast/dom/Window/Location/window-shadow-location-using-string-expected.txt:
+        * fast/dom/Window/Location/window-shadow-location-using-string.html:
+        * fast/frames/resources/viewsource-frame-unfinished-script.html: Added.
+        * fast/frames/resources/viewsource-frame-unfinished-textarea.html: Added.
+        * fast/frames/viewsource-unfinished-tags-expected.txt: Added.
+        * fast/frames/viewsource-unfinished-tags.html: Added.
+
 2009-06-10  Brent Fulgham  <bfulgham@gmail.com>
 
         Unreviewed build fix.
index c78b273..2197b1d 100644 (file)
@@ -22,7 +22,7 @@
 
     successfullyParsed = true;
 </script>
-<iframe onload="frameLoaded()" src="resources/window-shadow-location-using-js-object-with-toString-iframe.html">
+<iframe onload="frameLoaded()" src="resources/window-shadow-location-using-js-object-with-toString-iframe.html"></iframe>
 <script src="../../../js/resources/js-test-post.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 40dcf19..a5f0519 100644 (file)
@@ -22,7 +22,7 @@
 
     successfullyParsed = true;
 </script>
-<iframe onload="frameLoaded()" src="resources/window-shadow-location-using-string-iframe.html">
+<iframe onload="frameLoaded()" src="resources/window-shadow-location-using-string-iframe.html"></iframe>
 <script src="../../../js/resources/js-test-post.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/LayoutTests/fast/frames/resources/viewsource-frame-unfinished-script.html b/LayoutTests/fast/frames/resources/viewsource-frame-unfinished-script.html
new file mode 100644 (file)
index 0000000..4aead79
--- /dev/null
@@ -0,0 +1 @@
+<script>foobar in script
diff --git a/LayoutTests/fast/frames/resources/viewsource-frame-unfinished-textarea.html b/LayoutTests/fast/frames/resources/viewsource-frame-unfinished-textarea.html
new file mode 100644 (file)
index 0000000..9c1f3fa
--- /dev/null
@@ -0,0 +1 @@
+<textarea>foobar in textarea
diff --git a/LayoutTests/fast/frames/viewsource-unfinished-tags-expected.txt b/LayoutTests/fast/frames/viewsource-unfinished-tags-expected.txt
new file mode 100644 (file)
index 0000000..34e180b
--- /dev/null
@@ -0,0 +1,3 @@
+script: PASS
+textarea: PASS
+
diff --git a/LayoutTests/fast/frames/viewsource-unfinished-tags.html b/LayoutTests/fast/frames/viewsource-unfinished-tags.html
new file mode 100644 (file)
index 0000000..abc7597
--- /dev/null
@@ -0,0 +1,46 @@
+<html>
+<head>
+<script>
+    if (window.layoutTestController) {
+        layoutTestController.dumpAsText();
+        layoutTestController.waitUntilDone();
+    }
+
+    var results = {};
+    function report(frame, tag) {
+        var result = frame.contentDocument.documentElement.innerHTML;
+        var regex = new RegExp("foobar", "g");
+        matches = result.match(regex);
+
+        if (matches)
+            var resultText = "PASS";
+        else
+            var resultText = "FAIL";
+
+        results[tag] = resultText;
+        if (window.layoutTestController && results["script"] && results["textarea"]) {
+            document.open();
+            document.write("script: " + results["script"] + "<br>");
+            document.write("textarea: " + results["textarea"] + "<br>");
+            document.close();
+
+            layoutTestController.notifyDone();
+        } else {
+            document.getElementById(tag + "_result").textContent = resultText;
+        }
+    }
+</script>
+</head>
+<body>
+<p>You should see a frame in 'view source' mode below.</p>
+<p>"foobar" should be seen after the &lt;script&gt; tag and &lt;textarea&gt; tag.</p>
+<hr>
+<iframe viewsource src="resources/viewsource-frame-unfinished-script.html" height="250" onload="report(this, 'script')"></iframe>
+<iframe viewsource src="resources/viewsource-frame-unfinished-textarea.html" height="250" onload="report(this, 'textarea')"></iframe>
+<hr>
+<div id="result">
+<div id="script_result"></div>
+<div id="textarea_result"></div>
+</div>
+</body>
+</html>
index 0546b1d..c754208 100644 (file)
@@ -1,3 +1,23 @@
+2009-06-11  Shinichiro Hamaji  <hamaji@chromium.org>
+
+        Reviewed by Adam Barth.
+
+        https://bugs.webkit.org/show_bug.cgi?id=25512
+        Handle texts after unfinished special tags (i.e., script, style, textarea,
+        title, xmp, and iframe) as the text node under the tags in view-source mode.
+        Before this change, all texts in unfinished special tags cannot be seen even in view-source mode.
+
+        This was already done only for title. This change allows other special tags to be handled as well.
+
+        Test: fast/frames/viewsource-unfinished-tags.html
+
+        * html/HTMLTokenizer.cpp:
+        (WebCore::HTMLTokenizer::parseNonHTMLText):
+        (WebCore::HTMLTokenizer::parseTag):
+        (WebCore::HTMLTokenizer::write):
+        * html/HTMLTokenizer.h:
+        (WebCore::HTMLTokenizer::State::inAnyNonHTMLText):
+
 2009-06-11  Yongjun Zhang  <yongjun.zhang@nokia.com>
 
         Reviewed by Ariya Hidayat.
index 341eecc..3f50e4f 100644 (file)
@@ -316,7 +316,7 @@ HTMLTokenizer::State HTMLTokenizer::processListing(SegmentedString list, State s
     return state;
 }
 
-HTMLTokenizer::State HTMLTokenizer::parseSpecial(SegmentedString& src, State state)
+HTMLTokenizer::State HTMLTokenizer::parseNonHTMLText(SegmentedString& src, State state)
 {
     ASSERT(state.inTextArea() || state.inTitle() || state.inIFrame() || !state.hasEntityState());
     ASSERT(!state.hasTagState());
@@ -1477,6 +1477,9 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString& src, State state)
             RefPtr<Node> n = processToken();
             m_cBufferPos = cBufferPos;
             if (n || inViewSourceMode()) {
+                State savedState = state;
+                SegmentedString savedSrc = src;
+                long savedLineno = m_lineNumber;
                 if ((tagName == preTag || tagName == listingTag) && !inViewSourceMode()) {
                     if (beginTag)
                         state.setDiscardLF(true); // Discard the first LF after we open a pre.
@@ -1489,7 +1492,7 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString& src, State state)
                         m_searchStopper = scriptEnd;
                         m_searchStopperLength = 8;
                         state.setInScript(true);
-                        state = parseSpecial(src, state);
+                        state = parseNonHTMLText(src, state);
                     } else if (isSelfClosingScript) { // Handle <script src="foo"/>
                         state.setInScript(true);
                         state = scriptHandler(state);
@@ -1499,53 +1502,50 @@ HTMLTokenizer::State HTMLTokenizer::parseTag(SegmentedString& src, State state)
                         m_searchStopper = styleEnd;
                         m_searchStopperLength = 7;
                         state.setInStyle(true);
-                        state = parseSpecial(src, state);
+                        state = parseNonHTMLText(src, state);
                     }
                 } else if (tagName == textareaTag) {
                     if (beginTag) {
                         m_searchStopper = textareaEnd;
                         m_searchStopperLength = 10;
                         state.setInTextArea(true);
-                        state = parseSpecial(src, state);
+                        state = parseNonHTMLText(src, state);
                     }
                 } else if (tagName == titleTag) {
                     if (beginTag) {
                         m_searchStopper = titleEnd;
                         m_searchStopperLength = 7;
-                        State savedState = state;
-                        SegmentedString savedSrc = src;
-                        long savedLineno = m_lineNumber;
                         state.setInTitle(true);
-                        state = parseSpecial(src, state);
-                        if (state.inTitle() && src.isEmpty()) {
-                            // We just ate the rest of the document as the title #text node!
-                            // Reset the state then retokenize without special title handling.
-                            // Let the parser clean up the missing </title> tag.
-                            // FIXME: This is incorrect, because src.isEmpty() doesn't mean we're
-                            // at the end of the document unless m_noMoreData is also true. We need
-                            // to detect this case elsewhere, and save the state somewhere other
-                            // than a local variable.
-                            state = savedState;
-                            src = savedSrc;
-                            m_lineNumber = savedLineno;
-                            m_scriptCodeSize = 0;
-                        }
+                        state = parseNonHTMLText(src, state);
                     }
                 } else if (tagName == xmpTag) {
                     if (beginTag) {
                         m_searchStopper = xmpEnd;
                         m_searchStopperLength = 5;
                         state.setInXmp(true);
-                        state = parseSpecial(src, state);
+                        state = parseNonHTMLText(src, state);
                     }
                 } else if (tagName == iframeTag) {
                     if (beginTag) {
                         m_searchStopper = iframeEnd;
                         m_searchStopperLength = 8;
                         state.setInIFrame(true);
-                        state = parseSpecial(src, state);
+                        state = parseNonHTMLText(src, state);
                     }
                 }
+                if (src.isEmpty() && (state.inTitle() || inViewSourceMode()) && !state.inComment() && !(state.inScript() && m_currentScriptTagStartLineNumber)) {
+                    // We just ate the rest of the document as the #text node under the special tag!
+                    // Reset the state then retokenize without special handling.
+                    // Let the parser clean up the missing close tag.
+                    // FIXME: This is incorrect, because src.isEmpty() doesn't mean we're
+                    // at the end of the document unless m_noMoreData is also true. We need
+                    // to detect this case elsewhere, and save the state somewhere other
+                    // than a local variable.
+                    state = savedState;
+                    src = savedSrc;
+                    m_lineNumber = savedLineno;
+                    m_scriptCodeSize = 0;
+                }
             }
             if (tagName == plaintextTag)
                 state.setInPlainText(beginTag);
@@ -1661,8 +1661,8 @@ void HTMLTokenizer::write(const SegmentedString& str, bool appendData)
                 state = parseEntity(m_src, m_dest, state, m_cBufferPos, false, state.hasTagState());
             else if (state.inPlainText())
                 state = parseText(m_src, state);
-            else if (state.inAnySpecial())
-                state = parseSpecial(m_src, state);
+            else if (state.inAnyNonHTMLText())
+                state = parseNonHTMLText(m_src, state);
             else if (state.inComment())
                 state = parseComment(m_src, state);
             else if (state.inDoctype())
index 2896974..6612af8 100644 (file)
@@ -173,7 +173,7 @@ private:
     State parseDoctype(SegmentedString&, State);
     State parseServer(SegmentedString&, State);
     State parseText(SegmentedString&, State);
-    State parseSpecial(SegmentedString&, State);
+    State parseNonHTMLText(SegmentedString&, State);
     State parseTag(SegmentedString&, State);
     State parseEntity(SegmentedString&, UChar*& dest, State, unsigned& cBufferPos, bool start, bool parsingTag);
     State parseProcessingInstruction(SegmentedString&, State);
@@ -288,7 +288,7 @@ private:
         bool forceSynchronous() const { return testBit(ForceSynchronous); }
         void setForceSynchronous(bool v) { setBit(ForceSynchronous, v); }
 
-        bool inAnySpecial() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | InIFrame); }
+        bool inAnyNonHTMLText() const { return m_bits & (InScript | InStyle | InXmp | InTextArea | InTitle | InIFrame); }
         bool hasTagState() const { return m_bits & TagMask; }
         bool hasEntityState() const { return m_bits & EntityMask; }