Title: [90460] trunk/Source/WebCore
Revision
90460
Author
[email protected]
Date
2011-07-06 08:25:40 -0700 (Wed, 06 Jul 2011)

Log Message

2011-07-06  Pavel Feldman  <[email protected]>

        Web Inspector: implement drag'n'drop in the elements panel for reordering nodes.
        https://bugs.webkit.org/show_bug.cgi?id=63990

        Reviewed by Yury Semikhatsky.

        * inspector/Inspector.json:
        * inspector/InspectorDOMAgent.cpp:
        (WebCore::InspectorDOMAgent::moveTo):
        * inspector/InspectorDOMAgent.h:
        * inspector/front-end/DOMAgent.js:
        (WebInspector.DOMNode.prototype._removeChild):
        (WebInspector.DOMNode.prototype.ownerDocumentElement):
        (WebInspector.DOMNode.prototype.moveTo):
        (WebInspector.DOMAgent.prototype._childNodeRemoved):
        * inspector/front-end/ElementsTreeOutline.js:
        (WebInspector.ElementsTreeOutline):
        (WebInspector.ElementsTreeOutline.prototype._ondragstart):
        (WebInspector.ElementsTreeOutline.prototype._ondragover):
        (WebInspector.ElementsTreeOutline.prototype._ondragleave):
        (WebInspector.ElementsTreeOutline.prototype._isValidDragSourceOrTarget):
        (WebInspector.ElementsTreeOutline.prototype._ondragend.callback):
        (WebInspector.ElementsTreeOutline.prototype._ondragend):
        (WebInspector.ElementsTreeOutline.prototype._clearDragOverTreeElementMarker):
        (WebInspector.ElementsTreeOutline.prototype.populateContextMenu.focusElement):
        (WebInspector.ElementsTreeOutline.prototype.populateContextMenu):
        (WebInspector.ElementsTreeElement.prototype.onattach):
        * inspector/front-end/inspector.css:
        (.outline-disclosure li.elements-drag-over .selection):
        * inspector/front-end/treeoutline.js:
        (TreeOutline.prototype.treeElementFromEvent):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (90459 => 90460)


--- trunk/Source/WebCore/ChangeLog	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/ChangeLog	2011-07-06 15:25:40 UTC (rev 90460)
@@ -1,3 +1,36 @@
+2011-07-06  Pavel Feldman  <[email protected]>
+
+        Web Inspector: implement drag'n'drop in the elements panel for reordering nodes.
+        https://bugs.webkit.org/show_bug.cgi?id=63990
+
+        Reviewed by Yury Semikhatsky.
+
+        * inspector/Inspector.json:
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::moveTo):
+        * inspector/InspectorDOMAgent.h:
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.DOMNode.prototype._removeChild):
+        (WebInspector.DOMNode.prototype.ownerDocumentElement):
+        (WebInspector.DOMNode.prototype.moveTo):
+        (WebInspector.DOMAgent.prototype._childNodeRemoved):
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeOutline):
+        (WebInspector.ElementsTreeOutline.prototype._ondragstart):
+        (WebInspector.ElementsTreeOutline.prototype._ondragover):
+        (WebInspector.ElementsTreeOutline.prototype._ondragleave):
+        (WebInspector.ElementsTreeOutline.prototype._isValidDragSourceOrTarget):
+        (WebInspector.ElementsTreeOutline.prototype._ondragend.callback):
+        (WebInspector.ElementsTreeOutline.prototype._ondragend):
+        (WebInspector.ElementsTreeOutline.prototype._clearDragOverTreeElementMarker):
+        (WebInspector.ElementsTreeOutline.prototype.populateContextMenu.focusElement):
+        (WebInspector.ElementsTreeOutline.prototype.populateContextMenu):
+        (WebInspector.ElementsTreeElement.prototype.onattach):
+        * inspector/front-end/inspector.css:
+        (.outline-disclosure li.elements-drag-over .selection):
+        * inspector/front-end/treeoutline.js:
+        (TreeOutline.prototype.treeElementFromEvent):
+
 2011-07-06  Andras Becsi  <[email protected]>
 
         Fix "warning: a `;' might be needed at the end of action code"

Modified: trunk/Source/WebCore/inspector/Inspector.json (90459 => 90460)


--- trunk/Source/WebCore/inspector/Inspector.json	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/Inspector.json	2011-07-06 15:25:40 UTC (rev 90460)
@@ -1015,6 +1015,18 @@
                     { "name": "attributes", "type": "array", "items": { "type": "Attributes" }, "description": "Attribute holders for the requested nodes." }
                 ],
                 "description": "Returns attributes for the specified nodes."
+            },
+            {
+                "name": "moveTo",
+                "parameters": [
+                    { "name": "nodeId", "type": "integer", "description": "Id of the node to drop." },
+                    { "name": "targetNodeId", "type": "integer", "description": "Id of the node to drop into." },
+                    { "name": "anchorNodeId", "type": "integer", "optional": true, "description": "Drop node before given one." }
+                ],
+                "returns": [
+                    { "name": "nodeId", "type": "integer", "description": "New id of the moved node." }
+                ],
+                "description": "Moves node into the new container, places it before the given anchor."
             }
         ],
         "events": [

Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp (90459 => 90460)


--- trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp	2011-07-06 15:25:40 UTC (rev 90460)
@@ -1032,6 +1032,36 @@
     m_client->hideHighlight();
 }
 
+void InspectorDOMAgent::moveTo(ErrorString* error, int nodeId, int targetNodeId, const int* const anchorNodeId, int* newNodeId)
+{
+    Element* element = assertElement(error, nodeId);
+    if (!element)
+        return;
+
+    Element* targetElement = assertElement(error, targetNodeId);
+    if (!targetElement)
+        return;
+
+    Element* anchorElement = 0;
+    if (anchorNodeId && *anchorNodeId) {
+        anchorElement = assertElement(error, *anchorNodeId);
+        if (!anchorElement)
+            return;
+        if (anchorElement->parentNode() != targetElement) {
+            *error = "Anchor node must be child of the target node.";
+            return;
+        }
+    }
+
+    ExceptionCode ec = 0;
+    bool success = targetElement->insertBefore(element, anchorElement, ec);
+    if (ec || !success) {
+        *error = "Could not drop node.";
+        return;
+    }
+    *newNodeId = pushNodePathToFrontend(element);
+}
+
 void InspectorDOMAgent::resolveNode(ErrorString* error, int nodeId, const String* const objectGroup, RefPtr<InspectorObject>* result)
 {
     String objectGroupName = objectGroup ? *objectGroup : "";

Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.h (90459 => 90460)


--- trunk/Source/WebCore/inspector/InspectorDOMAgent.h	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.h	2011-07-06 15:25:40 UTC (rev 90460)
@@ -136,6 +136,8 @@
     void hideNodeHighlight(ErrorString* error) { hideHighlight(error); }
     void highlightFrame(ErrorString*, const String& frameId);
     void hideFrameHighlight(ErrorString* error) { hideHighlight(error); }
+    void moveTo(ErrorString*, int nodeId, int targetNodeId, const int* const anchorNodeId, int* newNodeId);
+
     Node* highlightedNode() const { return m_highlightedNode.get(); }
 
     // Methods called from the InspectorInstrumentation.

Modified: trunk/Source/WebCore/inspector/front-end/DOMAgent.js (90459 => 90460)


--- trunk/Source/WebCore/inspector/front-end/DOMAgent.js	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/front-end/DOMAgent.js	2011-07-06 15:25:40 UTC (rev 90460)
@@ -259,7 +259,7 @@
         return node;
     },
 
-    removeChild_: function(node)
+    _removeChild: function(node)
     {
         this.children.splice(this.children.indexOf(node), 1);
         node.parentNode = null;
@@ -315,6 +315,11 @@
         while (node.parentNode && !node.parentNode.documentURL)
             node = node.parentNode;
         return node;
+    },
+
+    moveTo: function(targetNode, anchorNode, callback)
+    {
+        DOMAgent.moveTo(this.id, targetNode.id, anchorNode ? anchorNode.id : undefined, callback); 
     }
 }
 
@@ -535,7 +540,7 @@
     {
         var parent = this._idToDOMNode[parentId];
         var node = this._idToDOMNode[nodeId];
-        parent.removeChild_(node);
+        parent._removeChild(node);
         this.dispatchEventToListeners(WebInspector.DOMAgent.Events.NodeRemoved, {node:node, parent:parent});
         delete this._idToDOMNode[nodeId];
         if (Preferences.nativeInstrumentationEnabled)

Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (90459 => 90460)


--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js	2011-07-06 15:25:40 UTC (rev 90460)
@@ -33,6 +33,10 @@
     this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
     this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
     this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);
+    this.element.addEventListener("dragstart", this._ondragstart.bind(this), false);
+    this.element.addEventListener("dragover", this._ondragover.bind(this), false);
+    this.element.addEventListener("dragleave", this._ondragleave.bind(this), false);
+    this.element.addEventListener("dragend", this._ondragend.bind(this), false);
 
     TreeOutline.call(this, this.element);
 
@@ -258,17 +262,143 @@
         WebInspector.highlightDOMNode(0);
     },
 
+    _ondragstart: function(event)
+    {
+        var treeElement = this._treeElementFromEvent(event);
+        if (!treeElement)
+            return false;
+
+        if (!this._isValidDragSourceOrTarget(treeElement))
+            return false;
+
+        if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD")
+            return false;
+
+        event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent);
+        event.dataTransfer.effectAllowed = "copy";
+        this._nodeBeingDragged = treeElement.representedObject;
+
+        WebInspector.highlightDOMNode(0);
+
+        return true;
+    },
+
+    _ondragover: function(event)
+    {
+        this._clearDragOverTreeElementMarker();
+
+        if (!this._nodeBeingDragged)
+            return;
+        
+        var treeElement = this._treeElementFromEvent(event);
+        if (!this._isValidDragSourceOrTarget(treeElement))
+            return;
+
+        var node = treeElement.representedObject;
+        while (node) {
+            if (node === this._nodeBeingDragged)
+                return;
+            node = node.parentNode;
+        }
+
+        treeElement.updateSelection();
+        treeElement.listItemElement.addStyleClass("elements-drag-over");
+        this._dragOverTreeElement = treeElement;
+    },
+
+    _ondragleave: function(event)
+    {
+        this._clearDragOverTreeElementMarker();
+
+        if (!this._nodeBeingDragged)
+            return;
+        
+        var treeElement = this._treeElementFromEvent(event);
+        if (!this._isValidDragSourceOrTarget(treeElement))
+            return false;
+
+        var node = treeElement.representedObject;
+        while (node) {
+            if (node === this._nodeBeingDragged)
+                return;
+            node = node.parentNode;
+        }
+
+        treeElement.updateSelection();
+        treeElement.listItemElement.addStyleClass("elements-drag-over");
+        this._dragOverTreeElement = treeElement;
+    },
+
+    _isValidDragSourceOrTarget: function(treeElement)
+    {
+        if (!treeElement)
+            return false;
+
+        var node = treeElement.representedObject;
+        if (!(node instanceof WebInspector.DOMNode))
+            return false;
+
+        if (node.nodeType() !== Node.ELEMENT_NODE)
+            return false;
+
+        if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
+            return false;
+
+        return true;
+    },
+
+    _ondragend: function(event)
+    {
+        if (this._nodeBeingDragged && this._dragOverTreeElement) {
+            var parentNode;
+            var anchorNode;
+
+            if (this._dragOverTreeElement._elementCloseTag) {
+                // Drop onto closing tag -> insert as last child.
+                parentNode = this._dragOverTreeElement.representedObject;
+            } else {
+                var dragTargetNode = this._dragOverTreeElement.representedObject;
+                parentNode = dragTargetNode.parentNode;
+                anchorNode = dragTargetNode;
+            }
+
+            function callback(error, newNodeId)
+            {
+                if (error)
+                    return;
+
+                WebInspector.panels.elements.updateModifiedNodes();
+                var newNode = WebInspector.domAgent.nodeForId(newNodeId);
+                if (newNode)
+                    this.focusedDOMNode = newNode;
+            }
+            this._nodeBeingDragged.moveTo(parentNode, anchorNode, callback.bind(this));
+        }
+        
+        this._clearDragOverTreeElementMarker();
+        delete this._nodeBeingDragged;
+    },
+
+    _clearDragOverTreeElementMarker: function()
+    {
+        if (this._dragOverTreeElement) {
+            this._dragOverTreeElement.updateSelection();
+            this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over");
+            delete this._dragOverTreeElement;
+        }
+    },
+
     populateContextMenu: function(contextMenu, event)
     {
-        var listItem = event.target.enclosingNodeOrSelfWithNodeName("LI");
-        if (!listItem || !listItem.treeElement)
+        var treeElement = this._treeElementFromEvent(event);
+        if (!treeElement)
             return false;
 
         var populated;
         if (this.showInElementsPanelEnabled) {
             function focusElement()
             {
-                WebInspector.panels.elements.switchToAndFocus(listItem.treeElement.representedObject);
+                WebInspector.panels.elements.switchToAndFocus(treeElement.representedObject);
             }
             contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
             populated = true;
@@ -278,15 +408,15 @@
             var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
             if (href)
                 populated = WebInspector.panels.elements.populateHrefContextMenu(contextMenu, event, href);
-            if (tag && listItem.treeElement._populateTagContextMenu) {
+            if (tag && treeElement._populateTagContextMenu) {
                 if (populated)
                     contextMenu.appendSeparator();
-                listItem.treeElement._populateTagContextMenu(contextMenu, event);
+                treeElement._populateTagContextMenu(contextMenu, event);
                 populated = true;
-            } else if (textNode && listItem.treeElement._populateTextContextMenu) {
+            } else if (textNode && treeElement._populateTextContextMenu) {
                 if (populated)
                     contextMenu.appendSeparator();
-                listItem.treeElement._populateTextContextMenu(contextMenu, textNode);
+                treeElement._populateTextContextMenu(contextMenu, textNode);
                 populated = true;
             }
         }
@@ -508,8 +638,8 @@
         }
 
         this.updateTitle();
-
         this._preventFollowingLinksOnDoubleClick();
+        this.listItemElement.draggable = true;
     },
 
     _preventFollowingLinksOnDoubleClick: function()

Modified: trunk/Source/WebCore/inspector/front-end/inspector.css (90459 => 90460)


--- trunk/Source/WebCore/inspector/front-end/inspector.css	2011-07-06 15:25:27 UTC (rev 90459)
+++ trunk/Source/WebCore/inspector/front-end/inspector.css	2011-07-06 15:25:40 UTC (rev 90460)
@@ -1221,6 +1221,12 @@
     background-color: rgb(212, 212, 212);
 }
 
+.outline-disclosure li.elements-drag-over .selection {
+    display: block;
+    margin-top: -2px;
+    border-top: 2px solid rgb(56, 121, 217);
+}
+
 .outline-disclosure ol:focus li.selected .selection {
     background-color: rgb(56, 121, 217);
 }
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to