Title: [229443] trunk/Source/WebInspectorUI
Revision
229443
Author
nvasil...@apple.com
Date
2018-03-08 17:32:51 -0800 (Thu, 08 Mar 2018)

Log Message

Web Inspector: Sources: add SourcesTabContentView and SourceSidebarPanel classes
https://bugs.webkit.org/show_bug.cgi?id=183316
<rdar://problem/38107639>

Reviewed by Matt Baker.

Add Sources tab and sidebar panel, which are copies of the corresponding Resources classes.
The Sources tab is shown when it's enabled in the experimental settings. This patch doesn't
remove existing Resources and Debugger tabs.

* UserInterface/Base/Main.js:
(WI.contentLoaded):
* UserInterface/Main.html:
* UserInterface/Views/SourcesSidebarPanel.css: Added.
(.sidebar > .panel.navigation.sources > .content):
(.sidebar > .panel.navigation.sources > .navigation-bar):
* UserInterface/Views/SourcesSidebarPanel.js: Added.
(WI.SourcesSidebarPanel):
(WI.SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel):
(WI.SourcesSidebarPanel.prototype.get minimumWidth):
(WI.SourcesSidebarPanel.prototype.closed):
(WI.SourcesSidebarPanel.prototype.showDefaultContentView):
(WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject.isAncestor):
(WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject.getParent):
(WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject):
(WI.SourcesSidebarPanel.prototype.initialLayout):
(WI.SourcesSidebarPanel.prototype.hasCustomFilters):
(WI.SourcesSidebarPanel.prototype.matchTreeElementAgainstCustomFilters.match):
(WI.SourcesSidebarPanel.prototype.matchTreeElementAgainstCustomFilters):
(WI.SourcesSidebarPanel.prototype._mainResourceDidChange):
(WI.SourcesSidebarPanel.prototype._mainFrameDidChange):
(WI.SourcesSidebarPanel.prototype._mainFrameMainResourceDidChange.delayedWork):
(WI.SourcesSidebarPanel.prototype._mainFrameMainResourceDidChange):
(WI.SourcesSidebarPanel.prototype._scriptWasAdded):
(WI.SourcesSidebarPanel.prototype._addScript):
(WI.SourcesSidebarPanel.prototype._scriptWasRemoved):
(WI.SourcesSidebarPanel.prototype._scriptsCleared):
(WI.SourcesSidebarPanel.prototype._styleSheetAdded):
(WI.SourcesSidebarPanel.prototype._addTargetWithMainResource):
(WI.SourcesSidebarPanel.prototype._targetRemoved):
(WI.SourcesSidebarPanel.prototype._treeSelectionDidChange):
(WI.SourcesSidebarPanel.prototype._compareTreeElements):
(WI.SourcesSidebarPanel.prototype._extraDomainsActivated):
(WI.SourcesSidebarPanel.prototype._scopeBarSelectionDidChange):
* UserInterface/Views/SourcesTabContentView.js: Added.
(WI.SourcesTabContentView):
(WI.SourcesTabContentView.tabInfo):
(WI.SourcesTabContentView.isTabAllowed):
(WI.SourcesTabContentView.prototype.get type):
(WI.SourcesTabContentView.prototype.get supportsSplitContentBrowser):
(WI.SourcesTabContentView.prototype.canShowRepresentedObject):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (229442 => 229443)


--- trunk/Source/WebInspectorUI/ChangeLog	2018-03-09 00:59:58 UTC (rev 229442)
+++ trunk/Source/WebInspectorUI/ChangeLog	2018-03-09 01:32:51 UTC (rev 229443)
@@ -1,3 +1,57 @@
+2018-03-08  Nikita Vasilyev  <nvasil...@apple.com>
+
+        Web Inspector: Sources: add SourcesTabContentView and SourceSidebarPanel classes
+        https://bugs.webkit.org/show_bug.cgi?id=183316
+        <rdar://problem/38107639>
+
+        Reviewed by Matt Baker.
+
+        Add Sources tab and sidebar panel, which are copies of the corresponding Resources classes.
+        The Sources tab is shown when it's enabled in the experimental settings. This patch doesn't
+        remove existing Resources and Debugger tabs.
+
+        * UserInterface/Base/Main.js:
+        (WI.contentLoaded):
+        * UserInterface/Main.html:
+        * UserInterface/Views/SourcesSidebarPanel.css: Added.
+        (.sidebar > .panel.navigation.sources > .content):
+        (.sidebar > .panel.navigation.sources > .navigation-bar):
+        * UserInterface/Views/SourcesSidebarPanel.js: Added.
+        (WI.SourcesSidebarPanel):
+        (WI.SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel):
+        (WI.SourcesSidebarPanel.prototype.get minimumWidth):
+        (WI.SourcesSidebarPanel.prototype.closed):
+        (WI.SourcesSidebarPanel.prototype.showDefaultContentView):
+        (WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject.isAncestor):
+        (WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject.getParent):
+        (WI.SourcesSidebarPanel.prototype.treeElementForRepresentedObject):
+        (WI.SourcesSidebarPanel.prototype.initialLayout):
+        (WI.SourcesSidebarPanel.prototype.hasCustomFilters):
+        (WI.SourcesSidebarPanel.prototype.matchTreeElementAgainstCustomFilters.match):
+        (WI.SourcesSidebarPanel.prototype.matchTreeElementAgainstCustomFilters):
+        (WI.SourcesSidebarPanel.prototype._mainResourceDidChange):
+        (WI.SourcesSidebarPanel.prototype._mainFrameDidChange):
+        (WI.SourcesSidebarPanel.prototype._mainFrameMainResourceDidChange.delayedWork):
+        (WI.SourcesSidebarPanel.prototype._mainFrameMainResourceDidChange):
+        (WI.SourcesSidebarPanel.prototype._scriptWasAdded):
+        (WI.SourcesSidebarPanel.prototype._addScript):
+        (WI.SourcesSidebarPanel.prototype._scriptWasRemoved):
+        (WI.SourcesSidebarPanel.prototype._scriptsCleared):
+        (WI.SourcesSidebarPanel.prototype._styleSheetAdded):
+        (WI.SourcesSidebarPanel.prototype._addTargetWithMainResource):
+        (WI.SourcesSidebarPanel.prototype._targetRemoved):
+        (WI.SourcesSidebarPanel.prototype._treeSelectionDidChange):
+        (WI.SourcesSidebarPanel.prototype._compareTreeElements):
+        (WI.SourcesSidebarPanel.prototype._extraDomainsActivated):
+        (WI.SourcesSidebarPanel.prototype._scopeBarSelectionDidChange):
+        * UserInterface/Views/SourcesTabContentView.js: Added.
+        (WI.SourcesTabContentView):
+        (WI.SourcesTabContentView.tabInfo):
+        (WI.SourcesTabContentView.isTabAllowed):
+        (WI.SourcesTabContentView.prototype.get type):
+        (WI.SourcesTabContentView.prototype.get supportsSplitContentBrowser):
+        (WI.SourcesTabContentView.prototype.canShowRepresentedObject):
+
 2018-03-07  Devin Rousso  <web...@devinrousso.com>
 
         Web Inspector: Canvas tab: ensure that the Recording TreeOutline has a specified height for virtualization

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Main.js (229442 => 229443)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2018-03-09 00:59:58 UTC (rev 229442)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Main.js	2018-03-09 01:32:51 UTC (rev 229443)
@@ -440,6 +440,7 @@
     let productionTabClasses = [
         WI.ElementsTabContentView,
         WI.NetworkTabContentView,
+        WI.SourcesTabContentView,
         WI.DebuggerTabContentView,
         WI.ResourcesTabContentView,
         WI.TimelineTabContentView,

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (229442 => 229443)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2018-03-09 00:59:58 UTC (rev 229442)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2018-03-09 01:32:51 UTC (rev 229443)
@@ -179,6 +179,7 @@
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
+    <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
     <link rel="stylesheet" href=""
@@ -527,6 +528,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
 
@@ -741,6 +743,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
 
     <script src=""

Added: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.css (0 => 229443)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.css	2018-03-09 01:32:51 UTC (rev 229443)
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+.sidebar > .panel.navigation.sources > .content {
+    top: var(--navigation-bar-height);
+}
+
+.sidebar > .panel.navigation.sources > .navigation-bar {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+}

Added: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.js (0 => 229443)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesSidebarPanel.js	2018-03-09 01:32:51 UTC (rev 229443)
@@ -0,0 +1,504 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+WI.SourcesSidebarPanel = class SourcesSidebarPanel extends WI.NavigationSidebarPanel
+{
+    constructor()
+    {
+        super("sources", WI.UIString("Sources"), true);
+
+        this._navigationBar = new WI.NavigationBar;
+        this.addSubview(this._navigationBar);
+
+        this._targetTreeElementMap = new Map;
+
+        let scopeItemPrefix = "sources-sidebar-";
+        let scopeBarItems = [];
+
+        scopeBarItems.push(new WI.ScopeBarItem(scopeItemPrefix + "type-all", WI.UIString("All Resources"), true));
+
+        for (let key in WI.Resource.Type) {
+            let value = WI.Resource.Type[key];
+            let scopeBarItem = new WI.ScopeBarItem(scopeItemPrefix + value, WI.Resource.displayNameForType(value, true));
+            scopeBarItem[WI.SourcesSidebarPanel.ResourceTypeSymbol] = value;
+            scopeBarItems.push(scopeBarItem);
+        }
+
+        this._scopeBar = new WI.ScopeBar("sources-sidebar-scope-bar", scopeBarItems, scopeBarItems[0], true);
+        this._scopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._scopeBarSelectionDidChange, this);
+
+        this._navigationBar.addNavigationItem(this._scopeBar);
+
+        WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
+
+        WI.frameResourceManager.addEventListener(WI.FrameResourceManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);
+
+        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptAdded, this._scriptWasAdded, this);
+        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptRemoved, this._scriptWasRemoved, this);
+        WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
+
+        WI.cssStyleManager.addEventListener(WI.CSSStyleManager.Event.StyleSheetAdded, this._styleSheetAdded, this);
+
+        WI.targetManager.addEventListener(WI.TargetManager.Event.TargetRemoved, this._targetRemoved, this);
+
+        WI.notifications.addEventListener(WI.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
+
+        this.contentTreeOutline.addEventListener(WI.TreeOutline.Event.SelectionDidChange, this._treeSelectionDidChange, this);
+        this.contentTreeOutline.includeSourceMapResourceChildren = true;
+
+        if (SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel()) {
+            this.contentTreeOutline.disclosureButtons = false;
+            WI.SourceCode.addEventListener(WI.SourceCode.Event.SourceMapAdded, () => { this.contentTreeOutline.disclosureButtons = true; }, this);
+        }
+    }
+
+    // Static
+
+    static shouldPlaceResourcesAtTopLevel()
+    {
+        return (WI.sharedApp.debuggableType === WI.DebuggableType._javascript_ && !WI.sharedApp.hasExtraDomains)
+            || WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker;
+    }
+
+    // Public
+
+    get minimumWidth()
+    {
+        return this._navigationBar.minimumWidth;
+    }
+
+    closed()
+    {
+        super.closed();
+
+        WI.Frame.removeEventListener(null, null, this);
+        WI.frameResourceManager.removeEventListener(null, null, this);
+        WI.debuggerManager.removeEventListener(null, null, this);
+        WI.notifications.removeEventListener(null, null, this);
+    }
+
+    showDefaultContentView()
+    {
+        if (WI.frameResourceManager.mainFrame) {
+            this.contentBrowser.showContentViewForRepresentedObject(WI.frameResourceManager.mainFrame);
+            return;
+        }
+
+        let firstTreeElement = this.contentTreeOutline.children[0];
+        if (firstTreeElement)
+            this.showDefaultContentViewForTreeElement(firstTreeElement);
+    }
+
+    treeElementForRepresentedObject(representedObject)
+    {
+        // A custom implementation is needed for this since the frames are populated lazily.
+
+        if (!this._mainFrameTreeElement && (representedObject instanceof WI.Resource || representedObject instanceof WI.Frame || representedObject instanceof WI.Collection)) {
+            // All resources are under the main frame, so we need to return early if we don't have the main frame yet.
+            return null;
+        }
+
+        // The Frame is used as the representedObject instead of the main resource in our tree.
+        if (representedObject instanceof WI.Resource && representedObject.parentFrame && representedObject.parentFrame.mainResource === representedObject)
+            representedObject = representedObject.parentFrame;
+
+        function isAncestor(ancestor, resourceOrFrame)
+        {
+            // SourceMapResources are descendants of another SourceCode object.
+            if (resourceOrFrame instanceof WI.SourceMapResource) {
+                if (resourceOrFrame.sourceMap.originalSourceCode === ancestor)
+                    return true;
+
+                // Not a direct ancestor, so check the ancestors of the parent SourceCode object.
+                resourceOrFrame = resourceOrFrame.sourceMap.originalSourceCode;
+            }
+
+            let currentFrame = resourceOrFrame.parentFrame;
+            while (currentFrame) {
+                if (currentFrame === ancestor)
+                    return true;
+                currentFrame = currentFrame.parentFrame;
+            }
+
+            return false;
+        }
+
+        function getParent(resourceOrFrame)
+        {
+            // SourceMapResources are descendants of another SourceCode object.
+            if (resourceOrFrame instanceof WI.SourceMapResource)
+                return resourceOrFrame.sourceMap.originalSourceCode;
+            return resourceOrFrame.parentFrame;
+        }
+
+        let treeElement = this.contentTreeOutline.findTreeElement(representedObject, isAncestor, getParent);
+        if (treeElement)
+            return treeElement;
+
+        // Only special case Script objects.
+        if (!(representedObject instanceof WI.Script)) {
+            console.error("Didn't find a TreeElement for representedObject", representedObject);
+            return null;
+        }
+
+        // If the Script has a URL we should have found it earlier.
+        if (representedObject.url) {
+            console.error("Didn't find a ScriptTreeElement for a Script with a URL.");
+            return null;
+        }
+
+        // Since the Script does not have a URL we consider it an 'anonymous' script. These scripts happen from calls to
+        // window.eval() or browser features like Auto Fill and Reader. They are not normally added to the sidebar, but since
+        // we have a ScriptContentView asking for the tree element we will make a ScriptTreeElement on demand and add it.
+
+        if (!this._anonymousScriptsFolderTreeElement) {
+            let collection = new WI.ScriptCollection;
+            this._anonymousScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Anonymous Scripts"), collection);
+        }
+
+        if (!this._anonymousScriptsFolderTreeElement.parent) {
+            let index = insertionIndexForObjectInListSortedByFunction(this._anonymousScriptsFolderTreeElement, this.contentTreeOutline.children, this._compareTreeElements);
+            this.contentTreeOutline.insertChild(this._anonymousScriptsFolderTreeElement, index);
+        }
+
+        this._anonymousScriptsFolderTreeElement.representedObject.add(representedObject);
+
+        let scriptTreeElement = new WI.ScriptTreeElement(representedObject);
+        this._anonymousScriptsFolderTreeElement.appendChild(scriptTreeElement);
+
+        return scriptTreeElement;
+    }
+
+    // Protected
+
+    initialLayout()
+    {
+        super.initialLayout();
+
+        if (WI.frameResourceManager.mainFrame)
+            this._mainFrameMainResourceDidChange(WI.frameResourceManager.mainFrame);
+
+        for (let script of WI.debuggerManager.knownNonResourceScripts) {
+            this._addScript(script);
+
+            if (script.sourceMaps.length && SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel())
+                this.contentTreeOutline.disclosureButtons = true;
+        }
+    }
+
+    hasCustomFilters()
+    {
+        console.assert(this._scopeBar.selectedItems.length === 1);
+        let selectedScopeBarItem = this._scopeBar.selectedItems[0];
+        return selectedScopeBarItem && !selectedScopeBarItem.exclusive;
+    }
+
+    matchTreeElementAgainstCustomFilters(treeElement, flags)
+    {
+        console.assert(this._scopeBar.selectedItems.length === 1);
+        let selectedScopeBarItem = this._scopeBar.selectedItems[0];
+
+        // Show everything if there is no selection or "All Resources" is selected (the exclusive item).
+        if (!selectedScopeBarItem || selectedScopeBarItem.exclusive)
+            return true;
+
+        // Folders are hidden on the first pass, but visible childen under the folder will force the folder visible again.
+        if (treeElement instanceof WI.FolderTreeElement)
+            return false;
+
+        function match()
+        {
+            if (treeElement instanceof WI.FrameTreeElement)
+                return selectedScopeBarItem[WI.SourcesSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.Document;
+
+            if (treeElement instanceof WI.ScriptTreeElement)
+                return selectedScopeBarItem[WI.SourcesSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.Script;
+
+            if (treeElement instanceof WI.CSSStyleSheetTreeElement)
+                return selectedScopeBarItem[WI.SourcesSidebarPanel.ResourceTypeSymbol] === WI.Resource.Type.Stylesheet;
+
+            console.assert(treeElement instanceof WI.ResourceTreeElement, "Unknown treeElement", treeElement);
+            if (!(treeElement instanceof WI.ResourceTreeElement))
+                return false;
+
+            return treeElement.resource.type === selectedScopeBarItem[WI.SourcesSidebarPanel.ResourceTypeSymbol];
+        }
+
+        let matched = match();
+        if (matched)
+            flags.expandTreeElement = true;
+        return matched;
+    }
+
+    // Private
+
+    _mainResourceDidChange(event)
+    {
+        if (!event.target.isMainFrame())
+            return;
+
+        this._mainFrameMainResourceDidChange(event.target);
+    }
+
+    _mainFrameDidChange(event)
+    {
+        this._mainFrameMainResourceDidChange(WI.frameResourceManager.mainFrame);
+    }
+
+    _mainFrameMainResourceDidChange(mainFrame)
+    {
+        this.contentBrowser.contentViewContainer.closeAllContentViews();
+
+        if (this._mainFrameTreeElement) {
+            this.contentTreeOutline.removeChild(this._mainFrameTreeElement);
+            this._mainFrameTreeElement = null;
+        }
+
+        if (!mainFrame)
+            return;
+
+        this._mainFrameTreeElement = new WI.FrameTreeElement(mainFrame);
+        this.contentTreeOutline.insertChild(this._mainFrameTreeElement, 0);
+
+        function delayedWork()
+        {
+            if (!this.contentTreeOutline.selectedTreeElement) {
+                let currentContentView = this.contentBrowser.currentContentView;
+                let treeElement = currentContentView ? this.treeElementForRepresentedObject(currentContentView.representedObject) : null;
+                if (!treeElement)
+                    treeElement = this._mainFrameTreeElement;
+                this.showDefaultContentViewForTreeElement(treeElement);
+            }
+        }
+
+        // Cookie restoration will attempt to re-select the resource we were showing.
+        // Give it time to do that before selecting the main frame resource.
+        setTimeout(delayedWork.bind(this));
+    }
+
+    _scriptWasAdded(event)
+    {
+        this._addScript(event.data.script);
+    }
+
+    _addScript(script)
+    {
+        // We don't add scripts without URLs here. Those scripts can quickly clutter the interface and
+        // are usually more transient. They will get added if/when they need to be shown in a content view.
+        if (!script.url && !script.sourceURL)
+            return;
+
+        // Target main resource.
+        if (script.target !== WI.pageTarget) {
+            if (script.isMainResource())
+                this._addTargetWithMainResource(script.target);
+            this.contentTreeOutline.disclosureButtons = true;
+            return;
+        }
+
+        // If the script URL matches a resource we can assume it is part of that resource and does not need added.
+        if (script.resource || script.dynamicallyAddedScriptElement)
+            return;
+
+        let insertIntoTopLevel = false;
+        let parentFolderTreeElement = null;
+
+        if (script.injected) {
+            if (!this._extensionScriptsFolderTreeElement) {
+                let collection = new WI.ScriptCollection;
+                this._extensionScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extension Scripts"), collection);
+            }
+
+            parentFolderTreeElement = this._extensionScriptsFolderTreeElement;
+        } else {
+            if (SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel())
+                insertIntoTopLevel = true;
+            else {
+                if (!this._extraScriptsFolderTreeElement) {
+                    let collection = new WI.ScriptCollection;
+                    this._extraScriptsFolderTreeElement = new WI.FolderTreeElement(WI.UIString("Extra Scripts"), collection);
+                }
+
+                parentFolderTreeElement = this._extraScriptsFolderTreeElement;
+            }
+        }
+
+        if (parentFolderTreeElement)
+            parentFolderTreeElement.representedObject.add(script);
+
+        let scriptTreeElement = new WI.ScriptTreeElement(script);
+
+        if (insertIntoTopLevel) {
+            let index = insertionIndexForObjectInListSortedByFunction(scriptTreeElement, this.contentTreeOutline.children, this._compareTreeElements);
+            this.contentTreeOutline.insertChild(scriptTreeElement, index);
+        } else {
+            if (!parentFolderTreeElement.parent) {
+                let index = insertionIndexForObjectInListSortedByFunction(parentFolderTreeElement, this.contentTreeOutline.children, this._compareTreeElements);
+                this.contentTreeOutline.insertChild(parentFolderTreeElement, index);
+            }
+
+            parentFolderTreeElement.appendChild(scriptTreeElement);
+        }
+    }
+
+    _scriptWasRemoved(event)
+    {
+        let script = event.data.script;
+        let scriptTreeElement = this.contentTreeOutline.getCachedTreeElement(script);
+        if (!scriptTreeElement)
+            return;
+
+        let parentTreeElement = scriptTreeElement.parent;
+        parentTreeElement.removeChild(scriptTreeElement);
+
+        if (parentTreeElement instanceof WI.FolderTreeElement) {
+            parentTreeElement.representedObject.remove(script);
+
+            if (!parentTreeElement.children.length)
+                parentTreeElement.parent.removeChild(parentTreeElement);
+        }
+    }
+
+    _scriptsCleared(event)
+    {
+        const suppressOnDeselect = true;
+        const suppressSelectSibling = true;
+
+        if (this._extensionScriptsFolderTreeElement) {
+            if (this._extensionScriptsFolderTreeElement.parent)
+                this._extensionScriptsFolderTreeElement.parent.removeChild(this._extensionScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);
+
+            this._extensionScriptsFolderTreeElement.representedObject.clear();
+            this._extensionScriptsFolderTreeElement = null;
+        }
+
+        if (this._extraScriptsFolderTreeElement) {
+            if (this._extraScriptsFolderTreeElement.parent)
+                this._extraScriptsFolderTreeElement.parent.removeChild(this._extraScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);
+
+            this._extraScriptsFolderTreeElement.representedObject.clear();
+            this._extraScriptsFolderTreeElement = null;
+        }
+
+        if (this._anonymousScriptsFolderTreeElement) {
+            if (this._anonymousScriptsFolderTreeElement.parent)
+                this._anonymousScriptsFolderTreeElement.parent.removeChild(this._anonymousScriptsFolderTreeElement, suppressOnDeselect, suppressSelectSibling);
+
+            this._anonymousScriptsFolderTreeElement.representedObject.clear();
+            this._anonymousScriptsFolderTreeElement = null;
+        }
+
+        if (this._targetTreeElementMap.size) {
+            for (let treeElement of this._targetTreeElementMap)
+                treeElement.parent.removeChild(treeElement, suppressOnDeselect, suppressSelectSibling);
+            this._targetTreeElementMap.clear();
+        }
+    }
+
+    _styleSheetAdded(event)
+    {
+        let styleSheet = event.data.styleSheet;
+        if (!styleSheet.isInspectorStyleSheet())
+            return;
+
+        let frameTreeElement = this.treeElementForRepresentedObject(styleSheet.parentFrame);
+        if (!frameTreeElement)
+            return;
+
+        frameTreeElement.addRepresentedObjectToNewChildQueue(styleSheet);
+    }
+
+    _addTargetWithMainResource(target)
+    {
+        console.assert(target.type === WI.Target.Type.Worker || target.type === WI.Target.Type.ServiceWorker);
+
+        let targetTreeElement = new WI.WorkerTreeElement(target);
+        this._targetTreeElementMap.set(target, targetTreeElement);
+
+        let index = insertionIndexForObjectInListSortedByFunction(targetTreeElement, this.contentTreeOutline.children, this._compareTreeElements);
+        this.contentTreeOutline.insertChild(targetTreeElement, index);
+    }
+
+    _targetRemoved(event)
+    {
+        let removedTarget = event.data.target;
+
+        let targetTreeElement = this._targetTreeElementMap.take(removedTarget);
+        if (targetTreeElement)
+            targetTreeElement.parent.removeChild(targetTreeElement);
+    }
+
+    _treeSelectionDidChange(event)
+    {
+        if (!this.visible)
+            return;
+
+        let treeElement = event.data.selectedElement;
+        if (!treeElement)
+            return;
+
+        if (treeElement instanceof WI.FolderTreeElement
+            || treeElement instanceof WI.ResourceTreeElement
+            || treeElement instanceof WI.ScriptTreeElement
+            || treeElement instanceof WI.CSSStyleSheetTreeElement) {
+            const cookie = null;
+            const options = {
+                ignoreNetworkTab: true,
+                ignoreSearchTab: true,
+            };
+            WI.showRepresentedObject(treeElement.representedObject, cookie, options);
+            return;
+        }
+
+        console.error("Unknown tree element", treeElement);
+    }
+
+    _compareTreeElements(a, b)
+    {
+        // Always sort the main frame element first.
+        if (a instanceof WI.FrameTreeElement)
+            return -1;
+        if (b instanceof WI.FrameTreeElement)
+            return 1;
+
+        console.assert(a.mainTitle);
+        console.assert(b.mainTitle);
+
+        return (a.mainTitle || "").extendedLocaleCompare(b.mainTitle || "");
+    }
+
+    _extraDomainsActivated()
+    {
+        if (SourcesSidebarPanel.shouldPlaceResourcesAtTopLevel())
+            this.contentTreeOutline.disclosureButtons = true;
+    }
+
+    _scopeBarSelectionDidChange(event)
+    {
+        this.updateFilter();
+    }
+};
+
+WI.SourcesSidebarPanel.ResourceTypeSymbol = Symbol("resource-type");

Added: trunk/Source/WebInspectorUI/UserInterface/Views/SourcesTabContentView.js (0 => 229443)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SourcesTabContentView.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourcesTabContentView.js	2018-03-09 01:32:51 UTC (rev 229443)
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2018 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.
+ */
+
+WI.SourcesTabContentView = class SourcesTabContentView extends WI.ContentBrowserTabContentView
+{
+    constructor(identifier)
+    {
+        let tabBarItem = WI.GeneralTabBarItem.fromTabInfo(WI.SourcesTabContentView.tabInfo());
+        const detailsSidebarPanelConstructors = [WI.ResourceDetailsSidebarPanel, WI.ProbeDetailsSidebarPanel];
+        super(identifier || "sources", "sources", tabBarItem, WI.SourcesSidebarPanel, detailsSidebarPanelConstructors);
+    }
+
+    static tabInfo()
+    {
+        return {
+            image: "Images/Resources.svg",
+            title: WI.UIString("Sources"),
+        };
+    }
+
+    static isTabAllowed()
+    {
+        return WI.settings.experimentalEnableSourcesTab.value;
+    }
+
+    // Public
+
+    get type()
+    {
+        return WI.SourcesTabContentView.Type;
+    }
+
+    get supportsSplitContentBrowser()
+    {
+        return true;
+    }
+
+    canShowRepresentedObject(representedObject)
+    {
+        return representedObject instanceof WI.Frame
+            || representedObject instanceof WI.Resource
+            || representedObject instanceof WI.Script
+            || representedObject instanceof WI.CSSStyleSheet
+            || (representedObject instanceof WI.Collection && !(representedObject instanceof WI.CanvasCollection));
+    }
+};
+
+WI.SourcesTabContentView.Type = "sources";
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to