2 * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 * OF THE POSSIBILITY OF SUCH DAMAGE.
32 * @extends {WebInspector.SidebarView}
34 WebInspector.CSSNamedFlowCollectionsView = function()
36 WebInspector.SidebarView.call(this, WebInspector.SidebarView.SidebarPosition.Start);
37 this.registerRequiredCSS("cssNamedFlows.css");
39 this._namedFlows = {};
40 this._contentNodes = {};
41 this._regionNodes = {};
43 this.element.classList.add("css-named-flow-collections-view");
44 this.element.classList.add("fill");
46 this._statusElement = document.createElement("span");
47 this._statusElement.textContent = WebInspector.UIString("CSS Named Flows");
49 var sidebarHeader = this.firstElement().createChild("div", "tabbed-pane-header selected sidebar-header");
50 var tab = sidebarHeader.createChild("div", "tabbed-pane-header-tab");
51 tab.createChild("span", "tabbed-pane-header-tab-title").textContent = WebInspector.UIString("CSS Named Flows");
53 this._sidebarContentElement = this.firstElement().createChild("div", "sidebar-content outline-disclosure");
54 this._flowListElement = this._sidebarContentElement.createChild("ol");
55 this._flowTree = new TreeOutline(this._flowListElement);
57 this._emptyElement = document.createElement("div");
58 this._emptyElement.classList.add("info");
59 this._emptyElement.textContent = WebInspector.UIString("No CSS Named Flows");
61 this._tabbedPane = new WebInspector.TabbedPane();
62 this._tabbedPane.closeableTabs = true;
63 this._tabbedPane.show(this.secondElement());
66 WebInspector.CSSNamedFlowCollectionsView.prototype = {
67 showInDrawer: function()
69 WebInspector.inspectorView.showCloseableViewInDrawer("css-flows", WebInspector.UIString("CSS Flows"), this);
77 WebInspector.cssModel.getNamedFlowCollectionAsync(this._document.id, this._resetNamedFlows.bind(this));
81 * @param {!WebInspector.DOMDocument} document
83 _setDocument: function(document)
85 this._document = document;
90 * @param {!WebInspector.Event} event
92 _documentUpdated: function(event)
94 var document = /** @type {!WebInspector.DOMDocument} */ (event.data);
95 this._setDocument(document);
99 * @param {boolean} hasContent
101 _setSidebarHasContent: function(hasContent)
104 if (!this._emptyElement.parentNode)
107 this._sidebarContentElement.removeChild(this._emptyElement);
108 this._sidebarContentElement.appendChild(this._flowListElement);
110 if (!this._flowListElement.parentNode)
113 this._sidebarContentElement.removeChild(this._flowListElement);
114 this._sidebarContentElement.appendChild(this._emptyElement);
119 * @param {!WebInspector.NamedFlow} flow
121 _appendNamedFlow: function(flow)
123 var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
124 var flowContainer = { flow: flow, flowHash: flowHash };
126 for (var i = 0; i < flow.content.length; ++i)
127 this._contentNodes[flow.content[i]] = flowHash;
128 for (var i = 0; i < flow.regions.length; ++i)
129 this._regionNodes[flow.regions[i].nodeId] = flowHash;
131 var flowTreeItem = new WebInspector.FlowTreeElement(flowContainer);
132 flowTreeItem.onselect = this._selectNamedFlowTab.bind(this, flowHash);
134 flowContainer.flowTreeItem = flowTreeItem;
135 this._namedFlows[flowHash] = flowContainer;
137 if (!this._flowTree.children.length)
138 this._setSidebarHasContent(true);
139 this._flowTree.appendChild(flowTreeItem);
143 * @param {string} flowHash
145 _removeNamedFlow: function(flowHash)
147 var flowContainer = this._namedFlows[flowHash];
149 if (this._tabbedPane._tabsById[flowHash])
150 this._tabbedPane.closeTab(flowHash);
151 this._flowTree.removeChild(flowContainer.flowTreeItem);
153 var flow = flowContainer.flow;
154 for (var i = 0; i < flow.content.length; ++i)
155 delete this._contentNodes[flow.content[i]];
156 for (var i = 0; i < flow.regions.length; ++i)
157 delete this._regionNodes[flow.regions[i].nodeId];
159 delete this._namedFlows[flowHash];
161 if (!this._flowTree.children.length)
162 this._setSidebarHasContent(false);
166 * @param {!WebInspector.NamedFlow} flow
168 _updateNamedFlow: function(flow)
170 var flowHash = this._hashNamedFlow(flow.documentNodeId, flow.name);
171 var flowContainer = this._namedFlows[flowHash];
176 var oldFlow = flowContainer.flow;
177 flowContainer.flow = flow;
179 for (var i = 0; i < oldFlow.content.length; ++i)
180 delete this._contentNodes[oldFlow.content[i]];
181 for (var i = 0; i < oldFlow.regions.length; ++i)
182 delete this._regionNodes[oldFlow.regions[i].nodeId];
184 for (var i = 0; i < flow.content.length; ++i)
185 this._contentNodes[flow.content[i]] = flowHash;
186 for (var i = 0; i < flow.regions.length; ++i)
187 this._regionNodes[flow.regions[i].nodeId] = flowHash;
189 flowContainer.flowTreeItem.setOverset(flow.overset);
191 if (flowContainer.flowView)
192 flowContainer.flowView.flow = flow;
196 * @param {?WebInspector.NamedFlowCollection} namedFlowCollection
198 _resetNamedFlows: function(namedFlowCollection)
200 for (var flowHash in this._namedFlows)
201 this._removeNamedFlow(flowHash);
203 var namedFlows = namedFlowCollection ? namedFlowCollection.namedFlowMap : {};
204 for (var flowName in namedFlows)
205 this._appendNamedFlow(namedFlows[flowName]);
207 if (!this._flowTree.children.length)
208 this._setSidebarHasContent(false);
210 this._showNamedFlowForNode(WebInspector.panel("elements").treeOutline.selectedDOMNode());
214 * @param {!WebInspector.Event} event
216 _namedFlowCreated: function(event)
218 // FIXME: We only have support for Named Flows in the main document.
219 if (event.data.documentNodeId !== this._document.id)
222 var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
223 this._appendNamedFlow(flow);
227 * @param {!WebInspector.Event} event
229 _namedFlowRemoved: function(event)
231 // FIXME: We only have support for Named Flows in the main document.
232 if (event.data.documentNodeId !== this._document.id)
235 this._removeNamedFlow(this._hashNamedFlow(event.data.documentNodeId, event.data.flowName));
239 * @param {!WebInspector.Event} event
241 _regionLayoutUpdated: function(event)
243 // FIXME: We only have support for Named Flows in the main document.
244 if (event.data.documentNodeId !== this._document.id)
247 var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
248 this._updateNamedFlow(flow);
252 * @param {!WebInspector.Event} event
254 _regionOversetChanged: function(event)
256 // FIXME: We only have support for Named Flows in the main document.
257 if (event.data.documentNodeId !== this._document.id)
260 var flow = /** @type {!WebInspector.NamedFlow} */ (event.data);
261 this._updateNamedFlow(flow);
265 * @param {!DOMAgent.NodeId} documentNodeId
266 * @param {string} flowName
268 _hashNamedFlow: function(documentNodeId, flowName)
270 return documentNodeId + "|" + flowName;
274 * @param {string} flowHash
276 _showNamedFlow: function(flowHash)
278 this._selectNamedFlowInSidebar(flowHash);
279 this._selectNamedFlowTab(flowHash);
283 * @param {string} flowHash
285 _selectNamedFlowInSidebar: function(flowHash)
287 this._namedFlows[flowHash].flowTreeItem.select(true);
291 * @param {string} flowHash
294 _selectNamedFlowTab: function(flowHash)
296 var flowContainer = this._namedFlows[flowHash];
298 if (this._tabbedPane.selectedTabId === flowHash)
301 if (!this._tabbedPane.selectTab(flowHash)) {
302 if (!flowContainer.flowView)
303 flowContainer.flowView = new WebInspector.CSSNamedFlowView(flowContainer.flow);
305 this._tabbedPane.appendTab(flowHash, flowContainer.flow.name, flowContainer.flowView);
306 this._tabbedPane.selectTab(flowHash);
312 * @param {!WebInspector.Event} event
314 _selectedNodeChanged: function(event)
316 var node = /** @type {!WebInspector.DOMNode} */ (event.data);
317 this._showNamedFlowForNode(node);
321 * @param {!WebInspector.Event} event
323 _tabSelected: function(event)
325 this._selectNamedFlowInSidebar(event.data.tabId);
329 * @param {!WebInspector.Event} event
331 _tabClosed: function(event)
333 this._namedFlows[event.data.tabId].flowTreeItem.deselect();
337 * @param {?WebInspector.DOMNode} node
339 _showNamedFlowForNode: function(node)
344 if (this._regionNodes[node.id]) {
345 this._showNamedFlow(this._regionNodes[node.id]);
350 if (this._contentNodes[node.id]) {
351 this._showNamedFlow(this._contentNodes[node.id]);
355 node = node.parentNode;
361 WebInspector.SidebarView.prototype.wasShown.call(this);
363 WebInspector.domAgent.requestDocument(this._setDocument.bind(this));
365 WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
367 WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
368 WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
369 WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
370 WebInspector.cssModel.addEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);
372 WebInspector.panel("elements").treeOutline.addEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
374 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
375 this._tabbedPane.addEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
380 WebInspector.domAgent.removeEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
382 WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowCreated, this._namedFlowCreated, this);
383 WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, this._namedFlowRemoved, this);
384 WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, this._regionLayoutUpdated, this);
385 WebInspector.cssModel.removeEventListener(WebInspector.CSSStyleModel.Events.RegionOversetChanged, this._regionOversetChanged, this);
387 WebInspector.panel("elements").treeOutline.removeEventListener(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedNodeChanged, this);
389 this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabSelected, this._tabSelected, this);
390 this._tabbedPane.removeEventListener(WebInspector.TabbedPane.EventTypes.TabClosed, this._tabClosed, this);
393 __proto__: WebInspector.SidebarView.prototype
398 * @extends {TreeElement}
400 WebInspector.FlowTreeElement = function(flowContainer)
402 var container = document.createElement("div");
403 container.createChild("div", "selection");
404 container.createChild("span", "title").createChild("span").textContent = flowContainer.flow.name;
406 TreeElement.call(this, container, flowContainer, false);
408 this._overset = false;
409 this.setOverset(flowContainer.flow.overset);
412 WebInspector.FlowTreeElement.prototype = {
414 * @param {boolean} newOverset
416 setOverset: function(newOverset)
418 if (this._overset === newOverset)
422 this.title.classList.add("named-flow-overflow");
423 this.tooltip = WebInspector.UIString("Overflows.");
425 this.title.classList.remove("named-flow-overflow");
429 this._overset = newOverset;
432 __proto__: TreeElement.prototype