Commit 6cc49d07 authored by pfeldman@chromium.org's avatar pfeldman@chromium.org
Browse files

2009-12-02 Pavel Feldman <pfeldman@dhcp-172-28-174-220.spb.corp.google.com>

        Reviewed by Timothy Hatcher.

        Web Inspector: DOM tree selection disappears upon page refresh.

        https://bugs.webkit.org/show_bug.cgi?id=31142

        Test: inspector/elements-panel-selection-on-refresh.html

        * inspector/InjectedScriptHost.cpp:
        (WebCore::InjectedScriptHost::pushNodeByPathToFrontend):
        * inspector/InjectedScriptHost.h:
        * inspector/InjectedScriptHost.idl:
        * inspector/InspectorBackend.h:
        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::close):
        (WebCore::InspectorController::releaseDOMAgent):
        (WebCore::InspectorController::resetScriptObjects):
        * inspector/InspectorDOMAgent.cpp:
        (WebCore::InspectorDOMAgent::~InspectorDOMAgent):
        (WebCore::InspectorDOMAgent::reset):
        (WebCore::InspectorDOMAgent::setDocument):
        (WebCore::InspectorDOMAgent::pushDocumentToFrontend):
        (WebCore::InspectorDOMAgent::nodeForPath):
        (WebCore::InspectorDOMAgent::pushNodePathToFrontend):
        * inspector/InspectorDOMAgent.h:
        * inspector/front-end/DOMAgent.js:
        (WebInspector.DOMNode.prototype._renumber):
        (WebInspector.DOMAgent.prototype._setDocument):
        * inspector/front-end/ElementsPanel.js:
        (WebInspector.ElementsPanel.prototype.reset):
        (WebInspector.ElementsPanel.prototype.setDocument.selectDefaultNode):
        (WebInspector.ElementsPanel.prototype.setDocument.selectLastSelectedNode):
        (WebInspector.ElementsPanel.prototype.setDocument):
        * inspector/front-end/InjectedScript.js:
        (InjectedScript.pushNodeByPathToFrontend):
        * inspector/front-end/InjectedScriptAccess.js:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@51601 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent d140c858
2009-12-02 Pavel Feldman <pfeldman@dhcp-172-28-174-220.spb.corp.google.com>
Reviewed by Timothy Hatcher.
Web Inspector: DOM tree selection disappears upon page refresh.
https://bugs.webkit.org/show_bug.cgi?id=31142
* inspector/elements-panel-selection-on-refresh-expected.txt: Added.
* inspector/elements-panel-selection-on-refresh.html: Added.
2009-12-02 Csaba Osztrogonác <ossy@webkit.org>
 
[Qt] r51577 made fast/frames/sandboxed-iframe-plugins.html crash.
Tests that elements panel preserves selected node on page refresh.
Selected element should be 'P', was: 'P'
<html>
<head>
<script src="inspector-test.js"></script>
<script src="elements-tests.js"></script>
<script>
function doit()
{
function callback(result)
{
if (result === "reload")
window.location.reload();
else {
output("Selected element should be 'P', was: '" + result + "'");
notifyDone();
}
}
evaluateInWebInspector("frontend_selectElement", callback);
}
// Frontend functions.
function frontend_selectElement(testController)
{
if (window.refreshCalled) {
// We should have "test-topic" element selected after refresh.
var selectedElement = WebInspector.panels.elements.treeOutline.selectedTreeElement;
return selectedElement ? selectedElement.representedObject.nodeName : "null";
} else {
// Select the "test-topic" element.
testController.waitUntilDone();
frontend_expandDOMSubtree(WebInspector.domAgent.document);
testController.runAfterPendingDispatches(function() {
frontend_selectElementContinuation(testController);
});
}
}
function frontend_selectElementContinuation(testController)
{
var innerMapping = WebInspector.domAgent._idToDOMNode;
for (var nodeId in innerMapping) {
var node = innerMapping[nodeId];
if (node.nodeName === "P" && node.getAttribute("id") === "test-topic") {
WebInspector.panels.elements.treeOutline.revealAndSelectNode(node);
window.refreshCalled = true;
testController.notifyDone("reload");
return;
}
}
testController.notifyDone("FAIL");
}
</script>
</head>
<body onload="onload()">
<p id="test-topic">
Tests that elements panel preserves selected node on page refresh.
</p>
</body>
</html>
2009-12-02 Pavel Feldman <pfeldman@dhcp-172-28-174-220.spb.corp.google.com>
Reviewed by Timothy Hatcher.
Web Inspector: DOM tree selection disappears upon page refresh.
https://bugs.webkit.org/show_bug.cgi?id=31142
Test: inspector/elements-panel-selection-on-refresh.html
* inspector/InjectedScriptHost.cpp:
(WebCore::InjectedScriptHost::pushNodeByPathToFrontend):
* inspector/InjectedScriptHost.h:
* inspector/InjectedScriptHost.idl:
* inspector/InspectorBackend.h:
* inspector/InspectorController.cpp:
(WebCore::InspectorController::close):
(WebCore::InspectorController::releaseDOMAgent):
(WebCore::InspectorController::resetScriptObjects):
* inspector/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::~InspectorDOMAgent):
(WebCore::InspectorDOMAgent::reset):
(WebCore::InspectorDOMAgent::setDocument):
(WebCore::InspectorDOMAgent::pushDocumentToFrontend):
(WebCore::InspectorDOMAgent::nodeForPath):
(WebCore::InspectorDOMAgent::pushNodePathToFrontend):
* inspector/InspectorDOMAgent.h:
* inspector/front-end/DOMAgent.js:
(WebInspector.DOMNode.prototype._renumber):
(WebInspector.DOMAgent.prototype._setDocument):
* inspector/front-end/ElementsPanel.js:
(WebInspector.ElementsPanel.prototype.reset):
(WebInspector.ElementsPanel.prototype.setDocument.selectDefaultNode):
(WebInspector.ElementsPanel.prototype.setDocument.selectLastSelectedNode):
(WebInspector.ElementsPanel.prototype.setDocument):
* inspector/front-end/InjectedScript.js:
(InjectedScript.pushNodeByPathToFrontend):
* inspector/front-end/InjectedScriptAccess.js:
2009-12-01 Dave Hyatt <hyatt@apple.com>
 
Reviewed by Dan Bernstein.
......@@ -123,6 +123,19 @@ void InjectedScriptHost::addNodesToSearchResult(const String& nodeIds)
frontend->addNodesToSearchResult(nodeIds);
}
long InjectedScriptHost::pushNodeByPathToFrontend(const String& path)
{
InspectorDOMAgent* domAgent = inspectorDOMAgent();
if (!domAgent)
return 0;
Node* node = domAgent->nodeForPath(path);
if (!node)
return 0;
return domAgent->pushNodePathToFrontend(node);
}
#if ENABLE(JAVASCRIPT_DEBUGGER)
JavaScriptCallFrame* InjectedScriptHost::currentCallFrame() const
{
......
......@@ -63,7 +63,10 @@ public:
ScriptValue wrapObject(const ScriptValue& object, const String& objectGroup);
ScriptValue unwrapObject(const String& objectId);
long pushNodePathToFrontend(Node* node, bool selectInUI);
void addNodesToSearchResult(const String& nodeIds);
long pushNodeByPathToFrontend(const String& path);
#if ENABLE(JAVASCRIPT_DEBUGGER)
JavaScriptCallFrame* currentCallFrame() const;
#endif
......
......@@ -41,7 +41,9 @@ module core {
[Custom] long wrapObject(in DOMObject object, in DOMString objectGroup);
[Custom] DOMObject unwrapObject(in long objectId);
[Custom] int pushNodePathToFrontend(in DOMObject node, in boolean selectInUI);
void addNodesToSearchResult(in DOMString nodeIds);
long pushNodeByPathToFrontend(in DOMString path);
#if defined(ENABLE_JAVASCRIPT_DEBUGGER) && ENABLE_JAVASCRIPT_DEBUGGER
[Custom] DOMObject currentCallFrame();
......
......@@ -624,9 +624,9 @@ void InspectorController::close()
#endif
closeWindow();
m_frontend.set(0);
m_injectedScriptObj = ScriptObject();
releaseDOMAgent();
m_frontend.set(0);
m_timelineAgent = 0;
m_scriptState = 0;
if (m_page) {
......@@ -664,7 +664,7 @@ void InspectorController::releaseDOMAgent()
// m_domAgent is RefPtr. Remove DOM listeners first to ensure that there are
// no references to the DOM agent from the DOM tree.
if (m_domAgent)
m_domAgent->setDocument(0);
m_domAgent->reset();
m_domAgent = 0;
}
......@@ -727,7 +727,7 @@ void InspectorController::resetScriptObjects()
m_timelineAgent->reset();
m_frontend->reset();
m_domAgent->setDocument(0);
m_domAgent->reset();
m_objectGroups.clear();
m_idToWrappedObject.clear();
}
......
......@@ -68,13 +68,11 @@ InspectorDOMAgent::InspectorDOMAgent(InspectorFrontend* frontend)
InspectorDOMAgent::~InspectorDOMAgent()
{
setDocument(0);
reset();
}
void InspectorDOMAgent::setDocument(Document* doc)
void InspectorDOMAgent::reset()
{
if (doc == mainFrameDocument())
return;
discardBindings();
ListHashSet<RefPtr<Document> > copy = m_documents;
......@@ -82,13 +80,21 @@ void InspectorDOMAgent::setDocument(Document* doc)
stopListening((*it).get());
ASSERT(!m_documents.size());
}
void InspectorDOMAgent::setDocument(Document* doc)
{
if (doc == mainFrameDocument())
return;
reset();
if (doc) {
startListening(doc);
if (doc->documentElement()) {
if (doc->documentElement())
pushDocumentToFrontend();
}
}
} else
m_frontend->setDocument(ScriptObject());
}
void InspectorDOMAgent::releaseDanglingNodes()
......@@ -239,11 +245,14 @@ void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
}
}
void InspectorDOMAgent::pushDocumentToFrontend()
bool InspectorDOMAgent::pushDocumentToFrontend()
{
Document* document = mainFrameDocument();
if (!document)
return false;
if (!m_documentNodeToIdMap.contains(document))
m_frontend->setDocument(buildObjectForNode(document, 2, &m_documentNodeToIdMap));
return true;
}
void InspectorDOMAgent::pushChildNodesToFrontend(long nodeId)
......@@ -279,6 +288,35 @@ Node* InspectorDOMAgent::nodeForId(long id)
return 0;
}
Node* InspectorDOMAgent::nodeForPath(const String& path)
{
// The path is of form "1,HTML,2,BODY,1,DIV"
Node* node = mainFrameDocument();
if (!node)
return 0;
Vector<String> pathTokens;
path.split(",", false, pathTokens);
for (size_t i = 0; i < pathTokens.size() - 1; i += 2) {
bool success = true;
unsigned childNumber = pathTokens[i].toUInt(&success);
if (!success)
return 0;
if (childNumber >= innerChildNodeCount(node))
return 0;
Node* child = innerFirstChild(node);
String childName = pathTokens[i + 1];
for (size_t j = 0; child && j < childNumber; ++j)
child = innerNextSibling(child);
if (!child || child->nodeName() != childName)
return 0;
node = child;
}
return node;
}
void InspectorDOMAgent::getChildNodes(long callId, long nodeId)
{
pushChildNodesToFrontend(nodeId);
......@@ -290,7 +328,8 @@ long InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
ASSERT(nodeToPush); // Invalid input
// If we are sending information to the client that is currently being created. Send root node first.
pushDocumentToFrontend();
if (!pushDocumentToFrontend())
return 0;
// Return id in case the node is known.
long result = m_documentNodeToIdMap.get(nodeToPush);
......@@ -570,9 +609,9 @@ Node* InspectorDOMAgent::innerPreviousSibling(Node* node)
return node;
}
int InspectorDOMAgent::innerChildNodeCount(Node* node)
unsigned InspectorDOMAgent::innerChildNodeCount(Node* node)
{
int count = 0;
unsigned count = 0;
Node* child = innerFirstChild(node);
while (child) {
count++;
......
......@@ -83,6 +83,8 @@ namespace WebCore {
InspectorDOMAgent(InspectorFrontend* frontend);
~InspectorDOMAgent();
void reset();
virtual bool operator==(const EventListener& other);
// Methods called from the frontend.
......@@ -97,6 +99,7 @@ namespace WebCore {
void releaseDanglingNodes();
Node* nodeForId(long nodeId);
Node* nodeForPath(const String& path);
long pushNodePathToFrontend(Node* node);
private:
......@@ -109,7 +112,7 @@ namespace WebCore {
long bind(Node* node, NodeToIdMap* nodesMap);
void unbind(Node* node, NodeToIdMap* nodesMap);
void pushDocumentToFrontend();
bool pushDocumentToFrontend();
void pushChildNodesToFrontend(long nodeId);
ScriptObject buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap);
......@@ -123,7 +126,7 @@ namespace WebCore {
Node* innerFirstChild(Node* node);
Node* innerNextSibling(Node* node);
Node* innerPreviousSibling(Node* node);
int innerChildNodeCount(Node* node);
unsigned innerChildNodeCount(Node* node);
Node* innerParentNode(Node* node);
bool isWhitespace(Node* node);
......
......@@ -179,6 +179,7 @@ WebInspector.DOMNode.prototype = {
this.lastChild = this.children[this._childNodeCount - 1];
for (var i = 0; i < this._childNodeCount; ++i) {
var child = this.children[i];
child.index = i;
child.nextSibling = i + 1 < this._childNodeCount ? this.children[i + 1] : null;
child.prevSibling = i - 1 >= 0 ? this.children[i - 1] : null;
child.parentNode = this;
......@@ -373,13 +374,13 @@ WebInspector.DOMAgent.prototype = {
_setDocument: function(payload)
{
this._idToDOMNode = {};
if (payload) {
if (payload && "id" in payload) {
this.document = new WebInspector.DOMDocument(this, this._window, payload);
this._idToDOMNode[payload.id] = this.document;
this._bindNodes(this.document.children);
} else
this.document = null;
WebInspector.panels.elements.reset();
WebInspector.panels.elements.setDocument(this.document);
},
_setDetachedRoot: function(payload)
......
......@@ -164,6 +164,17 @@ WebInspector.ElementsPanel.prototype = {
reset: function()
{
if (this.focusedDOMNode) {
this._selectedPathOnReset = [];
var node = this.focusedDOMNode;
while ("index" in node) {
this._selectedPathOnReset.push(node.nodeName);
this._selectedPathOnReset.push(node.index);
node = node.parentNode;
}
this._selectedPathOnReset.reverse();
}
this.rootDOMNode = null;
this.focusedDOMNode = null;
......@@ -178,26 +189,52 @@ WebInspector.ElementsPanel.prototype = {
delete this.currentQuery;
this.searchCanceled();
},
var domWindow = WebInspector.domAgent.domWindow;
if (!domWindow || !domWindow.document || !domWindow.document.firstChild)
setDocument: function(inspectedRootDocument)
{
this.reset();
if (!inspectedRootDocument)
return;
var inspectedRootDocument = domWindow.document;
inspectedRootDocument.addEventListener("DOMNodeInserted", this._nodeInserted.bind(this));
inspectedRootDocument.addEventListener("DOMNodeRemoved", this._nodeRemoved.bind(this));
this.treeOutline.suppressSelectHighlight = true;
this.rootDOMNode = inspectedRootDocument;
this.treeOutline.suppressSelectHighlight = false;
var canidateFocusNode = inspectedRootDocument.body || inspectedRootDocument.documentElement;
if (canidateFocusNode) {
this.focusedDOMNode = canidateFocusNode;
function selectDefaultNode()
{
this.treeOutline.suppressSelectHighlight = true;
var candidateFocusNode = inspectedRootDocument.body || inspectedRootDocument.documentElement;
if (candidateFocusNode) {
this.focusedDOMNode = candidateFocusNode;
if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.expand();
if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.expand();
}
}
this.treeOutline.suppressSelectHighlight = false;
function selectLastSelectedNode(nodeId)
{
var node = nodeId ? WebInspector.domAgent.nodeForId(nodeId) : 0;
if (!node) {
selectDefaultNode.call(this);
return;
}
this.treeOutline.suppressSelectHighlight = true;
this.focusedDOMNode = node;
this.treeOutline.suppressSelectHighlight = false;
}
if (this._selectedPathOnReset)
InjectedScriptAccess.nodeByPath(this._selectedPathOnReset, selectLastSelectedNode.bind(this));
else
selectDefaultNode.call(this);
delete this._selectedPathOnReset;
},
searchCanceled: function()
......
......@@ -1050,6 +1050,13 @@ InjectedScript.pushNodeToFrontend = function(objectProxy)
return InjectedScriptHost.pushNodePathToFrontend(object, false);
}
InjectedScript.nodeByPath = function(path)
{
// We make this call through the injected script only to get a nice
// callback for it.
return InjectedScriptHost.pushNodeByPathToFrontend(path.join(","));
}
// Called from within InspectorController on the 'inspected page' side.
InjectedScript.createProxyObject = function(object, objectId, abbreviate)
{
......
......@@ -70,6 +70,7 @@ InjectedScriptAccess._installHandler("getStyles");
InjectedScriptAccess._installHandler("openInInspectedWindow");
InjectedScriptAccess._installHandler("performSearch");
InjectedScriptAccess._installHandler("pushNodeToFrontend");
InjectedScriptAccess._installHandler("nodeByPath");
InjectedScriptAccess._installHandler("searchCanceled");
InjectedScriptAccess._installHandler("setPropertyValue");
InjectedScriptAccess._installHandler("setStyleProperty");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment