Commit 5aef1877 authored by achicu@adobe.com's avatar achicu@adobe.com

Web Inspector: ContentFlowTreeContentView should use only one DOMTreeOutline

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

Reviewed by Timothy Hatcher.

Changed ContentFlowTreeContentView to use one DOMTreeOutline by just
populating it with root DOMTreeElements directly. That is very
similar to how DOMTreeOutline works when omitRootDOMNode is used.

Now that ContentFlowTreeContentView has only one DOMTreeOutline,
it makes sense to change its base class to be DOMTreeContentView instead.
Also, with that I've changed its name to ContentFlowDOMTreeContentView.

I had to move all the DOMTree document loading code from DOMTreeContentView to a
new class called FrameDOMTreeContentView. This is used to display the DOM of the
frame objects. FrameDOMTreeContentView is also inheriting from DOMTreeContentView.

Issues that are fixed as a side effect:
- Selection path components are now displaying all the sibling elements for contentFlow.contentNodes
(those are the nodes that have "-webkit-flow-into" set directly).
- Keyboard navigation works for the contentFlow.contentNodes.
- Search is implemented in DOMTreeContentView, so that code now works for flows too.
The DOMAgents's search API will use all the Documents to lookup for nodes, so it might
find DOM nodes that are not part of the flow. This is in line with the behavior for the
frames.

* UserInterface/ContentFlowDOMTreeContentView.js: Renamed from ContentFlowTreeContentView
to better reflect the inheritance from DOMTreeContentView.
(WebInspector.ContentFlowDOMTreeContentView):
(WebInspector.ContentFlowDOMTreeContentView.prototype.closed):
(WebInspector.ContentFlowDOMTreeContentView.prototype._createContentTrees):
(WebInspector.ContentFlowDOMTreeContentView.prototype._contentNodeWasAdded):
(WebInspector.ContentFlowDOMTreeContentView.prototype._contentNodeWasRemoved):
* UserInterface/ContentView.js:
(WebInspector.ContentView):
* UserInterface/DOMTreeContentView.js:
(WebInspector.DOMTreeContentView):
(WebInspector.DOMTreeContentView.prototype.closed):
(WebInspector.DOMTreeContentView.prototype.):
(WebInspector.DOMTreeContentView.prototype._restoreSelectedNodeAfterUpdate):
(WebInspector.DOMTreeContentView.prototype._selectedNodeDidChange):
* UserInterface/FrameDOMTreeContentView.js: Added.
(WebInspector.FrameDOMTreeContentView):
(WebInspector.FrameDOMTreeContentView.prototype.get domTree):
(WebInspector.FrameDOMTreeContentView.prototype.closed):
(WebInspector.FrameDOMTreeContentView.prototype._rootDOMNodeAvailable):
(WebInspector.FrameDOMTreeContentView.prototype._rootDOMNodeInvalidated):
(WebInspector.FrameDOMTreeContentView.prototype._requestRootDOMNode):
* UserInterface/Main.html:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159151 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e96ebafe
2013-11-12 Alexandru Chiculita <achicu@adobe.com>
Web Inspector: ContentFlowTreeContentView should use only one DOMTreeOutline
https://bugs.webkit.org/show_bug.cgi?id=124230
Reviewed by Timothy Hatcher.
Changed ContentFlowTreeContentView to use one DOMTreeOutline by just
populating it with root DOMTreeElements directly. That is very
similar to how DOMTreeOutline works when omitRootDOMNode is used.
Now that ContentFlowTreeContentView has only one DOMTreeOutline,
it makes sense to change its base class to be DOMTreeContentView instead.
Also, with that I've changed its name to ContentFlowDOMTreeContentView.
I had to move all the DOMTree document loading code from DOMTreeContentView to a
new class called FrameDOMTreeContentView. This is used to display the DOM of the
frame objects. FrameDOMTreeContentView is also inheriting from DOMTreeContentView.
Issues that are fixed as a side effect:
- Selection path components are now displaying all the sibling elements for contentFlow.contentNodes
(those are the nodes that have "-webkit-flow-into" set directly).
- Keyboard navigation works for the contentFlow.contentNodes.
- Search is implemented in DOMTreeContentView, so that code now works for flows too.
The DOMAgents's search API will use all the Documents to lookup for nodes, so it might
find DOM nodes that are not part of the flow. This is in line with the behavior for the
frames.
* UserInterface/ContentFlowDOMTreeContentView.js: Renamed from ContentFlowTreeContentView
to better reflect the inheritance from DOMTreeContentView.
(WebInspector.ContentFlowDOMTreeContentView):
(WebInspector.ContentFlowDOMTreeContentView.prototype.closed):
(WebInspector.ContentFlowDOMTreeContentView.prototype._createContentTrees):
(WebInspector.ContentFlowDOMTreeContentView.prototype._contentNodeWasAdded):
(WebInspector.ContentFlowDOMTreeContentView.prototype._contentNodeWasRemoved):
* UserInterface/ContentView.js:
(WebInspector.ContentView):
* UserInterface/DOMTreeContentView.js:
(WebInspector.DOMTreeContentView):
(WebInspector.DOMTreeContentView.prototype.closed):
(WebInspector.DOMTreeContentView.prototype.):
(WebInspector.DOMTreeContentView.prototype._restoreSelectedNodeAfterUpdate):
(WebInspector.DOMTreeContentView.prototype._selectedNodeDidChange):
* UserInterface/FrameDOMTreeContentView.js: Added.
(WebInspector.FrameDOMTreeContentView):
(WebInspector.FrameDOMTreeContentView.prototype.get domTree):
(WebInspector.FrameDOMTreeContentView.prototype.closed):
(WebInspector.FrameDOMTreeContentView.prototype._rootDOMNodeAvailable):
(WebInspector.FrameDOMTreeContentView.prototype._rootDOMNodeInvalidated):
(WebInspector.FrameDOMTreeContentView.prototype._requestRootDOMNode):
* UserInterface/Main.html:
2013-11-08 Joseph Pecoraro <pecoraro@apple.com>
Web Inspector: remove -webkit-min and -webkit-max from CSS completions
......
......@@ -27,162 +27,64 @@
* SUCH DAMAGE.
*/
WebInspector.ContentFlowTreeContentView = function(contentFlow)
WebInspector.ContentFlowDOMTreeContentView = function(contentFlow)
{
console.assert(contentFlow);
WebInspector.ContentView.call(this, contentFlow);
this._selectedTreeElement = null;
// Map of contentNode ids to DOMTreeOutline objects.
this._nodesMap = new Map();
this._createContentTrees();
WebInspector.DOMTreeContentView.call(this, contentFlow);
contentFlow.addEventListener(WebInspector.ContentFlow.Event.ContentNodeWasAdded, this._contentNodeWasAdded, this);
contentFlow.addEventListener(WebInspector.ContentFlow.Event.ContentNodeWasRemoved, this._contentNodeWasRemoved, this);
};
WebInspector.ContentFlowTreeContentView.StyleClassName = "content-flow-tree";
this._createContentTrees();
};
WebInspector.ContentFlowTreeContentView.prototype = {
constructor: WebInspector.ContentFlowTreeContentView,
__proto__: WebInspector.ContentView.prototype,
WebInspector.ContentFlowDOMTreeContentView.prototype = {
constructor: WebInspector.ContentFlowDOMTreeContentView,
__proto__: WebInspector.DOMTreeContentView.prototype,
// Public
get selectionPathComponents()
{
var treeElement = this._selectedTreeElement;
var pathComponents = [];
while (treeElement && !treeElement.root) {
// The close tag is contained within the element it closes. So skip it since we don't want to
// show the same node twice in the hierarchy.
if (treeElement.isCloseTag()) {
treeElement = treeElement.parent;
continue;
}
// FIXME: ContentFlow.contentNodes should be linked to each other.
var pathComponent = new WebInspector.DOMTreeElementPathComponent(treeElement, treeElement.representedObject);
pathComponent.addEventListener(WebInspector.HierarchicalPathComponent.Event.SiblingWasSelected, this._pathComponentSelected, this);
pathComponents.unshift(pathComponent);
// Do not display elements outside the ContentFlow.
if (this._nodesMap.has(treeElement.representedObject.id))
break;
treeElement = treeElement.parent;
}
return pathComponents;
},
updateLayout: function()
{
this._nodesMap.forEach(function(node) {
node.updateSelection();
});
},
shown: function()
{
var omitFocus = WebInspector.isConsoleFocused();
this._nodesMap.forEach(function(node) {
node.setVisible(true, omitFocus);
});
},
hidden: function()
{
WebInspector.domTreeManager.hideDOMNodeHighlight();
this._nodesMap.forEach(function(node) {
node.setVisible(false);
});
},
closed: function()
{
this.representedObject.removeEventListener(WebInspector.ContentFlow.Event.ContentNodeWasAdded, this._contentNodeWasAdded, this);
this.representedObject.removeEventListener(WebInspector.ContentFlow.Event.ContentNodeWasRemoved, this._contentNodeWasRemoved, this);
this._nodesMap.forEach(function(node) {
node.close();
});
WebInspector.DOMTreeContentView.prototype.closed.call(this);
},
// Private
_selectedNodeDidChange: function(contentNodeOutline, event)
{
var selectedTreeElement = contentNodeOutline.selectedTreeElement;
if (this._selectedTreeElement === selectedTreeElement)
return;
// Make sure that moving from one tree to the other will deselect the previous element.
if (this._selectedTreeElement && this._selectedTreeElement.treeOutline !== contentNodeOutline)
this._selectedTreeElement.deselect();
this._selectedTreeElement = selectedTreeElement;
if (selectedTreeElement) {
// FIXME: Switching between different ContentFlowTreeContentView or DOMTreeContentView elements should call ConsoleAgent.addInspectedNode.
ConsoleAgent.addInspectedNode(selectedTreeElement.representedObject.id);
}
this.dispatchEventToListeners(WebInspector.ContentView.Event.SelectionPathComponentsDidChange);
},
_pathComponentSelected: function(event)
_createContentTrees: function()
{
console.assert(event.data.pathComponent instanceof WebInspector.DOMTreeElementPathComponent);
console.assert(event.data.pathComponent.domTreeElement instanceof WebInspector.DOMTreeElement);
var contentNodes = this.representedObject.contentNodes;
for (var contentNode of contentNodes)
this.domTreeOutline.appendChild(new WebInspector.DOMTreeElement(contentNode));
var treeElement = event.data.pathComponent.domTreeElement;
treeElement.treeOutline.selectDOMNode(treeElement.representedObject, true);
var documentURL = contentNodes.length ? contentNodes[0].ownerDocument.documentURL : null;
this._restoreSelectedNodeAfterUpdate(documentURL, contentNodes[0]);
},
_createContentNodeTree: function(node)
_contentNodeWasAdded: function(event)
{
console.assert(!this._nodesMap.has(node.id));
// FIXME: DOMTree's should be linked to each other when navigating with keyboard up/down events.
var contentNodeOutline = new WebInspector.DOMTreeOutline(false, true, true);
contentNodeOutline.addEventListener(WebInspector.DOMTreeOutline.Event.SelectedNodeChanged, this._selectedNodeDidChange.bind(this, contentNodeOutline), this);
contentNodeOutline.setVisible(this.visible, WebInspector.isConsoleFocused());
contentNodeOutline.wireToDomAgent();
contentNodeOutline.rootDOMNode = node;
var treeElement = new WebInspector.DOMTreeElement(event.data.node);
if (!event.data.before) {
this.domTreeOutline.appendChild(treeElement);
return;
}
this._nodesMap.set(node.id, contentNodeOutline);
var beforeElement = this.domTreeOutline.findTreeElement(event.data.before);
console.assert(beforeElement);
return contentNodeOutline;
},
var index = this.domTreeOutline.children.indexOf(beforeElement);
console.assert(index !== -1);
_createContentTrees: function()
{
for (var contentNode of this.representedObject.contentNodes) {
var contentNodeOutline = this._createContentNodeTree(contentNode);
this.element.appendChild(contentNodeOutline.element);
}
},
_contentNodeWasAdded: function(event)
{
var treeElement = this._createContentNodeTree(event.data.node);
if (event.data.before) {
var beforeElement = this._nodesMap.get(event.data.before.id);
console.assert(beforeElement);
this.element.insertBefore(treeElement.element, beforeElement.element);
} else
this.element.appendChild(treeElement.element);
this.domTreeOutline.insertChild(treeElement, index);
},
_contentNodeWasRemoved: function(event)
{
var contentNodeOutline = this._nodesMap.get(event.data.node.id);
contentNodeOutline.close();
contentNodeOutline.element.remove();
this._nodesMap.delete(event.data.node.id);
var treeElement = this.domTreeOutline.findTreeElement(event.data.node);
console.assert(treeElement);
this.domTreeOutline.removeChild(treeElement);
}
};
......@@ -55,7 +55,7 @@ WebInspector.ContentView = function(representedObject)
return new WebInspector.ApplicationCacheFrameContentView(representedObject);
if (representedObject instanceof WebInspector.DOMTree)
return new WebInspector.DOMTreeContentView(representedObject);
return new WebInspector.FrameDOMTreeContentView(representedObject);
if (representedObject instanceof WebInspector.LogObject)
return new WebInspector.LogContentView(representedObject);
......@@ -73,7 +73,7 @@ WebInspector.ContentView = function(representedObject)
return new WebInspector.CanvasProfileView(representedObject);
if (representedObject instanceof WebInspector.ContentFlow)
return new WebInspector.ContentFlowTreeContentView(representedObject);
return new WebInspector.ContentFlowDOMTreeContentView(representedObject);
if (typeof representedObject === "string" || representedObject instanceof String)
return new WebInspector.TextContentView(representedObject);
......
......@@ -23,11 +23,11 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.DOMTreeContentView = function(domTree)
WebInspector.DOMTreeContentView = function(representedObject)
{
console.assert(domTree);
console.assert(representedObject);
WebInspector.ContentView.call(this, domTree);
WebInspector.ContentView.call(this, representedObject);
this._compositingBordersButtonNavigationItem = new WebInspector.ActivateButtonNavigationItem("layer-borders", WebInspector.UIString("Show compositing borders"), WebInspector.UIString("Hide compositing borders"), "Images/LayerBorders.svg", 16, 16);
this._compositingBordersButtonNavigationItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._toggleCompositingBorders, this);
......@@ -41,9 +41,6 @@ WebInspector.DOMTreeContentView = function(domTree)
this.element.classList.add(WebInspector.DOMTreeContentView.StyleClassName);
this.element.addEventListener("click", this._mouseWasClicked.bind(this), false);
this._domTree = domTree;
this._domTree.addEventListener(WebInspector.DOMTree.Event.RootDOMNodeInvalidated, this._rootDOMNodeInvalidated, this);
this._domTreeOutline = new WebInspector.DOMTreeOutline(true, true, false);
this._domTreeOutline.addEventListener(WebInspector.DOMTreeOutline.Event.SelectedNodeChanged, this._selectedNodeDidChange, this);
this._domTreeOutline.wireToDomAgent();
......@@ -56,14 +53,13 @@ WebInspector.DOMTreeContentView = function(domTree)
this._lastSelectedNodePathSetting = new WebInspector.Setting("last-selected-node-path", null);
this._numberOfSearchResults = null;
this._requestRootDOMNode();
};
WebInspector.DOMTreeContentView.StyleClassName = "dom-tree";
WebInspector.DOMTreeContentView.prototype = {
constructor: WebInspector.DOMTreeContentView,
__proto__: WebInspector.ContentView.prototype,
// Public
......@@ -72,9 +68,9 @@ WebInspector.DOMTreeContentView.prototype = {
return [this._showsShadowDOMButtonNavigationItem, this._compositingBordersButtonNavigationItem];
},
get domTree()
get domTreeOutline()
{
return this._domTree;
return this._domTreeOutline;
},
get scrollableElements()
......@@ -101,7 +97,6 @@ WebInspector.DOMTreeContentView.prototype = {
closed: function()
{
this._domTree.removeEventListener(null, null, this);
WebInspector.domTreeManager.removeEventListener(null, null, this);
this._domTreeOutline.close();
......@@ -284,20 +279,13 @@ WebInspector.DOMTreeContentView.prototype = {
DOMAgent.getSearchResults(this._searchIdentifier, index, index + 1, revealResult.bind(this));
},
_rootDOMNodeAvailable: function(rootDOMNode)
_restoreSelectedNodeAfterUpdate: function(documentURL, defaultNode)
{
this._domTreeOutline.rootDOMNode = rootDOMNode;
if (!rootDOMNode) {
this._domTreeOutline.selectDOMNode(null, false);
return;
}
function selectNode(lastSelectedNode)
{
var nodeToFocus = lastSelectedNode;
if (!nodeToFocus)
nodeToFocus = rootDOMNode.body || rootDOMNode.documentElement;
nodeToFocus = defaultNode;
if (!nodeToFocus)
return;
......@@ -316,27 +304,17 @@ WebInspector.DOMTreeContentView.prototype = {
selectNode.call(this, WebInspector.domTreeManager.nodeForId(nodeId));
}
if (this._lastSelectedNodePathSetting.value && this._lastSelectedNodePathSetting.value.path && this._lastSelectedNodePathSetting.value.url === this._domTree.frame.url.hash)
if (documentURL && this._lastSelectedNodePathSetting.value && this._lastSelectedNodePathSetting.value.path && this._lastSelectedNodePathSetting.value.url === documentURL.hash)
WebInspector.domTreeManager.pushNodeByPathToFrontend(this._lastSelectedNodePathSetting.value.path, selectLastSelectedNode.bind(this));
else
selectNode.call(this);
},
_rootDOMNodeInvalidated: function(event)
{
this._requestRootDOMNode();
},
_requestRootDOMNode: function()
{
this._domTree.requestRootDOMNode(this._rootDOMNodeAvailable.bind(this));
},
_selectedNodeDidChange: function(event)
{
var selectedDOMNode = this._domTreeOutline.selectedDOMNode();
if (selectedDOMNode && !this._dontSetLastSelectedNodePath)
this._lastSelectedNodePathSetting.value = {url: this._domTree.frame.url.hash, path: selectedDOMNode.path()};
this._lastSelectedNodePathSetting.value = {url: selectedDOMNode.ownerDocument.documentURL.hash, path: selectedDOMNode.path()};
if (selectedDOMNode)
ConsoleAgent.addInspectedNode(selectedDOMNode.id);
......@@ -409,7 +387,7 @@ WebInspector.DOMTreeContentView.prototype = {
this._compositingBordersButtonNavigationItem.activated = activated;
PageAgent.setCompositingBordersVisible(activated);
},
_updateCompositingBordersButtonToMatchPageSettings: function()
{
if (!PageAgent.getCompositingBordersVisible)
......@@ -434,5 +412,3 @@ WebInspector.DOMTreeContentView.prototype = {
WebInspector.showShadowDOMSetting.value = !WebInspector.showShadowDOMSetting.value;
}
};
WebInspector.DOMTreeContentView.prototype.__proto__ = WebInspector.ContentView.prototype;
/*
* Copyright (C) 2013 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
WebInspector.FrameDOMTreeContentView = function(domTree)
{
console.assert(domTree);
WebInspector.DOMTreeContentView.call(this, domTree);
this._domTree = domTree;
this._domTree.addEventListener(WebInspector.DOMTree.Event.RootDOMNodeInvalidated, this._rootDOMNodeInvalidated, this);
this._requestRootDOMNode();
};
WebInspector.FrameDOMTreeContentView.prototype = {
constructor: WebInspector.FrameDOMTreeContentView,
__proto__: WebInspector.DOMTreeContentView.prototype,
// Public
get domTree()
{
return this._domTree;
},
closed: function()
{
this._domTree.removeEventListener(null, null, this);
WebInspector.DOMTreeContentView.prototype.closed.call(this);
},
// Private
_rootDOMNodeAvailable: function(rootDOMNode)
{
this.domTreeOutline.rootDOMNode = rootDOMNode;
if (!rootDOMNode) {
this.domTreeOutline.selectDOMNode(null, false);
return;
}
this._restoreSelectedNodeAfterUpdate(this._domTree.frame.url, rootDOMNode.body || rootDOMNode.documentElement);
},
_rootDOMNodeInvalidated: function(event)
{
this._requestRootDOMNode();
},
_requestRootDOMNode: function()
{
this._domTree.requestRootDOMNode(this._rootDOMNodeAvailable.bind(this));
}
};
......@@ -275,6 +275,7 @@
<script src="DOMTreeElement.js"></script>
<script src="DOMTreeElementPathComponent.js"></script>
<script src="DOMTreeContentView.js"></script>
<script src="FrameDOMTreeContentView.js"></script>
<script src="LayerTreeManager.js"></script>
<script src="DOMSearchMatchObject.js"></script>
<script src="ResourceSearchMatchObject.js"></script>
......@@ -400,7 +401,7 @@
<script src="MIMETypeUtilities.js"></script>
<script src="LoadLocalizedStrings.js"></script>
<script src="GoToLineDialog.js"></script>
<script src="ContentFlowTreeContentView.js"></script>
<script src="ContentFlowDOMTreeContentView.js"></script>
<script src="Main.js"></script>
<script>
......
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