Modified: trunk/LayoutTests/inspector/elements/edit-dom-actions.html (99400 => 99401)
--- trunk/LayoutTests/inspector/elements/edit-dom-actions.html 2011-11-07 09:26:00 UTC (rev 99400)
+++ trunk/LayoutTests/inspector/elements/edit-dom-actions.html 2011-11-07 09:59:27 UTC (rev 99401)
@@ -18,7 +18,7 @@
function testRemove(next)
{
- domActionTest("testRemove", "node-to-remove", testBody, next);
+ domActionTestForNodeId("testRemove", "node-to-remove", testBody, next);
function testBody(node, done)
{
@@ -30,7 +30,7 @@
function testSetNodeName(next)
{
- domActionTest("testSetNodeName", "node-to-set-name", testBody, next);
+ domActionTestForNodeId("testSetNodeName", "node-to-set-name", testBody, next);
function testBody(node, done)
{
@@ -40,7 +40,7 @@
function testSetNodeNameInput(next)
{
- domActionTest("testSetNodeNameInput", "node-to-set-name-input", testBody, next);
+ domActionTestForNodeId("testSetNodeNameInput", "node-to-set-name-input", testBody, next);
function testBody(node, done)
{
@@ -50,7 +50,7 @@
function testSetNodeValue(next)
{
- domActionTest("testSetNodeValue", "node-to-set-value", testBody, next);
+ domActionTestForNodeId("testSetNodeValue", "node-to-set-value", testBody, next);
function testBody(node, done)
{
@@ -60,7 +60,7 @@
function testSetAttribute(next)
{
- domActionTest("testSetAttribute", "node-to-set-attribute", testBody, next);
+ domActionTestForNodeId("testSetAttribute", "node-to-set-attribute", testBody, next);
function testBody(node, done)
{
@@ -70,7 +70,7 @@
function testRemoveAttribute(next)
{
- domActionTest("testRemoveAttribute", "node-to-remove-attribute", testBody, next);
+ domActionTestForNodeId("testRemoveAttribute", "node-to-remove-attribute", testBody, next);
function testBody(node, done)
{
@@ -80,7 +80,7 @@
function testAddAttribute(next)
{
- domActionTest("testAddAttribute", "node-to-add-attribute", testBody, next);
+ domActionTestForNodeId("testAddAttribute", "node-to-add-attribute", testBody, next);
function testBody(node, done)
{
@@ -99,9 +99,44 @@
}
},
+ function testEditCommentAsHTML(next)
+ {
+ function commentNodeSelectionCallback(testNode, callback)
+ {
+ var childNodes = testNode.children;
+ for (var i = 0; i < childNodes.length; ++i) {
+ if (childNodes[i].nodeType() === 8) {
+ WebInspector.updateFocusedNode(childNodes[i].id);
+ callback(childNodes[i]);
+ return;
+ }
+ }
+ InspectorTest.addResult("Comment node not found");
+ InspectorTest.completeTest();
+ }
+ domActionTest("testEditCommentAsHTML", commentNodeSelectionCallback, testBody, next);
+
+ function testBody(node, done)
+ {
+ var treeElement = WebInspector.panels.elements.treeOutline.findTreeElement(node);
+ treeElement._editAsHTML();
+ InspectorTest.runAfterPendingDispatches(step2);
+
+ function step2()
+ {
+ InspectorTest.addResult(treeElement._htmlEditElement.textContent);
+ treeElement._htmlEditElement.textContent = "<div foo=\"bar-comment\">Element</div>";
+ var event = InspectorTest.createKeyEvent("Enter");
+ event.isMetaOrCtrlForTest = true;
+ treeElement._htmlEditElement.dispatchEvent(event);
+ InspectorTest.runAfterPendingDispatches(done);
+ }
+ }
+ },
+
function testEditAsHTML(next)
{
- domActionTest("testEditAsHTML", "node-to-edit-as-html", testBody, next);
+ domActionTestForNodeId("testEditAsHTML", "node-to-edit-as-html", testBody, next);
function testBody(node, done)
{
@@ -116,19 +151,28 @@
var event = InspectorTest.createKeyEvent("Enter");
event.isMetaOrCtrlForTest = true;
treeElement._htmlEditElement.dispatchEvent(event);
- InspectorTest.runAfterPendingDispatches(done);
+ InspectorTest.runAfterPendingDispatches(InspectorTest.expandElementsTree.bind(InspectorTest, done));
}
}
}
]);
- function domActionTest(testName, dataNode, testBody, next)
+ function domActionTestForNodeId(testName, dataNodeId, testBody, next)
{
+ function callback(testNode, continuation)
+ {
+ InspectorTest.selectNodeWithId(dataNodeId, continuation);
+ }
+ domActionTest(testName, callback, testBody, next);
+ }
+
+ function domActionTest(testName, dataNodeSelectionCallback, testBody, next)
+ {
var testNode = InspectorTest.expandedNodeWithId(testName);
InspectorTest.addResult("==== before ====");
InspectorTest.dumpElementsTree(testNode);
- InspectorTest.selectNodeWithId(dataNode, step0);
+ dataNodeSelectionCallback(testNode, step0);
function step0(node)
{
@@ -208,6 +252,11 @@
<div id="testEditAsHTML">
<div id="node-to-edit-as-html"><span id="span">Text</span></div>
</div>
+
+ <div id="testEditCommentAsHTML">
+ <!-- Comment -->
+ </div>
+
</div>
</body>
</html>
Modified: trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp (99400 => 99401)
--- trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp 2011-11-07 09:26:00 UTC (rev 99400)
+++ trunk/Source/WebCore/inspector/InspectorDOMAgent.cpp 2011-11-07 09:59:27 UTC (rev 99401)
@@ -50,6 +50,7 @@
#include "DOMNodeHighlighter.h"
#include "DOMWindow.h"
#include "Document.h"
+#include "DocumentFragment.h"
#include "DocumentType.h"
#include "Event.h"
#include "EventContext.h"
@@ -738,28 +739,60 @@
void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::String* outerHTML)
{
- HTMLElement* element = assertHTMLElement(errorString, nodeId);
- if (element)
- *outerHTML = element->outerHTML();
+ Node* node = assertNode(errorString, nodeId);
+ if (!node)
+ return;
+
+ if (node->isHTMLElement()) {
+ *outerHTML = static_cast<HTMLElement*>(node)->outerHTML();
+ return;
+ }
+
+ if (node->isCommentNode()) {
+ *outerHTML = "<!--" + node->nodeValue() + "-->";
+ return;
+ }
+
+ if (node->isTextNode()) {
+ *outerHTML = node->nodeValue();
+ return;
+ }
+
+ *errorString = "Only HTMLElements, Comments, and Text nodes are supported";
}
void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML, int* newId)
{
- HTMLElement* htmlElement = assertHTMLElement(errorString, nodeId);
- if (!htmlElement)
+ Node* node = assertNode(errorString, nodeId);
+ if (!node)
return;
- bool requiresTotalUpdate = htmlElement->tagName() == "HTML" || htmlElement->tagName() == "BODY" || htmlElement->tagName() == "HEAD";
+ Element* parentElement = node->parentElement();
+ if (!parentElement)
+ return;
- bool childrenRequested = m_childrenRequested.contains(nodeId);
- Node* previousSibling = htmlElement->previousSibling();
- ContainerNode* parentNode = htmlElement->parentNode();
+ Document* document = node->ownerDocument();
+ if (!document->isHTMLDocument()) {
+ *errorString = "Not an HTML document";
+ return;
+ }
+ Node* previousSibling = node->previousSibling(); // Remember previous sibling before replacing node.
+
+ RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
+ fragment->parseHTML(outerHTML, parentElement);
+
ExceptionCode ec = 0;
- htmlElement->setOuterHTML(outerHTML, ec);
- if (ec)
+ parentElement->replaceChild(fragment.release(), node, ec);
+ if (ec) {
+ *errorString = "Failed to replace Node with new contents";
return;
+ }
+ bool requiresTotalUpdate = false;
+ if (node->isHTMLElement())
+ requiresTotalUpdate = node->nodeName() == "HTML" || node->nodeName() == "BODY" || node->nodeName() == "HEAD";
+
if (requiresTotalUpdate) {
RefPtr<Document> document = m_document;
reset();
@@ -768,7 +801,7 @@
return;
}
- Node* newNode = previousSibling ? previousSibling->nextSibling() : parentNode->firstChild();
+ Node* newNode = previousSibling ? previousSibling->nextSibling() : parentElement->firstChild();
if (!newNode) {
// The only child node has been deleted.
*newId = 0;
@@ -776,6 +809,8 @@
}
*newId = pushNodePathToFrontend(newNode);
+
+ bool childrenRequested = m_childrenRequested.contains(nodeId);
if (childrenRequested)
pushChildNodesToFrontend(*newId);
}
Modified: trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js (99400 => 99401)
--- trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js 2011-11-07 09:26:00 UTC (rev 99400)
+++ trunk/Source/WebCore/inspector/front-end/ElementsTreeOutline.js 2011-11-07 09:59:27 UTC (rev 99401)
@@ -457,6 +457,7 @@
var tag = event.target.enclosingNodeOrSelfWithClass("webkit-html-tag");
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
+ var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
var populated = WebInspector.populateHrefContextMenu(contextMenu, this.selectedDOMNode(), event);
if (tag && treeElement._populateTagContextMenu) {
if (populated)
@@ -468,6 +469,11 @@
contextMenu.appendSeparator();
treeElement._populateTextContextMenu(contextMenu, textNode);
populated = true;
+ } else if (commentNode && treeElement._populateNodeContextMenu) {
+ if (populated)
+ contextMenu.appendSeparator();
+ treeElement._populateNodeContextMenu(contextMenu, textNode);
+ populated = true;
}
return populated;
@@ -1039,19 +1045,24 @@
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
contextMenu.appendSeparator();
- // Add free-form node-related actions.
- contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
- contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
- contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
-
+ this._populateNodeContextMenu(contextMenu);
this.treeOutline._populateContextMenu(contextMenu, this.representedObject);
},
_populateTextContextMenu: function(contextMenu, textNode)
{
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
+ this._populateNodeContextMenu(contextMenu);
},
+ _populateNodeContextMenu: function(contextMenu)
+ {
+ // Add free-form node-related actions.
+ contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
+ contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
+ contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
+ },
+
_startEditing: function()
{
if (this.treeOutline.selectedDOMNode() !== this.representedObject)