Make clicking anywhere in a row in the DOM tree select that row's node
authoraroben@apple.com <aroben@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Mar 2008 20:39:18 +0000 (20:39 +0000)
committeraroben@apple.com <aroben@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Mar 2008 20:39:18 +0000 (20:39 +0000)
        We now have mousedown and dblclick event listeners on the root of the
        tree that forward the event to the node on the row the mouse is over.

        Reviewed by Tim Hatcher.

        * page/inspector/DocumentPanel.js:
        (WebInspector.DocumentPanel): Added a dblclick and mousedown event
        listeners to the root of the tree.
        (WebInspector.DocumentPanel._treeElementFromEvent): Added. Finds the
        tree element for the row underneath the mouse.
        (WebInspector.DocumentPanel._ondblclick): Added. Sends the dblclick
        event on to the tree element in the current row.
        (WebInspector.DocumentPanel._onmousedown): Added. Selects the tree
        element in the current row.
        * page/inspector/treeoutline.js:
        (TreeOutline.treeElementFromPoint): Added.
        (TreeElement.treeElementSelected): Changed to call
        TreeElement.isEventWithinDisclosureTriangle, and added an early return.
        (TreeElement.treeElementToggled): Ditto.
        (TreeElement.isEventWithinDisclosureTriangle): Added.
        * page/inspector/utilities.js:
        (Node.enclosingNodeOrSelfWithNodeNameInArray): Added.
        (Node.enclosingNodeOrSelfWithNodeName): Now just calls
        enclosingNodeOrSelfWithNodeNameInArray.
        (Elemnt.get totalOffsetLeft): Added.
        (Elemnt.get totalOffsetTop): Added.

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

WebCore/ChangeLog
WebCore/page/inspector/DocumentPanel.js
WebCore/page/inspector/treeoutline.js
WebCore/page/inspector/utilities.js

index e7914ab..2f03fc6 100644 (file)
@@ -1,3 +1,34 @@
+2008-03-19  Adam Roben  <aroben@apple.com>
+
+        Make clicking anywhere in a row in the DOM tree select that row's node
+
+        We now have mousedown and dblclick event listeners on the root of the
+        tree that forward the event to the node on the row the mouse is over.
+
+        Reviewed by Tim Hatcher.
+
+        * page/inspector/DocumentPanel.js:
+        (WebInspector.DocumentPanel): Added a dblclick and mousedown event
+        listeners to the root of the tree.
+        (WebInspector.DocumentPanel._treeElementFromEvent): Added. Finds the
+        tree element for the row underneath the mouse.
+        (WebInspector.DocumentPanel._ondblclick): Added. Sends the dblclick
+        event on to the tree element in the current row.
+        (WebInspector.DocumentPanel._onmousedown): Added. Selects the tree
+        element in the current row.
+        * page/inspector/treeoutline.js:
+        (TreeOutline.treeElementFromPoint): Added.
+        (TreeElement.treeElementSelected): Changed to call
+        TreeElement.isEventWithinDisclosureTriangle, and added an early return.
+        (TreeElement.treeElementToggled): Ditto.
+        (TreeElement.isEventWithinDisclosureTriangle): Added.
+        * page/inspector/utilities.js:
+        (Node.enclosingNodeOrSelfWithNodeNameInArray): Added.
+        (Node.enclosingNodeOrSelfWithNodeName): Now just calls
+        enclosingNodeOrSelfWithNodeNameInArray.
+        (Elemnt.get totalOffsetLeft): Added.
+        (Elemnt.get totalOffsetTop): Added.
+
 2008-03-19  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Sam Weinig.
index e4a6b1f..636f9d9 100644 (file)
@@ -50,6 +50,8 @@ WebInspector.DocumentPanel = function(resource, views)
     domView.treeContentElement.className = "content tree outline-disclosure";
 
     domView.treeListElement = document.createElement("ol");
+    domView.treeListElement.addEventListener("mousedown", this._onmousedown.bind(this), false);
+    domView.treeListElement.addEventListener("dblclick", this._ondblclick.bind(this), false);
     domView.treeOutline = new TreeOutline(domView.treeListElement);
     domView.treeOutline.panel = this;
 
@@ -771,6 +773,52 @@ WebInspector.DocumentPanel.prototype = {
 
         return false;
     },
+
+    _treeElementFromEvent: function(event)
+    {
+        var outline = this.views.dom.treeOutline;
+
+        var root = this.views.dom.treeListElement;
+
+        // We choose this X coordinate based on the knowledge that our list
+        // items extend nearly to the right edge of the outer <ol>.
+        var x = root.totalOffsetLeft + root.offsetWidth - 20;
+
+        var y = event.pageY;
+
+        // Our list items have 1-pixel cracks between them vertically. We avoid
+        // the cracks by checking slightly above and slightly below the mouse
+        // and seeing if we hit the same element each time.
+        var elementUnderMouse = outline.treeElementFromPoint(x, y);
+        var elementAboveMouse = outline.treeElementFromPoint(x, y - 2);
+        var element;
+        if (elementUnderMouse === elementAboveMouse)
+            element = elementUnderMouse;
+        else
+            element = outline.treeElementFromPoint(x, y + 2);
+
+        return element;
+    },
+
+    _ondblclick: function(event)
+    {
+        var element = this._treeElementFromEvent(event);
+
+        if (!element)
+            return;
+
+        element.ondblclick();
+    },
+
+    _onmousedown: function(event)
+    {
+        var element = this._treeElementFromEvent(event);
+
+        if (!element || element.isEventWithinDisclosureTriangle(event))
+            return;
+
+        element.select();
+    },
 }
 
 WebInspector.DocumentPanel.prototype.__proto__ = WebInspector.SourcePanel.prototype;
index 228136a..b025890 100644 (file)
@@ -285,6 +285,13 @@ TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor,
     return item;
 }
 
+TreeOutline.prototype.treeElementFromPoint = function(x, y)
+{
+    var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
+    var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
+    return listNode.parentTreeElement || listNode.treeElement;
+}
+
 TreeOutline.prototype.handleKeyEvent = function(event)
 {
     if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
@@ -511,8 +518,10 @@ TreeElement.treeElementSelected = function(event)
     if (!element || !element.treeElement || !element.treeElement.selectable)
         return;
 
-    if (event.offsetX > element.treeElement.arrowToggleWidth || !element.treeElement.hasChildren)
-        element.treeElement.select();
+    if (element.treeElement.isEventWithinDisclosureTriangle(event))
+        return;
+
+    element.treeElement.select();
 }
 
 TreeElement.treeElementToggled = function(event)
@@ -521,18 +530,19 @@ TreeElement.treeElementToggled = function(event)
     if (!element || !element.treeElement)
         return;
 
-    if (event.offsetX <= element.treeElement.arrowToggleWidth && element.treeElement.hasChildren) {
-        if (element.treeElement.expanded) {
-            if (event.altKey)
-                element.treeElement.collapseRecursively();
-            else
-                element.treeElement.collapse();
-        } else {
-            if (event.altKey)
-                element.treeElement.expandRecursively();
-            else
-                element.treeElement.expand();
-        }
+    if (!element.treeElement.isEventWithinDisclosureTriangle(event))
+        return;
+
+    if (element.treeElement.expanded) {
+        if (event.altKey)
+            element.treeElement.collapseRecursively();
+        else
+            element.treeElement.collapse();
+    } else {
+        if (event.altKey)
+            element.treeElement.expandRecursively();
+        else
+            element.treeElement.expand();
     }
 }
 
@@ -726,3 +736,9 @@ TreeElement.prototype.traversePreviousTreeElement = function(skipHidden, dontPop
 
     return this.parent;
 }
+
+TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
+{
+    var left = this._listItemNode.totalOffsetLeft;
+    return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
+}
index 50c0172..c6f399f 100644 (file)
@@ -123,14 +123,20 @@ Element.prototype.hasStyleClass = function(className)
     return regex.test(this.className);
 }
 
-Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
+Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
 {
     for (var node = this; node && (node !== document); node = node.parentNode)
-        if (node.nodeName.toLowerCase() === nodeName.toLowerCase())
-            return node;
+        for (var i = 0; i < nameArray.length; ++i)
+            if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
+                return node;
     return null;
 }
 
+Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
+{
+    return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
+}
+
 Node.prototype.enclosingNodeOrSelfWithClass = function(className)
 {
     for (var node = this; node && (node !== document); node = node.parentNode)
@@ -157,6 +163,20 @@ Element.prototype.removeChildren = function()
         this.removeChild(this.firstChild);        
 }
 
+Element.prototype.__defineGetter__("totalOffsetLeft", function() {
+    var total = 0;
+    for (var element = this; element; element = element.offsetParent)
+        total += element.offsetLeft;
+    return total;
+});
+
+Element.prototype.__defineGetter__("totalOffsetTop", function() {
+    var total = 0;
+    for (var element = this; element; element = element.offsetParent)
+        total += element.offsetTop;
+    return total;
+});
+
 Element.prototype.firstChildSkippingWhitespace = firstChildSkippingWhitespace;
 Element.prototype.lastChildSkippingWhitespace = lastChildSkippingWhitespace;