Factors out the TextPrompt.scanBackwards function into a generic
authortimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Aug 2008 16:46:56 +0000 (16:46 +0000)
committertimothy@apple.com <timothy@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Aug 2008 16:46:56 +0000 (16:46 +0000)
        helper function on the Node prototype, named rangeOfWord.

        Reviewed by Adam Roben.

        * page/inspector/Console.js:
        (WebInspector.Console.prototype.completions): Use rangeOfWord.
        * page/inspector/TextPrompt.js:
        (WebInspector.TextPrompt.prototype.complete): Ditto.
        (WebInspector.TextPrompt.prototype.scanBackwards): Removed.
        * page/inspector/utilities.js:
        (Node.prototype.rangeOfWord): Added. Copied from TextPrompt.scanBackwards,
        and added a direction argument allowing scanning forward, backward or
        both directions from the offset.

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

WebCore/ChangeLog
WebCore/page/inspector/Console.js
WebCore/page/inspector/TextPrompt.js
WebCore/page/inspector/utilities.js

index 1c34c13..adada74 100644 (file)
@@ -1,5 +1,22 @@
 2008-08-04  Timothy Hatcher  <timothy@apple.com>
 
+        Factors out the TextPrompt.scanBackwards function into a generic
+        helper function on the Node prototype, named rangeOfWord.
+
+        Reviewed by Adam Roben.
+
+        * page/inspector/Console.js:
+        (WebInspector.Console.prototype.completions): Use rangeOfWord.
+        * page/inspector/TextPrompt.js:
+        (WebInspector.TextPrompt.prototype.complete): Ditto.
+        (WebInspector.TextPrompt.prototype.scanBackwards): Removed.
+        * page/inspector/utilities.js:
+        (Node.prototype.rangeOfWord): Added. Copied from TextPrompt.scanBackwards,
+        and added a direction argument allowing scanning forward, backward or
+        both directions from the offset.
+
+2008-08-04  Timothy Hatcher  <timothy@apple.com>
+
         Fixes a bug where the property toggle button would not be hidden
         during editing.
 
index 79aef1f..93fd270 100644 (file)
@@ -170,9 +170,10 @@ WebInspector.Console.prototype = {
 
     completions: function(wordRange, bestMatchOnly)
     {
-        // Pass less characters to scanBackwards so the range will be a more complete expression.
-        var expression = this.prompt.scanBackwards(" =:{;", wordRange.startContainer, wordRange.startOffset);
-        var expressionString = expression.toString();
+        // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
+        const expressionStopCharacters = " =:{;";
+        var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, expressionStopCharacters, this.promptElement, "backward");
+        var expressionString = expressionRange.toString();
         var lastIndex = expressionString.length - 1;
 
         var dotNotation = (expressionString[lastIndex] === ".");
index 264cb4c..61e1b52 100644 (file)
@@ -151,8 +151,7 @@ WebInspector.TextPrompt.prototype = {
         if (auto && !this.isCaretAtEndOfPrompt())
             return;
 
-        var wordPrefixRange = this.scanBackwards(this.completionStopCharacters, selectionRange.startContainer, selectionRange.startOffset, this.element);
-
+        var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this.completionStopCharacters, this.element, "backward");
         var completions = this.completions(wordPrefixRange, auto);
 
         if (!completions || !completions.length)
@@ -219,47 +218,6 @@ WebInspector.TextPrompt.prototype = {
         selection.addRange(finalSelectionRange);
     },
 
-    scanBackwards: function(stopCharacters, endNode, endOffset, stayWithinElement)
-    {
-        var startNode;
-        var startOffset = 0;
-        var node = endNode;
-
-        if (!stayWithinElement)
-            stayWithinElement = this.element;
-
-        while (node) {
-            if (node === stayWithinElement) {
-                if (!startNode)
-                    startNode = stayWithinElement;
-                break;
-            }
-
-            if (node.nodeType === Node.TEXT_NODE) {
-                var start = (node === endNode ? endOffset : node.nodeValue.length);
-                for (var i = (start - 1); i >= 0; --i) {
-                    var character = node.nodeValue[i];
-                    if (stopCharacters.indexOf(character) !== -1) {
-                        startNode = node;
-                        startOffset = i + 1;
-                        break;
-                    }
-                }
-            }
-
-            if (startNode)
-                break;
-
-            node = node.traversePreviousNode();
-        }
-
-        var result = document.createRange();
-        result.setStart(startNode, startOffset);
-        result.setEnd(endNode, endOffset);
-
-        return result;
-    },
-
     isCaretInsidePrompt: function()
     {
         return this.element.isInsertionCaretInside();
index 001e26f..5e444fd 100644 (file)
@@ -107,6 +107,93 @@ Function.prototype.bind = function(thisObject)
     return function() { return func.apply(thisObject, args.concat(Array.prototype.slice.call(arguments, 0))) };
 }
 
+Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
+{
+    var startNode;
+    var startOffset = 0;
+    var endNode;
+    var endOffset = 0;
+
+    if (!stayWithinNode)
+        stayWithinNode = this;
+
+    if (!direction || direction === "backward" || direction === "both") {
+        var node = this;
+        while (node) {
+            if (node === stayWithinNode) {
+                if (!startNode)
+                    startNode = stayWithinNode;
+                break;
+            }
+
+            if (node.nodeType === Node.TEXT_NODE) {
+                var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
+                for (var i = start; i >= 0; --i) {
+                    if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
+                        startNode = node;
+                        startOffset = i + 1;
+                        break;
+                    }
+                }
+            }
+
+            if (startNode)
+                break;
+
+            node = node.traversePreviousNode(false, stayWithinNode);
+        }
+
+        if (!startNode) {
+            startNode = stayWithinNode;
+            startOffset = 0;
+        }
+    } else {
+        startNode = this;
+        startOffset = offset;
+    }
+
+    if (!direction || direction === "forward" || direction === "both") {
+        node = this;
+        while (node) {
+            if (node === stayWithinNode) {
+                if (!endNode)
+                    endNode = stayWithinNode;
+                break;
+            }
+
+            if (node.nodeType === Node.TEXT_NODE) {
+                var start = (node === this ? offset : 0);
+                for (var i = start; i < node.nodeValue.length; ++i) {
+                    if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
+                        endNode = node;
+                        endOffset = i;
+                        break;
+                    }
+                }
+            }
+
+            if (endNode)
+                break;
+
+            node = node.traverseNextNode(false, stayWithinNode);
+        }
+
+        if (!endNode) {
+            endNode = stayWithinNode;
+            endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
+        }
+    } else {
+        endNode = this;
+        endOffset = offset;
+    }
+
+    var result = this.ownerDocument.createRange();
+    result.setStart(startNode, startOffset);
+    result.setEnd(endNode, endOffset);
+
+    return result;
+}
+
 Element.prototype.removeStyleClass = function(className) 
 {
     // Test for the simple case before using a RegExp.
@@ -624,10 +711,12 @@ function traverseNextNode(skipWhitespace, stayWithin)
     return skipWhitespace ? nextSiblingSkippingWhitespace.call(node) : node.nextSibling;
 }
 
-function traversePreviousNode(skipWhitespace)
+function traversePreviousNode(skipWhitespace, stayWithin)
 {
     if (!this)
         return;
+    if (stayWithin && objectsAreSame(this, stayWithin))
+        return null;
     var node = skipWhitespace ? previousSiblingSkippingWhitespace.call(this) : this.previousSibling;
     while (node && (skipWhitespace ? lastChildSkippingWhitespace.call(node) : node.lastChild) )
         node = skipWhitespace ? lastChildSkippingWhitespace.call(node) : node.lastChild;