[SCM] WebKit Debian packaging branch, webkit-1.3, updated. upstream/1.3.7-4207-g178b198

commit-queue at webkit.org commit-queue at webkit.org
Sun Feb 20 22:55:40 UTC 2011


The following commit has been merged in the webkit-1.3 branch:
commit 129fb5fc58b3b29732e7724431692d355eefe0dd
Author: commit-queue at webkit.org <commit-queue at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jan 13 22:49:44 2011 +0000

    2011-01-13  Emil Eklund  <eae at chromium.org>
    
            Reviewed by Dimitri Glazkov.
    
            Setting outerText should convert CR/LF to <br>
            https://bugs.webkit.org/show_bug.cgi?id=52268
    
            Add test for setting Element.outerText.
    
            * fast/dom/set-outer-text-expected.txt: Added.
            * fast/dom/set-outer-text.html: Added.
            * fast/dom/text-node-append-data-remove-crash-expected.txt: Changed
                expectation to "didn't crash" from "threw dom exception" as test
                assumed the DOMCharacterDataModified event would fire before the node
                would be replaced.
            * fast/dom/text-node-append-data-remove-crash.html:
    2011-01-13  Emil Eklund  <eae at chromium.org>
    
            Reviewed by Dimitri Glazkov.
    
            Setting outerText should convert CR/LF to <br>
            https://bugs.webkit.org/show_bug.cgi?id=52268
    
            Make set outerText support line breaks (sharing the text to fragment code
            with setInnerText) and handle empty text nodes the same way IE does.
    
            Test: fast/dom/set-outer-text.html
    
            * html/HTMLElement.cpp:
            (WebCore::HTMLElement::textToFragment): Shared between setInnerText and setOuterText
            (WebCore::HTMLElement::setInnerText): Split out text parsing code.
            (WebCore::mergeWithNextTextNode): Split out text node merging code.
            (WebCore::HTMLElement::setOuterText): Added support for line breaks.
            * html/HTMLElement.h:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@75738 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 2a032dc..557c104 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,20 @@
+2011-01-13  Emil Eklund  <eae at chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Setting outerText should convert CR/LF to <br>
+        https://bugs.webkit.org/show_bug.cgi?id=52268
+        
+        Add test for setting Element.outerText.
+
+        * fast/dom/set-outer-text-expected.txt: Added.
+        * fast/dom/set-outer-text.html: Added.
+        * fast/dom/text-node-append-data-remove-crash-expected.txt: Changed
+            expectation to "didn't crash" from "threw dom exception" as test
+            assumed the DOMCharacterDataModified event would fire before the node
+            would be replaced.
+        * fast/dom/text-node-append-data-remove-crash.html:
+
 2011-01-13  Adam Roben  <aroben at apple.com>
 
         Skip a crashing test on Windows
diff --git a/LayoutTests/fast/dom/set-outer-text-expected.txt b/LayoutTests/fast/dom/set-outer-text-expected.txt
new file mode 100644
index 0000000..328c367
--- /dev/null
+++ b/LayoutTests/fast/dom/set-outer-text-expected.txt
@@ -0,0 +1,8 @@
+Replaced node using outerText.
+removing node using outerText.
+Testing adding br
+using outerText.
+PASS: replace
+PASS: remove
+PASS: empty text node
+PASS: line break
diff --git a/LayoutTests/fast/dom/set-outer-text.html b/LayoutTests/fast/dom/set-outer-text.html
new file mode 100644
index 0000000..8d82a7b
--- /dev/null
+++ b/LayoutTests/fast/dom/set-outer-text.html
@@ -0,0 +1,53 @@
+<html>
+<head>
+    <style>
+        pre { margin: 0; }
+    </style>
+    <script src="../../resources/dump-as-markup.js"></script>
+    <script>
+    Markup.noAutoDump();
+    
+    function assertMarkup(name, element, expected) {
+      var markup = Markup.get(element);
+      if (markup == expected)
+          log('PASS: ' + name);
+      else
+          log('FAIL: ' + name  + '\nWas:\n' + markup + '\nExpected:\n' + expected);
+    }
+    
+    function log(text) {
+      var el = document.createElement('pre');
+      el.appendChild(document.createTextNode(text));
+      document.getElementById('result').appendChild(el);
+    }
+    
+    function runTest() {
+        if (window.layoutTestController)
+            layoutTestController.dumpAsText()
+
+        var items = document.getElementsByTagName('li');
+
+        document.getElementById('testReplace').outerText = 'Replaced';
+        assertMarkup('replace', items[0], '| "Replaced node using outerText."');
+        
+        document.getElementById('testRemove').outerText = '';
+        assertMarkup('remove', items[1], '| " removing node using outerText."');
+
+        document.getElementById('testEmpty').outerText = '';
+        assertMarkup('empty text node', items[2], '| ""');
+        
+        document.getElementById('testAddBr').outerText = 'br\n';
+        assertMarkup('line break', items[3], '| "Testing adding br"\n| <br>\n| " using outerText."');
+    }
+    </script>
+</head>
+<body onload="runTest()">
+    <ul>
+      <li><span id="testReplace">Testing replacing</span> node using outerText.</li>
+      <li><span id="testRemove">Testing</span> removing node using outerText.</li>
+      <li><span id="testEmpty">Test removing entire node</span></li>
+      <li>Testing adding <span id="testAddBr">line break</span> using outerText.</li>
+    </ul>
+    <div id="result"></div>
+</body>
+</html>
diff --git a/LayoutTests/fast/dom/text-node-append-data-remove-crash-expected.txt b/LayoutTests/fast/dom/text-node-append-data-remove-crash-expected.txt
index b1b3ec6..a96ffed 100644
--- a/LayoutTests/fast/dom/text-node-append-data-remove-crash-expected.txt
+++ b/LayoutTests/fast/dom/text-node-append-data-remove-crash-expected.txt
@@ -1 +1 @@
-PASS, threw an exception as expected - Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
+PASS, didn't crash.
diff --git a/LayoutTests/fast/dom/text-node-append-data-remove-crash.html b/LayoutTests/fast/dom/text-node-append-data-remove-crash.html
index 61c60bd..28fb29a 100644
--- a/LayoutTests/fast/dom/text-node-append-data-remove-crash.html
+++ b/LayoutTests/fast/dom/text-node-append-data-remove-crash.html
@@ -1,50 +1,50 @@
-<html>
-<body onload="runTest()">
-<script>
-var count = 0;
-if (window.layoutTestController)
-{
-    layoutTestController.dumpAsText();
-    layoutTestController.waitUntilDone();
-}
-
-function runTest()
-{   
-    try {
-       divBlock.addEventListener("DOMCharacterDataModified", eventListener, false);
-       pBlock.outerText = "text";
-    }
-    catch (exception) {
-       divBlock.innerHTML = "PASS, threw an exception as expected - " + exception;
-       if (window.layoutTestController)
-           layoutTestController.notifyDone();
-   }
-}
-
-function eventListener()
-{
-    count += 1;
-    if (count < 2)
-        return;
-    var range = document.createRange();
-    range.setStart(divBlock, 0);
-    range.setEnd(divBlock, divBlock.childNodes.length - 1);
-    range.deleteContents();
-    gc();
-}
-
-function gc()
-{
-    if (window.GCController)
-        return GCController.collect();
-
-    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
-        var s = new String("");
-    }
-}
-</script>
-<div id="divBlock">
-<br/>textnode1<p id="pBlock"></p>textnode2<br/>
-</div>
-</body>
-</html>
+<html>
+<body onload="runTest()">
+<script>
+var count = 0;
+if (window.layoutTestController)
+{
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+function runTest()
+{   
+    try {
+       divBlock.addEventListener("DOMCharacterDataModified", eventListener, false);
+       pBlock.outerText = "text";
+       divBlock.innerHTML = "PASS, didn't crash.";
+    }
+    catch (exception) {
+       divBlock.innerHTML = "Threw an exception - " + exception;
+    }
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+function eventListener()
+{
+    try {
+      var range = document.createRange();
+      range.setStart(divBlock, 0);
+      range.setEnd(divBlock, divBlock.childNodes.length - 1);
+      range.deleteContents();
+      gc();
+  } catch(e) { }
+}
+
+function gc()
+{
+    if (window.GCController)
+        return GCController.collect();
+
+    for (var i = 0; i < 10000; i++) { // > force garbage collection (FF requires about 9K allocations before a collect)
+        var s = new String("");
+    }
+}
+</script>
+<div id="divBlock">
+<br/>textnode1<p id="pBlock"></p>textnode2<br/>
+</div>
+</body>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 6ef43b6..d028743 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2011-01-13  Emil Eklund  <eae at chromium.org>
+
+        Reviewed by Dimitri Glazkov.
+
+        Setting outerText should convert CR/LF to <br>
+        https://bugs.webkit.org/show_bug.cgi?id=52268
+
+        Make set outerText support line breaks (sharing the text to fragment code
+        with setInnerText) and handle empty text nodes the same way IE does.
+
+        Test: fast/dom/set-outer-text.html
+
+        * html/HTMLElement.cpp:
+        (WebCore::HTMLElement::textToFragment): Shared between setInnerText and setOuterText
+        (WebCore::HTMLElement::setInnerText): Split out text parsing code.
+        (WebCore::mergeWithNextTextNode): Split out text node merging code.
+        (WebCore::HTMLElement::setOuterText): Added support for line breaks.
+        * html/HTMLElement.h:
+
 2011-01-13  Zhenyao Mo  <zmo at google.com>
 
         Reviewed by Kenneth Russell.
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index e489a3d..af3115c 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -376,6 +376,39 @@ void HTMLElement::setOuterHTML(const String& html, ExceptionCode& ec)
     }
 }
 
+PassRefPtr<DocumentFragment> HTMLElement::textToFragment(const String& text, ExceptionCode& ec)
+{
+    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
+    unsigned int i, length = text.length();
+    UChar c = 0;
+    for (unsigned int start = 0; start < length; ) {
+
+        // Find next line break.
+        for (i = start; i < length; i++) {
+          c = text[i];
+          if (c == '\r' || c == '\n')
+              break;
+        }
+
+        fragment->appendChild(Text::create(document(), text.substring(start, i - start)), ec);
+        if (ec)
+            return 0;
+
+        if (c == '\r' || c == '\n') {
+            fragment->appendChild(HTMLBRElement::create(document()), ec);
+            if (ec)
+                return 0;
+            // Make sure \r\n doesn't result in two line breaks.
+            if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
+                i++;
+        }
+
+        start = i + 1; // Character after line break.
+    }
+
+    return fragment;
+}
+
 void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
 {
     if (ieForbidsInsertHTML()) {
@@ -419,30 +452,25 @@ void HTMLElement::setInnerText(const String& text, ExceptionCode& ec)
 
     // Add text nodes and <br> elements.
     ec = 0;
-    RefPtr<DocumentFragment> fragment = DocumentFragment::create(document());
-    int lineStart = 0;
-    UChar prev = 0;
-    int length = text.length();
-    for (int i = 0; i < length; ++i) {
-        UChar c = text[i];
-        if (c == '\n' || c == '\r') {
-            if (i > lineStart) {
-                fragment->appendChild(Text::create(document(), text.substring(lineStart, i - lineStart)), ec);
-                if (ec)
-                    return;
-            }
-            if (!(c == '\n' && i != 0 && prev == '\r')) {
-                fragment->appendChild(HTMLBRElement::create(document()), ec);
-                if (ec)
-                    return;
-            }
-            lineStart = i + 1;
-        }
-        prev = c;
-    }
-    if (length > lineStart)
-        fragment->appendChild(Text::create(document(), text.substring(lineStart, length - lineStart)), ec);
-    replaceChildrenWithFragment(this, fragment.release(), ec);
+    RefPtr<DocumentFragment> fragment = textToFragment(text, ec);
+    if (!ec)
+        replaceChildrenWithFragment(this, fragment.release(), ec);
+}
+
+static void mergeWithNextTextNode(PassRefPtr<Node> node, ExceptionCode& ec)
+{
+    ASSERT(node && node->isTextNode());
+    Node* next = node->nextSibling();
+    if (!next || !next->isTextNode())
+        return;
+    
+    RefPtr<Text> textNode = static_cast<Text*>(node.get());
+    RefPtr<Text> textNext = static_cast<Text*>(next);
+    textNode->appendData(textNext->data(), ec);
+    if (ec)
+        return;
+    if (textNext->parentNode()) // Might have been removed by mutation event.
+        textNext->remove(ec);
 }
 
 void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
@@ -465,39 +493,29 @@ void HTMLElement::setOuterText(const String &text, ExceptionCode& ec)
         return;
     }
 
-    // FIXME: This creates a new text node even when the text is empty.
-    // FIXME: This creates a single text node even when the text has CR and LF
-    // characters in it. Instead it should create <br> elements.
-    RefPtr<Text> t = Text::create(document(), text);
+    RefPtr<Node> prev = previousSibling();
+    RefPtr<Node> next = nextSibling();
+    RefPtr<Node> newChild;
     ec = 0;
-    parent->replaceChild(t, this, ec);
+    
+    // Convert text to fragment with <br> tags instead of linebreaks if needed.
+    if (text.contains('\r') || text.contains('\n'))
+        newChild = textToFragment(text, ec);
+    else
+        newChild = Text::create(document(), text);
+
+    if (!this || !parentNode())
+        ec = HIERARCHY_REQUEST_ERR;
     if (ec)
         return;
+    parent->replaceChild(newChild.release(), this, ec);
 
-    // Is previous node a text node? If so, merge into it.
-    Node* prev = t->previousSibling();
-    if (prev && prev->isTextNode()) {
-        RefPtr<Text> textPrev = static_cast<Text*>(prev);
-        textPrev->appendData(t->data(), ec);
-        if (ec)
-            return;
-        t->remove(ec);
-        if (ec)
-            return;
-        t = textPrev;
-    }
+    RefPtr<Node> node = next ? next->previousSibling() : 0;
+    if (!ec && node && node->isTextNode())
+        mergeWithNextTextNode(node.release(), ec);
 
-    // Is next node a text node? If so, merge it in.
-    Node* next = t->nextSibling();
-    if (next && next->isTextNode()) {
-        RefPtr<Text> textNext = static_cast<Text*>(next);
-        t->appendData(textNext->data(), ec);
-        if (ec)
-            return;
-        textNext->remove(ec);
-        if (ec)
-            return;
-    }
+    if (!ec && prev && prev->isTextNode())
+        mergeWithNextTextNode(prev.release(), ec);
 }
 
 Node* HTMLElement::insertAdjacent(const String& where, Node* newChild, ExceptionCode& ec)
diff --git a/Source/WebCore/html/HTMLElement.h b/Source/WebCore/html/HTMLElement.h
index 63ce110..a64db2c 100644
--- a/Source/WebCore/html/HTMLElement.h
+++ b/Source/WebCore/html/HTMLElement.h
@@ -100,6 +100,7 @@ private:
     virtual HTMLFormElement* virtualForm() const;
 
     Node* insertAdjacent(const String& where, Node* newChild, ExceptionCode&);
+    PassRefPtr<DocumentFragment> textToFragment(const String&, ExceptionCode&);
 };
 
 inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document* document)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list