Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / layers / LayerTreeOutline.js
1 /*
2  * Copyright (C) 2013 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 /**
32  * @constructor
33  * @extends {WebInspector.Object}
34  * @param {!TreeOutline} treeOutline
35  */
36 WebInspector.LayerTreeOutline = function(treeOutline)
37 {
38     WebInspector.Object.call(this);
39     this._treeOutline = treeOutline;
40     this._treeOutline.childrenListElement.addEventListener("mousemove", this._onMouseMove.bind(this), false);
41     this._treeOutline.childrenListElement.addEventListener("mouseout", this._onMouseMove.bind(this), false);
42     this._treeOutline.childrenListElement.addEventListener("contextmenu", this._onContextMenu.bind(this), true);
43     this._lastHoveredNode = null;
44 }
45
46 /**
47  * @enum {string}
48  */
49 WebInspector.LayerTreeOutline.Events = {
50     LayerHovered: "LayerHovered",
51     LayerSelected: "LayerSelected"
52 }
53
54 WebInspector.LayerTreeOutline.prototype = {
55     /**
56      * @param {?WebInspector.Layer} layer
57      */
58     selectLayer: function(layer)
59     {
60         this.hoverLayer(null);
61         var node = layer && this._treeOutline.getCachedTreeElement(layer);
62         if (node)
63             node.revealAndSelect(true);
64         else if (this._treeOutline.selectedTreeElement)
65             this._treeOutline.selectedTreeElement.deselect();
66     },
67
68     /**
69      * @param {?WebInspector.Layer} layer
70      */
71     hoverLayer: function(layer)
72     {
73         var node = layer && this._treeOutline.getCachedTreeElement(layer);
74         if (node === this._lastHoveredNode)
75             return;
76         if (this._lastHoveredNode)
77             this._lastHoveredNode.setHovered(false);
78         if (node)
79             node.setHovered(true);
80         this._lastHoveredNode = node;
81     },
82
83     /**
84      * @param {?WebInspector.LayerTreeBase} layerTree
85      */
86     update: function(layerTree)
87     {
88         var seenLayers = new Map();
89
90         /**
91          * @param {!WebInspector.Layer} layer
92          * @this {WebInspector.LayerTreeOutline}
93          */
94         function updateLayer(layer)
95         {
96             if (seenLayers.get(layer))
97                 console.assert(false, "Duplicate layer: " + layer.id());
98             seenLayers.set(layer, true);
99             var node = this._treeOutline.getCachedTreeElement(layer);
100             var parent = layer === layerTree.contentRoot() ? this._treeOutline : this._treeOutline.getCachedTreeElement(layer.parent());
101             if (!parent)
102                 console.assert(false, "Parent is not in the tree");
103             if (!node) {
104                 node = new WebInspector.LayerTreeElement(this, layer);
105                 parent.appendChild(node);
106             } else {
107                 if (node.parent !== parent) {
108                     node.parent.removeChild(node);
109                     parent.appendChild(node);
110                 }
111                 node._update();
112             }
113         }
114         if (layerTree && layerTree.contentRoot())
115             layerTree.forEachLayer(updateLayer.bind(this), layerTree.contentRoot());
116         // Cleanup layers that don't exist anymore from tree.
117         for (var node = /** @type {!TreeElement|!TreeOutline|null} */ (this._treeOutline.children[0]); node && !node.root;) {
118             if (seenLayers.get(node.representedObject)) {
119                 node = node.traverseNextTreeElement(false);
120             } else {
121                 var nextNode = node.nextSibling || node.parent;
122                 node.parent.removeChild(node);
123                 if (node === this._lastHoveredNode)
124                     this._lastHoveredNode = null;
125                 node = nextNode;
126             }
127         }
128     },
129
130     /**
131      * @param {!Event} event
132      */
133     _onMouseMove: function(event)
134     {
135         var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
136         if (node === this._lastHoveredNode)
137             return;
138         this.dispatchEventToListeners(WebInspector.LayerTreeOutline.Events.LayerHovered, node && node.representedObject ? {layer: node.representedObject} : null);
139     },
140
141     /**
142      * @param {!WebInspector.LayerTreeElement} node
143      */
144     _selectedNodeChanged: function(node)
145     {
146         var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
147         this.dispatchEventToListeners(WebInspector.LayerTreeOutline.Events.LayerSelected, {layer: layer});
148     },
149
150     /**
151      * @param {!Event} event
152      */
153     _onContextMenu: function(event)
154     {
155         var node = this._treeOutline.treeElementFromPoint(event.pageX, event.pageY);
156         if (!node || !node.representedObject)
157             return;
158         var layer = /** @type {!WebInspector.Layer} */ (node.representedObject);
159         if (!layer)
160             return;
161         var domNode = layer.nodeForSelfOrAncestor();
162         if (!domNode)
163             return;
164         var contextMenu = new WebInspector.ContextMenu(event);
165         contextMenu.appendApplicableItems(domNode);
166         contextMenu.show();
167     },
168
169     __proto__: WebInspector.Object.prototype
170 }
171
172 /**
173   * @constructor
174   * @param {!WebInspector.LayerTreeOutline} tree
175   * @param {!WebInspector.Layer} layer
176   * @extends {TreeElement}
177   */
178 WebInspector.LayerTreeElement = function(tree, layer)
179 {
180     TreeElement.call(this, "", layer);
181     this._treeOutline = tree;
182     this._update();
183 }
184
185 WebInspector.LayerTreeElement.prototype = {
186     onattach: function()
187     {
188         var selection = document.createElement("div");
189         selection.className = "selection";
190         this.listItemElement.insertBefore(selection, this.listItemElement.firstChild);
191     },
192
193     _update: function()
194     {
195         var layer = /** @type {!WebInspector.Layer} */ (this.representedObject);
196         var node = layer.nodeForSelfOrAncestor();
197         var title = document.createDocumentFragment();
198         title.createChild("div", "selection");
199         title.createTextChild(node ? WebInspector.DOMPresentationUtils.simpleSelector(node) : "#" + layer.id());
200         var details = title.createChild("span", "dimmed");
201         details.textContent = WebInspector.UIString(" (%d × %d)", layer.width(), layer.height());
202         this.title = title;
203     },
204
205     /**
206      * @override
207      * @return {boolean}
208      */
209     onselect: function()
210     {
211         this._treeOutline._selectedNodeChanged(this);
212         return false;
213     },
214
215     /**
216      * @param {boolean} hovered
217      */
218     setHovered: function(hovered)
219     {
220         this.listItemElement.classList.toggle("hovered", hovered);
221     },
222
223     __proto__: TreeElement.prototype
224 }