Title: [97628] trunk
Revision
97628
Author
[email protected]
Date
2011-10-17 09:56:13 -0700 (Mon, 17 Oct 2011)

Log Message

Web Inspector: Search matches highlighting in text does not work correctly.
https://bugs.webkit.org/show_bug.cgi?id=70244

Reviewed by Pavel Feldman.

Source/WebCore:

Test: inspector/utilities-highlight-results.html

* inspector/front-end/utilities.js:
():

LayoutTests:

* inspector/utilities-highlight-results-expected.txt: Added.
* inspector/utilities-highlight-results.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (97627 => 97628)


--- trunk/LayoutTests/ChangeLog	2011-10-17 16:47:37 UTC (rev 97627)
+++ trunk/LayoutTests/ChangeLog	2011-10-17 16:56:13 UTC (rev 97628)
@@ -1,3 +1,13 @@
+2011-10-17  Vsevolod Vlasov  <[email protected]>
+
+        Web Inspector: Search matches highlighting in text does not work correctly.
+        https://bugs.webkit.org/show_bug.cgi?id=70244
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/utilities-highlight-results-expected.txt: Added.
+        * inspector/utilities-highlight-results.html: Added.
+
 2011-10-17  Chris Fleizach  <[email protected]>
 
         AX: webkit won't always send live region notifications

Added: trunk/LayoutTests/inspector/utilities-highlight-results-expected.txt (0 => 97628)


--- trunk/LayoutTests/inspector/utilities-highlight-results-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/utilities-highlight-results-expected.txt	2011-10-17 16:56:13 UTC (rev 97628)
@@ -0,0 +1,52 @@
+Tests how utilities functions highlight text and then revert/re-apply highlighting changes.
+
+Bug 70244
+--------- Running test: ----------
+After highlight: [function]
+After revert: function
+After apply: [function]
+--------- Running test: ----------
+After highlight: [functio]n
+After revert: function
+After apply: [functio]n
+--------- Running test: ----------
+After highlight: f[unction]
+After revert: function
+After apply: f[unction]
+--------- Running test: ----------
+After highlight: f[unctio]n
+After revert: function
+After apply: f[unctio]n
+--------- Running test: ----------
+After highlight: [function functionName]
+After revert: function functionName
+After apply: [function functionName]
+--------- Running test: ----------
+After highlight: [function functionNam]e
+After revert: function functionName
+After apply: [function functionNam]e
+--------- Running test: ----------
+After highlight: f[unction functionName]
+After revert: function functionName
+After apply: f[unction functionName]
+--------- Running test: ----------
+After highlight: f[unction functionNam]e
+After revert: function functionName
+After apply: f[unction functionNam]e
+--------- Running test: ----------
+After highlight: functio[n f]unctionName
+After revert: function functionName
+After apply: functio[n f]unctionName
+--------- Running test: ----------
+After highlight: [f]unction[ ][f]unctionName
+After revert: function functionName
+After apply: [f]unction[ ][f]unctionName
+--------- Running test: ----------
+After highlight: functio[n][ ]functionNam[e]
+After revert: function functionName
+After apply: functio[n][ ]functionNam[e]
+--------- Running test: ----------
+After highlight: [f]unctio[n f]unctionNam[e]
+After revert: function functionName
+After apply: [f]unctio[n f]unctionNam[e]
+
Property changes on: trunk/LayoutTests/inspector/utilities-highlight-results-expected.txt
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/inspector/utilities-highlight-results.html (0 => 97628)


--- trunk/LayoutTests/inspector/utilities-highlight-results.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/utilities-highlight-results.html	2011-10-17 16:56:13 UTC (rev 97628)
@@ -0,0 +1,92 @@
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function test()
+{
+    function dumpTextNodesAsString(node)
+    {
+        var result = "";
+        function dumpTextNode(node)
+        {
+            var str = node.textContent;
+            if (node.parentElement.className)
+                result += "[" + str + "]";
+            else
+                result += str;
+        };
+
+        function dumpElement(element)
+        {
+            for (var i = 0; i < element.childNodes.length; i++)
+                dumpNode(element.childNodes[i]);
+        }
+
+        function dumpNode(node)
+        {
+            if (node.nodeType === Node.TEXT_NODE)
+                dumpTextNode(node);
+            else if (node.nodeType === Node.ELEMENT_NODE)
+                dumpElement(node);
+        };
+
+        dumpNode(node);
+
+        return result;
+    }
+
+    function performTestForElement(element, ranges)
+    {
+        var changes = [];
+        InspectorTest.addResult("--------- Running test: ----------");
+        highlightRangesWithStyleClass(element, ranges, "highlighted", changes);
+        InspectorTest.addResult("After highlight: " + dumpTextNodesAsString(element));
+        revertDomChanges(changes);
+        InspectorTest.addResult("After revert: " + dumpTextNodesAsString(element));
+        applyDomChanges(changes);
+        InspectorTest.addResult("After apply: " + dumpTextNodesAsString(element));
+    }
+
+    function textElement(strings)
+    {
+        var element = document.createElement("div");
+        for (var i = 0; i < strings.length; i++) {
+            var span = document.createElement("span");
+            span.textContent = strings[i];
+            element.appendChild(span);
+        }
+        return element;
+    }
+
+    function range(offset, length)
+    {
+        var result = {};
+        result.offset = offset;
+        result.length = length;
+        return result;
+    }
+
+    performTestForElement(textElement(["function"]), [range(0, 8)]); // Highlight whole text node.
+    performTestForElement(textElement(["function"]), [range(0, 7)]); // Highlight only text node beginning.
+    performTestForElement(textElement(["function"]), [range(1, 7)]); // Highlight only text node ending.
+    performTestForElement(textElement(["function"]), [range(1, 6)]); // Highlight in the middle of text node.
+
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(0, 21)]); // Highlight all text in 3 text nodes.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(0, 20)]); // Highlight all text in 3 text nodes except for the last character.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(1, 20)]); // Highlight all text in 3 text nodes except for the first character.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(1, 19)]); // Highlight all text in 3 text nodes except for the first and the last characters.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(7, 3)]); // Highlight like that "functio[n f]unctionName"
+
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(0, 1), range(8, 1), range(9, 1)]); // Highlight first characters in text nodes.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(7, 1), range(8, 1), range(20, 1)]); // Highlight last characters in text node.
+    performTestForElement(textElement(["function", " ", "functionName"]), [range(0, 1), range(7, 3), range(20, 1)]); // Highlight like that: "[f]unctio[n f]unctionNam[e]"
+    InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Tests how utilities functions highlight text and then revert/re-apply highlighting changes.</p>
+    <a href="" 70244</a>
+</body>
+</html>
Property changes on: trunk/LayoutTests/inspector/utilities-highlight-results.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/Source/WebCore/ChangeLog (97627 => 97628)


--- trunk/Source/WebCore/ChangeLog	2011-10-17 16:47:37 UTC (rev 97627)
+++ trunk/Source/WebCore/ChangeLog	2011-10-17 16:56:13 UTC (rev 97628)
@@ -1,3 +1,15 @@
+2011-10-17  Vsevolod Vlasov  <[email protected]>
+
+        Web Inspector: Search matches highlighting in text does not work correctly.
+        https://bugs.webkit.org/show_bug.cgi?id=70244
+
+        Reviewed by Pavel Feldman.
+
+        Test: inspector/utilities-highlight-results.html
+
+        * inspector/front-end/utilities.js:
+        ():
+
 2011-10-17  Chris Fleizach  <[email protected]>
 
         AX: webkit won't always send live region notifications

Modified: trunk/Source/WebCore/inspector/front-end/utilities.js (97627 => 97628)


--- trunk/Source/WebCore/inspector/front-end/utilities.js	2011-10-17 16:47:37 UTC (rev 97627)
+++ trunk/Source/WebCore/inspector/front-end/utilities.js	2011-10-17 16:56:13 UTC (rev 97628)
@@ -874,82 +874,73 @@
     var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
 
     var snapshotLength = textNodeSnapshot.snapshotLength;
-    var snapshotNodeOffset = 0;
-    var currentSnapshotItem = 0;
+    if (snapshotLength === 0)
+        return highlightNodes;
 
+    var nodeRanges = [];
+    var rangeEndOffset = 0;
+    for (var i = 0; i < snapshotLength; ++i) {
+        var range = {};
+        range.offset = rangeEndOffset;
+        range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
+        rangeEndOffset = range.offset + range.length;
+        nodeRanges.push(range);
+    }
+
+    var startIndex = 0;
     for (var i = 0; i < resultRanges.length; ++i) {
-        var resultLength = resultRanges[i].length;
         var startOffset = resultRanges[i].offset;
-        var endOffset = startOffset + resultLength;
-        var length = resultLength;
-        var textNode;
-        var textNodeOffset;
-        var found;
+        var endOffset = startOffset + resultRanges[i].length;
 
-        while (currentSnapshotItem < snapshotLength) {
-            textNode = textNodeSnapshot.snapshotItem(currentSnapshotItem++);
-            var textNodeLength = textNode.nodeValue.length;
-            if (snapshotNodeOffset + textNodeLength > startOffset) {
-                textNodeOffset = startOffset - snapshotNodeOffset;
-                snapshotNodeOffset += textNodeLength;
-                found = true;
-                break;
-            }
-            snapshotNodeOffset += textNodeLength;
-        }
-
-        if (!found) {
-            textNode = element;
-            textNodeOffset = 0;
-        }
-
+        while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
+            startIndex++;
+        var endIndex = startIndex; 
+        while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
+            endIndex++;
+        if (endIndex === snapshotLength)
+            break;
+        
         var highlightNode = ownerDocument.createElement("span");
         highlightNode.className = styleClass;
         highlightNode.textContent = lineText.substring(startOffset, endOffset);
 
-        var text = textNode.textContent;
-        if (textNodeOffset + resultLength < text.length) {
-            // Selection belongs to a single split mode.
-            textNode.textContent = text.substring(textNodeOffset + resultLength);
-            changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
+        var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
+        var lastText = lastTextNode.textContent;
+        lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
+        changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });
+        
+        if (startIndex === endIndex) {
+            lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
+            changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
+            highlightNodes.push(highlightNode);
+            
+            var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
+            lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
+            changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
+        } else {
+            var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
+            var firstText = firstTextNode.textContent;
+            var anchorElement = firstTextNode.nextSibling;
 
-            textNode.parentElement.insertBefore(highlightNode, textNode);
-            changes.push({ node: highlightNode, type: "added", nextSibling: textNode, parent: textNode.parentElement });
-
-            var prefixNode = ownerDocument.createTextNode(text.substring(0, textNodeOffset));
-            textNode.parentElement.insertBefore(prefixNode, highlightNode);
-            changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: textNode.parentElement });
+            firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
+            changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
             highlightNodes.push(highlightNode);
-            continue;
-        }
 
-        var parentElement = textNode.parentElement;
-        var anchorElement = textNode.nextSibling;
+            firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
+            changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });
 
-        length -= text.length - textNodeOffset;
-        textNode.textContent = text.substring(0, textNodeOffset);
-        changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
-
-        while (currentSnapshotItem < snapshotLength) {
-            textNode = textNodeSnapshot.snapshotItem(currentSnapshotItem++);
-            snapshotNodeOffset += textNode.nodeValue.length;
-            text = textNode.textContent;
-            if (length < text.length) {
-                textNode.textContent = text.substring(length);
+            for (var j = startIndex + 1; j < endIndex; j++) {
+                var textNode = textNodeSnapshot.snapshotItem(j);
+                var text = textNode.textContent;
+                textNode.textContent = "";
                 changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
-                break;
             }
-
-            length -= text.length;
-            textNode.textContent = "";
-            changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
         }
-
-        parentElement.insertBefore(highlightNode, anchorElement);
-        changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: parentElement });
-        highlightNodes.push(highlightNode);
+        startIndex = endIndex;
+        nodeRanges[startIndex].offset = endOffset;
+        nodeRanges[startIndex].length = lastTextNode.textContent.length;
+            
     }
-
     return highlightNodes;
 }
 
@@ -970,7 +961,7 @@
 
 function revertDomChanges(domChanges)
 {
-    for (var i = 0, size = domChanges.length; i < size; ++i) {
+    for (var i = domChanges.length - 1; i >= 0; --i) {
         var entry = domChanges[i];
         switch (entry.type) {
         case "added":
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to