2011-05-16 Pavel Feldman <pfeldman@chromium.org>
authorpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 May 2011 12:00:10 +0000 (12:00 +0000)
committerpfeldman@chromium.org <pfeldman@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 May 2011 12:00:10 +0000 (12:00 +0000)
        Reviewed by Yury Semikhatsky.

        Web Inspector: parse edited attributes by means of InspectorDOMAgent.
        https://bugs.webkit.org/show_bug.cgi?id=60807

        This change moves attribute parsing from the front-end to the backend.

        * inspector/InspectorDOMAgent.cpp:
        (WebCore::InspectorDOMAgent::setAttribute):
        * inspector/front-end/DOMAgent.js:
        (WebInspector.DOMNode.prototype.setAttribute):
        * inspector/front-end/ElementsTreeOutline.js:
        (WebInspector.ElementsTreeElement.prototype._attributeEditingCommitted.moveToNextAttributeIfNeeded):
        (WebInspector.ElementsTreeElement.prototype._attributeEditingCommitted):

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

LayoutTests/http/tests/inspector/change-iframe-src.html
Source/WebCore/ChangeLog
Source/WebCore/inspector/InspectorDOMAgent.cpp
Source/WebCore/inspector/front-end/DOMAgent.js
Source/WebCore/inspector/front-end/ElementsTreeOutline.js

index b2ee8ee..9edad9a 100644 (file)
@@ -20,7 +20,7 @@ function test()
 
     function step1(node)
     {
-        node.setAttribute("src", "http://localhost:8000/inspector/resources/iframe-from-different-domain-data.html");
+        node.setAttribute("src", "src=\"http://localhost:8000/inspector/resources/iframe-from-different-domain-data.html\"");
         InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "addMessage", step2);
     }
 
index d5d7450..ae73c63 100644 (file)
@@ -1,3 +1,20 @@
+2011-05-16  Pavel Feldman  <pfeldman@chromium.org>
+
+        Reviewed by Yury Semikhatsky.
+
+        Web Inspector: parse edited attributes by means of InspectorDOMAgent.
+        https://bugs.webkit.org/show_bug.cgi?id=60807
+
+        This change moves attribute parsing from the front-end to the backend. 
+
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::setAttribute):
+        * inspector/front-end/DOMAgent.js:
+        (WebInspector.DOMNode.prototype.setAttribute):
+        * inspector/front-end/ElementsTreeOutline.js:
+        (WebInspector.ElementsTreeElement.prototype._attributeEditingCommitted.moveToNextAttributeIfNeeded):
+        (WebInspector.ElementsTreeElement.prototype._attributeEditingCommitted):
+
 2011-05-16  Nikolas Zimmermann  <nzimmermann@rim.com>
 
         Not reviewed.
index 3cb369d..cda5810 100644 (file)
@@ -574,11 +574,48 @@ int InspectorDOMAgent::boundNodeId(Node* node)
 void InspectorDOMAgent::setAttribute(ErrorString* errorString, int elementId, const String& name, const String& value)
 {
     Element* element = assertElement(errorString, elementId);
-    if (element) {
-        ExceptionCode ec = 0;
-        element->setAttribute(name, value, ec);
+    if (!element)
+        return;
+
+    ExceptionCode ec = 0;
+    RefPtr<Element> parsedElement = element->document()->createElement("span", ec);
+    if (ec) {
+        *errorString = "Internal error: could not set attribute value.";
+        return;
+    }
+
+    toHTMLElement(parsedElement.get())->setInnerHTML("<span " + value + "></span>", ec);
+    if (ec) {
+        *errorString = "Could not parse value as attributes.";
+        return;
+    }
+
+    const NamedNodeMap* attrMap = toHTMLElement(parsedElement->firstChild())->attributes(true);
+    if (!attrMap) {
+        element->removeAttribute(name, ec);
         if (ec)
-            *errorString = "Exception while setting attribute value";
+            *errorString = "Could not remove attribute.";
+        return;
+    }
+
+    bool foundOriginalAttribute = false;
+    unsigned numAttrs = attrMap->length();
+    for (unsigned i = 0; i < numAttrs; ++i) {
+        // Add attribute pair
+        const Attribute *attribute = attrMap->attributeItem(i);
+        foundOriginalAttribute = foundOriginalAttribute || attribute->name().toString() == name;
+        element->setAttribute(attribute->name(), attribute->value(), ec);
+        if (ec) {
+            *errorString = "Internal error: could not set attribute value.";
+            return;
+        }
+    }
+
+    if (!foundOriginalAttribute) {
+        element->removeAttribute(name, ec);
+        if (ec)
+            *errorString = "Could not remove attribute.";
+        return;
     }
 }
 
index 3deef72..25ad810 100644 (file)
@@ -135,20 +135,7 @@ WebInspector.DOMNode.prototype = {
 
     setAttribute: function(name, value, callback)
     {
-        function mycallback(error)
-        {
-            if (!error) {
-                var attr = this._attributesMap[name];
-                if (attr)
-                    attr.value = value;
-                else
-                    attr = this._addAttribute(name, value);
-            }
-
-            if (callback)
-                callback();
-        }
-        DOMAgent.setAttribute(this.id, name, value, mycallback.bind(this));
+        DOMAgent.setAttribute(this.id, name, value, callback);
     },
 
     attributes: function()
index 6f2af65..4b90ddb 100644 (file)
@@ -1026,100 +1026,50 @@ WebInspector.ElementsTreeElement.prototype = {
     {
         delete this._editing;
 
-        // Before we do anything, determine where we should move
-        // next based on the current element's settings
-        var moveToAttribute, moveToTagName, moveToNewAttribute;
-        if (moveDirection) {
-            var found = false;
+        function moveToNextAttributeIfNeeded(error)
+        {
+            WebInspector.panels.elements.updateModifiedNodes();
 
             // Search for the attribute's position, and then decide where to move to.
             var attributes = this.representedObject.attributes();
             for (var i = 0; i < attributes.length; ++i) {
-                if (attributes[i].name === attributeName) {
-                    found = true;
-                    if (moveDirection === "backward") {
-                        if (i === 0)
-                            moveToTagName = true;
-                        else
-                            moveToAttribute = attributes[i - 1].name;
-                    } else if (moveDirection === "forward") {
-                        if (i === attributes.length - 1)
-                            moveToNewAttribute = true;
-                        else
-                            moveToAttribute = attributes[i + 1].name;
-                    }
+                if (attributes[i].name !== attributeName)
+                    continue;
+                    
+                if (moveDirection === "backward") {
+                    if (i === 0)
+                        this._startEditingTagName();
+                    else
+                        this._triggerEditAttribute(attributes[i - 1].name);
+                } else {
+                    if (i === attributes.length - 1)
+                        this._addNewAttribute();
+                    else
+                        this._triggerEditAttribute(attributes[i + 1].name);
                 }
+                return;
             }
 
             // Moving From the "New Attribute" position.
-            if (!found) {
-                if (moveDirection === "backward" && attributes.length > 0)
-                    moveToAttribute = attributes[attributes.length - 1].name;
-                else if (moveDirection === "forward") {
-                    if (!/^\s*$/.test(newText))
-                        moveToNewAttribute = true;
-                    else
-                        moveToTagName = true;
+            if (moveDirection === "backward") {
+                if (newText === " ") {
+                    // Moving from "New Attribute" that was not edited
+                    if (attributes.length > 0)
+                        this._triggerEditAttribute(attributes[attributes.length - 1].name);
+                } else {
+                    // Moving from "New Attribute" that holds new value
+                    if (attributes.length > 1)
+                        this._triggerEditAttribute(attributes[attributes.length - 2].name);
                 }
+            } else if (moveDirection === "forward") {
+                if (!/^\s*$/.test(newText))
+                    this._addNewAttribute();
+                else
+                    this._startEditingTagName();
             }
         }
 
-        function moveToNextAttributeIfNeeded()
-        {
-            // Cleanup empty new attribute sections.
-            if (element.textContent.trim().length === 0)
-                element.parentNode.removeChild(element);
-
-            // Make the move.
-            if (moveToAttribute)
-                this._triggerEditAttribute(moveToAttribute);
-            else if (moveToNewAttribute)
-                this._addNewAttribute();
-            else if (moveToTagName)
-                this._startEditingTagName();
-        }
-
-        function regenerateStyledAttribute(name, value)
-        {
-            var previous = element.previousSibling;
-            if (!previous || previous.nodeType !== Node.TEXT_NODE)
-                element.parentNode.insertBefore(document.createTextNode(" "), element);
-            element.outerHTML = this._attributeHTML(name, value);
-        }
-
-        var parseContainerElement = document.createElement("span");
-        parseContainerElement.innerHTML = "<span " + newText + "></span>";
-        var parseElement = parseContainerElement.firstChild;
-
-        if (!parseElement) {
-            this._editingCancelled(element, attributeName);
-            moveToNextAttributeIfNeeded.call(this);
-            return;
-        }
-
-        if (!parseElement.hasAttributes()) {
-            this.representedObject.removeAttribute(attributeName, this.updateTitle.bind(this));
-            this.treeOutline.focusedNodeChanged(true);
-            moveToNextAttributeIfNeeded.call(this);
-            return;
-        }
-
-        var foundOriginalAttribute = false;
-        for (var i = 0; i < parseElement.attributes.length; ++i) {
-            var attr = parseElement.attributes[i];
-            foundOriginalAttribute = foundOriginalAttribute || attr.name === attributeName;
-            try {
-                this.representedObject.setAttribute(attr.name, attr.value, this.updateTitle.bind(this));
-                regenerateStyledAttribute.call(this, attr.name, attr.value);
-            } catch(e) {} // ignore invalid attribute (innerHTML doesn't throw errors, but this can)
-        }
-
-        if (!foundOriginalAttribute)
-            this.representedObject.removeAttribute(attributeName, this.updateTitle.bind(this));
-
-        this.treeOutline.focusedNodeChanged(true);
-
-        moveToNextAttributeIfNeeded.call(this);
+        this.representedObject.setAttribute(attributeName, newText, moveDirection ? moveToNextAttributeIfNeeded.bind(this) : undefined);
     },
 
     _tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)