Web Inspector: decouple child element folderization logic from FrameTreeElement
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 Nov 2014 03:17:40 +0000 (03:17 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 9 Nov 2014 03:17:40 +0000 (03:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=138364

Patch by Matt Baker <mattbaker@apple.com> on 2014-11-08
Reviewed by Timothy Hatcher.

Created FolderizedTreeElement base class, which FrameTreeElement now inherits via SourceCodeTreeElement.
FolderizedTreeElement uses settings provided by derived classes for labeling subfolders and to determine
folder membership for child items.

* UserInterface/Base/Main.js:
(WebInspector.canArchiveMainFrame):
* UserInterface/Main.html:
* UserInterface/Models/LayoutTimelineRecord.js:
(WebInspector.LayoutTimelineRecord.displayNameForEventType):
(WebInspector.LayoutTimelineRecord.EventType.displayName): Deleted.
* UserInterface/Models/Resource.js:
(WebInspector.Resource):
(WebInspector.Resource.typeFromMIMEType):
(WebInspector.Resource.displayNameForType):
(WebInspector.Resource.prototype.get syntheticMIMEType):
(WebInspector.Resource.prototype.updateForResponse):
(WebInspector.Resource.Type.fromMIMEType): Deleted.
(WebInspector.Resource.Type.displayName): Deleted.
* UserInterface/Models/SourceMapResource.js:
(WebInspector.SourceMapResource):
* UserInterface/Views/FolderizedTreeElement.js: Added.
(WebInspector.FolderizedTreeElement):
(WebInspector.FolderizedTreeElement.prototype.get groupedIntoFolders):
(WebInspector.FolderizedTreeElement.prototype.set folderSettingsKey):
(WebInspector.FolderizedTreeElement.prototype.registerFolderizeSettings):
(WebInspector.FolderizedTreeElement.prototype.set removeChildren):
(WebInspector.FolderizedTreeElement.prototype.addChildForRepresentedObject):
(WebInspector.FolderizedTreeElement.prototype.addRepresentedObjectToNewChildQueue):
(WebInspector.FolderizedTreeElement.prototype.removeChildForRepresentedObject):
(WebInspector.FolderizedTreeElement.prototype.compareChildTreeElements):
(WebInspector.FolderizedTreeElement.prototype.updateParentStatus):
(WebInspector.FolderizedTreeElement.prototype._clearNewChildQueue):
(WebInspector.FolderizedTreeElement.prototype._populateFromNewChildQueue):
(WebInspector.FolderizedTreeElement.prototype._removeRepresentedObjectFromNewChildQueue):
(WebInspector.FolderizedTreeElement.prototype._addTreeElement):
(WebInspector.FolderizedTreeElement.prototype._compareTreeElementsByMainTitle):
(WebInspector.FolderizedTreeElement.prototype._insertFolderTreeElement):
(WebInspector.FolderizedTreeElement.prototype._insertChildTreeElement):
(WebInspector.FolderizedTreeElement.prototype._removeTreeElement):
(WebInspector.FolderizedTreeElement.prototype._parentTreeElementForRepresentedObject):
(WebInspector.FolderizedTreeElement.prototype._folderTreeElementExpandedStateChange):
(WebInspector.FolderizedTreeElement.prototype._settingsForRepresentedObject):
(WebInspector.FolderizedTreeElement.prototype._shouldGroupIntoFolders.pushCategory):
(WebInspector.FolderizedTreeElement.prototype._shouldGroupIntoFolders):
* UserInterface/Views/FrameTreeElement.js:
(.this):
(WebInspector.FrameTreeElement.prototype.updateSourceMapResources):
(WebInspector.FrameTreeElement.prototype.onattach):
(WebInspector.FrameTreeElement.prototype.ondetach):
(WebInspector.FrameTreeElement.prototype.compareChildTreeElements):
(WebInspector.FrameTreeElement.prototype.onpopulate):
(WebInspector.FrameTreeElement.prototype._mainResourceDidChange):
(WebInspector.FrameTreeElement.prototype._resourceWasAdded):
(WebInspector.FrameTreeElement.prototype._resourceWasRemoved):
(WebInspector.FrameTreeElement.prototype._childFrameWasAdded):
(WebInspector.FrameTreeElement.prototype._childFrameWasRemoved):
(WebInspector.FrameTreeElement.prototype._childContentFlowWasAdded):
(WebInspector.FrameTreeElement.prototype._childContentFlowWasRemoved):
(WebInspector.FrameTreeElement.prototype._rootDOMNodeInvalidated):
(WebInspector.FrameTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype.removeChildren): Deleted.
(WebInspector.FrameTreeElement.prototype._updateParentStatus): Deleted.
(WebInspector.FrameTreeElement.prototype._addRepresentedObjectToNewChildQueue): Deleted.
(WebInspector.FrameTreeElement.prototype._removeRepresentedObjectFromNewChildQueue): Deleted.
(WebInspector.FrameTreeElement.prototype._populateFromNewChildQueue): Deleted.
(WebInspector.FrameTreeElement.prototype._clearNewChildQueue): Deleted.
(WebInspector.FrameTreeElement.prototype._addChildForRepresentedObject): Deleted.
(WebInspector.FrameTreeElement.prototype._removeChildForRepresentedObject): Deleted.
(WebInspector.FrameTreeElement.prototype._addTreeElementForRepresentedObject): Deleted.
(WebInspector.FrameTreeElement.prototype._addTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype._compareTreeElementsByMainTitle): Deleted.
(WebInspector.FrameTreeElement.prototype._insertFolderTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype._compareResourceTreeElements): Deleted.
(WebInspector.FrameTreeElement.prototype._insertResourceTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype._removeTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype._folderNameForResourceType): Deleted.
(WebInspector.FrameTreeElement.prototype._parentTreeElementForRepresentedObject.createFolderTreeElement): Deleted.
(WebInspector.FrameTreeElement.prototype._parentTreeElementForRepresentedObject): Deleted.
(WebInspector.FrameTreeElement.prototype._folderTreeElementExpandedStateChange): Deleted.
(WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders.pushResourceType): Deleted.
(WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders.pushCategory): Deleted.
(WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders): Deleted.
* UserInterface/Views/LayoutTimelineDataGridNode.js:
(WebInspector.LayoutTimelineDataGridNode.prototype.createCellContent):
* UserInterface/Views/LayoutTimelineView.js:
(WebInspector.LayoutTimelineView): Deleted.
* UserInterface/Views/NetworkTimelineView.js:
(WebInspector.NetworkTimelineView): Deleted.
* UserInterface/Views/ResourceDetailsSidebarPanel.js:
(WebInspector.ResourceDetailsSidebarPanel.prototype._refreshResourceType):
* UserInterface/Views/ResourceTimelineDataGridNode.js:
(WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
* UserInterface/Views/SourceCodeTreeElement.js:
(WebInspector.SourceCodeTreeElement):
* UserInterface/Views/TimelineDataGrid.js:
(WebInspector.TimelineDataGrid.createColumnScopeBar):
* UserInterface/Views/TimelineRecordTreeElement.js:
(WebInspector.TimelineRecordTreeElement):
* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
* WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@175784 268f45cc-cd09-0410-ab3c-d52691b4dbfc

18 files changed:
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/UserInterface/Base/Main.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/LayoutTimelineRecord.js
Source/WebInspectorUI/UserInterface/Models/Resource.js
Source/WebInspectorUI/UserInterface/Models/SourceMapResource.js
Source/WebInspectorUI/UserInterface/Views/FolderizedTreeElement.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Views/FrameTreeElement.js
Source/WebInspectorUI/UserInterface/Views/LayoutTimelineDataGridNode.js
Source/WebInspectorUI/UserInterface/Views/LayoutTimelineView.js
Source/WebInspectorUI/UserInterface/Views/NetworkTimelineView.js
Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/ResourceTimelineDataGridNode.js
Source/WebInspectorUI/UserInterface/Views/SourceCodeTreeElement.js
Source/WebInspectorUI/UserInterface/Views/TimelineDataGrid.js
Source/WebInspectorUI/UserInterface/Views/TimelineRecordTreeElement.js
Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj
Source/WebInspectorUI/WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters

index 4b657d9a9e2ebece9f70bd9713c687fb6bb73b4c..ba9bfb1eb1844bc4264798b7077afb6e7881fa20 100644 (file)
@@ -1,3 +1,111 @@
+2014-11-08  Matt Baker  <mattbaker@apple.com>
+
+        Web Inspector: decouple child element folderization logic from FrameTreeElement
+        https://bugs.webkit.org/show_bug.cgi?id=138364
+
+        Reviewed by Timothy Hatcher.
+
+        Created FolderizedTreeElement base class, which FrameTreeElement now inherits via SourceCodeTreeElement.
+        FolderizedTreeElement uses settings provided by derived classes for labeling subfolders and to determine
+        folder membership for child items.
+
+        * UserInterface/Base/Main.js:
+        (WebInspector.canArchiveMainFrame):
+        * UserInterface/Main.html:
+        * UserInterface/Models/LayoutTimelineRecord.js:
+        (WebInspector.LayoutTimelineRecord.displayNameForEventType):
+        (WebInspector.LayoutTimelineRecord.EventType.displayName): Deleted.
+        * UserInterface/Models/Resource.js:
+        (WebInspector.Resource):
+        (WebInspector.Resource.typeFromMIMEType):
+        (WebInspector.Resource.displayNameForType):
+        (WebInspector.Resource.prototype.get syntheticMIMEType):
+        (WebInspector.Resource.prototype.updateForResponse):
+        (WebInspector.Resource.Type.fromMIMEType): Deleted.
+        (WebInspector.Resource.Type.displayName): Deleted.
+        * UserInterface/Models/SourceMapResource.js:
+        (WebInspector.SourceMapResource):
+        * UserInterface/Views/FolderizedTreeElement.js: Added.
+        (WebInspector.FolderizedTreeElement):
+        (WebInspector.FolderizedTreeElement.prototype.get groupedIntoFolders):
+        (WebInspector.FolderizedTreeElement.prototype.set folderSettingsKey):
+        (WebInspector.FolderizedTreeElement.prototype.registerFolderizeSettings):
+        (WebInspector.FolderizedTreeElement.prototype.set removeChildren):
+        (WebInspector.FolderizedTreeElement.prototype.addChildForRepresentedObject):
+        (WebInspector.FolderizedTreeElement.prototype.addRepresentedObjectToNewChildQueue):
+        (WebInspector.FolderizedTreeElement.prototype.removeChildForRepresentedObject):
+        (WebInspector.FolderizedTreeElement.prototype.compareChildTreeElements):
+        (WebInspector.FolderizedTreeElement.prototype.updateParentStatus):
+        (WebInspector.FolderizedTreeElement.prototype._clearNewChildQueue):
+        (WebInspector.FolderizedTreeElement.prototype._populateFromNewChildQueue):
+        (WebInspector.FolderizedTreeElement.prototype._removeRepresentedObjectFromNewChildQueue):
+        (WebInspector.FolderizedTreeElement.prototype._addTreeElement):
+        (WebInspector.FolderizedTreeElement.prototype._compareTreeElementsByMainTitle):
+        (WebInspector.FolderizedTreeElement.prototype._insertFolderTreeElement):
+        (WebInspector.FolderizedTreeElement.prototype._insertChildTreeElement):
+        (WebInspector.FolderizedTreeElement.prototype._removeTreeElement):
+        (WebInspector.FolderizedTreeElement.prototype._parentTreeElementForRepresentedObject):
+        (WebInspector.FolderizedTreeElement.prototype._folderTreeElementExpandedStateChange):
+        (WebInspector.FolderizedTreeElement.prototype._settingsForRepresentedObject):
+        (WebInspector.FolderizedTreeElement.prototype._shouldGroupIntoFolders.pushCategory):
+        (WebInspector.FolderizedTreeElement.prototype._shouldGroupIntoFolders):
+        * UserInterface/Views/FrameTreeElement.js:
+        (.this):
+        (WebInspector.FrameTreeElement.prototype.updateSourceMapResources):
+        (WebInspector.FrameTreeElement.prototype.onattach):
+        (WebInspector.FrameTreeElement.prototype.ondetach):
+        (WebInspector.FrameTreeElement.prototype.compareChildTreeElements):
+        (WebInspector.FrameTreeElement.prototype.onpopulate):
+        (WebInspector.FrameTreeElement.prototype._mainResourceDidChange):
+        (WebInspector.FrameTreeElement.prototype._resourceWasAdded):
+        (WebInspector.FrameTreeElement.prototype._resourceWasRemoved):
+        (WebInspector.FrameTreeElement.prototype._childFrameWasAdded):
+        (WebInspector.FrameTreeElement.prototype._childFrameWasRemoved):
+        (WebInspector.FrameTreeElement.prototype._childContentFlowWasAdded):
+        (WebInspector.FrameTreeElement.prototype._childContentFlowWasRemoved):
+        (WebInspector.FrameTreeElement.prototype._rootDOMNodeInvalidated):
+        (WebInspector.FrameTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype.removeChildren): Deleted.
+        (WebInspector.FrameTreeElement.prototype._updateParentStatus): Deleted.
+        (WebInspector.FrameTreeElement.prototype._addRepresentedObjectToNewChildQueue): Deleted.
+        (WebInspector.FrameTreeElement.prototype._removeRepresentedObjectFromNewChildQueue): Deleted.
+        (WebInspector.FrameTreeElement.prototype._populateFromNewChildQueue): Deleted.
+        (WebInspector.FrameTreeElement.prototype._clearNewChildQueue): Deleted.
+        (WebInspector.FrameTreeElement.prototype._addChildForRepresentedObject): Deleted.
+        (WebInspector.FrameTreeElement.prototype._removeChildForRepresentedObject): Deleted.
+        (WebInspector.FrameTreeElement.prototype._addTreeElementForRepresentedObject): Deleted.
+        (WebInspector.FrameTreeElement.prototype._addTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype._compareTreeElementsByMainTitle): Deleted.
+        (WebInspector.FrameTreeElement.prototype._insertFolderTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype._compareResourceTreeElements): Deleted.
+        (WebInspector.FrameTreeElement.prototype._insertResourceTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype._removeTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype._folderNameForResourceType): Deleted.
+        (WebInspector.FrameTreeElement.prototype._parentTreeElementForRepresentedObject.createFolderTreeElement): Deleted.
+        (WebInspector.FrameTreeElement.prototype._parentTreeElementForRepresentedObject): Deleted.
+        (WebInspector.FrameTreeElement.prototype._folderTreeElementExpandedStateChange): Deleted.
+        (WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders.pushResourceType): Deleted.
+        (WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders.pushCategory): Deleted.
+        (WebInspector.FrameTreeElement.prototype._shouldGroupIntoFolders): Deleted.
+        * UserInterface/Views/LayoutTimelineDataGridNode.js:
+        (WebInspector.LayoutTimelineDataGridNode.prototype.createCellContent):
+        * UserInterface/Views/LayoutTimelineView.js:
+        (WebInspector.LayoutTimelineView): Deleted.
+        * UserInterface/Views/NetworkTimelineView.js:
+        (WebInspector.NetworkTimelineView): Deleted.
+        * UserInterface/Views/ResourceDetailsSidebarPanel.js:
+        (WebInspector.ResourceDetailsSidebarPanel.prototype._refreshResourceType):
+        * UserInterface/Views/ResourceTimelineDataGridNode.js:
+        (WebInspector.ResourceTimelineDataGridNode.prototype.createCellContent):
+        * UserInterface/Views/SourceCodeTreeElement.js:
+        (WebInspector.SourceCodeTreeElement):
+        * UserInterface/Views/TimelineDataGrid.js:
+        (WebInspector.TimelineDataGrid.createColumnScopeBar):
+        * UserInterface/Views/TimelineRecordTreeElement.js:
+        (WebInspector.TimelineRecordTreeElement):
+        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj:
+        * WebInspectorUI.vcxproj/WebInspectorUI.vcxproj.filters:
+
 2014-11-07  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: Layer summary should be bottom sticky
index 26720ceda1cbdc21bf307c96532e4c68ca563843..8b9457df2f9be580057b4b8aacbb18be38b40439 100644 (file)
@@ -1863,7 +1863,7 @@ WebInspector.canArchiveMainFrame = function()
     if (!PageAgent.archive)
         return false;
 
-    return WebInspector.Resource.Type.fromMIMEType(WebInspector.frameResourceManager.mainFrame.mainResource.mimeType) === WebInspector.Resource.Type.Document;
+    return WebInspector.Resource.typeFromMIMEType(WebInspector.frameResourceManager.mainFrame.mainResource.mimeType) === WebInspector.Resource.Type.Document;
 }
 
 WebInspector.addWindowKeydownListener = function(listener)
index 73d0be67b867a14fc84a2c37edb37230681ae005..b9729e9f3722eff81e984822b9e1f9c9c28e19da 100644 (file)
     <script src="Views/TimelineDataGridNode.js"></script>
 
     <script src="Views/DOMDetailsSidebarPanel.js"></script>
+    <script src="Views/FolderizedTreeElement.js"></script>
     <script src="Views/SourceCodeTreeElement.js"></script>
     <script src="Views/StorageTreeElement.js"></script>
     <script src="Views/TimelineRecordTreeElement.js"></script>
index a34c69155d0c7f9ddb0027460b2e037d551ab3f2..a96e09e35db919eea83bbee6f04924f9ee2764bb 100644 (file)
@@ -49,7 +49,7 @@ WebInspector.LayoutTimelineRecord.EventType = {
     Paint: "layout-timeline-record-paint"
 };
 
-WebInspector.LayoutTimelineRecord.EventType.displayName = function(eventType)
+WebInspector.LayoutTimelineRecord.displayNameForEventType = function(eventType)
 {
     switch(eventType) {
     case WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles:
index a05460ec384db41a040803d164c4e83fd276a949..f3bbdb069692e82aeea27c77154f3de58eaa856c 100644 (file)
@@ -34,7 +34,7 @@ WebInspector.Resource = function(url, mimeType, type, loaderIdentifier, requestI
 
     this._url = url;
     this._mimeType = mimeType;
-    this._type = type || WebInspector.Resource.Type.fromMIMEType(mimeType);
+    this._type = type || WebInspector.Resource.typeFromMIMEType(mimeType);
     this._loaderIdentifier = loaderIdentifier || null;
     this._requestIdentifier = requestIdentifier || null;
     this._requestMethod = requestMethod || null;
@@ -85,8 +85,8 @@ WebInspector.Resource.Type = {
     Other: "resource-type-other"
 };
 
-// This MIME Type map is private, use WebInspector.Resource.Type.fromMIMEType().
-WebInspector.Resource.Type._mimeTypeMap = {
+// This MIME Type map is private, use WebInspector.Resource.typeFromMIMEType().
+WebInspector.Resource._mimeTypeMap = {
     "text/html": WebInspector.Resource.Type.Document,
     "text/xml": WebInspector.Resource.Type.Document,
     "text/plain": WebInspector.Resource.Type.Document,
@@ -126,15 +126,15 @@ WebInspector.Resource.Type._mimeTypeMap = {
     "text/x-coffeescript": WebInspector.Resource.Type.Script
 };
 
-WebInspector.Resource.Type.fromMIMEType = function(mimeType)
+WebInspector.Resource.typeFromMIMEType = function(mimeType)
 {
     if (!mimeType)
         return WebInspector.Resource.Type.Other;
 
     mimeType = parseMIMEType(mimeType).type;
 
-    if (mimeType in WebInspector.Resource.Type._mimeTypeMap)
-        return WebInspector.Resource.Type._mimeTypeMap[mimeType];
+    if (mimeType in WebInspector.Resource._mimeTypeMap)
+        return WebInspector.Resource._mimeTypeMap[mimeType];
 
     if (mimeType.startsWith("image/"))
         return WebInspector.Resource.Type.Image;
@@ -145,7 +145,7 @@ WebInspector.Resource.Type.fromMIMEType = function(mimeType)
     return WebInspector.Resource.Type.Other;
 };
 
-WebInspector.Resource.Type.displayName = function(type, plural)
+WebInspector.Resource.displayNameForType = function(type, plural)
 {
     switch(type) {
     case WebInspector.Resource.Type.Document:
@@ -235,7 +235,7 @@ WebInspector.Resource.prototype = {
         // This getter generates a MIME-type, if needed, that matches the resource type.
 
         // If the type matches the Resource.Type of the MIME-type, then return the actual MIME-type.
-        if (this._type === WebInspector.Resource.Type.fromMIMEType(this._mimeType))
+        if (this._type === WebInspector.Resource.typeFromMIMEType(this._mimeType))
             return this._mimeType;
 
         // Return the default MIME-types for the Resource.Type, since the current MIME-type
@@ -497,7 +497,7 @@ WebInspector.Resource.prototype = {
 
         this._url = url;
         this._mimeType = mimeType;
-        this._type = type || WebInspector.Resource.Type.fromMIMEType(mimeType);
+        this._type = type || WebInspector.Resource.typeFromMIMEType(mimeType);
         this._statusCode = statusCode;
         this._statusText = statusText;
         this._responseHeaders = responseHeaders || {};
index 61cd71f06d002c6538f1c992e20c25ce3dad0a84..8d898a26405c6e7ee84db0db3ead242e3195ea84 100644 (file)
@@ -41,7 +41,7 @@ WebInspector.SourceMapResource = function(url, sourceMap)
     // FIXME: This is a layering violation. It should use a helper function on the
     // Resource base-class to set _mimeType and _type.
     this._mimeType = fileExtensionMIMEType || inheritedMIMEType || "text/javascript";
-    this._type = WebInspector.Resource.Type.fromMIMEType(this._mimeType);
+    this._type = WebInspector.Resource.typeFromMIMEType(this._mimeType);
 
     // Mark the resource as loaded so it does not show a spinner in the sidebar.
     // We will really load the resource the first time content is requested.
diff --git a/Source/WebInspectorUI/UserInterface/Views/FolderizedTreeElement.js b/Source/WebInspectorUI/UserInterface/Views/FolderizedTreeElement.js
new file mode 100644 (file)
index 0000000..2dac1dc
--- /dev/null
@@ -0,0 +1,365 @@
+/*
+ * Copyright (C) 2014 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.FolderizedTreeElement = function(classNames, title, subtitle, representedObject, hasChildren)
+{
+    WebInspector.GeneralTreeElement.call(this, classNames, title, subtitle, representedObject, hasChildren);
+
+    this.shouldRefreshChildren = true;
+
+    this._folderSettingsKey = "";
+    this._folderTypeMap = new Map;
+    this._folderizeSettingsMap = new Map;
+    this._groupedIntoFolders = false;
+    this._clearNewChildQueue();
+};
+
+WebInspector.FolderizedTreeElement.MediumChildCountThreshold = 5;
+WebInspector.FolderizedTreeElement.LargeChildCountThreshold = 15;
+WebInspector.FolderizedTreeElement.NumberOfMediumCategoriesThreshold = 2;
+WebInspector.FolderizedTreeElement.NewChildQueueUpdateInterval = 500;
+
+WebInspector.FolderizedTreeElement.prototype = {
+    constructor: WebInspector.FolderizedTreeElement,
+    __proto__: WebInspector.GeneralTreeElement.prototype,
+
+    // Public
+
+    get groupedIntoFolders()
+    {
+        return this._groupedIntoFolders;
+    },
+
+    set folderSettingsKey(x)
+    {
+        this._folderSettingsKey = x;
+    },
+
+    registerFolderizeSettings: function(type, folderDisplayName, validateRepresentedObjectCallback, countChildrenCallback, treeElementConstructor)
+    {
+        console.assert(type);
+        console.assert(folderDisplayName);
+        console.assert(typeof validateRepresentedObjectCallback === "function");
+        console.assert(typeof countChildrenCallback === "function");
+        console.assert(typeof treeElementConstructor === "function");
+
+        var settings = {
+            type: type,
+            folderDisplayName: folderDisplayName,
+            validateRepresentedObjectCallback: validateRepresentedObjectCallback,
+            countChildrenCallback: countChildrenCallback,
+            treeElementConstructor: treeElementConstructor
+        };
+
+        this._folderizeSettingsMap.set(type, settings);
+    },
+
+    // Overrides from TreeElement (Private).
+
+    removeChildren: function()
+    {
+        TreeElement.prototype.removeChildren.call(this);
+
+        this._clearNewChildQueue();
+
+        for (var folder of this._folderTypeMap.values())
+            folder.removeChildren();
+
+        this._folderTypeMap.clear();
+    },
+
+    // Protected
+
+    addChildForRepresentedObject: function(representedObject)
+    {
+        var settings = this._settingsForRepresentedObject(representedObject);
+        console.assert(settings);
+        if (!settings) {
+            console.error("No settings for represented object", representedObject);
+            return;
+        }
+
+        this.updateParentStatus();
+
+        if (!this.treeOutline) {
+            // Just mark as needing to update to avoid doing work that might not be needed.
+            this.shouldRefreshChildren = true;
+            return;
+        }
+
+        if (!this._groupedIntoFolders && this._shouldGroupIntoFolders()) {
+            // Mark as needing a refresh to rebuild the tree into folders.
+            this._groupedIntoFolders = true;
+            this.shouldRefreshChildren = true;
+            return;
+        }
+
+        var childTreeElement = this.treeOutline.getCachedTreeElement(representedObject);
+        if (!childTreeElement)
+            childTreeElement = new settings.treeElementConstructor(representedObject);
+
+        this._addTreeElement(childTreeElement);
+    },
+
+    addRepresentedObjectToNewChildQueue: function(representedObject)
+    {
+        // This queue reduces flashing as resources load and change folders when their type becomes known.
+
+        this._newChildQueue.push(representedObject);
+        if (!this._newChildQueueTimeoutIdentifier)
+            this._newChildQueueTimeoutIdentifier = setTimeout(this._populateFromNewChildQueue.bind(this), WebInspector.FolderizedTreeElement.NewChildQueueUpdateInterval);
+    },
+
+    removeChildForRepresentedObject: function(representedObject)
+    {
+        this._removeRepresentedObjectFromNewChildQueue(representedObject);
+        this.updateParentStatus();
+
+        if (!this.treeOutline) {
+            // Just mark as needing to update to avoid doing work that might not be needed.
+            this.shouldRefreshChildren = true;
+            return;
+        }
+
+        // Find the tree element for the frame by using getCachedTreeElement
+        // to only get the item if it has been created already.
+        var childTreeElement = this.treeOutline.getCachedTreeElement(representedObject);
+        if (!childTreeElement || !childTreeElement.parent)
+            return;
+
+        this._removeTreeElement(childTreeElement);
+    },
+
+    compareChildTreeElements: function(a, b)
+    {
+        return this._compareTreeElementsByMainTitle(a, b);
+    },
+
+    updateParentStatus: function()
+    {
+        var hasChildren = false;
+        for (var settings of this._folderizeSettingsMap.values()) {
+            if (settings.countChildrenCallback()) {
+                hasChildren = true;
+                break;
+            }
+        }
+
+        this.hasChildren = hasChildren;
+        if (!this.hasChildren)
+            this.removeChildren();
+    },
+
+    // Private
+
+    _clearNewChildQueue: function()
+    {
+        this._newChildQueue = [];
+        if (this._newChildQueueTimeoutIdentifier) {
+            clearTimeout(this._newChildQueueTimeoutIdentifier);
+            this._newChildQueueTimeoutIdentifier = null;
+        }
+    },
+
+    _populateFromNewChildQueue: function()
+    {
+        if (!this.children.length) {
+            this.updateParentStatus();
+            this.shouldRefreshChildren = true;
+            return;
+        }
+
+        for (var i = 0; i < this._newChildQueue.length; ++i)
+            this.addChildForRepresentedObject(this._newChildQueue[i]);
+
+        this._clearNewChildQueue();
+    },
+
+    _removeRepresentedObjectFromNewChildQueue: function(representedObject)
+    {
+        this._newChildQueue.remove(representedObject);
+    },
+
+    _addTreeElement: function(childTreeElement)
+    {
+        console.assert(childTreeElement);
+        if (!childTreeElement)
+            return;
+
+        var wasSelected = childTreeElement.selected;
+
+        this._removeTreeElement(childTreeElement, true, true);
+
+        var parentTreeElement = this._parentTreeElementForRepresentedObject(childTreeElement.representedObject);
+        if (parentTreeElement !== this && !parentTreeElement.parent)
+            this._insertFolderTreeElement(parentTreeElement);
+
+        this._insertChildTreeElement(parentTreeElement, childTreeElement);
+
+        if (wasSelected)
+            childTreeElement.revealAndSelect(true, false, true, true);
+    },
+
+    _compareTreeElementsByMainTitle: function(a, b)
+    {
+        return a.mainTitle.localeCompare(b.mainTitle);
+    },
+
+    _insertFolderTreeElement: function(folderTreeElement)
+    {
+        console.assert(this._groupedIntoFolders);
+        console.assert(!folderTreeElement.parent);
+        this.insertChild(folderTreeElement, insertionIndexForObjectInListSortedByFunction(folderTreeElement, this.children, this._compareTreeElementsByMainTitle));
+    },
+
+    _insertChildTreeElement: function(parentTreeElement, childTreeElement)
+    {
+        console.assert(!childTreeElement.parent);
+        parentTreeElement.insertChild(childTreeElement, insertionIndexForObjectInListSortedByFunction(childTreeElement, parentTreeElement.children, this.compareChildTreeElements));
+    },
+
+    _removeTreeElement: function(childTreeElement, suppressOnDeselect, suppressSelectSibling)
+    {
+        var oldParent = childTreeElement.parent;
+        if (!oldParent)
+            return;
+
+        oldParent.removeChild(childTreeElement, suppressOnDeselect, suppressSelectSibling);
+
+        if (oldParent === this)
+            return;
+
+        console.assert(oldParent instanceof WebInspector.FolderTreeElement);
+        if (!(oldParent instanceof WebInspector.FolderTreeElement))
+            return;
+
+        // Remove the old parent folder if it is now empty.
+        if (!oldParent.children.length)
+            oldParent.parent.removeChild(oldParent);
+    },
+
+    _parentTreeElementForRepresentedObject: function(representedObject)
+    {
+        if (!this._groupedIntoFolders)
+            return this;
+
+        console.assert(this._folderSettingsKey !== "");
+
+        function createFolderTreeElement(type, displayName)
+        {
+            var folderTreeElement = new WebInspector.FolderTreeElement(displayName);
+            folderTreeElement.__expandedSetting = new WebInspector.Setting(type + "-folder-expanded-" + this._folderSettingsKey, false);
+            if (folderTreeElement.__expandedSetting.value)
+                folderTreeElement.expand();
+            folderTreeElement.onexpand = this._folderTreeElementExpandedStateChange.bind(this);
+            folderTreeElement.oncollapse = this._folderTreeElementExpandedStateChange.bind(this);
+            return folderTreeElement;
+        }
+
+        var settings = this._settingsForRepresentedObject(representedObject);
+        if (!settings) {
+            console.error("Unknown representedObject", representedObject);
+            return this;
+        }
+
+        var folder = this._folderTypeMap.get(settings.type);
+        if (folder)
+            return folder;
+
+        folder = createFolderTreeElement.call(this, settings.type, settings.folderDisplayName);
+        this._folderTypeMap.set(settings.type, folder);
+        return folder;
+    },
+
+    _folderTreeElementExpandedStateChange: function(folderTreeElement)
+    {
+        console.assert(folderTreeElement.__expandedSetting);
+        folderTreeElement.__expandedSetting.value = folderTreeElement.expanded;
+    },
+
+    _settingsForRepresentedObject: function(representedObject)
+    {
+        for (var settings of this._folderizeSettingsMap.values()) {
+            if (settings.validateRepresentedObjectCallback(representedObject))
+                return settings;
+        }
+        return null;
+    },
+
+    _shouldGroupIntoFolders: function()
+    {
+        // Already grouped into folders, keep it that way.
+        if (this._groupedIntoFolders)
+            return true;
+
+        // Child objects are grouped into folders if one of two thresholds are met:
+        // 1) Once the number of medium categories passes NumberOfMediumCategoriesThreshold.
+        // 2) When there is a category that passes LargeChildCountThreshold and there are
+        //    any child objects in another category.
+
+        // Folders are avoided when there is only one category or most categories are small.
+
+        var numberOfSmallCategories = 0;
+        var numberOfMediumCategories = 0;
+        var foundLargeCategory = false;
+
+        function pushCategory(childCount)
+        {
+            if (!childCount)
+                return false;
+
+            // If this type has any resources and there is a known large category, make folders.
+            if (foundLargeCategory)
+                return true;
+
+            // If there are lots of this resource type, then count it as a large category.
+            if (childCount >= WebInspector.FolderizedTreeElement.LargeChildCountThreshold) {
+                // If we already have other resources in other small or medium categories, make folders.
+                if (numberOfSmallCategories || numberOfMediumCategories)
+                    return true;
+
+                foundLargeCategory = true;
+                return false;
+            }
+
+            // Check if this is a medium category.
+            if (childCount >= WebInspector.FolderizedTreeElement.MediumChildCountThreshold) {
+                // If this is the medium category that puts us over the maximum allowed, make folders.
+                return ++numberOfMediumCategories >= WebInspector.FolderizedTreeElement.NumberOfMediumCategoriesThreshold;
+            }
+
+            // This is a small category.
+            ++numberOfSmallCategories;
+            return false;
+        }
+
+        // Iterate over all the available child object types.
+        for (var settings of this._folderizeSettingsMap.values()) {
+            if (pushCategory(settings.countChildrenCallback()))
+                return true;
+        }
+        return false;
+    }
+};
index 867faf32a624bd195bb8062d9f87a5c77b2e4e94..a99564e1289de0d33d2da5cc44805721743b866f 100644 (file)
@@ -30,7 +30,6 @@ WebInspector.FrameTreeElement = function(frame, representedObject)
     WebInspector.ResourceTreeElement.call(this, frame.mainResource, representedObject || frame);
 
     this._frame = frame;
-    this._newChildQueue = [];
 
     this._updateExpandedSetting();
 
@@ -44,23 +43,52 @@ WebInspector.FrameTreeElement = function(frame, representedObject)
     frame.domTree.addEventListener(WebInspector.DOMTree.Event.ContentFlowWasRemoved, this._childContentFlowWasRemoved, this);
     frame.domTree.addEventListener(WebInspector.DOMTree.Event.RootDOMNodeInvalidated, this._rootDOMNodeInvalidated, this);
 
-    if (this._frame.isMainFrame()) {
+    if (this._frame.isMainFrame())
         this._downloadingPage = false;
-        WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
-        WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
-    }
 
-    this._updateParentStatus();
     this.shouldRefreshChildren = true;
-};
+    this.folderSettingsKey = this._frame.url.hash;
+
+    this.registerFolderizeSettings("frames", WebInspector.UIString("Frames"),
+        function(representedObject) { return representedObject instanceof WebInspector.Frame; },
+        function() { return this.frame.childFrames.length; }.bind(this),
+        WebInspector.FrameTreeElement
+    );
+
+    this.registerFolderizeSettings("flows", WebInspector.UIString("Flows"),
+        function(representedObject) { return representedObject instanceof WebInspector.ContentFlow; },
+        function() { return this.frame.domTree.flowsCount; }.bind(this),
+        WebInspector.ContentFlowTreeElement
+    );
+
+    function makeValidateCallback(resourceType) {
+        return function(representedObject) {
+            return representedObject instanceof WebInspector.Resource && representedObject.type === resourceType;
+        };
+    }
+
+    function makeChildCountCallback(frame, resourceType) {
+        return function() {
+            return frame.resourcesWithType(resourceType).length;
+        };
+    }
+
+    for (var key in WebInspector.Resource.Type) {
+        var value = WebInspector.Resource.Type[key];
+        var folderName = WebInspector.Resource.displayNameForType(value, true);
+        this.registerFolderizeSettings(key, folderName,
+            makeValidateCallback(value),
+            makeChildCountCallback(this.frame, value),
+            WebInspector.ResourceTreeElement
+        );
+    }
 
-WebInspector.FrameTreeElement.MediumChildCountThreshold = 5;
-WebInspector.FrameTreeElement.LargeChildCountThreshold = 15;
-WebInspector.FrameTreeElement.NumberOfMediumCategoriesThreshold = 2;
-WebInspector.FrameTreeElement.NewChildQueueUpdateInterval = 500;
+    this.updateParentStatus();
+};
 
 WebInspector.FrameTreeElement.prototype = {
     constructor: WebInspector.FrameTreeElement,
+    __proto__: WebInspector.ResourceTreeElement.prototype,
 
     // Public
 
@@ -99,7 +127,7 @@ WebInspector.FrameTreeElement.prototype = {
         if (!this._frame)
             return;
 
-        this._updateParentStatus();
+        this.updateParentStatus();
 
         if (this.resource && this.resource.sourceMaps.length)
             this.shouldRefreshChildren = true;
@@ -107,9 +135,46 @@ WebInspector.FrameTreeElement.prototype = {
 
     onattach: function()
     {
-        // Frames handle their own SourceMapResources.
-
+        // Immediate superclasses are skipped, since Frames handle their own SourceMapResources.
         WebInspector.GeneralTreeElement.prototype.onattach.call(this);
+
+        if (this._frame.isMainFrame()) {
+            WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
+            WebInspector.notifications.addEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
+        }
+    },
+
+    ondetach: function()
+    {
+        WebInspector.ResourceTreeElement.prototype.ondetach.call(this);
+
+        if (this._frame.isMainFrame()) {
+            WebInspector.notifications.removeEventListener(WebInspector.Notification.PageArchiveStarted, this._pageArchiveStarted, this);
+            WebInspector.notifications.removeEventListener(WebInspector.Notification.PageArchiveEnded, this._pageArchiveEnded, this);
+        }
+    },
+
+    // Overrides from FolderizedTreeElement (Protected).
+
+    compareChildTreeElements: function(a, b)
+    {
+        if (a === b)
+            return 0;
+
+        var aIsResource = a instanceof WebInspector.ResourceTreeElement;
+        var bIsResource = b instanceof WebInspector.ResourceTreeElement;
+
+        if (aIsResource && bIsResource)
+            return WebInspector.ResourceTreeElement.compareResourceTreeElements(a, b);
+
+        if (!aIsResource && !bIsResource) {
+            // When both components are not resources then default to base class comparison.
+            return WebInspector.ResourceTreeElement.prototype.compareChildTreeElements.call(this, a, b);
+        }
+
+        // Non-resources should appear before the resources.
+        // FIXME: There should be a better way to group the elements by their type.
+        return aIsResource ? 1 : -1;
     },
 
     // Called from ResourceTreeElement.
@@ -163,27 +228,23 @@ WebInspector.FrameTreeElement.prototype = {
         this.shouldRefreshChildren = false;
 
         this.removeChildren();
-        this._clearNewChildQueue();
-
-        if (this._shouldGroupIntoFolders() && !this._groupedIntoFolders)
-            this._groupedIntoFolders = true;
 
         for (var i = 0; i < this._frame.childFrames.length; ++i)
-            this._addTreeElementForRepresentedObject(this._frame.childFrames[i]);
+            this.addChildForRepresentedObject(this._frame.childFrames[i]);
 
         for (var i = 0; i < this._frame.resources.length; ++i)
-            this._addTreeElementForRepresentedObject(this._frame.resources[i]);
+            this.addChildForRepresentedObject(this._frame.resources[i]);
 
         var sourceMaps = this.resource && this.resource.sourceMaps;
         for (var i = 0; i < sourceMaps.length; ++i) {
             var sourceMap = sourceMaps[i];
             for (var j = 0; j < sourceMap.resources.length; ++j)
-            this._addTreeElementForRepresentedObject(sourceMap.resources[j]);
+                this.addChildForRepresentedObject(sourceMap.resources[j]);
         }
 
         var flowMap = this._frame.domTree.flowMap;
         for (var flowKey in flowMap)
-            this._addTreeElementForRepresentedObject(flowMap[flowKey]);
+            this.addChildForRepresentedObject(flowMap[flowKey]);
     },
 
     onexpand: function()
@@ -200,20 +261,6 @@ WebInspector.FrameTreeElement.prototype = {
             this._expandedSetting.value = false;
     },
 
-    removeChildren: function()
-    {
-        TreeElement.prototype.removeChildren.call(this);
-
-        if (this._framesFolderTreeElement)
-            this._framesFolderTreeElement.removeChildren();
-
-        for (var type in this._resourceFoldersTypeMap)
-            this._resourceFoldersTypeMap[type].removeChildren();
-
-        delete this._resourceFoldersTypeMap;
-        delete this._framesFolderTreeElement;
-    },
-
     // Private
 
     _updateExpandedSetting: function()
@@ -225,22 +272,11 @@ WebInspector.FrameTreeElement.prototype = {
             this.collapse();
     },
 
-    _updateParentStatus: function()
-    {
-        this.hasChildren = (this._frame.resources.length || this._frame.childFrames.length || (this.resource && this.resource.sourceMaps.length));
-        if (!this.hasChildren)
-            this.removeChildren();
-    },
-
     _mainResourceDidChange: function(event)
     {
         this._updateResource(this._frame.mainResource);
-        this._updateParentStatus();
-
-        this._groupedIntoFolders = false;
-
-        this._clearNewChildQueue();
 
+        this.updateParentStatus();
         this.removeChildren();
 
         // Change the expanded setting since the frame URL has changed. Do this before setting shouldRefreshChildren, since
@@ -255,342 +291,40 @@ WebInspector.FrameTreeElement.prototype = {
 
     _resourceWasAdded: function(event)
     {
-        this._addRepresentedObjectToNewChildQueue(event.data.resource);
+        this.addRepresentedObjectToNewChildQueue(event.data.resource);
     },
 
     _resourceWasRemoved: function(event)
     {
-        this._removeChildForRepresentedObject(event.data.resource);
+        this.removeChildForRepresentedObject(event.data.resource);
     },
 
     _childFrameWasAdded: function(event)
     {
-        this._addRepresentedObjectToNewChildQueue(event.data.childFrame);
+        this.addRepresentedObjectToNewChildQueue(event.data.childFrame);
     },
 
     _childFrameWasRemoved: function(event)
     {
-        this._removeChildForRepresentedObject(event.data.childFrame);
+        this.removeChildForRepresentedObject(event.data.childFrame);
     },
 
     _childContentFlowWasAdded: function(event)
     {
-        this._addRepresentedObjectToNewChildQueue(event.data.flow);
+        this.addRepresentedObjectToNewChildQueue(event.data.flow);
     },
 
     _childContentFlowWasRemoved: function(event)
     {
-        this._removeChildForRepresentedObject(event.data.flow);
+        this.removeChildForRepresentedObject(event.data.flow);
     },
 
-    _rootDOMNodeInvalidated: function() {
+    _rootDOMNodeInvalidated: function()
+    {
         if (this.expanded)
             this._frame.domTree.requestContentFlowList();
     },
 
-    _addRepresentedObjectToNewChildQueue: function(representedObject)
-    {
-        // This queue reduces flashing as resources load and change folders when their type becomes known.
-
-        this._newChildQueue.push(representedObject);
-        if (!this._newChildQueueTimeoutIdentifier)
-            this._newChildQueueTimeoutIdentifier = setTimeout(this._populateFromNewChildQueue.bind(this), WebInspector.FrameTreeElement.NewChildQueueUpdateInterval);
-    },
-
-    _removeRepresentedObjectFromNewChildQueue: function(representedObject)
-    {
-        this._newChildQueue.remove(representedObject);
-    },
-
-    _populateFromNewChildQueue: function()
-    {
-        if (!this.children.length) {
-            this._updateParentStatus();
-            this.shouldRefreshChildren = true;
-            return;
-        }
-
-        for (var i = 0; i < this._newChildQueue.length; ++i)
-            this._addChildForRepresentedObject(this._newChildQueue[i]);
-
-        this._newChildQueue = [];
-        this._newChildQueueTimeoutIdentifier = null;
-    },
-
-    _clearNewChildQueue: function()
-    {
-        this._newChildQueue = [];
-        if (this._newChildQueueTimeoutIdentifier) {
-            clearTimeout(this._newChildQueueTimeoutIdentifier);
-            this._newChildQueueTimeoutIdentifier = null;
-        }
-    },
-
-    _addChildForRepresentedObject: function(representedObject)
-    {
-        console.assert(representedObject instanceof WebInspector.Resource || representedObject instanceof WebInspector.Frame || representedObject instanceof WebInspector.ContentFlow);
-        if (!(representedObject instanceof WebInspector.Resource || representedObject instanceof WebInspector.Frame || representedObject instanceof WebInspector.ContentFlow))
-            return;
-
-        this._updateParentStatus();
-
-        if (!this.treeOutline) {
-            // Just mark as needing to update to avoid doing work that might not be needed.
-            this.shouldRefreshChildren = true;
-            return;
-        }
-
-        if (this._shouldGroupIntoFolders() && !this._groupedIntoFolders) {
-            // Mark as needing a refresh to rebuild the tree into folders.
-            this._groupedIntoFolders = true;
-            this.shouldRefreshChildren = true;
-            return;
-        }
-
-        this._addTreeElementForRepresentedObject(representedObject);
-    },
-
-    _removeChildForRepresentedObject: function(representedObject)
-    {
-        console.assert(representedObject instanceof WebInspector.Resource || representedObject instanceof WebInspector.Frame || representedObject instanceof WebInspector.ContentFlow);
-        if (!(representedObject instanceof WebInspector.Resource || representedObject instanceof WebInspector.Frame || representedObject instanceof WebInspector.ContentFlow))
-            return;
-
-        this._removeRepresentedObjectFromNewChildQueue(representedObject);
-
-        this._updateParentStatus();
-
-        if (!this.treeOutline) {
-            // Just mark as needing to update to avoid doing work that might not be needed.
-            this.shouldRefreshChildren = true;
-            return;
-        }
-
-        // Find the tree element for the frame by using getCachedTreeElement
-        // to only get the item if it has been created already.
-        var childTreeElement = this.treeOutline.getCachedTreeElement(representedObject);
-        if (!childTreeElement || !childTreeElement.parent)
-            return;
-
-        this._removeTreeElement(childTreeElement);
-    },
-
-    _addTreeElementForRepresentedObject: function(representedObject)
-    {
-        var childTreeElement = this.treeOutline.getCachedTreeElement(representedObject);
-        if (!childTreeElement) {
-            if (representedObject instanceof WebInspector.SourceMapResource)
-                childTreeElement = new WebInspector.SourceMapResourceTreeElement(representedObject);
-            else if (representedObject instanceof WebInspector.Resource)
-                childTreeElement = new WebInspector.ResourceTreeElement(representedObject);
-            else if (representedObject instanceof WebInspector.Frame)
-                childTreeElement = new WebInspector.FrameTreeElement(representedObject);
-            else if (representedObject instanceof WebInspector.ContentFlow)
-                childTreeElement = new WebInspector.ContentFlowTreeElement(representedObject);
-        }
-
-        this._addTreeElement(childTreeElement);
-    },
-
-    _addTreeElement: function(childTreeElement)
-    {
-        console.assert(childTreeElement);
-        if (!childTreeElement)
-            return;
-
-        var wasSelected = childTreeElement.selected;
-
-        this._removeTreeElement(childTreeElement, true, true);
-
-        var parentTreeElement = this._parentTreeElementForRepresentedObject(childTreeElement.representedObject);
-        if (parentTreeElement !== this && !parentTreeElement.parent)
-            this._insertFolderTreeElement(parentTreeElement);
-
-        this._insertResourceTreeElement(parentTreeElement, childTreeElement);
-
-        if (wasSelected)
-            childTreeElement.revealAndSelect(true, false, true, true);
-    },
-
-    _compareTreeElementsByMainTitle: function(a, b)
-    {
-        return a.mainTitle.localeCompare(b.mainTitle);
-    },
-
-    _insertFolderTreeElement: function(folderTreeElement)
-    {
-        console.assert(this._groupedIntoFolders);
-        console.assert(!folderTreeElement.parent);
-        this.insertChild(folderTreeElement, insertionIndexForObjectInListSortedByFunction(folderTreeElement, this.children, this._compareTreeElementsByMainTitle));
-    },
-
-    _compareResourceTreeElements: function(a, b)
-    {
-        if (a === b)
-            return 0;
-
-        var aIsResource = a instanceof WebInspector.ResourceTreeElement;
-        var bIsResource = b instanceof WebInspector.ResourceTreeElement;
-
-        if (aIsResource && bIsResource)
-            return WebInspector.ResourceTreeElement.compareResourceTreeElements(a, b);
-
-        if (!aIsResource && !bIsResource) {
-            // When both components are not resources then just compare the titles.
-            return a.mainTitle.localeCompare(b.mainTitle);
-        }
-
-        // Non-resources should appear before the resources.
-        // FIXME: There should be a better way to group the elements by their type.
-        return aIsResource ? 1 : -1;
-    },
-
-    _insertResourceTreeElement: function(parentTreeElement, childTreeElement)
-    {
-        console.assert(!childTreeElement.parent);
-        parentTreeElement.insertChild(childTreeElement, insertionIndexForObjectInListSortedByFunction(childTreeElement, parentTreeElement.children, this._compareResourceTreeElements));
-    },
-
-    _removeTreeElement: function(childTreeElement, suppressOnDeselect, suppressSelectSibling)
-    {
-        var oldParent = childTreeElement.parent;
-        if (!oldParent)
-            return;
-
-        oldParent.removeChild(childTreeElement, suppressOnDeselect, suppressSelectSibling);
-
-        if (oldParent === this)
-            return;
-
-        console.assert(oldParent instanceof WebInspector.FolderTreeElement);
-        if (!(oldParent instanceof WebInspector.FolderTreeElement))
-            return;
-
-        // Remove the old parent folder if it is now empty.
-        if (!oldParent.children.length)
-            oldParent.parent.removeChild(oldParent);
-    },
-
-    _folderNameForResourceType: function(type)
-    {
-        return WebInspector.Resource.Type.displayName(type, true);
-    },
-
-    _parentTreeElementForRepresentedObject: function(representedObject)
-    {
-        if (!this._groupedIntoFolders)
-            return this;
-
-        function createFolderTreeElement(type, displayName)
-        {
-            var folderTreeElement = new WebInspector.FolderTreeElement(displayName);
-            folderTreeElement._expandedSetting = new WebInspector.Setting(type + "-folder-expanded-" + this._frame.url.hash, false);
-            if (folderTreeElement._expandedSetting.value)
-                folderTreeElement.expand();
-            folderTreeElement.onexpand = this._folderTreeElementExpandedStateChange.bind(this);
-            folderTreeElement.oncollapse = this._folderTreeElementExpandedStateChange.bind(this);
-            return folderTreeElement;
-        }
-
-        if (representedObject instanceof WebInspector.Frame) {
-            if (!this._framesFolderTreeElement)
-                this._framesFolderTreeElement = createFolderTreeElement.call(this, "frames", WebInspector.UIString("Frames"));
-            return this._framesFolderTreeElement;
-        }
-
-        if (representedObject instanceof WebInspector.ContentFlow) {
-            if (!this._flowsFolderTreeElement)
-                this._flowsFolderTreeElement = createFolderTreeElement.call(this, "flows", WebInspector.UIString("Flows"));
-            return this._flowsFolderTreeElement;
-        }
-
-        if (representedObject instanceof WebInspector.Resource) {
-            var folderName = this._folderNameForResourceType(representedObject.type);
-            if (!folderName)
-                return this;
-
-            if (!this._resourceFoldersTypeMap)
-                this._resourceFoldersTypeMap = {};
-            if (!this._resourceFoldersTypeMap[representedObject.type])
-                this._resourceFoldersTypeMap[representedObject.type] = createFolderTreeElement.call(this, representedObject.type, folderName);
-            return this._resourceFoldersTypeMap[representedObject.type];
-        }
-
-        console.error("Unknown representedObject: ", representedObject);
-        return this;
-    },
-
-    _folderTreeElementExpandedStateChange: function(folderTreeElement)
-    {
-        console.assert(folderTreeElement._expandedSetting);
-        folderTreeElement._expandedSetting.value = folderTreeElement.expanded;
-    },
-
-    _shouldGroupIntoFolders: function()
-    {
-        // Already grouped into folders, keep it that way.
-        if (this._groupedIntoFolders)
-            return true;
-
-        // Resources and Frames are grouped into folders if one of two thresholds are met:
-        // 1) Once the number of medium categories passes NumberOfMediumCategoriesThreshold.
-        // 2) When there is a category that passes LargeChildCountThreshold and there are
-        //    any resources in another category.
-
-        // Folders are avoided when there is only one category or most categories are small.
-
-        var numberOfSmallCategories = 0;
-        var numberOfMediumCategories = 0;
-        var foundLargeCategory = false;
-        var frame = this._frame;
-
-        function pushResourceType(type) {
-            // There are some other properties on WebInspector.Resource.Type that we need to skip, like private data and functions
-            if (type.charAt(0) === "_")
-                return false;
-
-            // Only care about the values that are strings, not functions, etc.
-            var typeValue = WebInspector.Resource.Type[type];
-            if (typeof typeValue !== "string")
-                return false;
-
-            return pushCategory(frame.resourcesWithType(typeValue).length);
-        }
-
-        function pushCategory(resourceCount)
-        {
-            if (!resourceCount)
-                return false;
-
-            // If this type has any resources and there is a known large category, make folders.
-            if (foundLargeCategory)
-                return true;
-
-            // If there are lots of this resource type, then count it as a large category.
-            if (resourceCount >= WebInspector.FrameTreeElement.LargeChildCountThreshold) {
-                // If we already have other resources in other small or medium categories, make folders.
-                if (numberOfSmallCategories || numberOfMediumCategories)
-                    return true;
-
-                foundLargeCategory = true;
-                return false;
-            }
-
-            // Check if this is a medium category.
-            if (resourceCount >= WebInspector.FrameTreeElement.MediumChildCountThreshold) {
-                // If this is the medium category that puts us over the maximum allowed, make folders.
-                return ++numberOfMediumCategories >= WebInspector.FrameTreeElement.NumberOfMediumCategoriesThreshold;
-            }
-
-            // This is a small category.
-            ++numberOfSmallCategories;
-            return false;
-        }
-
-        // Iterate over all the available resource types.
-        return pushCategory(frame.childFrames.length) || pushCategory(frame.domTree.flowsCount) || Object.keys(WebInspector.Resource.Type).some(pushResourceType);
-    },
-
     _reloadPageClicked: function(event)
     {
         // Ignore cache when the shift key is pressed.
@@ -633,5 +367,3 @@ WebInspector.FrameTreeElement.prototype = {
         this._updateDownloadButton();
     }
 };
-
-WebInspector.FrameTreeElement.prototype.__proto__ = WebInspector.ResourceTreeElement.prototype;
index 6d06249a6624a107abb98a5e87a6eea4896a2345..5e1ca81d2baf56ba6d70a08af0befca61a4ec1c4 100644 (file)
@@ -64,7 +64,7 @@ WebInspector.LayoutTimelineDataGridNode.prototype = {
 
         switch (columnIdentifier) {
         case "eventType":
-            return WebInspector.LayoutTimelineRecord.EventType.displayName(value);
+            return WebInspector.LayoutTimelineRecord.displayNameForEventType(value);
 
         case "width":
         case "height":
index a0002e5910ca132e5a0150fc18a0ee0da2e2f3f1..d48635a153d184be74d97861e2581e203017087b 100644 (file)
@@ -38,7 +38,14 @@ WebInspector.LayoutTimelineView = function(timeline)
 
     columns.eventType.title = WebInspector.UIString("Type");
     columns.eventType.width = "15%";
-    columns.eventType.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", WebInspector.LayoutTimelineRecord.EventType);
+
+    var typeToLabelMap = new Map;
+    for (var key in WebInspector.LayoutTimelineRecord.EventType) {
+        var value = WebInspector.LayoutTimelineRecord.EventType[key];
+        typeToLabelMap.set(value, WebInspector.LayoutTimelineRecord.displayNameForEventType(value));
+    }
+
+    columns.eventType.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("layout", typeToLabelMap);
     columns.eventType.hidden = true;
 
     columns.initiatorCallFrame.title = WebInspector.UIString("Initiator");
index 68077236c78253d2a24593bca477c949abe19a8b..75feb8d107a1859eb536f1b5b22a8fc2ad93c251 100644 (file)
@@ -41,7 +41,14 @@ WebInspector.NetworkTimelineView = function(timeline)
 
     columns.type.title = WebInspector.UIString("Type");
     columns.type.width = "8%";
-    columns.type.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("network", WebInspector.Resource.Type);
+
+    var typeToLabelMap = new Map;
+    for (var key in WebInspector.Resource.Type) {
+        var value = WebInspector.Resource.Type[key];
+        typeToLabelMap.set(value, WebInspector.Resource.displayNameForType(value, true));
+    }
+
+    columns.type.scopeBar = WebInspector.TimelineDataGrid.createColumnScopeBar("network", typeToLabelMap);
 
     columns.method.title = WebInspector.UIString("Method");
     columns.method.width = "6%";
index 293c62ff95b23244650db14f8b518e455588cf4f..cde7d3cfd214289b4ebaba7d1bb72ece0567262b 100644 (file)
@@ -245,7 +245,7 @@ WebInspector.ResourceDetailsSidebarPanel.prototype = {
         if (!this._resource)
             return;
 
-        this._typeResourceTypeRow.value = WebInspector.Resource.Type.displayName(this._resource.type);
+        this._typeResourceTypeRow.value = WebInspector.Resource.displayNameForType(this._resource.type);
     },
 
     _refreshMIMEType: function()
index 3ada5012ae6bd11f7065f94463eff7ed63c07176..9b6ac7d1bdaedae5de263c9cef574b85a7c1e7bc 100644 (file)
@@ -127,7 +127,7 @@ WebInspector.ResourceTimelineDataGridNode.prototype = {
             return fragment;
 
         case "type":
-            return WebInspector.Resource.Type.displayName(value);
+            return WebInspector.Resource.displayNameForType(value);
 
         case "statusCode":
             cell.title = resource.statusText || "";
index d885eb28decfb8beb85ebe28037c469b57d32654..8703d7b39370554432fd3367db153cc122abdaa5 100644 (file)
@@ -27,7 +27,7 @@ WebInspector.SourceCodeTreeElement = function(sourceCode, classNames, title, sub
 {
     console.assert(sourceCode instanceof WebInspector.SourceCode);
 
-    WebInspector.GeneralTreeElement.call(this, classNames, title, subtitle, representedObject || sourceCode, hasChildren);
+    WebInspector.FolderizedTreeElement.call(this, classNames, title, subtitle, representedObject || sourceCode, hasChildren);
 
     this.small = true;
 
@@ -36,6 +36,7 @@ WebInspector.SourceCodeTreeElement = function(sourceCode, classNames, title, sub
 
 WebInspector.SourceCodeTreeElement.prototype = {
     constructor: WebInspector.SourceCodeTreeElement,
+    __proto__: WebInspector.FolderizedTreeElement.prototype,
 
     // Public
 
@@ -204,5 +205,3 @@ WebInspector.SourceCodeTreeElement.prototype = {
         this.updateSourceMapResources();
     }
 };
-
-WebInspector.SourceCodeTreeElement.prototype.__proto__ = WebInspector.GeneralTreeElement.prototype;
index 0b9eae60d6d3e2e8110b584146c5b380078d0d7c..083b7bbaffab3ccda466939ac5fb27c5c0fb5c4b 100644 (file)
@@ -77,16 +77,11 @@ WebInspector.TimelineDataGrid.createColumnScopeBar = function(prefix, dictionary
 {
     prefix = prefix + "-timeline-data-grid-";
 
-    var keys = Object.keys(dictionary).filter(function(key) {
-        return typeof dictionary[key] === "string" || dictionary[key] instanceof String;
-    });
-
-    var scopeBarItems = keys.map(function(key) {
-        var value = dictionary[key];
-        var id = prefix + value;
-        var label = dictionary.displayName(value, true);
+    var scopeBarItems = Object.keys(dictionary).map(function(key) {
+        var id = prefix + key;
+        var label = dictionary[key];
         var item = new WebInspector.ScopeBarItem(id, label);
-        item.value = value;
+        item.value = key;
         return item;
     });
 
index f2261e631dd6940b1fc172c1ff7225c811b7eb74..8421ba488d50554f8a33ca50e9030feb0d9f2b90 100644 (file)
@@ -46,7 +46,7 @@ WebInspector.TimelineRecordTreeElement = function(timelineRecord, subtitleNameSt
 
     switch (timelineRecord.type) {
     case WebInspector.TimelineRecord.Type.Layout:
-        title = WebInspector.LayoutTimelineRecord.EventType.displayName(timelineRecord.eventType);
+        title = WebInspector.LayoutTimelineRecord.displayNameForEventType(timelineRecord.eventType);
 
         switch (timelineRecord.eventType) {
         case WebInspector.LayoutTimelineRecord.EventType.InvalidateStyles:
index f4fa9f0763457ce677a5330db09a0d1bcb8d0ff9..958cd0c8e9a6fc589cf1fe318c38e67140349586 100644 (file)
     <None Include="..\UserInterface\FlexibleSpaceNavigationItem.js" />
     <None Include="..\UserInterface\FolderIcon.css" />
     <None Include="..\UserInterface\FolderTreeElement.js" />
+    <None Include="..\UserInterface\FolderizedTreeElement.js" />
     <None Include="..\UserInterface\FontResourceContentView.css" />
     <None Include="..\UserInterface\FontResourceContentView.js" />
     <None Include="..\UserInterface\Formatter.js" />
index 5795fd53ace5addea43d702773bfbbf9f4750aa2..069e48288148da032e5ff3712f2d6769217dcc7c 100644 (file)
     <None Include="..\UserInterface\FolderTreeElement.js">
       <Filter>UserInterface</Filter>
     </None>
+    <None Include="..\UserInterface\FolderizedTreeElement.js">
+      <Filter>UserInterface</Filter>
+    </None>
     <None Include="..\UserInterface\FontResourceContentView.css">
       <Filter>UserInterface</Filter>
     </None>