2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
26 WebInspector.FrameTreeElement = class FrameTreeElement extends WebInspector.ResourceTreeElement
28 constructor(frame, representedObject)
30 console.assert(frame instanceof WebInspector.Frame);
32 super(frame.mainResource, representedObject || frame);
36 this._updateExpandedSetting();
38 frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
39 frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceWasAdded, this);
40 frame.addEventListener(WebInspector.Frame.Event.ResourceWasRemoved, this._resourceWasRemoved, this);
41 frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasAdded, this._childFrameWasAdded, this);
42 frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasRemoved, this._childFrameWasRemoved, this);
44 frame.domTree.addEventListener(WebInspector.DOMTree.Event.ContentFlowWasAdded, this._childContentFlowWasAdded, this);
45 frame.domTree.addEventListener(WebInspector.DOMTree.Event.ContentFlowWasRemoved, this._childContentFlowWasRemoved, this);
46 frame.domTree.addEventListener(WebInspector.DOMTree.Event.RootDOMNodeInvalidated, this._rootDOMNodeInvalidated, this);
48 if (this._frame.isMainFrame())
49 this._downloadingPage = false;
51 this.shouldRefreshChildren = true;
52 this.folderSettingsKey = this._frame.url.hash;
54 this.registerFolderizeSettings("frames", WebInspector.UIString("Frames"),
55 function(representedObject) { return representedObject instanceof WebInspector.Frame; },
56 function() { return this.frame.childFrames.length; }.bind(this),
57 WebInspector.FrameTreeElement
60 this.registerFolderizeSettings("flows", WebInspector.UIString("Flows"),
61 function(representedObject) { return representedObject instanceof WebInspector.ContentFlow; },
62 function() { return this.frame.domTree.flowsCount; }.bind(this),
63 WebInspector.ContentFlowTreeElement
66 function makeValidateCallback(resourceType) {
67 return function(representedObject) {
68 return representedObject instanceof WebInspector.Resource && representedObject.type === resourceType;
72 function makeChildCountCallback(frame, resourceType) {
74 return frame.resourcesWithType(resourceType).length;
78 for (var key in WebInspector.Resource.Type) {
79 var value = WebInspector.Resource.Type[key];
80 var folderName = WebInspector.Resource.displayNameForType(value, true);
81 this.registerFolderizeSettings(key, folderName,
82 makeValidateCallback(value),
83 makeChildCountCallback(this.frame, value),
84 WebInspector.ResourceTreeElement
88 this.updateParentStatus();
98 descendantResourceTreeElementTypeDidChange(resourceTreeElement, oldType)
100 // Called by descendant ResourceTreeElements.
102 // Add the tree element again, which will move it to the new location
103 // based on sorting and possible folder changes.
104 this._addTreeElement(resourceTreeElement);
107 descendantResourceTreeElementMainTitleDidChange(resourceTreeElement, oldMainTitle)
109 // Called by descendant ResourceTreeElements.
111 // Add the tree element again, which will move it to the new location
112 // based on sorting and possible folder changes.
113 this._addTreeElement(resourceTreeElement);
116 // Overrides from SourceCodeTreeElement.
118 updateSourceMapResources()
120 // Frames handle their own SourceMapResources.
122 if (!this.treeOutline || !this.treeOutline.includeSourceMapResourceChildren)
128 this.updateParentStatus();
130 if (this.resource && this.resource.sourceMaps.length)
131 this.shouldRefreshChildren = true;
136 // Immediate superclasses are skipped, since Frames handle their own SourceMapResources.
137 WebInspector.GeneralTreeElement.prototype.onattach.call(this);
140 // Overrides from FolderizedTreeElement (Protected).
142 compareChildTreeElements(a, b)
147 var aIsResource = a instanceof WebInspector.ResourceTreeElement;
148 var bIsResource = b instanceof WebInspector.ResourceTreeElement;
150 if (aIsResource && bIsResource)
151 return WebInspector.ResourceTreeElement.compareResourceTreeElements(a, b);
153 if (!aIsResource && !bIsResource) {
154 // When both components are not resources then default to base class comparison.
155 return super.compareChildTreeElements(a, b);
158 // Non-resources should appear before the resources.
159 // FIXME: There should be a better way to group the elements by their type.
160 return aIsResource ? 1 : -1;
163 // Overrides from TreeElement (Private).
167 if (this.children.length && !this.shouldRefreshChildren)
169 this.shouldRefreshChildren = false;
171 this.removeChildren();
172 this.updateParentStatus();
173 this.prepareToPopulate();
175 for (var i = 0; i < this._frame.childFrames.length; ++i)
176 this.addChildForRepresentedObject(this._frame.childFrames[i]);
178 for (var i = 0; i < this._frame.resources.length; ++i)
179 this.addChildForRepresentedObject(this._frame.resources[i]);
181 var sourceMaps = this.resource && this.resource.sourceMaps;
182 for (var i = 0; i < sourceMaps.length; ++i) {
183 var sourceMap = sourceMaps[i];
184 for (var j = 0; j < sourceMap.resources.length; ++j)
185 this.addChildForRepresentedObject(sourceMap.resources[j]);
188 var flowMap = this._frame.domTree.flowMap;
189 for (var flowKey in flowMap)
190 this.addChildForRepresentedObject(flowMap[flowKey]);
196 this._expandedSetting.value = true;
197 this._frame.domTree.requestContentFlowList();
202 // Only store the setting if we have children, since setting hasChildren to false will cause a collapse,
203 // and we only care about user triggered collapses.
204 if (this.hasChildren)
205 this._expandedSetting.value = false;
210 _updateExpandedSetting()
212 this._expandedSetting = new WebInspector.Setting("frame-expanded-" + this._frame.url.hash, this._frame.isMainFrame() ? true : false);
213 if (this._expandedSetting.value)
219 _mainResourceDidChange(event)
221 this._updateResource(this._frame.mainResource);
223 this.updateParentStatus();
224 this.removeChildren();
226 // Change the expanded setting since the frame URL has changed. Do this before setting shouldRefreshChildren, since
227 // shouldRefreshChildren will call onpopulate if expanded is true.
228 this._updateExpandedSetting();
230 this.shouldRefreshChildren = true;
233 _resourceWasAdded(event)
235 this.addRepresentedObjectToNewChildQueue(event.data.resource);
238 _resourceWasRemoved(event)
240 this.removeChildForRepresentedObject(event.data.resource);
243 _childFrameWasAdded(event)
245 this.addRepresentedObjectToNewChildQueue(event.data.childFrame);
248 _childFrameWasRemoved(event)
250 this.removeChildForRepresentedObject(event.data.childFrame);
253 _childContentFlowWasAdded(event)
255 this.addRepresentedObjectToNewChildQueue(event.data.flow);
258 _childContentFlowWasRemoved(event)
260 this.removeChildForRepresentedObject(event.data.flow);
263 _rootDOMNodeInvalidated()
266 this._frame.domTree.requestContentFlowList();