Changeset 182041 in webkit


Ignore:
Timestamp:
Mar 26, 2015 4:37:55 PM (9 years ago)
Author:
timothy@apple.com
Message:

Web Inspector: Convert sidebar classes to ES6
https://bugs.webkit.org/show_bug.cgi?id=143108

Reviewed by Joseph Pecoraro.

  • UserInterface/Models/KeyboardShortcut.js:

(WebInspector.KeyboardShortcut._handleKeyDown): Continue if callback is null.
(WebInspector.KeyboardShortcut.prototype.set callback): Added.

  • UserInterface/Views/ApplicationCacheDetailsSidebarPanel.js:
  • UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
  • UserInterface/Views/DOMDetailsSidebarPanel.js:
  • UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
  • UserInterface/Views/DebuggerSidebarPanel.js:
  • UserInterface/Views/DetailsSidebarPanel.js:
  • UserInterface/Views/LayerTreeDetailsSidebarPanel.js:
  • UserInterface/Views/NavigationSidebarPanel.js:
  • UserInterface/Views/ProbeDetailsSidebarPanel.js:
  • UserInterface/Views/ResourceDetailsSidebarPanel.js:
  • UserInterface/Views/ResourceSidebarPanel.js:
  • UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
  • UserInterface/Views/Sidebar.js:
  • UserInterface/Views/SidebarPanel.js:
  • UserInterface/Views/TimelineSidebarPanel.js:

Converted to ES6 classes.

Location:
trunk/Source/WebInspectorUI
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r182040 r182041  
     12015-03-26  Timothy Hatcher  <timothy@apple.com>
     2
     3        Web Inspector: Convert sidebar classes to ES6
     4        https://bugs.webkit.org/show_bug.cgi?id=143108
     5
     6        Reviewed by Joseph Pecoraro.
     7
     8        * UserInterface/Models/KeyboardShortcut.js:
     9        (WebInspector.KeyboardShortcut._handleKeyDown): Continue if callback is null.
     10        (WebInspector.KeyboardShortcut.prototype.set callback): Added.
     11
     12        * UserInterface/Views/ApplicationCacheDetailsSidebarPanel.js:
     13        * UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
     14        * UserInterface/Views/DOMDetailsSidebarPanel.js:
     15        * UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
     16        * UserInterface/Views/DebuggerSidebarPanel.js:
     17        * UserInterface/Views/DetailsSidebarPanel.js:
     18        * UserInterface/Views/LayerTreeDetailsSidebarPanel.js:
     19        * UserInterface/Views/NavigationSidebarPanel.js:
     20        * UserInterface/Views/ProbeDetailsSidebarPanel.js:
     21        * UserInterface/Views/ResourceDetailsSidebarPanel.js:
     22        * UserInterface/Views/ResourceSidebarPanel.js:
     23        * UserInterface/Views/ScopeChainDetailsSidebarPanel.js:
     24        * UserInterface/Views/Sidebar.js:
     25        * UserInterface/Views/SidebarPanel.js:
     26        * UserInterface/Views/TimelineSidebarPanel.js:
     27        Converted to ES6 classes.
     28
    1292015-03-26  Timothy Hatcher  <timothy@apple.com>
    230
  • trunk/Source/WebInspectorUI/UserInterface/Models/KeyboardShortcut.js

    r181769 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    7979                    continue;
    8080
     81                if (!keyboardShortcut.callback)
     82                    continue;
     83
    8184                keyboardShortcut.callback(event, keyboardShortcut);
    8285
     
    122125    {
    123126        return this._callback;
     127    }
     128
     129    set callback(callback)
     130    {
     131        console.assert(!callback || typeof callback === "function");
     132
     133        this._callback = callback || null;
    124134    }
    125135
  • trunk/Source/WebInspectorUI/UserInterface/Views/ApplicationCacheDetailsSidebarPanel.js

    r175767 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.ApplicationCacheDetailsSidebarPanel = function()
     26WebInspector.ApplicationCacheDetailsSidebarPanel = class ApplicationCacheDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
    2727{
    28     WebInspector.DetailsSidebarPanel.call(this, "application-cache-details", WebInspector.UIString("Storage"), WebInspector.UIString("Storage"), "Images/NavigationItemStorage.svg");
     28    constructor()
     29    {
     30        super("application-cache-details", WebInspector.UIString("Storage"), WebInspector.UIString("Storage"), "Images/NavigationItemStorage.svg");
    2931
    30     this.element.classList.add(WebInspector.ApplicationCacheDetailsSidebarPanel.StyleClassName);
     32        this.element.classList.add("application-cache");
    3133
    32     this._applicationCacheFrame = null;
     34        this._applicationCacheFrame = null;
    3335
    34     this._locationManifestURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Manifest URL"));
    35     this._locationFrameURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Frame URL"));
     36        this._locationManifestURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Manifest URL"));
     37        this._locationFrameURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Frame URL"));
    3638
    37     this._locationGroup = new WebInspector.DetailsSectionGroup([this._locationManifestURLRow, this._locationFrameURLRow]);
     39        this._locationGroup = new WebInspector.DetailsSectionGroup([this._locationManifestURLRow, this._locationFrameURLRow]);
    3840
    39     this._locationSection = new WebInspector.DetailsSection("application-cache-location", WebInspector.UIString("Location"), [this._locationGroup]);
     41        this._locationSection = new WebInspector.DetailsSection("application-cache-location", WebInspector.UIString("Location"), [this._locationGroup]);
    4042
    41     this._onlineRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Online"));
    42     this._statusRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Status"));
     43        this._onlineRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Online"));
     44        this._statusRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Status"));
    4345
    44     this._statusGroup = new WebInspector.DetailsSectionGroup([this._onlineRow, this._statusRow]);
     46        this._statusGroup = new WebInspector.DetailsSectionGroup([this._onlineRow, this._statusRow]);
    4547
    46     this._statusSection = new WebInspector.DetailsSection("application-cache-status", WebInspector.UIString("Status"), [this._statusGroup]);
     48        this._statusSection = new WebInspector.DetailsSection("application-cache-status", WebInspector.UIString("Status"), [this._statusGroup]);
    4749
    48     this.contentElement.appendChild(this._locationSection.element);
    49     this.contentElement.appendChild(this._statusSection.element);
     50        this.contentElement.appendChild(this._locationSection.element);
     51        this.contentElement.appendChild(this._statusSection.element);
    5052
    51     WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.NetworkStateUpdated, this._networkStateUpdated, this);
    52     WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestStatusChanged, this._frameManifestStatusChanged, this);
    53 };
    54 
    55 WebInspector.ApplicationCacheDetailsSidebarPanel.StyleClassName = "application-cache";
    56 
    57 // This needs to be kept in sync with ApplicationCacheManager.js.
    58 WebInspector.ApplicationCacheDetailsSidebarPanel.Status = {
    59     0: "Uncached",
    60     1: "Idle",
    61     2: "Checking",
    62     3: "Downloading",
    63     4: "UpdateReady",
    64     5: "Obsolete"
    65 };
    66 
    67 WebInspector.ApplicationCacheDetailsSidebarPanel.prototype = {
    68     constructor: WebInspector.ApplicationCacheDetailsSidebarPanel,
    69     __proto__: WebInspector.DetailsSidebarPanel.prototype,
     53        WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.NetworkStateUpdated, this._networkStateUpdated, this);
     54        WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestStatusChanged, this._frameManifestStatusChanged, this);
     55    }
    7056
    7157    // Public
    7258
    73     inspect: function(objects)
     59    inspect(objects)
    7460    {
    7561        // Convert to a single item array if needed.
     
    9076
    9177        return !!this.applicationCacheFrame;
    92     },
     78    }
    9379
    9480    get applicationCacheFrame()
    9581    {
    9682        return this._applicationCacheFrame;
    97     },
     83    }
    9884
    9985    set applicationCacheFrame(applicationCacheFrame)
     
    10591
    10692        this.needsRefresh();
    107     },
     93    }
    10894
    109     refresh: function()
     95    refresh()
    11096    {
    11197        if (!this.applicationCacheFrame)
     
    117103        this._refreshOnlineRow();
    118104        this._refreshStatusRow();
    119     },
     105    }
    120106
    121107    // Private
    122108
    123     _networkStateUpdated: function(event)
     109    _networkStateUpdated(event)
    124110    {
    125111        if (!this.applicationCacheFrame)
     
    127113
    128114        this._refreshOnlineRow();
    129     },
     115    }
    130116
    131     _frameManifestStatusChanged: function(event)
     117    _frameManifestStatusChanged(event)
    132118    {
    133119        if (!this.applicationCacheFrame)
     
    139125
    140126        this._refreshStatusRow();
    141     },
     127    }
    142128
    143     _refreshOnlineRow: function()
     129    _refreshOnlineRow()
    144130    {
    145131        this._onlineRow.value = WebInspector.applicationCacheManager.online ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
    146     },
     132    }
    147133
    148     _refreshStatusRow: function()
     134    _refreshStatusRow()
    149135    {
    150136        this._statusRow.value = WebInspector.ApplicationCacheDetailsSidebarPanel.Status[this.applicationCacheFrame.status];
    151137    }
    152138};
     139
     140// This needs to be kept in sync with ApplicationCacheManager.js.
     141WebInspector.ApplicationCacheDetailsSidebarPanel.Status = {
     142    0: "Uncached",
     143    1: "Idle",
     144    2: "Checking",
     145    3: "Downloading",
     146    4: "UpdateReady",
     147    5: "Obsolete"
     148};
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js

    r175767 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.CSSStyleDetailsSidebarPanel = function()
     26WebInspector.CSSStyleDetailsSidebarPanel = class CSSStyleDetailsSidebarPanel extends WebInspector.DOMDetailsSidebarPanel
    2727{
    28     WebInspector.DOMDetailsSidebarPanel.call(this, "css-style", WebInspector.UIString("Styles"), WebInspector.UIString("Style"), "Images/NavigationItemBrushAndRuler.svg", "4");
    29 
    30     this._selectedPanel = null;
    31 
    32     this._navigationBar = new WebInspector.NavigationBar(null, null, "tablist");
    33     this._navigationBar.addEventListener(WebInspector.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
    34     this.element.insertBefore(this._navigationBar.element, this.contentElement);
    35 
    36     this._forcedPseudoClassCheckboxes = {};
    37 
    38     if (WebInspector.cssStyleManager.canForcePseudoClasses()) {
    39         this._forcedPseudoClassContainer = document.createElement("div");
    40         this._forcedPseudoClassContainer.className = WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesElementStyleClassName;
    41 
    42         var groupElement = null;
    43 
    44         WebInspector.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
    45             // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
    46             var label = pseudoClass.capitalize();
    47 
    48             var labelElement = document.createElement("label");
    49 
    50             var checkboxElement = document.createElement("input");
    51             checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
    52             checkboxElement.type = "checkbox";
    53 
    54             this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
    55 
    56             labelElement.appendChild(checkboxElement);
    57             labelElement.appendChild(document.createTextNode(label));
    58 
    59             if (!groupElement || groupElement.children.length === 2) {
    60                 groupElement = document.createElement("div");
    61                 groupElement.className = WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesGroupElementStyleClassName;
    62                 this._forcedPseudoClassContainer.appendChild(groupElement);
    63             }
    64 
    65             groupElement.appendChild(labelElement);
    66         }, this);
    67 
    68         this.contentElement.appendChild(this._forcedPseudoClassContainer);
    69     }
    70 
    71     this._computedStyleDetailsPanel = new WebInspector.ComputedStyleDetailsPanel;
    72     this._rulesStyleDetailsPanel = new WebInspector.RulesStyleDetailsPanel;
    73     this._metricsStyleDetailsPanel = new WebInspector.MetricsStyleDetailsPanel;
    74 
    75     this._panels = [this._computedStyleDetailsPanel, this._rulesStyleDetailsPanel, this._metricsStyleDetailsPanel];
    76 
    77     this._navigationBar.addNavigationItem(this._computedStyleDetailsPanel.navigationItem);
    78     this._navigationBar.addNavigationItem(this._rulesStyleDetailsPanel.navigationItem);
    79     this._navigationBar.addNavigationItem(this._metricsStyleDetailsPanel.navigationItem);
    80 
    81     this._lastSelectedSectionSetting = new WebInspector.Setting("last-selected-style-details-panel", this._rulesStyleDetailsPanel.navigationItem.identifier);
    82 
    83     // This will cause the selected panel to be set in _navigationItemSelected.
    84     this._navigationBar.selectedNavigationItem = this._lastSelectedSectionSetting.value;
    85 };
    86 
    87 WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesElementStyleClassName = "pseudo-classes";
    88 WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesGroupElementStyleClassName = "group";
    89 WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 38; // Default height of the forced pseudo classes container. Updated in widthDidChange.
    90 
    91 WebInspector.CSSStyleDetailsSidebarPanel.prototype = {
    92     constructor: WebInspector.CSSStyleDetailsSidebarPanel,
    93     __proto__: WebInspector.DOMDetailsSidebarPanel.prototype,
     28    constructor()
     29    {
     30        super("css-style", WebInspector.UIString("Styles"), WebInspector.UIString("Style"), "Images/NavigationItemBrushAndRuler.svg", "4");
     31
     32        this._selectedPanel = null;
     33
     34        this._navigationBar = new WebInspector.NavigationBar(null, null, "tablist");
     35        this._navigationBar.addEventListener(WebInspector.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
     36        this.element.insertBefore(this._navigationBar.element, this.contentElement);
     37
     38        this._forcedPseudoClassCheckboxes = {};
     39
     40        if (WebInspector.cssStyleManager.canForcePseudoClasses()) {
     41            this._forcedPseudoClassContainer = document.createElement("div");
     42            this._forcedPseudoClassContainer.className = WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesElementStyleClassName;
     43
     44            var groupElement = null;
     45
     46            WebInspector.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
     47                // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
     48                var label = pseudoClass.capitalize();
     49
     50                var labelElement = document.createElement("label");
     51
     52                var checkboxElement = document.createElement("input");
     53                checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
     54                checkboxElement.type = "checkbox";
     55
     56                this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
     57
     58                labelElement.appendChild(checkboxElement);
     59                labelElement.appendChild(document.createTextNode(label));
     60
     61                if (!groupElement || groupElement.children.length === 2) {
     62                    groupElement = document.createElement("div");
     63                    groupElement.className = WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesGroupElementStyleClassName;
     64                    this._forcedPseudoClassContainer.appendChild(groupElement);
     65                }
     66
     67                groupElement.appendChild(labelElement);
     68            }, this);
     69
     70            this.contentElement.appendChild(this._forcedPseudoClassContainer);
     71        }
     72
     73        this._computedStyleDetailsPanel = new WebInspector.ComputedStyleDetailsPanel;
     74        this._rulesStyleDetailsPanel = new WebInspector.RulesStyleDetailsPanel;
     75        this._metricsStyleDetailsPanel = new WebInspector.MetricsStyleDetailsPanel;
     76
     77        this._panels = [this._computedStyleDetailsPanel, this._rulesStyleDetailsPanel, this._metricsStyleDetailsPanel];
     78
     79        this._navigationBar.addNavigationItem(this._computedStyleDetailsPanel.navigationItem);
     80        this._navigationBar.addNavigationItem(this._rulesStyleDetailsPanel.navigationItem);
     81        this._navigationBar.addNavigationItem(this._metricsStyleDetailsPanel.navigationItem);
     82
     83        this._lastSelectedSectionSetting = new WebInspector.Setting("last-selected-style-details-panel", this._rulesStyleDetailsPanel.navigationItem.identifier);
     84
     85        // This will cause the selected panel to be set in _navigationItemSelected.
     86        this._navigationBar.selectedNavigationItem = this._lastSelectedSectionSetting.value;
     87    }
    9488
    9589    // Public
    9690
    97     supportsDOMNode: function(nodeToInspect)
     91    supportsDOMNode(nodeToInspect)
    9892    {
    9993        return nodeToInspect.nodeType() === Node.ELEMENT_NODE;
    100     },
    101 
    102     refresh: function()
     94    }
     95
     96    refresh()
    10397    {
    10498        var domNode = this.domNode;
     
    114108
    115109        this._updatePseudoClassCheckboxes();
    116     },
    117 
    118     visibilityDidChange: function()
     110    }
     111
     112    visibilityDidChange()
    119113    {
    120114        WebInspector.SidebarPanel.prototype.visibilityDidChange.call(this);
     
    134128        this._selectedPanel.shown();
    135129        this._selectedPanel.markAsNeedsRefresh(this.domNode);
    136     },
    137 
    138     widthDidChange: function()
     130    }
     131
     132    widthDidChange()
    139133    {
    140134        this._updateNoForcedPseudoClassesScrollOffset();
     
    142136        if (this._selectedPanel)
    143137            this._selectedPanel.widthDidChange();
    144     },
     138    }
    145139
    146140    // Protected
    147141
    148     addEventListeners: function()
     142    addEventListeners()
    149143    {
    150144        this.domNode.addEventListener(WebInspector.DOMNode.Event.EnabledPseudoClassesChanged, this._updatePseudoClassCheckboxes, this);
    151     },
    152 
    153     removeEventListeners: function()
     145    }
     146
     147    removeEventListeners()
    154148    {
    155149        this.domNode.removeEventListener(null, null, this);
    156     },
     150    }
    157151
    158152    // Private
     
    163157            return 0;
    164158        return this.domNode && this.domNode.enabledPseudoClasses.length ? 0 : WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset;
    165     },
    166 
    167     _updateNoForcedPseudoClassesScrollOffset: function()
     159    }
     160
     161    _updateNoForcedPseudoClassesScrollOffset()
    168162    {
    169163        if (this._forcedPseudoClassContainer)
    170164            WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = this._forcedPseudoClassContainer.offsetHeight;
    171     },
    172 
    173     _navigationItemSelected: function(event)
     165    }
     166
     167    _navigationItemSelected(event)
    174168    {
    175169        console.assert(event.target.selectedNavigationItem);
     
    209203
    210204        this._lastSelectedSectionSetting.value = selectedNavigationItem.identifier;
    211     },
    212 
    213     _forcedPseudoClassCheckboxChanged: function(pseudoClass, event)
     205    }
     206
     207    _forcedPseudoClassCheckboxChanged(pseudoClass, event)
    214208    {
    215209        if (!this.domNode)
     
    217211
    218212        this.domNode.setPseudoClassEnabled(pseudoClass, event.target.checked);
    219     },
    220 
    221     _updatePseudoClassCheckboxes: function()
     213    }
     214
     215    _updatePseudoClassCheckboxes()
    222216    {
    223217        if (!this.domNode)
     
    232226    }
    233227};
     228
     229WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesElementStyleClassName = "pseudo-classes";
     230WebInspector.CSSStyleDetailsSidebarPanel.PseudoClassesGroupElementStyleClassName = "group";
     231WebInspector.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 38; // Default height of the forced pseudo classes container. Updated in widthDidChange.
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMDetailsSidebarPanel.js

    r175767 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.DOMDetailsSidebarPanel = function(identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element)
     26WebInspector.DOMDetailsSidebarPanel = class DOMDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
    2727{
    28     WebInspector.DetailsSidebarPanel.call(this, identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element);
     28    constructor(identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element)
     29    {
     30        super(identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element);
    2931
    30     this.element.addEventListener("click", this._mouseWasClicked.bind(this), true);
     32        this.element.addEventListener("click", this._mouseWasClicked.bind(this), true);
    3133
    32     this._domNode = null;
    33 };
    34 
    35 WebInspector.DOMDetailsSidebarPanel.prototype = {
    36     constructor: WebInspector.DOMDetailsSidebarPanel,
    37     __proto__: WebInspector.DetailsSidebarPanel.prototype,
     34        this._domNode = null;
     35    }
    3836
    3937    // Public
    4038
    41     inspect: function(objects)
     39    inspect(objects)
    4240    {
    4341        // Convert to a single item array if needed.
     
    6159
    6260        return !!this._domNode;
    63     },
     61    }
    6462
    6563    get domNode()
    6664    {
    6765        return this._domNode;
    68     },
     66    }
    6967
    7068    set domNode(domNode)
     
    8280
    8381        this.needsRefresh();
    84     },
     82    }
    8583
    86     supportsDOMNode: function(nodeToInspect)
     84    supportsDOMNode(nodeToInspect)
    8785    {
    8886        // Implemented by subclasses.
    8987        return true;
    90     },
     88    }
    9189
    92     addEventListeners: function()
     90    addEventListeners()
    9391    {
    9492        // Implemented by subclasses.
    95     },
     93    }
    9694
    97     removeEventListeners: function()
     95    removeEventListeners()
    9896    {
    9997        // Implemented by subclasses.
    100     },
     98    }
    10199
    102100    // Private
    103101
    104     _mouseWasClicked: function(event)
     102    _mouseWasClicked(event)
    105103    {
    106104        if (this._domNode && this._domNode.ownerDocument) {
  • trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js

    r181723 r182041  
    11/*
    2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.DOMNodeDetailsSidebarPanel = function()
     26WebInspector.DOMNodeDetailsSidebarPanel = class DOMNodeDetailsSidebarPanel extends WebInspector.DOMDetailsSidebarPanel
    2727{
    28     WebInspector.DOMDetailsSidebarPanel.call(this, "dom-node-details", WebInspector.UIString("Node"), WebInspector.UIString("Node"), "Images/NavigationItemAngleBrackets.svg", "2");
    29 
    30     WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeModified, this._attributesChanged, this);
    31     WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeRemoved, this._attributesChanged, this);
    32     WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.CharacterDataModified, this._characterDataModified, this);
    33 
    34     this.element.classList.add(WebInspector.DOMNodeDetailsSidebarPanel.StyleClassName);
    35 
    36     this._identityNodeTypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Type"));
    37     this._identityNodeNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Name"));
    38     this._identityNodeValueRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Value"));
    39 
    40     var identityGroup = new WebInspector.DetailsSectionGroup([this._identityNodeTypeRow, this._identityNodeNameRow, this._identityNodeValueRow]);
    41     var identitySection = new WebInspector.DetailsSection("dom-node-identity", WebInspector.UIString("Identity"), [identityGroup]);
    42 
    43     this._attributesDataGridRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Attributes"));
    44 
    45     var attributesGroup = new WebInspector.DetailsSectionGroup([this._attributesDataGridRow]);
    46     var attributesSection = new WebInspector.DetailsSection("dom-node-attributes", WebInspector.UIString("Attributes"), [attributesGroup]);
    47 
    48     this._propertiesRow = new WebInspector.DetailsSectionRow;
    49 
    50     var propertiesGroup = new WebInspector.DetailsSectionGroup([this._propertiesRow]);
    51     var propertiesSection = new WebInspector.DetailsSection("dom-node-properties", WebInspector.UIString("Properties"), [propertiesGroup]);
    52 
    53     this._eventListenersSectionGroup = new WebInspector.DetailsSectionGroup;
    54     var eventListenersSection = new WebInspector.DetailsSection("dom-node-event-listeners", WebInspector.UIString("Event Listeners"), [this._eventListenersSectionGroup]);   
    55 
    56     this.contentElement.appendChild(identitySection.element);
    57     this.contentElement.appendChild(attributesSection.element);
    58     this.contentElement.appendChild(propertiesSection.element);
    59     this.contentElement.appendChild(eventListenersSection.element);
    60 
    61     if (this._accessibilitySupported()) {
    62         this._accessibilityEmptyRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Accessibility Information"));
    63         this._accessibilityNodeActiveDescendantRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Shared Focus"));
    64         this._accessibilityNodeBusyRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Busy"));
    65         this._accessibilityNodeCheckedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Checked"));
    66         this._accessibilityNodeChildrenRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Children"));
    67         this._accessibilityNodeControlsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Controls"));
    68         this._accessibilityNodeDisabledRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Disabled"));
    69         this._accessibilityNodeExpandedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Expanded"));
    70         this._accessibilityNodeFlowsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Flows"));
    71         this._accessibilityNodeFocusedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Focused"));
    72         this._accessibilityNodeIgnoredRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Ignored"));
    73         this._accessibilityNodeInvalidRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Invalid"));
    74         this._accessibilityNodeLiveRegionStatusRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Live"));
    75         this._accessibilityNodeMouseEventRow = new WebInspector.DetailsSectionSimpleRow("");
    76         this._accessibilityNodeLabelRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Label"));
    77         this._accessibilityNodeOwnsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Owns"));
    78         this._accessibilityNodeParentRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Parent"));
    79         this._accessibilityNodePressedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Pressed"));
    80         this._accessibilityNodeReadonlyRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Readonly"));
    81         this._accessibilityNodeRequiredRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Required"));
    82         this._accessibilityNodeRoleRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Role"));
    83         this._accessibilityNodeSelectedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Selected"));
    84         this._accessibilityNodeSelectedChildrenRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Selected Items"));
    85    
    86         this._accessibilityGroup = new WebInspector.DetailsSectionGroup([this._accessibilityEmptyRow]);
    87         var accessibilitySection = new WebInspector.DetailsSection("dom-node-accessibility", WebInspector.UIString("Accessibility"), [this._accessibilityGroup]);   
    88 
    89         this.contentElement.appendChild(accessibilitySection.element);
    90     }
    91 };
    92 
    93 WebInspector.DOMNodeDetailsSidebarPanel.StyleClassName = "dom-node";
    94 WebInspector.DOMNodeDetailsSidebarPanel.PropertiesObjectGroupName = "dom-node-details-sidebar-properties-object-group";
    95 
    96 WebInspector.DOMNodeDetailsSidebarPanel.prototype = {
    97     constructor: WebInspector.DOMNodeDetailsSidebarPanel,
    98     __proto__: WebInspector.DOMDetailsSidebarPanel.prototype,
     28    constructor()
     29    {
     30        super("dom-node-details", WebInspector.UIString("Node"), WebInspector.UIString("Node"), "Images/NavigationItemAngleBrackets.svg", "2");
     31
     32        WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeModified, this._attributesChanged, this);
     33        WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.AttributeRemoved, this._attributesChanged, this);
     34        WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.CharacterDataModified, this._characterDataModified, this);
     35
     36        this.element.classList.add("dom-node");
     37
     38        this._identityNodeTypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Type"));
     39        this._identityNodeNameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Name"));
     40        this._identityNodeValueRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Value"));
     41
     42        var identityGroup = new WebInspector.DetailsSectionGroup([this._identityNodeTypeRow, this._identityNodeNameRow, this._identityNodeValueRow]);
     43        var identitySection = new WebInspector.DetailsSection("dom-node-identity", WebInspector.UIString("Identity"), [identityGroup]);
     44
     45        this._attributesDataGridRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Attributes"));
     46
     47        var attributesGroup = new WebInspector.DetailsSectionGroup([this._attributesDataGridRow]);
     48        var attributesSection = new WebInspector.DetailsSection("dom-node-attributes", WebInspector.UIString("Attributes"), [attributesGroup]);
     49
     50        this._propertiesRow = new WebInspector.DetailsSectionRow;
     51
     52        var propertiesGroup = new WebInspector.DetailsSectionGroup([this._propertiesRow]);
     53        var propertiesSection = new WebInspector.DetailsSection("dom-node-properties", WebInspector.UIString("Properties"), [propertiesGroup]);
     54
     55        this._eventListenersSectionGroup = new WebInspector.DetailsSectionGroup;
     56        var eventListenersSection = new WebInspector.DetailsSection("dom-node-event-listeners", WebInspector.UIString("Event Listeners"), [this._eventListenersSectionGroup]);
     57
     58        this.contentElement.appendChild(identitySection.element);
     59        this.contentElement.appendChild(attributesSection.element);
     60        this.contentElement.appendChild(propertiesSection.element);
     61        this.contentElement.appendChild(eventListenersSection.element);
     62
     63        if (this._accessibilitySupported()) {
     64            this._accessibilityEmptyRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Accessibility Information"));
     65            this._accessibilityNodeActiveDescendantRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Shared Focus"));
     66            this._accessibilityNodeBusyRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Busy"));
     67            this._accessibilityNodeCheckedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Checked"));
     68            this._accessibilityNodeChildrenRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Children"));
     69            this._accessibilityNodeControlsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Controls"));
     70            this._accessibilityNodeDisabledRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Disabled"));
     71            this._accessibilityNodeExpandedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Expanded"));
     72            this._accessibilityNodeFlowsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Flows"));
     73            this._accessibilityNodeFocusedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Focused"));
     74            this._accessibilityNodeIgnoredRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Ignored"));
     75            this._accessibilityNodeInvalidRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Invalid"));
     76            this._accessibilityNodeLiveRegionStatusRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Live"));
     77            this._accessibilityNodeMouseEventRow = new WebInspector.DetailsSectionSimpleRow("");
     78            this._accessibilityNodeLabelRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Label"));
     79            this._accessibilityNodeOwnsRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Owns"));
     80            this._accessibilityNodeParentRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Parent"));
     81            this._accessibilityNodePressedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Pressed"));
     82            this._accessibilityNodeReadonlyRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Readonly"));
     83            this._accessibilityNodeRequiredRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Required"));
     84            this._accessibilityNodeRoleRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Role"));
     85            this._accessibilityNodeSelectedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Selected"));
     86            this._accessibilityNodeSelectedChildrenRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Selected Items"));
     87
     88            this._accessibilityGroup = new WebInspector.DetailsSectionGroup([this._accessibilityEmptyRow]);
     89            var accessibilitySection = new WebInspector.DetailsSection("dom-node-accessibility", WebInspector.UIString("Accessibility"), [this._accessibilityGroup]);
     90
     91            this.contentElement.appendChild(accessibilitySection.element);
     92        }
     93        }
    9994
    10095    // Public
    10196
    102     refresh: function()
     97    refresh()
    10398    {
    10499        var domNode = this.domNode;
     
    114109        this._refreshEventListeners();
    115110        this._refreshAccessibility();
    116     },
     111    }
    117112
    118113    // Private
    119114
    120     _accessibilitySupported: function()
     115    _accessibilitySupported()
    121116    {
    122117        return window.DOMAgent && DOMAgent.getAccessibilityPropertiesForNode;
    123     },
    124 
    125     _refreshAttributes: function()
     118    }
     119
     120    _refreshAttributes()
    126121    {
    127122        this._attributesDataGridRow.dataGrid = this._createAttributesDataGrid();
    128     },
    129 
    130     _refreshProperties: function()
     123    }
     124
     125    _refreshProperties()
    131126    {
    132127        var domNode = this.domNode;
     
    215210            }
    216211        }
    217     },
    218 
    219     _refreshEventListeners: function()
     212    }
     213
     214    _refreshEventListeners()
    220215    {
    221216        var domNode = this.domNode;
     
    265260            this._eventListenersSectionGroup.rows = rows;
    266261        }
    267     },
    268 
    269     _refreshAccessibility: (function() {
     262    }
     263
     264    _refreshAccessibility()
     265    {
     266        if (!this._accessibilitySupported())
     267            return;
     268
     269        var domNode = this.domNode;
     270        if (!domNode)
     271            return;
     272
    270273        var properties = {};
    271         var domNode;
    272274
    273275        function booleanValueToLocalizedStringIfTrue(property) {
     
    526528        }
    527529
    528         function refreshAX() {
    529             if (!this._accessibilitySupported())
    530                 return;
    531 
    532             // Make sure the domNode is available in the closure scope.
    533             domNode = this.domNode;
    534             if (!domNode)
    535                 return;
    536 
    537             domNode.accessibilityProperties(accessibilityPropertiesCallback.bind(this));
    538         }
    539 
    540         return refreshAX;
    541     }()),
    542 
    543     _attributesChanged: function(event)
     530        domNode.accessibilityProperties(accessibilityPropertiesCallback.bind(this));
     531    }
     532
     533    _attributesChanged(event)
    544534    {
    545535        if (event.data.node !== this.domNode)
     
    547537        this._refreshAttributes();
    548538        this._refreshAccessibility();
    549     },
    550 
    551     _characterDataModified: function(event)
     539    }
     540
     541    _characterDataModified(event)
    552542    {
    553543        if (event.data.node !== this.domNode)
    554544            return;
    555545        this._identityNodeValueRow.value = this.domNode.nodeValue();
    556     },
    557 
    558     _nodeTypeDisplayName: function()
     546    }
     547
     548    _nodeTypeDisplayName()
    559549    {
    560550        switch (this.domNode.nodeType()) {
     
    579569            return this.domNode.nodeType();
    580570        }
    581     },
    582 
    583     _createAttributesDataGrid: function()
     571    }
     572
     573    _createAttributesDataGrid()
    584574    {
    585575        var domNode = this.domNode;
     
    603593    }
    604594};
     595
     596WebInspector.DOMNodeDetailsSidebarPanel.PropertiesObjectGroupName = "dom-node-details-sidebar-properties-object-group";
  • trunk/Source/WebInspectorUI/UserInterface/Views/DebuggerSidebarPanel.js

    r181872 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.DebuggerSidebarPanel = function()
     26WebInspector.DebuggerSidebarPanel = class DebuggerSidebarPanel extends WebInspector.NavigationSidebarPanel
    2727{
    28     WebInspector.NavigationSidebarPanel.call(this, "debugger", WebInspector.UIString("Debugger"), "Images/NavigationItemBug.svg", "3", true);
    29 
    30     WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this);
    31     WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceAdded, this);
    32 
    33     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this);
    34     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, this._debuggerCallFramesDidChange, this);
    35     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
    36     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
    37     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, this._scriptAdded, this);
    38     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
    39     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, this._debuggerDidPause, this);
    40     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, this._debuggerDidResume, this);
    41     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._debuggerActiveCallFrameDidChange, this);
    42 
    43     this._toggleBreakpointsKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "Y", this._breakpointsToggleButtonClicked.bind(this));
    44     this.pauseOrResumeKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control | WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "Y", this._debuggerPauseResumeButtonClicked.bind(this));
    45     this._stepOverKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F6, this._debuggerStepOverButtonClicked.bind(this));
    46     this._stepIntoKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F7, this._debuggerStepIntoButtonClicked.bind(this));
    47     this._stepOutKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F8, this._debuggerStepOutButtonClicked.bind(this));
    48 
    49     this.pauseOrResumeAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Backslash, this._debuggerPauseResumeButtonClicked.bind(this));
    50     this._stepOverAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.SingleQuote, this._debuggerStepOverButtonClicked.bind(this));
    51     this._stepIntoAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Semicolon, this._debuggerStepIntoButtonClicked.bind(this));
    52     this._stepOutAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Shift | WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Semicolon, this._debuggerStepOutButtonClicked.bind(this));
    53 
    54     this._navigationBar = new WebInspector.NavigationBar;
    55     this.element.appendChild(this._navigationBar.element);
    56    
    57     var imageSize = WebInspector.Platform.isLegacyMacOS ? 16 : 15;
    58 
    59     var breakpointsImage = {src: platformImagePath("Breakpoints.svg"), width: imageSize, height: imageSize};
    60     var pauseImage = {src: platformImagePath("Pause.svg"), width: imageSize, height: imageSize};
    61     var resumeImage = {src: platformImagePath("Resume.svg"), width: imageSize, height: imageSize};
    62     var stepOverImage = {src: platformImagePath("StepOver.svg"), width: imageSize, height: imageSize};
    63     var stepIntoImage = {src: platformImagePath("StepInto.svg"), width: imageSize, height: imageSize};
    64     var stepOutImage = {src: platformImagePath("StepOut.svg"), width: imageSize, height: imageSize};
    65 
    66     var toolTip = WebInspector.UIString("Enable all breakpoints (%s)").format(this._toggleBreakpointsKeyboardShortcut.displayName);
    67     var altToolTip = WebInspector.UIString("Disable all breakpoints (%s)").format(this._toggleBreakpointsKeyboardShortcut.displayName);
    68 
    69     this._debuggerBreakpointsButtonItem = new WebInspector.ActivateButtonNavigationItem("debugger-breakpoints", toolTip, altToolTip, breakpointsImage.src, breakpointsImage.width, breakpointsImage.height);
    70     this._debuggerBreakpointsButtonItem.activated = WebInspector.debuggerManager.breakpointsEnabled;
    71     this._debuggerBreakpointsButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._breakpointsToggleButtonClicked, this);
    72     this._navigationBar.addNavigationItem(this._debuggerBreakpointsButtonItem);
    73 
    74     toolTip = WebInspector.UIString("Pause script execution (%s or %s)").format(this.pauseOrResumeKeyboardShortcut.displayName, this.pauseOrResumeAlternateKeyboardShortcut.displayName);
    75     altToolTip = WebInspector.UIString("Continue script execution (%s or %s)").format(this.pauseOrResumeKeyboardShortcut.displayName, this.pauseOrResumeAlternateKeyboardShortcut.displayName);
    76 
    77     this._debuggerPauseResumeButtonItem = new WebInspector.ToggleButtonNavigationItem("debugger-pause-resume", toolTip, altToolTip, pauseImage.src, resumeImage.src, pauseImage.width, pauseImage.height);
    78     this._debuggerPauseResumeButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerPauseResumeButtonClicked, this);
    79     this._navigationBar.addNavigationItem(this._debuggerPauseResumeButtonItem);
    80 
    81     this._debuggerStepOverButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-over", WebInspector.UIString("Step over (%s or %s)").format(this._stepOverKeyboardShortcut.displayName, this._stepOverAlternateKeyboardShortcut.displayName), stepOverImage.src, stepOverImage.width, stepOverImage.height);
    82     this._debuggerStepOverButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepOverButtonClicked, this);
    83     this._debuggerStepOverButtonItem.enabled = false;
    84     this._navigationBar.addNavigationItem(this._debuggerStepOverButtonItem);
    85 
    86     this._debuggerStepIntoButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-into", WebInspector.UIString("Step into (%s or %s)").format(this._stepIntoKeyboardShortcut.displayName, this._stepIntoAlternateKeyboardShortcut.displayName), stepIntoImage.src, stepIntoImage.width, stepIntoImage.height);
    87     this._debuggerStepIntoButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepIntoButtonClicked, this);
    88     this._debuggerStepIntoButtonItem.enabled = false;
    89     this._navigationBar.addNavigationItem(this._debuggerStepIntoButtonItem);
    90 
    91     this._debuggerStepOutButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-out", WebInspector.UIString("Step out (%s or %s)").format(this._stepOutKeyboardShortcut.displayName, this._stepOutAlternateKeyboardShortcut.displayName), stepOutImage.src, stepOutImage.width, stepOutImage.height);
    92     this._debuggerStepOutButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepOutButtonClicked, this);
    93     this._debuggerStepOutButtonItem.enabled = false;
    94     this._navigationBar.addNavigationItem(this._debuggerStepOutButtonItem);
    95 
    96     // Add this offset-sections class name so the sticky headers don't overlap the navigation bar.
    97     this.element.classList.add(WebInspector.DebuggerSidebarPanel.OffsetSectionsStyleClassName);
    98 
    99     this._globalBreakpointsFolderTreeElement = new WebInspector.FolderTreeElement(WebInspector.UIString("Global Breakpoints"), null, WebInspector.DebuggerSidebarPanel.GlobalIconStyleClassName);
    100     this._allExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Exceptions"));
    101     this._allUncaughtExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allUncaughtExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Uncaught Exceptions"));
    102 
    103     this.filterBar.placeholder = WebInspector.UIString("Filter Breakpoint List");
    104     var showResourcesWithBreakpointsOnlyFilterFunction = function(treeElement)
    105     {
    106         // Keep breakpoints and other elements that aren't resources.
    107         if (!treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.BreakpointTreeElement)
    108             return true;
    109 
    110         // Keep resources with breakpoints.
    111         if (treeElement.hasChildren) {
    112             for (var child of treeElement.children) {
    113                 if (child instanceof WebInspector.BreakpointTreeElement)
    114                     return true;
     28    constructor()
     29    {
     30        super("debugger", WebInspector.UIString("Debugger"), "Images/NavigationItemBug.svg", "3", true);
     31
     32        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._mainResourceChanged, this);
     33        WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasAdded, this._resourceAdded, this);
     34
     35        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointsEnabledDidChange, this._breakpointsEnabledDidChange, this);
     36        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.CallFramesDidChange, this._debuggerCallFramesDidChange, this);
     37        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointAdded, this._breakpointAdded, this);
     38        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.BreakpointRemoved, this._breakpointRemoved, this);
     39        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, this._scriptAdded, this);
     40        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
     41        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Paused, this._debuggerDidPause, this);
     42        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.Resumed, this._debuggerDidResume, this);
     43        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ActiveCallFrameDidChange, this._debuggerActiveCallFrameDidChange, this);
     44
     45        this._toggleBreakpointsKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "Y", this._breakpointsToggleButtonClicked.bind(this));
     46        this.pauseOrResumeKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control | WebInspector.KeyboardShortcut.Modifier.CommandOrControl, "Y", this._debuggerPauseResumeButtonClicked.bind(this));
     47        this._stepOverKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F6, this._debuggerStepOverButtonClicked.bind(this));
     48        this._stepIntoKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F7, this._debuggerStepIntoButtonClicked.bind(this));
     49        this._stepOutKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.F8, this._debuggerStepOutButtonClicked.bind(this));
     50
     51        this.pauseOrResumeAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Backslash, this._debuggerPauseResumeButtonClicked.bind(this));
     52        this._stepOverAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.SingleQuote, this._debuggerStepOverButtonClicked.bind(this));
     53        this._stepIntoAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Semicolon, this._debuggerStepIntoButtonClicked.bind(this));
     54        this._stepOutAlternateKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Shift | WebInspector.KeyboardShortcut.Modifier.CommandOrControl, WebInspector.KeyboardShortcut.Key.Semicolon, this._debuggerStepOutButtonClicked.bind(this));
     55
     56        this._navigationBar = new WebInspector.NavigationBar;
     57        this.element.appendChild(this._navigationBar.element);
     58
     59        var imageSize = WebInspector.Platform.isLegacyMacOS ? 16 : 15;
     60
     61        var breakpointsImage = {src: platformImagePath("Breakpoints.svg"), width: imageSize, height: imageSize};
     62        var pauseImage = {src: platformImagePath("Pause.svg"), width: imageSize, height: imageSize};
     63        var resumeImage = {src: platformImagePath("Resume.svg"), width: imageSize, height: imageSize};
     64        var stepOverImage = {src: platformImagePath("StepOver.svg"), width: imageSize, height: imageSize};
     65        var stepIntoImage = {src: platformImagePath("StepInto.svg"), width: imageSize, height: imageSize};
     66        var stepOutImage = {src: platformImagePath("StepOut.svg"), width: imageSize, height: imageSize};
     67
     68        var toolTip = WebInspector.UIString("Enable all breakpoints (%s)").format(this._toggleBreakpointsKeyboardShortcut.displayName);
     69        var altToolTip = WebInspector.UIString("Disable all breakpoints (%s)").format(this._toggleBreakpointsKeyboardShortcut.displayName);
     70
     71        this._debuggerBreakpointsButtonItem = new WebInspector.ActivateButtonNavigationItem("debugger-breakpoints", toolTip, altToolTip, breakpointsImage.src, breakpointsImage.width, breakpointsImage.height);
     72        this._debuggerBreakpointsButtonItem.activated = WebInspector.debuggerManager.breakpointsEnabled;
     73        this._debuggerBreakpointsButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._breakpointsToggleButtonClicked, this);
     74        this._navigationBar.addNavigationItem(this._debuggerBreakpointsButtonItem);
     75
     76        toolTip = WebInspector.UIString("Pause script execution (%s or %s)").format(this.pauseOrResumeKeyboardShortcut.displayName, this.pauseOrResumeAlternateKeyboardShortcut.displayName);
     77        altToolTip = WebInspector.UIString("Continue script execution (%s or %s)").format(this.pauseOrResumeKeyboardShortcut.displayName, this.pauseOrResumeAlternateKeyboardShortcut.displayName);
     78
     79        this._debuggerPauseResumeButtonItem = new WebInspector.ToggleButtonNavigationItem("debugger-pause-resume", toolTip, altToolTip, pauseImage.src, resumeImage.src, pauseImage.width, pauseImage.height);
     80        this._debuggerPauseResumeButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerPauseResumeButtonClicked, this);
     81        this._navigationBar.addNavigationItem(this._debuggerPauseResumeButtonItem);
     82
     83        this._debuggerStepOverButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-over", WebInspector.UIString("Step over (%s or %s)").format(this._stepOverKeyboardShortcut.displayName, this._stepOverAlternateKeyboardShortcut.displayName), stepOverImage.src, stepOverImage.width, stepOverImage.height);
     84        this._debuggerStepOverButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepOverButtonClicked, this);
     85        this._debuggerStepOverButtonItem.enabled = false;
     86        this._navigationBar.addNavigationItem(this._debuggerStepOverButtonItem);
     87
     88        this._debuggerStepIntoButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-into", WebInspector.UIString("Step into (%s or %s)").format(this._stepIntoKeyboardShortcut.displayName, this._stepIntoAlternateKeyboardShortcut.displayName), stepIntoImage.src, stepIntoImage.width, stepIntoImage.height);
     89        this._debuggerStepIntoButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepIntoButtonClicked, this);
     90        this._debuggerStepIntoButtonItem.enabled = false;
     91        this._navigationBar.addNavigationItem(this._debuggerStepIntoButtonItem);
     92
     93        this._debuggerStepOutButtonItem = new WebInspector.ButtonNavigationItem("debugger-step-out", WebInspector.UIString("Step out (%s or %s)").format(this._stepOutKeyboardShortcut.displayName, this._stepOutAlternateKeyboardShortcut.displayName), stepOutImage.src, stepOutImage.width, stepOutImage.height);
     94        this._debuggerStepOutButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._debuggerStepOutButtonClicked, this);
     95        this._debuggerStepOutButtonItem.enabled = false;
     96        this._navigationBar.addNavigationItem(this._debuggerStepOutButtonItem);
     97
     98        // Add this offset-sections class name so the sticky headers don't overlap the navigation bar.
     99        this.element.classList.add(WebInspector.DebuggerSidebarPanel.OffsetSectionsStyleClassName);
     100
     101        this._globalBreakpointsFolderTreeElement = new WebInspector.FolderTreeElement(WebInspector.UIString("Global Breakpoints"), null, WebInspector.DebuggerSidebarPanel.GlobalIconStyleClassName);
     102        this._allExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Exceptions"));
     103        this._allUncaughtExceptionsBreakpointTreeElement = new WebInspector.BreakpointTreeElement(WebInspector.debuggerManager.allUncaughtExceptionsBreakpoint, WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName, WebInspector.UIString("All Uncaught Exceptions"));
     104
     105        this.filterBar.placeholder = WebInspector.UIString("Filter Breakpoint List");
     106        var showResourcesWithBreakpointsOnlyFilterFunction = function(treeElement)
     107        {
     108            // Keep breakpoints and other elements that aren't resources.
     109            if (!treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.BreakpointTreeElement)
     110                return true;
     111
     112            // Keep resources with breakpoints.
     113            if (treeElement.hasChildren) {
     114                for (var child of treeElement.children) {
     115                    if (child instanceof WebInspector.BreakpointTreeElement)
     116                        return true;
     117                }
    115118            }
    116         }
    117         return false;
    118     };
    119 
    120     this.filterBar.addFilterBarButton("debugger-show-resources-with-children-only", showResourcesWithBreakpointsOnlyFilterFunction, true, WebInspector.UIString("Show only resources with breakpoints."), WebInspector.UIString("Show resources with and without breakpoints."), platformImagePath("Breakpoints.svg"), 15, 15);
    121 
    122     this._breakpointsContentTreeOutline = this.contentTreeOutline;
    123     this._breakpointsContentTreeOutline.onselect = this._treeElementSelected.bind(this);
    124     this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
    125     this._breakpointsContentTreeOutline.oncontextmenu = this._breakpointTreeOutlineContextMenuTreeElement.bind(this);
    126 
    127     this._breakpointsContentTreeOutline.appendChild(this._globalBreakpointsFolderTreeElement);
    128     this._globalBreakpointsFolderTreeElement.appendChild(this._allExceptionsBreakpointTreeElement);
    129     this._globalBreakpointsFolderTreeElement.appendChild(this._allUncaughtExceptionsBreakpointTreeElement);
    130     this._globalBreakpointsFolderTreeElement.expand();
    131 
    132     var breakpointsRow = new WebInspector.DetailsSectionRow;
    133     breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);
    134 
    135     var breakpointsGroup = new WebInspector.DetailsSectionGroup([breakpointsRow]);
    136     var breakpointsSection = new WebInspector.DetailsSection("scripts", WebInspector.UIString("Scripts"), [breakpointsGroup]);
    137     this.contentElement.appendChild(breakpointsSection.element);
    138 
    139     this._callStackContentTreeOutline = this.createContentTreeOutline(true);
    140     this._callStackContentTreeOutline.onselect = this._treeElementSelected.bind(this);
    141 
    142     this._callStackRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Call Frames"));
    143     this._callStackRow.showEmptyMessage();
    144 
    145     var callStackGroup = new WebInspector.DetailsSectionGroup([this._callStackRow]);
    146     this._callStackSection = new WebInspector.DetailsSection("call-stack", WebInspector.UIString("Call Stack"), [callStackGroup]);
    147 
    148     this._pauseReasonTreeOutline = null;
    149 
    150     this._pauseReasonLinkContainerElement = document.createElement("span");
    151     this._pauseReasonTextRow = new WebInspector.DetailsSectionTextRow;
    152     this._pauseReasonGroup = new WebInspector.DetailsSectionGroup([this._pauseReasonTextRow]);
    153     this._pauseReasonSection = new WebInspector.DetailsSection("paused-reason", null, [this._pauseReasonGroup], this._pauseReasonLinkContainerElement);
    154     this._pauseReasonSection.title = WebInspector.UIString("Pause Reason");
    155 
    156     WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this);
    157 };
    158 
    159 WebInspector.DebuggerSidebarPanel.OffsetSectionsStyleClassName = "offset-sections";
    160 WebInspector.DebuggerSidebarPanel.DebuggerPausedStyleClassName = "paused";
    161 WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName = "breakpoint-exception-icon";
    162 WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName = "breakpoint-paused-icon";
    163 WebInspector.DebuggerSidebarPanel.GlobalIconStyleClassName = "global-breakpoints-icon";
    164 
    165 WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = "debugger-sidebar-panel-all-exceptions-breakpoint";
    166 WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey = "debugger-sidebar-panel-all-uncaught-exceptions-breakpoint";
    167 
    168 WebInspector.DebuggerSidebarPanel.prototype = {
    169     constructor: WebInspector.DebuggerSidebarPanel,
    170     __proto__: WebInspector.NavigationSidebarPanel.prototype,
     119            return false;
     120        };
     121
     122        this.filterBar.addFilterBarButton("debugger-show-resources-with-children-only", showResourcesWithBreakpointsOnlyFilterFunction, true, WebInspector.UIString("Show only resources with breakpoints."), WebInspector.UIString("Show resources with and without breakpoints."), platformImagePath("Breakpoints.svg"), 15, 15);
     123
     124        this._breakpointsContentTreeOutline = this.contentTreeOutline;
     125        this._breakpointsContentTreeOutline.onselect = this._treeElementSelected.bind(this);
     126        this._breakpointsContentTreeOutline.ondelete = this._breakpointTreeOutlineDeleteTreeElement.bind(this);
     127        this._breakpointsContentTreeOutline.oncontextmenu = this._breakpointTreeOutlineContextMenuTreeElement.bind(this);
     128
     129        this._breakpointsContentTreeOutline.appendChild(this._globalBreakpointsFolderTreeElement);
     130        this._globalBreakpointsFolderTreeElement.appendChild(this._allExceptionsBreakpointTreeElement);
     131        this._globalBreakpointsFolderTreeElement.appendChild(this._allUncaughtExceptionsBreakpointTreeElement);
     132        this._globalBreakpointsFolderTreeElement.expand();
     133
     134        var breakpointsRow = new WebInspector.DetailsSectionRow;
     135        breakpointsRow.element.appendChild(this._breakpointsContentTreeOutline.element);
     136
     137        var breakpointsGroup = new WebInspector.DetailsSectionGroup([breakpointsRow]);
     138        var breakpointsSection = new WebInspector.DetailsSection("scripts", WebInspector.UIString("Scripts"), [breakpointsGroup]);
     139        this.contentElement.appendChild(breakpointsSection.element);
     140
     141        this._callStackContentTreeOutline = this.createContentTreeOutline(true);
     142        this._callStackContentTreeOutline.onselect = this._treeElementSelected.bind(this);
     143
     144        this._callStackRow = new WebInspector.DetailsSectionRow(WebInspector.UIString("No Call Frames"));
     145        this._callStackRow.showEmptyMessage();
     146
     147        var callStackGroup = new WebInspector.DetailsSectionGroup([this._callStackRow]);
     148        this._callStackSection = new WebInspector.DetailsSection("call-stack", WebInspector.UIString("Call Stack"), [callStackGroup]);
     149
     150        this._pauseReasonTreeOutline = null;
     151
     152        this._pauseReasonLinkContainerElement = document.createElement("span");
     153        this._pauseReasonTextRow = new WebInspector.DetailsSectionTextRow;
     154        this._pauseReasonGroup = new WebInspector.DetailsSectionGroup([this._pauseReasonTextRow]);
     155        this._pauseReasonSection = new WebInspector.DetailsSection("paused-reason", null, [this._pauseReasonGroup], this._pauseReasonLinkContainerElement);
     156        this._pauseReasonSection.title = WebInspector.UIString("Pause Reason");
     157
     158        WebInspector.Breakpoint.addEventListener(WebInspector.Breakpoint.Event.DisplayLocationDidChange, this._breakpointDisplayLocationDidChange, this);
     159    }
    171160
    172161    // Public
     
    177166            || !!this._callStackContentTreeOutline.selectedTreeElement
    178167            || (this._pauseReasonTreeOutline && !!this._pauseReasonTreeOutline.selectedTreeElement);
    179     },
    180 
    181     showDefaultContentView: function()
     168    }
     169
     170    showDefaultContentView()
    182171    {
    183172        WebInspector.resourceSidebarPanel.showDefaultContentView();
    184     },
    185 
    186     treeElementForRepresentedObject: function(representedObject)
     173    }
     174
     175    treeElementForRepresentedObject(representedObject)
    187176    {
    188177        // The main resource is used as the representedObject instead of Frame in our tree.
     
    191180
    192181        return this.contentTreeOutline.getCachedTreeElement(representedObject);
    193     },
     182    }
    194183
    195184    // Protected
    196185
    197     saveStateToCookie: function(cookie)
     186    saveStateToCookie(cookie)
    198187    {
    199188        console.assert(cookie);
     
    211200            cookie[WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey] = true;
    212201
    213         WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie.call(this, cookie);
    214     },
    215 
    216     restoreStateFromCookie: function(cookie, relaxedMatchDelay)
     202        super.saveStateToCookie(cookie);
     203    }
     204
     205    restoreStateFromCookie(cookie, relaxedMatchDelay)
    217206    {
    218207        console.assert(cookie);
     
    224213            this._allUncaughtExceptionsBreakpointTreeElement.revealAndSelect();
    225214        else
    226             WebInspector.NavigationSidebarPanel.prototype.restoreStateFromCookie.call(this, cookie, relaxedMatchDelay);
    227     },
     215            super.restoreStateFromCookie(cookie, relaxedMatchDelay);
     216    }
    228217
    229218    // Private
    230219
    231     _debuggerPauseResumeButtonClicked: function(event)
     220    _debuggerPauseResumeButtonClicked(event)
    232221    {
    233222        if (WebInspector.debuggerManager.paused)
     
    237226            WebInspector.debuggerManager.pause();
    238227        }
    239     },
    240 
    241     _debuggerStepOverButtonClicked: function(event)
     228    }
     229
     230    _debuggerStepOverButtonClicked(event)
    242231    {
    243232        WebInspector.debuggerManager.stepOver();
    244     },
    245 
    246     _debuggerStepIntoButtonClicked: function(event)
     233    }
     234
     235    _debuggerStepIntoButtonClicked(event)
    247236    {
    248237        WebInspector.debuggerManager.stepInto();
    249     },
    250 
    251     _debuggerStepOutButtonClicked: function(event)
     238    }
     239
     240    _debuggerStepOutButtonClicked(event)
    252241    {
    253242        WebInspector.debuggerManager.stepOut();
    254     },
    255 
    256     _debuggerDidPause: function(event)
     243    }
     244
     245    _debuggerDidPause(event)
    257246    {
    258247        this.contentElement.insertBefore(this._callStackSection.element, this.contentElement.firstChild);
     
    266255
    267256        this.element.classList.add(WebInspector.DebuggerSidebarPanel.DebuggerPausedStyleClassName);
    268     },
    269 
    270     _debuggerDidResume: function(event)
     257    }
     258
     259    _debuggerDidResume(event)
    271260    {
    272261        this._callStackSection.element.remove();
     
    280269
    281270        this.element.classList.remove(WebInspector.DebuggerSidebarPanel.DebuggerPausedStyleClassName);
    282     },
    283 
    284     _breakpointsEnabledDidChange: function(event)
     271    }
     272
     273    _breakpointsEnabledDidChange(event)
    285274    {
    286275        this._debuggerBreakpointsButtonItem.activated = WebInspector.debuggerManager.breakpointsEnabled;
    287     },
    288 
    289     _breakpointsToggleButtonClicked: function(event)
     276    }
     277
     278    _breakpointsToggleButtonClicked(event)
    290279    {
    291280        WebInspector.debuggerManager.breakpointsEnabled = !this._debuggerBreakpointsButtonItem.activated;
    292     },
    293 
    294     _addBreakpoint: function(breakpoint)
     281    }
     282
     283    _addBreakpoint(breakpoint)
    295284    {
    296285        var sourceCode = breakpoint.sourceCodeLocation.displaySourceCode;
     
    312301            parentTreeElement.expand();
    313302        return breakpointTreeElement;
    314     },
    315 
    316     _addBreakpointsForSourceCode: function(sourceCode)
     303    }
     304
     305    _addBreakpointsForSourceCode(sourceCode)
    317306    {
    318307        var breakpoints = WebInspector.debuggerManager.breakpointsForSourceCode(sourceCode);
    319308        for (var i = 0; i < breakpoints.length; ++i)
    320309            this._addBreakpoint(breakpoints[i], sourceCode);
    321     },
    322 
    323     _addTreeElementForSourceCodeToContentTreeOutline: function(sourceCode)
     310    }
     311
     312    _addTreeElementForSourceCodeToContentTreeOutline(sourceCode)
    324313    {
    325314        var treeElement = this._breakpointsContentTreeOutline.getCachedTreeElement(sourceCode);
     
    341330
    342331        return treeElement;
    343     },
    344 
    345     _resourceAdded: function(event)
     332    }
     333
     334    _resourceAdded(event)
    346335    {
    347336        var resource = event.data.resource;
     
    352341        this._addTreeElementForSourceCodeToContentTreeOutline(resource);
    353342        this._addBreakpointsForSourceCode(resource);
    354     },
    355 
    356     _mainResourceChanged: function(event)
     343    }
     344
     345    _mainResourceChanged(event)
    357346    {
    358347        var resource = event.target.mainResource;
    359348        this._addTreeElementForSourceCodeToContentTreeOutline(resource);
    360349        this._addBreakpointsForSourceCode(resource);
    361     },
    362 
    363     _scriptAdded: function(event)
     350    }
     351
     352    _scriptAdded(event)
    364353    {
    365354        var script = event.data.script;
     
    381370        this._addTreeElementForSourceCodeToContentTreeOutline(script);
    382371        this._addBreakpointsForSourceCode(script);
    383     },
    384 
    385     _scriptsCleared: function(event)
     372    }
     373
     374    _scriptsCleared(event)
    386375    {
    387376        for (var i = this._breakpointsContentTreeOutline.children.length - 1; i >= 0; --i) {
     
    392381            this._breakpointsContentTreeOutline.removeChildAtIndex(i, true, true);
    393382        }
    394     },
    395 
    396     _breakpointAdded: function(event)
     383    }
     384
     385    _breakpointAdded(event)
    397386    {
    398387        var breakpoint = event.data.breakpoint;
    399388        this._addBreakpoint(breakpoint);
    400     },
    401 
    402     _breakpointRemoved: function(event)
     389    }
     390
     391    _breakpointRemoved(event)
    403392    {
    404393        var breakpoint = event.data.breakpoint;
     
    416405
    417406        this._removeBreakpointTreeElement(breakpointTreeElement);
    418     },
    419 
    420     _breakpointDisplayLocationDidChange: function(event)
     407    }
     408
     409    _breakpointDisplayLocationDidChange(event)
    421410    {
    422411        var breakpoint = event.target;
     
    438427        if (newBreakpointTreeElement && wasSelected)
    439428            newBreakpointTreeElement.revealAndSelect(true, false, true, true);
    440     },
    441 
    442     _removeBreakpointTreeElement: function(breakpointTreeElement)
     429    }
     430
     431    _removeBreakpointTreeElement(breakpointTreeElement)
    443432    {
    444433        var parentTreeElement = breakpointTreeElement.parent;
     
    446435
    447436        console.assert(parentTreeElement.parent === this._breakpointsContentTreeOutline);
    448     },
    449 
    450     _debuggerCallFramesDidChange: function()
     437    }
     438
     439    _debuggerCallFramesDidChange()
    451440    {
    452441        this._callStackContentTreeOutline.removeChildren();
     
    473462        if (treeElementToSelect)
    474463            treeElementToSelect.select(true, true);
    475     },
    476 
    477     _debuggerActiveCallFrameDidChange: function()
     464    }
     465
     466    _debuggerActiveCallFrameDidChange()
    478467    {
    479468        var callFrames = WebInspector.debuggerManager.callFrames;
     
    486475        // frame payload.
    487476        this._debuggerStepOutButtonItem.enabled = indexOfActiveCallFrame < callFrames.length - 1;
    488     },
    489 
    490     _breakpointsBeneathTreeElement: function(treeElement)
     477    }
     478
     479    _breakpointsBeneathTreeElement(treeElement)
    491480    {
    492481        console.assert(treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement);
     
    505494
    506495        return breakpoints;
    507     },
    508 
    509     _removeAllBreakpoints: function(breakpoints)
     496    }
     497
     498    _removeAllBreakpoints(breakpoints)
    510499    {
    511500        for (var i = 0; i < breakpoints.length; ++i) {
     
    514503                WebInspector.debuggerManager.removeBreakpoint(breakpoint);
    515504        }
    516     },
    517 
    518     _toggleAllBreakpoints: function(breakpoints, disabled)
     505    }
     506
     507    _toggleAllBreakpoints(breakpoints, disabled)
    519508    {
    520509        for (var i = 0; i < breakpoints.length; ++i)
    521510            breakpoints[i].disabled = disabled;
    522     },
    523 
    524     _breakpointTreeOutlineDeleteTreeElement: function(treeElement)
     511    }
     512
     513    _breakpointTreeOutlineDeleteTreeElement(treeElement)
    525514    {
    526515        console.assert(treeElement.selected);
     
    539528
    540529        return true;
    541     },
    542 
    543     _breakpointTreeOutlineContextMenuTreeElement: function(event, treeElement)
     530    }
     531
     532    _breakpointTreeOutlineContextMenuTreeElement(event, treeElement)
    544533    {
    545534        console.assert(treeElement instanceof WebInspector.ResourceTreeElement || treeElement instanceof WebInspector.ScriptTreeElement || treeElement.constructor === WebInspector.FolderTreeElement);
     
    573562        contextMenu.appendItem(WebInspector.UIString("Delete Breakpoints"), removeAllResourceBreakpoints.bind(this));
    574563        contextMenu.show();
    575     },
    576 
    577     _treeElementSelected: function(treeElement, selectedByUser)
     564    }
     565
     566    _treeElementSelected(treeElement, selectedByUser)
    578567    {
    579568        function deselectCallStackContentTreeElements()
     
    644633
    645634        WebInspector.resourceSidebarPanel.showSourceCodeLocation(breakpoint.sourceCodeLocation);
    646     },
    647 
    648     _compareTopLevelTreeElements: function(a, b)
     635    }
     636
     637    _compareTopLevelTreeElements(a, b)
    649638    {
    650639        if (a === this._globalBreakpointsFolderTreeElement)
     
    654643
    655644        return a.mainTitle.localeCompare(b.mainTitle);
    656     },
    657 
    658     _compareBreakpointTreeElements: function(a, b)
     645    }
     646
     647    _compareBreakpointTreeElements(a, b)
    659648    {
    660649        var aLocation = a.breakpoint.sourceCodeLocation;
     
    666655
    667656        return aLocation.displayColumnNumber - bLocation.displayColumnNumber;
    668     },
    669 
    670     _updatePauseReason: function()
     657    }
     658
     659    _updatePauseReason()
    671660    {
    672661        this._pauseReasonTreeOutline = null;
     
    674663        this._updatePauseReasonGotoArrow();
    675664        return this._updatePauseReasonSection();
    676     },
    677 
    678     _updatePauseReasonSection: function()
     665    }
     666
     667    _updatePauseReasonSection()
    679668    {
    680669        var pauseData = WebInspector.debuggerManager.pauseData;
     
    747736
    748737        return false;
    749     },
    750 
    751     _updatePauseReasonGotoArrow: function()
     738    }
     739
     740    _updatePauseReasonGotoArrow()
    752741    {
    753742        this._pauseReasonLinkContainerElement.removeChildren();
     
    765754    }
    766755};
     756
     757WebInspector.DebuggerSidebarPanel.OffsetSectionsStyleClassName = "offset-sections";
     758WebInspector.DebuggerSidebarPanel.DebuggerPausedStyleClassName = "paused";
     759WebInspector.DebuggerSidebarPanel.ExceptionIconStyleClassName = "breakpoint-exception-icon";
     760WebInspector.DebuggerSidebarPanel.PausedBreakpointIconStyleClassName = "breakpoint-paused-icon";
     761WebInspector.DebuggerSidebarPanel.GlobalIconStyleClassName = "global-breakpoints-icon";
     762
     763WebInspector.DebuggerSidebarPanel.SelectedAllExceptionsCookieKey = "debugger-sidebar-panel-all-exceptions-breakpoint";
     764WebInspector.DebuggerSidebarPanel.SelectedAllUncaughtExceptionsCookieKey = "debugger-sidebar-panel-all-uncaught-exceptions-breakpoint";
  • trunk/Source/WebInspectorUI/UserInterface/Views/DetailsSidebarPanel.js

    r175767 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.DetailsSidebarPanel = function(identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element)
     26WebInspector.DetailsSidebarPanel = class DetailsSidebarPanel extends WebInspector.SidebarPanel
    2727{
    28     if (keyboardShortcutKey)
    29         this._keyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control | WebInspector.KeyboardShortcut.Modifier.Shift, keyboardShortcutKey, this.toggle.bind(this));
     28    constructor(identifier, displayName, singularDisplayName, image, keyboardShortcutKey, element)
     29    {
     30        var keyboardShortcut = null;
     31        if (keyboardShortcutKey)
     32            keyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control | WebInspector.KeyboardShortcut.Modifier.Shift, keyboardShortcutKey);
    3033
    31     if (this._keyboardShortcut) {
    32         var showToolTip = WebInspector.UIString("Show the %s details sidebar (%s)").format(singularDisplayName, this._keyboardShortcut.displayName);
    33         var hideToolTip = WebInspector.UIString("Hide the %s details sidebar (%s)").format(singularDisplayName, this._keyboardShortcut.displayName);
    34     } else {
    35         var showToolTip = WebInspector.UIString("Show the %s details sidebar").format(singularDisplayName);
    36         var hideToolTip = WebInspector.UIString("Hide the %s details sidebar").format(singularDisplayName);
     34        if (keyboardShortcut) {
     35            var showToolTip = WebInspector.UIString("Show the %s details sidebar (%s)").format(singularDisplayName, keyboardShortcut.displayName);
     36            var hideToolTip = WebInspector.UIString("Hide the %s details sidebar (%s)").format(singularDisplayName, keyboardShortcut.displayName);
     37        } else {
     38            var showToolTip = WebInspector.UIString("Show the %s details sidebar").format(singularDisplayName);
     39            var hideToolTip = WebInspector.UIString("Hide the %s details sidebar").format(singularDisplayName);
     40        }
     41
     42        super(identifier, displayName, showToolTip, hideToolTip, image, element);
     43
     44        this._keyboardShortcut = keyboardShortcut;
     45        if (this._keyboardShortcut)
     46            this._keyboardShortcut.callback = this.toggle.bind(this);
     47
     48        this.element.classList.add("details");
    3749    }
    38 
    39     WebInspector.SidebarPanel.call(this, identifier, displayName, showToolTip, hideToolTip, image, element);
    40 
    41     this.element.classList.add(WebInspector.DetailsSidebarPanel.StyleClassName);
    42 };
    43 
    44 WebInspector.DetailsSidebarPanel.StyleClassName = "details";
    45 
    46 WebInspector.DetailsSidebarPanel.prototype = {
    47     constructor: WebInspector.DetailsSidebarPanel,
    48     __proto__: WebInspector.SidebarPanel.prototype,
    4950
    5051    // Public
    5152
    52     inspect: function(objects)
     53    inspect(objects)
    5354    {
    5455        // Implemented by subclasses.
    5556        return false;
    56     },
     57    }
    5758
    58     shown: function()
     59    shown()
    5960    {
    6061        if (this._needsRefresh) {
     
    6263            this.refresh();
    6364        }
    64     },
     65    }
    6566
    66     needsRefresh: function()
     67    needsRefresh()
    6768    {
    6869        if (!this.selected) {
     
    7273
    7374        this.refresh();
    74     },
     75    }
    7576
    76     refresh: function()
     77    refresh()
    7778    {
    7879        // Implemented by subclasses.
  • trunk/Source/WebInspectorUI/UserInterface/Views/LayerTreeDetailsSidebarPanel.js

    r175767 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.LayerTreeDetailsSidebarPanel = function()
     26WebInspector.LayerTreeDetailsSidebarPanel = class LayerTreeDetailsSidebarPanel extends WebInspector.DOMDetailsSidebarPanel
    2727{
    28     WebInspector.DOMDetailsSidebarPanel.call(this, "layer-tree", WebInspector.UIString("Layers"), WebInspector.UIString("Layer"), "Images/NavigationItemLayers.svg", "3");
    29 
    30     this._dataGridNodesByLayerId = {};
    31 
    32     this.element.classList.add(WebInspector.LayerTreeDetailsSidebarPanel.StyleClassName);
    33 
    34     WebInspector.showShadowDOMSetting.addEventListener(WebInspector.Setting.Event.Changed, this._showShadowDOMSettingChanged, this);
    35 
    36     window.addEventListener("resize", this._windowResized.bind(this));
    37 
    38     this._buildLayerInfoSection();
    39     this._buildDataGridSection();
    40     this._buildBottomBar();
    41 };
    42 
    43 WebInspector.LayerTreeDetailsSidebarPanel.StyleClassName = "layer-tree";
    44 
    45 WebInspector.LayerTreeDetailsSidebarPanel.prototype = {
    46     constructor: WebInspector.LayerTreeDetailsSidebarPanel,
    47     __proto__: WebInspector.DOMDetailsSidebarPanel.prototype,
     28    constructor()
     29    {
     30        super("layer-tree", WebInspector.UIString("Layers"), WebInspector.UIString("Layer"), "Images/NavigationItemLayers.svg", "3");
     31
     32        this._dataGridNodesByLayerId = {};
     33
     34        this.element.classList.add("layer-tree");
     35
     36        WebInspector.showShadowDOMSetting.addEventListener(WebInspector.Setting.Event.Changed, this._showShadowDOMSettingChanged, this);
     37
     38        window.addEventListener("resize", this._windowResized.bind(this));
     39
     40        this._buildLayerInfoSection();
     41        this._buildDataGridSection();
     42        this._buildBottomBar();
     43    }
    4844
    4945    // DetailsSidebarPanel Overrides.
    5046
    51     shown: function()
     47    shown()
    5248    {
    5349        WebInspector.layerTreeManager.addEventListener(WebInspector.LayerTreeManager.Event.LayerTreeDidChange, this._layerTreeDidChange, this);
     
    5854
    5955        WebInspector.DOMDetailsSidebarPanel.prototype.shown.call(this);
    60     },
    61 
    62     hidden: function()
     56    }
     57
     58    hidden()
    6359    {
    6460        WebInspector.layerTreeManager.removeEventListener(WebInspector.LayerTreeManager.Event.LayerTreeDidChange, this._layerTreeDidChange, this);
    6561
    6662        WebInspector.DOMDetailsSidebarPanel.prototype.hidden.call(this);
    67     },
    68 
    69     refresh: function()
     63    }
     64
     65    refresh()
    7066    {
    7167        if (!this.domNode)
     
    7672            this._updateDisplayWithLayers(layerForNode, childLayers);
    7773        }.bind(this));
    78     },
     74    }
    7975
    8076    // DOMDetailsSidebarPanel Overrides
    8177
    82     supportsDOMNode: function(nodeToInspect)
     78    supportsDOMNode(nodeToInspect)
    8379    {
    8480        return WebInspector.layerTreeManager.supported && nodeToInspect.nodeType() === Node.ELEMENT_NODE;
    85     },
     81    }
    8682
    8783    // Private
    8884
    89     _layerTreeDidChange: function(event)
     85    _layerTreeDidChange(event)
    9086    {
    9187        this.needsRefresh();
    92     },
    93 
    94     _showShadowDOMSettingChanged: function(event)
     88    }
     89
     90    _showShadowDOMSettingChanged(event)
    9591    {
    9692        if (this.selected)
    9793            this._updateDisplayWithLayers(this._layerForNode, this._unfilteredChildLayers);
    98     },
    99 
    100     _windowResized: function(event)
     94    }
     95
     96    _windowResized(event)
    10197    {
    10298        if (this._popover && this._popover.visible)
    10399            this._updatePopoverForSelectedNode();
    104     },
    105 
    106     _buildLayerInfoSection: function()
     100    }
     101
     102    _buildLayerInfoSection()
    107103    {
    108104        var rows = this._layerInfoRows = {};
     
    123119
    124120        this.contentElement.appendChild(this._layerInfoSection.element);
    125     },
    126 
    127     _buildDataGridSection: function()
     121    }
     122
     123    _buildDataGridSection()
    128124    {
    129125        var columns = {name: {}, paintCount: {}, memory: {}};
     
    161157        var element = this.contentElement.appendChild(section.element);
    162158        element.classList.add(section.identifier);
    163     },
    164 
    165     _buildBottomBar: function()
     159    }
     160
     161    _buildBottomBar()
    166162    {
    167163        var bottomBar = this.element.appendChild(document.createElement("div"));
     
    173169        this._layersMemoryLabel = bottomBar.appendChild(document.createElement("div"));
    174170        this._layersMemoryLabel.className = "layers-memory-label";
    175     },
    176 
    177     _sortDataGrid: function()
     171    }
     172
     173    _sortDataGrid()
    178174    {
    179175        var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier;
     
    188184        this._dataGrid.sortNodes(comparator);
    189185        this._updatePopoverForSelectedNode();
    190     },
    191 
    192     _selectedDataGridNodeChanged: function()
     186    }
     187
     188    _selectedDataGridNodeChanged()
    193189    {
    194190        if (this._dataGrid.selectedNode) {
     
    199195            this._hidePopover();
    200196        }
    201     },
    202 
    203     _dataGridGainedFocus: function(event)
     197    }
     198
     199    _dataGridGainedFocus(event)
    204200    {
    205201        this._highlightSelectedNode();
    206202        this._showPopoverForSelectedNode();
    207     },
    208 
    209     _dataGridLostFocus: function(event)
     203    }
     204
     205    _dataGridLostFocus(event)
    210206    {
    211207        WebInspector.domTreeManager.hideDOMNodeHighlight();
    212208        this._hidePopover();
    213     },
    214 
    215     _dataGridWasClicked: function(event)
     209    }
     210
     211    _dataGridWasClicked(event)
    216212    {
    217213        if (this._dataGrid.selectedNode && event.target.parentNode.classList.contains("filler"))
    218214            this._dataGrid.selectedNode.deselect();
    219     },
    220 
    221     _highlightSelectedNode: function()
     215    }
     216
     217    _highlightSelectedNode()
    222218    {
    223219        var dataGridNode = this._dataGrid.selectedNode;
     
    230226        else
    231227            WebInspector.domTreeManager.highlightDOMNode(layer.nodeId);
    232     },
    233 
    234     _updateDisplayWithLayers: function(layerForNode, childLayers)
     228    }
     229
     230    _updateDisplayWithLayers(layerForNode, childLayers)
    235231    {
    236232        if (!WebInspector.showShadowDOMSetting.value) {
     
    246242        this._layerForNode = layerForNode;
    247243        this._childLayers = childLayers;
    248     },
    249 
    250     _updateLayerInfoSection: function(layer)
    251     {
    252         const emDash = "\u2014";
     244    }
     245
     246    _updateLayerInfoSection(layer)
     247    {
     248        var emDash = "\u2014";
    253249
    254250        this._layerInfoSection.groups = layer ? [this._layerInfoGroup] : [this._noLayerInformationGroup];
     
    261257        this._layerInfoRows["Height"].value = layer.compositedBounds.height + "px";
    262258        this._layerInfoRows["Paints"].value = layer.paintCount + "";
    263     },
    264 
    265     _updateDataGrid: function(layerForNode, childLayers)
     259    }
     260
     261    _updateDataGrid(layerForNode, childLayers)
    266262    {
    267263        var dataGrid = this._dataGrid;
     
    292288
    293289        this._childLayersRow.dataGrid = !isEmptyObject(childLayers) ? this._dataGrid : null;
    294     },
    295 
    296     _dataGridNodeForLayer: function(layer)
     290    }
     291
     292    _dataGridNodeForLayer(layer)
    297293    {
    298294        var node = new WebInspector.LayerTreeDataGridNode(layer);
     
    301297
    302298        return node;
    303     },
    304 
    305     _updateMetrics: function(layerForNode, childLayers)
     299    }
     300
     301    _updateMetrics(layerForNode, childLayers)
    306302    {
    307303        var layerCount = 0;
     
    320316        this._layersCountLabel.textContent = WebInspector.UIString("Layer Count: %d").format(layerCount);
    321317        this._layersMemoryLabel.textContent = WebInspector.UIString("Memory: %s").format(Number.bytesToString(totalMemory));
    322     },
    323 
    324     _showPopoverForSelectedNode: function()
     318    }
     319
     320    _showPopoverForSelectedNode()
    325321    {
    326322        var dataGridNode = this._dataGrid.selectedNode;
     
    332328                this._updatePopoverForSelectedNode(content);
    333329        }.bind(this));
    334     },
    335 
    336     _updatePopoverForSelectedNode: function(content)
     330    }
     331
     332    _updatePopoverForSelectedNode(content)
    337333    {
    338334        var dataGridNode = this._dataGrid.selectedNode;
     
    350346
    351347        popover.present(targetFrame.pad(2), [WebInspector.RectEdge.MIN_X]);
    352     },
    353 
    354     _hidePopover: function()
     348    }
     349
     350    _hidePopover()
    355351    {
    356352        if (this._popover)
    357353            this._popover.dismiss();
    358     },
    359 
    360     _contentForPopover: function(layer, callback)
     354    }
     355
     356    _contentForPopover(layer, callback)
    361357    {
    362358        var content = document.createElement("div");
     
    379375
    380376        return content;
    381     },
    382 
    383     _populateListOfCompositingReasons: function(list, compositingReasons)
     377    }
     378
     379    _populateListOfCompositingReasons(list, compositingReasons)
    384380    {
    385381        function addReason(reason)
  • trunk/Source/WebInspectorUI/UserInterface/Views/NavigationSidebarPanel.js

    r181872 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.NavigationSidebarPanel = function(identifier, displayName, image, keyboardShortcutKey, autoPruneOldTopLevelResourceTreeElements, autoHideToolbarItemWhenEmpty, wantsTopOverflowShadow, element, role, label)
     26WebInspector.NavigationSidebarPanel = class NavigationSidebarPanel extends WebInspector.SidebarPanel
    2727{
    28     if (keyboardShortcutKey)
    29         this._keyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control, keyboardShortcutKey, this.toggle.bind(this));
    30 
    31     if (this._keyboardShortcut) {
    32         var showToolTip = WebInspector.UIString("Show the %s navigation sidebar (%s)").format(displayName, this._keyboardShortcut.displayName);
    33         var hideToolTip = WebInspector.UIString("Hide the %s navigation sidebar (%s)").format(displayName, this._keyboardShortcut.displayName);
    34     } else {
    35         var showToolTip = WebInspector.UIString("Show the %s navigation sidebar").format(displayName);
    36         var hideToolTip = WebInspector.UIString("Hide the %s navigation sidebar").format(displayName);
    37     }
    38 
    39     WebInspector.SidebarPanel.call(this, identifier, displayName, showToolTip, hideToolTip, image, element, role, label || displayName);
    40 
    41     this.element.classList.add(WebInspector.NavigationSidebarPanel.StyleClassName);
    42 
    43     this._autoHideToolbarItemWhenEmpty = autoHideToolbarItemWhenEmpty || false;
    44 
    45     if (autoHideToolbarItemWhenEmpty)
    46         this.toolbarItem.hidden = true;
    47 
    48     this._visibleContentTreeOutlines = new Set;
    49 
    50     this.contentElement.addEventListener("scroll", this._updateContentOverflowShadowVisibility.bind(this));
    51 
    52     this._contentTreeOutline = this.createContentTreeOutline(true);
    53 
    54     this._filterBar = new WebInspector.FilterBar();
    55     this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
    56     this.element.appendChild(this._filterBar.element);
    57 
    58     this._bottomOverflowShadowElement = document.createElement("div");
    59     this._bottomOverflowShadowElement.className = WebInspector.NavigationSidebarPanel.OverflowShadowElementStyleClassName;
    60     this.element.appendChild(this._bottomOverflowShadowElement);
    61 
    62     if (wantsTopOverflowShadow) {
    63         this._topOverflowShadowElement = document.createElement("div");
    64         this._topOverflowShadowElement.classList.add(WebInspector.NavigationSidebarPanel.OverflowShadowElementStyleClassName);
    65         this._topOverflowShadowElement.classList.add(WebInspector.NavigationSidebarPanel.TopOverflowShadowElementStyleClassName);
    66         this.element.appendChild(this._topOverflowShadowElement);
    67     }
    68 
    69     window.addEventListener("resize", this._updateContentOverflowShadowVisibility.bind(this));
    70 
    71     this._filtersSetting = new WebInspector.Setting(identifier + "-navigation-sidebar-filters", {});
    72     this._filterBar.filters = this._filtersSetting.value;
    73 
    74     this._emptyContentPlaceholderElement = document.createElement("div");
    75     this._emptyContentPlaceholderElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderElementStyleClassName;
    76 
    77     this._emptyContentPlaceholderMessageElement = document.createElement("div");
    78     this._emptyContentPlaceholderMessageElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderMessageElementStyleClassName;
    79     this._emptyContentPlaceholderElement.appendChild(this._emptyContentPlaceholderMessageElement);
    80 
    81     this._generateStyleRulesIfNeeded();
    82     this._generateDisclosureTrianglesIfNeeded();
    83 
    84     if (autoPruneOldTopLevelResourceTreeElements) {
    85         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._checkForOldResources, this);
    86         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasRemoved, this._checkForOldResources, this);
    87         WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasRemoved, this._checkForOldResources, this);
     28    constructor(identifier, displayName, image, keyboardShortcutKey, autoPruneOldTopLevelResourceTreeElements, autoHideToolbarItemWhenEmpty, wantsTopOverflowShadow, element, role, label)
     29    {
     30        var keyboardShortcut = null;
     31        if (keyboardShortcutKey)
     32            keyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.Control, keyboardShortcutKey);
     33
     34        if (keyboardShortcut) {
     35            var showToolTip = WebInspector.UIString("Show the %s navigation sidebar (%s)").format(displayName, keyboardShortcut.displayName);
     36            var hideToolTip = WebInspector.UIString("Hide the %s navigation sidebar (%s)").format(displayName, keyboardShortcut.displayName);
     37        } else {
     38            var showToolTip = WebInspector.UIString("Show the %s navigation sidebar").format(displayName);
     39            var hideToolTip = WebInspector.UIString("Hide the %s navigation sidebar").format(displayName);
     40        }
     41
     42        super(identifier, displayName, showToolTip, hideToolTip, image, element, role, label || displayName);
     43
     44        this.element.classList.add("navigation");
     45
     46        this._keyboardShortcut = keyboardShortcut;
     47        this._keyboardShortcut.callback = this.toggle.bind(this);
     48
     49        this._autoHideToolbarItemWhenEmpty = autoHideToolbarItemWhenEmpty || false;
     50
     51        if (autoHideToolbarItemWhenEmpty)
     52            this.toolbarItem.hidden = true;
     53
     54        this._visibleContentTreeOutlines = new Set;
     55
     56        this.contentElement.addEventListener("scroll", this._updateContentOverflowShadowVisibility.bind(this));
     57
     58        this._contentTreeOutline = this.createContentTreeOutline(true);
     59
     60        this._filterBar = new WebInspector.FilterBar();
     61        this._filterBar.addEventListener(WebInspector.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
     62        this.element.appendChild(this._filterBar.element);
     63
     64        this._bottomOverflowShadowElement = document.createElement("div");
     65        this._bottomOverflowShadowElement.className = WebInspector.NavigationSidebarPanel.OverflowShadowElementStyleClassName;
     66        this.element.appendChild(this._bottomOverflowShadowElement);
     67
     68        if (wantsTopOverflowShadow) {
     69            this._topOverflowShadowElement = document.createElement("div");
     70            this._topOverflowShadowElement.classList.add(WebInspector.NavigationSidebarPanel.OverflowShadowElementStyleClassName);
     71            this._topOverflowShadowElement.classList.add(WebInspector.NavigationSidebarPanel.TopOverflowShadowElementStyleClassName);
     72            this.element.appendChild(this._topOverflowShadowElement);
     73        }
     74
     75        window.addEventListener("resize", this._updateContentOverflowShadowVisibility.bind(this));
     76
     77        this._filtersSetting = new WebInspector.Setting(identifier + "-navigation-sidebar-filters", {});
     78        this._filterBar.filters = this._filtersSetting.value;
     79
     80        this._emptyContentPlaceholderElement = document.createElement("div");
     81        this._emptyContentPlaceholderElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderElementStyleClassName;
     82
     83        this._emptyContentPlaceholderMessageElement = document.createElement("div");
     84        this._emptyContentPlaceholderMessageElement.className = WebInspector.NavigationSidebarPanel.EmptyContentPlaceholderMessageElementStyleClassName;
     85        this._emptyContentPlaceholderElement.appendChild(this._emptyContentPlaceholderMessageElement);
     86
     87        this._generateStyleRulesIfNeeded();
     88        this._generateDisclosureTrianglesIfNeeded();
     89
     90        if (autoPruneOldTopLevelResourceTreeElements) {
     91            WebInspector.Frame.addEventListener(WebInspector.Frame.Event.MainResourceDidChange, this._checkForOldResources, this);
     92            WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ChildFrameWasRemoved, this._checkForOldResources, this);
     93            WebInspector.Frame.addEventListener(WebInspector.Frame.Event.ResourceWasRemoved, this._checkForOldResources, this);
     94        }
     95    }
     96
     97    // Public
     98
     99    get contentTreeOutlineElement()
     100    {
     101        return this._contentTreeOutline.element;
     102    }
     103
     104    get contentTreeOutline()
     105    {
     106        return this._contentTreeOutline;
     107    }
     108
     109    set contentTreeOutline(newTreeOutline)
     110    {
     111        console.assert(newTreeOutline);
     112        if (!newTreeOutline)
     113            return;
     114
     115        if (this._contentTreeOutline)
     116            this._contentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
     117
     118        this._contentTreeOutline = newTreeOutline;
     119        this._contentTreeOutline.element.classList.remove(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
     120
     121        this._visibleContentTreeOutlines.delete(this._contentTreeOutline);
     122        this._visibleContentTreeOutlines.add(newTreeOutline);
     123
     124        this._updateFilter();
     125    }
     126
     127    get contentTreeOutlineToAutoPrune()
     128    {
     129        return this._contentTreeOutline;
     130    }
     131
     132    get visibleContentTreeOutlines()
     133    {
     134        return this._visibleContentTreeOutlines;
     135    }
     136
     137    get hasSelectedElement()
     138    {
     139        return !!this._contentTreeOutline.selectedTreeElement;
     140    }
     141
     142    get filterBar()
     143    {
     144        return this._filterBar;
     145    }
     146
     147    get restoringState()
     148    {
     149        return this._restoringState;
     150    }
     151
     152    createContentTreeOutline(dontHideByDefault, suppressFiltering)
     153    {
     154        var contentTreeOutlineElement = document.createElement("ol");
     155        contentTreeOutlineElement.className = WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName;
     156        if (!dontHideByDefault)
     157            contentTreeOutlineElement.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
     158        this.contentElement.appendChild(contentTreeOutlineElement);
     159
     160        var contentTreeOutline = new TreeOutline(contentTreeOutlineElement);
     161        contentTreeOutline.allowsRepeatSelection = true;
     162
     163        if (!suppressFiltering) {
     164            contentTreeOutline.onadd = this._treeElementAddedOrChanged.bind(this);
     165            contentTreeOutline.onchange = this._treeElementAddedOrChanged.bind(this);
     166            contentTreeOutline.onexpand = this._treeElementExpandedOrCollapsed.bind(this);
     167            contentTreeOutline.oncollapse = this._treeElementExpandedOrCollapsed.bind(this);
     168        }
     169
     170        if (dontHideByDefault)
     171            this._visibleContentTreeOutlines.add(contentTreeOutline);
     172
     173        return contentTreeOutline;
     174    }
     175
     176    treeElementForRepresentedObject(representedObject)
     177    {
     178        return this._contentTreeOutline.getCachedTreeElement(representedObject);
     179    }
     180
     181    showDefaultContentView()
     182    {
     183        // Implemneted by subclasses if needed to show a content view when no existing tree element is selected.
     184    }
     185
     186    showContentViewForCurrentSelection()
     187    {
     188        // Reselect the selected tree element to cause the content view to be shown as well. <rdar://problem/10854727>
     189        var selectedTreeElement = this._contentTreeOutline.selectedTreeElement;
     190        if (selectedTreeElement)
     191            selectedTreeElement.select();
     192    }
     193
     194    saveStateToCookie(cookie)
     195    {
     196        console.assert(cookie);
     197
     198        // This does not save folder selections, which lack a represented object and content view.
     199        var selectedTreeElement = null;
     200        this._visibleContentTreeOutlines.forEach(function(outline) {
     201            if (outline.selectedTreeElement)
     202                selectedTreeElement = outline.selectedTreeElement;
     203        });
     204
     205        if (!selectedTreeElement)
     206            return;
     207
     208        if (this._isTreeElementWithoutRepresentedObject(selectedTreeElement))
     209            return;
     210
     211        var representedObject = selectedTreeElement.representedObject;
     212        cookie[WebInspector.TypeIdentifierCookieKey] = representedObject.constructor.TypeIdentifier;
     213
     214        if (representedObject.saveIdentityToCookie)
     215            representedObject.saveIdentityToCookie(cookie);
     216        else
     217            console.error("Error: TreeElement.representedObject is missing a saveIdentityToCookie implementation. TreeElement.constructor: ", selectedTreeElement.constructor);
     218    }
     219
     220    // This can be supplemented by subclasses that admit a simpler strategy for static tree elements.
     221    restoreStateFromCookie(cookie, relaxedMatchDelay)
     222    {
     223        this._pendingViewStateCookie = cookie;
     224        this._restoringState = true;
     225
     226        // Check if any existing tree elements in any outline match the cookie.
     227        this._checkOutlinesForPendingViewStateCookie();
     228
     229        if (this._finalAttemptToRestoreViewStateTimeout)
     230            clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
     231
     232        function finalAttemptToRestoreViewStateFromCookie()
     233        {
     234            delete this._finalAttemptToRestoreViewStateTimeout;
     235
     236            this._checkOutlinesForPendingViewStateCookie(true);
     237
     238            delete this._pendingViewStateCookie;
     239            delete this._restoringState;
     240        }
     241
     242        // If the specific tree element wasn't found, we may need to wait for the resources
     243        // to be registered. We try one last time (match type only) after an arbitrary amount of timeout.
     244        this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay);
     245    }
     246
     247    showEmptyContentPlaceholder(message, hideToolbarItem)
     248    {
     249        console.assert(message);
     250
     251        if (this._emptyContentPlaceholderElement.parentNode && this._emptyContentPlaceholderMessageElement.textContent === message)
     252            return;
     253
     254        this._emptyContentPlaceholderMessageElement.textContent = message;
     255        this.element.appendChild(this._emptyContentPlaceholderElement);
     256
     257        this._hideToolbarItemWhenEmpty = hideToolbarItem || false;
     258        this._updateToolbarItemVisibility();
     259        this._updateContentOverflowShadowVisibility();
     260    }
     261
     262    hideEmptyContentPlaceholder()
     263    {
     264        if (!this._emptyContentPlaceholderElement.parentNode)
     265            return;
     266
     267        this._emptyContentPlaceholderElement.parentNode.removeChild(this._emptyContentPlaceholderElement);
     268
     269        this._hideToolbarItemWhenEmpty = false;
     270        this._updateToolbarItemVisibility();
     271        this._updateContentOverflowShadowVisibility();
     272    }
     273
     274    updateEmptyContentPlaceholder(message)
     275    {
     276        this._updateToolbarItemVisibility();
     277
     278        if (!this._contentTreeOutline.children.length) {
     279            // No tree elements, so no results.
     280            this.showEmptyContentPlaceholder(message);
     281        } else if (!this._emptyFilterResults) {
     282            // There are tree elements, and not all of them are hidden by the filter.
     283            this.hideEmptyContentPlaceholder();
     284        }
     285    }
     286
     287    updateFilter()
     288    {
     289        this._updateFilter();
     290    }
     291
     292    hasCustomFilters()
     293    {
     294        // Implemented by subclasses if needed.
     295        return false;
     296    }
     297
     298    matchTreeElementAgainstCustomFilters(treeElement)
     299    {
     300        // Implemented by subclasses if needed.
     301        return true;
     302    }
     303
     304    matchTreeElementAgainstFilterFunctions(treeElement)
     305    {
     306        for (var filterFunction of this._filterFunctions) {
     307            if (filterFunction(treeElement))
     308                return true;
     309        }
     310        return false;
     311    }
     312
     313    applyFiltersToTreeElement(treeElement)
     314    {
     315        if (!this._filterBar.hasActiveFilters() && !this.hasCustomFilters()) {
     316            // No filters, so make everything visible.
     317            treeElement.hidden = false;
     318
     319            // If this tree element was expanded during filtering, collapse it again.
     320            if (treeElement.expanded && treeElement.__wasExpandedDuringFiltering) {
     321                delete treeElement.__wasExpandedDuringFiltering;
     322                treeElement.collapse();
     323            }
     324
     325            return;
     326        }
     327
     328        var filterableData = treeElement.filterableData || {};
     329
     330        var matchedBuiltInFilters = false;
     331
     332        var self = this;
     333        function matchTextFilter(inputs)
     334        {
     335            if (!inputs || !self._textFilterRegex)
     336                return true;
     337
     338            // Convert to a single item array if needed.
     339            if (!(inputs instanceof Array))
     340                inputs = [inputs];
     341
     342            // Loop over all the inputs and try to match them.
     343            for (var input of inputs) {
     344                if (!input)
     345                    continue;
     346                if (self._textFilterRegex.test(input)) {
     347                    matchedBuiltInFilters = true;
     348                    return true;
     349                }
     350            }
     351
     352            // No inputs matched.
     353            return false;
     354        }
     355
     356        function makeVisible()
     357        {
     358            // Make this element visible.
     359            treeElement.hidden = false;
     360
     361            // Make the ancestors visible and expand them.
     362            var currentAncestor = treeElement.parent;
     363            while (currentAncestor && !currentAncestor.root) {
     364                currentAncestor.hidden = false;
     365
     366                // Only expand if the built-in filters matched, not custom filters.
     367                if (matchedBuiltInFilters && !currentAncestor.expanded) {
     368                    currentAncestor.__wasExpandedDuringFiltering = true;
     369                    currentAncestor.expand();
     370                }
     371
     372                currentAncestor = currentAncestor.parent;
     373            }
     374        }
     375
     376        if (matchTextFilter(filterableData.text) && this.matchTreeElementAgainstFilterFunctions(treeElement) && this.matchTreeElementAgainstCustomFilters(treeElement)) {
     377            // Make this element visible since it matches.
     378            makeVisible();
     379
     380            // If this tree element didn't match a built-in filter and was expanded earlier during filtering, collapse it again.
     381            if (!matchedBuiltInFilters && treeElement.expanded && treeElement.__wasExpandedDuringFiltering) {
     382                delete treeElement.__wasExpandedDuringFiltering;
     383                treeElement.collapse();
     384            }
     385
     386            return;
     387        }
     388
     389        // Make this element invisible since it does not match.
     390        treeElement.hidden = true;
     391    }
     392
     393    show()
     394    {
     395        if (!this.parentSidebar)
     396            return;
     397
     398        WebInspector.SidebarPanel.prototype.show.call(this);
     399
     400        this.contentTreeOutlineElement.focus();
     401    }
     402
     403    shown()
     404    {
     405        WebInspector.SidebarPanel.prototype.shown.call(this);
     406
     407        this._updateContentOverflowShadowVisibility();
     408
     409        // Force the navigation item to be visible. This makes sure it is
     410        // always visible when the panel is shown.
     411        this.toolbarItem.hidden = false;
     412    }
     413
     414    hidden()
     415    {
     416        WebInspector.SidebarPanel.prototype.hidden.call(this);
     417
     418        this._updateToolbarItemVisibility();
     419    }
     420
     421    // Private
     422   
     423    _updateContentOverflowShadowVisibilitySoon()
     424    {
     425        if (this._updateContentOverflowShadowVisibilityIdentifier)
     426            return;
     427
     428        this._updateContentOverflowShadowVisibilityIdentifier = setTimeout(this._updateContentOverflowShadowVisibility.bind(this), 0);
     429    }
     430
     431    _updateContentOverflowShadowVisibility()
     432    {
     433        delete this._updateContentOverflowShadowVisibilityIdentifier;
     434
     435        var scrollHeight = this.contentElement.scrollHeight;
     436        var offsetHeight = this.contentElement.offsetHeight;
     437
     438        if (scrollHeight < offsetHeight) {
     439            if (this._topOverflowShadowElement)
     440                this._topOverflowShadowElement.style.opacity = 0;
     441            this._bottomOverflowShadowElement.style.opacity = 0;
     442            return;
     443        }
     444
     445        if (WebInspector.Platform.isLegacyMacOS)
     446            var edgeThreshold = 10;
     447        else
     448            var edgeThreshold = 1;
     449
     450        var scrollTop = this.contentElement.scrollTop;
     451
     452        var topCoverage = Math.min(scrollTop, edgeThreshold);
     453        var bottomCoverage = Math.max(0, (offsetHeight + scrollTop) - (scrollHeight - edgeThreshold));
     454
     455        if (this._topOverflowShadowElement)
     456            this._topOverflowShadowElement.style.opacity = (topCoverage / edgeThreshold).toFixed(1);
     457        this._bottomOverflowShadowElement.style.opacity = (1 - (bottomCoverage / edgeThreshold)).toFixed(1);
     458    }
     459
     460    _updateToolbarItemVisibility()
     461    {
     462        // Hide the navigation item if requested or auto-hiding and we are not visible and we are empty.
     463        var shouldHide = ((this._hideToolbarItemWhenEmpty || this._autoHideToolbarItemWhenEmpty) && !this.selected && !this._contentTreeOutline.children.length);
     464        this.toolbarItem.hidden = shouldHide;
     465    }
     466
     467    _checkForEmptyFilterResults()
     468    {
     469        // No tree elements, so don't touch the empty content placeholder.
     470        if (!this._contentTreeOutline.children.length)
     471            return;
     472
     473        // Iterate over all the top level tree elements. If any are visible, return early.
     474        var currentTreeElement = this._contentTreeOutline.children[0];
     475        while (currentTreeElement) {
     476            if (!currentTreeElement.hidden) {
     477                // Not hidden, so hide any empty content message.
     478                this.hideEmptyContentPlaceholder();
     479                this._emptyFilterResults = false;
     480                return;
     481            }
     482
     483            currentTreeElement = currentTreeElement.nextSibling;
     484        }
     485
     486        // All top level tree elements are hidden, so filtering hid everything. Show a message.
     487        this.showEmptyContentPlaceholder(WebInspector.UIString("No Filter Results"));
     488        this._emptyFilterResults = true;
     489    }
     490
     491    _filterDidChange()
     492    {
     493        this._updateFilter();
     494    }
     495
     496    _updateFilter()
     497    {
     498        var selectedTreeElement = this._contentTreeOutline.selectedTreeElement;
     499        var selectionWasHidden = selectedTreeElement && selectedTreeElement.hidden;
     500
     501        var filters = this._filterBar.filters;
     502        this._textFilterRegex = simpleGlobStringToRegExp(filters.text, "i");
     503        this._filtersSetting.value = filters;
     504        this._filterFunctions = filters.functions;
     505
     506        // Don't populate if we don't have any active filters.
     507        // We only need to populate when a filter needs to reveal.
     508        var dontPopulate = !this._filterBar.hasActiveFilters();
     509
     510        // Update the whole tree.
     511        var currentTreeElement = this._contentTreeOutline.children[0];
     512        while (currentTreeElement && !currentTreeElement.root) {
     513            this.applyFiltersToTreeElement(currentTreeElement);
     514            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, dontPopulate);
     515        }
     516
     517        this._checkForEmptyFilterResults();
     518        this._updateContentOverflowShadowVisibility();
     519
     520        // Filter may have hidden the selected resource in the timeline view, which should now notify its listeners.
     521        if (selectedTreeElement && selectedTreeElement.hidden !== selectionWasHidden) {
     522            var currentContentView = WebInspector.contentBrowser.currentContentView;
     523            if (currentContentView instanceof WebInspector.TimelineRecordingContentView && typeof currentContentView.currentTimelineView.filterUpdated === "function")
     524                currentContentView.currentTimelineView.filterUpdated();
     525        }
     526    }
     527
     528    _treeElementAddedOrChanged(treeElement)
     529    {
     530        // Don't populate if we don't have any active filters.
     531        // We only need to populate when a filter needs to reveal.
     532        var dontPopulate = !this._filterBar.hasActiveFilters();
     533
     534        // Apply the filters to the tree element and its descendants.
     535        var currentTreeElement = treeElement;
     536        while (currentTreeElement && !currentTreeElement.root) {
     537            this.applyFiltersToTreeElement(currentTreeElement);
     538            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, treeElement, dontPopulate);
     539        }
     540
     541        this._checkForEmptyFilterResults();
     542        this._updateContentOverflowShadowVisibilitySoon();
     543
     544        if (this.selected)
     545            this._checkElementsForPendingViewStateCookie(treeElement);
     546    }
     547
     548    _treeElementExpandedOrCollapsed(treeElement)
     549    {
     550        this._updateContentOverflowShadowVisibility();
     551    }
     552
     553    _generateStyleRulesIfNeeded()
     554    {
     555        if (WebInspector.NavigationSidebarPanel._styleElement)
     556            return;
     557
     558        WebInspector.NavigationSidebarPanel._styleElement = document.createElement("style");
     559
     560        var maximumSidebarTreeDepth = 32;
     561        var baseLeftPadding = 5; // Matches the padding in NavigationSidebarPanel.css for the item class. Keep in sync.
     562        var depthPadding = 10;
     563
     564        var styleText = "";
     565        var childrenSubstring = "";
     566        for (var i = 1; i <= maximumSidebarTreeDepth; ++i) {
     567            // Keep all the elements at the same depth once the maximum is reached.
     568            childrenSubstring += i === maximumSidebarTreeDepth ? " .children" : " > .children";
     569            styleText += "." + WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName + childrenSubstring + " > .item { ";
     570            styleText += "padding-left: " + (baseLeftPadding + (depthPadding * i)) + "px; }\n";
     571        }
     572
     573        WebInspector.NavigationSidebarPanel._styleElement.textContent = styleText;
     574
     575        document.head.appendChild(WebInspector.NavigationSidebarPanel._styleElement);
     576    }
     577
     578    _generateDisclosureTrianglesIfNeeded()
     579    {
     580        if (WebInspector.NavigationSidebarPanel._generatedDisclosureTriangles)
     581            return;
     582
     583        // Set this early instead of in _generateDisclosureTriangle because we don't want multiple panels that are
     584        // created at the same time to duplicate the work (even though it would be harmless.)
     585        WebInspector.NavigationSidebarPanel._generatedDisclosureTriangles = true;
     586
     587        var specifications = {};
     588
     589        if (WebInspector.Platform.isLegacyMacOS) {
     590            specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleNormalCanvasIdentifierSuffix] = {
     591                fillColor: [112, 126, 139],
     592                shadowColor: [255, 255, 255, 0.8],
     593                shadowOffsetX: 0,
     594                shadowOffsetY: 1,
     595                shadowBlur: 0
     596            };
     597
     598            specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleSelectedCanvasIdentifierSuffix] = {
     599                fillColor: [255, 255, 255],
     600                shadowColor: [61, 91, 110, 0.8],
     601                shadowOffsetX: 0,
     602                shadowOffsetY: 1,
     603                shadowBlur: 2
     604            };
     605        } else {
     606            specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleNormalCanvasIdentifierSuffix] = {
     607                fillColor: [140, 140, 140]
     608            };
     609
     610            specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleSelectedCanvasIdentifierSuffix] = {
     611                fillColor: [255, 255, 255]
     612            };
     613        }
     614
     615        generateColoredImagesForCSS("Images/DisclosureTriangleSmallOpen.svg", specifications, 13, 13, WebInspector.NavigationSidebarPanel.DisclosureTriangleOpenCanvasIdentifier);
     616        generateColoredImagesForCSS("Images/DisclosureTriangleSmallClosed.svg", specifications, 13, 13, WebInspector.NavigationSidebarPanel.DisclosureTriangleClosedCanvasIdentifier);
     617    }
     618
     619    _checkForOldResources(event)
     620    {
     621        if (this._checkForOldResourcesTimeoutIdentifier)
     622            return;
     623
     624        function delayedWork()
     625        {
     626            delete this._checkForOldResourcesTimeoutIdentifier;
     627
     628            var contentTreeOutline = this.contentTreeOutlineToAutoPrune;
     629
     630            // Check all the ResourceTreeElements at the top level to make sure their Resource still has a parentFrame in the frame hierarchy.
     631            // If the parentFrame is no longer in the frame hierarchy we know it was removed due to a navigation or some other page change and
     632            // we should remove the issues for that resource.
     633            for (var i = contentTreeOutline.children.length - 1; i >= 0; --i) {
     634                var treeElement = contentTreeOutline.children[i];
     635                if (!(treeElement instanceof WebInspector.ResourceTreeElement))
     636                    continue;
     637
     638                var resource = treeElement.resource;
     639                if (!resource.parentFrame || resource.parentFrame.isDetached())
     640                    contentTreeOutline.removeChildAtIndex(i, true, true);
     641            }
     642
     643            if (typeof this._updateEmptyContentPlaceholder === "function")
     644                this._updateEmptyContentPlaceholder();
     645        }
     646
     647        // Check on a delay to coalesce multiple calls to _checkForOldResources.
     648        this._checkForOldResourcesTimeoutIdentifier = setTimeout(delayedWork.bind(this), 0);
     649    }
     650
     651    _isTreeElementWithoutRepresentedObject(treeElement)
     652    {
     653        return treeElement instanceof WebInspector.FolderTreeElement
     654            || treeElement instanceof WebInspector.DatabaseHostTreeElement
     655            || typeof treeElement.representedObject === "string"
     656            || treeElement.representedObject instanceof String;
     657    }
     658
     659    _checkOutlinesForPendingViewStateCookie(matchTypeOnly)
     660    {
     661        if (!this._pendingViewStateCookie)
     662            return;
     663
     664        var visibleTreeElements = [];
     665        this._visibleContentTreeOutlines.forEach(function(outline) {
     666            var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
     667            while (currentTreeElement) {
     668                visibleTreeElements.push(currentTreeElement);
     669                currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
     670            }
     671        });
     672
     673        return this._checkElementsForPendingViewStateCookie(visibleTreeElements, matchTypeOnly);
     674    }
     675
     676    _checkElementsForPendingViewStateCookie(treeElements, matchTypeOnly)
     677    {
     678        if (!this._pendingViewStateCookie)
     679            return;
     680
     681        var cookie = this._pendingViewStateCookie;
     682
     683        function treeElementMatchesCookie(treeElement)
     684        {
     685            if (this._isTreeElementWithoutRepresentedObject(treeElement))
     686                return false;
     687
     688            var representedObject = treeElement.representedObject;
     689            if (!representedObject)
     690                return false;
     691
     692            var typeIdentifier = cookie[WebInspector.TypeIdentifierCookieKey];
     693            if (typeIdentifier !== representedObject.constructor.TypeIdentifier)
     694                return false;
     695
     696            if (matchTypeOnly)
     697                return true;
     698
     699            var candidateObjectCookie = {};
     700            if (representedObject.saveIdentityToCookie)
     701                representedObject.saveIdentityToCookie(candidateObjectCookie);
     702
     703            var candidateCookieKeys = Object.keys(candidateObjectCookie);
     704            return candidateCookieKeys.length && candidateCookieKeys.every(function valuesMatchForKey(key) {
     705                return candidateObjectCookie[key] === cookie[key];
     706            });
     707        }
     708
     709        if (!(treeElements instanceof Array))
     710            treeElements = [treeElements];
     711
     712        var matchedElement = null;
     713        treeElements.some(function(element) {
     714            if (treeElementMatchesCookie.call(this, element)) {
     715                matchedElement = element;
     716                return true;
     717            }
     718        }, this);
     719
     720        if (matchedElement) {
     721            matchedElement.revealAndSelect();
     722
     723            delete this._pendingViewStateCookie;
     724
     725            // Delay clearing the restoringState flag until the next runloop so listeners
     726            // checking for it in this runloop still know state was being restored.
     727            setTimeout(function() {
     728                delete this._restoringState;
     729            }.bind(this));
     730
     731            if (this._finalAttemptToRestoreViewStateTimeout) {
     732                clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
     733                delete this._finalAttemptToRestoreViewStateTimeout;
     734            }
     735        }
    88736    }
    89737};
    90738
    91 WebInspector.NavigationSidebarPanel.StyleClassName = "navigation";
    92739WebInspector.NavigationSidebarPanel.OverflowShadowElementStyleClassName = "overflow-shadow";
    93740WebInspector.NavigationSidebarPanel.TopOverflowShadowElementStyleClassName = "top";
     
    101748WebInspector.NavigationSidebarPanel.DisclosureTriangleNormalCanvasIdentifierSuffix = "-normal";
    102749WebInspector.NavigationSidebarPanel.DisclosureTriangleSelectedCanvasIdentifierSuffix = "-selected";
    103 
    104 WebInspector.NavigationSidebarPanel.prototype = {
    105     constructor: WebInspector.NavigationSidebarPanel,
    106     __proto__: WebInspector.SidebarPanel.prototype,
    107 
    108     // Public
    109 
    110     get contentTreeOutlineElement()
    111     {
    112         return this._contentTreeOutline.element;
    113     },
    114 
    115     get contentTreeOutline()
    116     {
    117         return this._contentTreeOutline;
    118     },
    119 
    120     set contentTreeOutline(newTreeOutline)
    121     {
    122         console.assert(newTreeOutline);
    123         if (!newTreeOutline)
    124             return;
    125 
    126         if (this._contentTreeOutline)
    127             this._contentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
    128 
    129         this._contentTreeOutline = newTreeOutline;
    130         this._contentTreeOutline.element.classList.remove(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
    131 
    132         this._visibleContentTreeOutlines.delete(this._contentTreeOutline);
    133         this._visibleContentTreeOutlines.add(newTreeOutline);
    134 
    135         this._updateFilter();
    136     },
    137 
    138     get contentTreeOutlineToAutoPrune()
    139     {
    140         return this._contentTreeOutline;
    141     },
    142 
    143     get visibleContentTreeOutlines()
    144     {
    145         return this._visibleContentTreeOutlines;
    146     },
    147 
    148     get hasSelectedElement()
    149     {
    150         return !!this._contentTreeOutline.selectedTreeElement;
    151     },
    152 
    153     get filterBar()
    154     {
    155         return this._filterBar;
    156     },
    157 
    158     get restoringState()
    159     {
    160         return this._restoringState;
    161     },
    162 
    163     createContentTreeOutline: function(dontHideByDefault, suppressFiltering)
    164     {
    165         var contentTreeOutlineElement = document.createElement("ol");
    166         contentTreeOutlineElement.className = WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName;
    167         if (!dontHideByDefault)
    168             contentTreeOutlineElement.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
    169         this.contentElement.appendChild(contentTreeOutlineElement);
    170 
    171         var contentTreeOutline = new TreeOutline(contentTreeOutlineElement);
    172         contentTreeOutline.allowsRepeatSelection = true;
    173 
    174         if (!suppressFiltering) {
    175             contentTreeOutline.onadd = this._treeElementAddedOrChanged.bind(this);
    176             contentTreeOutline.onchange = this._treeElementAddedOrChanged.bind(this);
    177             contentTreeOutline.onexpand = this._treeElementExpandedOrCollapsed.bind(this);
    178             contentTreeOutline.oncollapse = this._treeElementExpandedOrCollapsed.bind(this);
    179         }
    180 
    181         if (dontHideByDefault)
    182             this._visibleContentTreeOutlines.add(contentTreeOutline);
    183 
    184         return contentTreeOutline;
    185     },
    186 
    187     treeElementForRepresentedObject: function(representedObject)
    188     {
    189         return this._contentTreeOutline.getCachedTreeElement(representedObject);
    190     },
    191 
    192     showDefaultContentView: function()
    193     {
    194         // Implemneted by subclasses if needed to show a content view when no existing tree element is selected.
    195     },
    196 
    197     showContentViewForCurrentSelection: function()
    198     {
    199         // Reselect the selected tree element to cause the content view to be shown as well. <rdar://problem/10854727>
    200         var selectedTreeElement = this._contentTreeOutline.selectedTreeElement;
    201         if (selectedTreeElement)
    202             selectedTreeElement.select();
    203     },
    204 
    205     saveStateToCookie: function(cookie)
    206     {
    207         console.assert(cookie);
    208 
    209         // This does not save folder selections, which lack a represented object and content view.
    210         var selectedTreeElement = null;
    211         this._visibleContentTreeOutlines.forEach(function(outline) {
    212             if (outline.selectedTreeElement)
    213                 selectedTreeElement = outline.selectedTreeElement;
    214         });
    215 
    216         if (!selectedTreeElement)
    217             return;
    218 
    219         if (this._isTreeElementWithoutRepresentedObject(selectedTreeElement))
    220             return;
    221 
    222         var representedObject = selectedTreeElement.representedObject;
    223         cookie[WebInspector.TypeIdentifierCookieKey] = representedObject.constructor.TypeIdentifier;
    224 
    225         if (representedObject.saveIdentityToCookie)
    226             representedObject.saveIdentityToCookie(cookie);
    227         else
    228             console.error("Error: TreeElement.representedObject is missing a saveIdentityToCookie implementation. TreeElement.constructor: ", selectedTreeElement.constructor);
    229     },
    230 
    231     // This can be supplemented by subclasses that admit a simpler strategy for static tree elements.
    232     restoreStateFromCookie: function(cookie, relaxedMatchDelay)
    233     {
    234         this._pendingViewStateCookie = cookie;
    235         this._restoringState = true;
    236 
    237         // Check if any existing tree elements in any outline match the cookie.
    238         this._checkOutlinesForPendingViewStateCookie();
    239 
    240         if (this._finalAttemptToRestoreViewStateTimeout)
    241             clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
    242 
    243         function finalAttemptToRestoreViewStateFromCookie()
    244         {
    245             delete this._finalAttemptToRestoreViewStateTimeout;
    246 
    247             this._checkOutlinesForPendingViewStateCookie(true);
    248 
    249             delete this._pendingViewStateCookie;
    250             delete this._restoringState;
    251         }
    252 
    253         // If the specific tree element wasn't found, we may need to wait for the resources
    254         // to be registered. We try one last time (match type only) after an arbitrary amount of timeout.
    255         this._finalAttemptToRestoreViewStateTimeout = setTimeout(finalAttemptToRestoreViewStateFromCookie.bind(this), relaxedMatchDelay);
    256     },
    257 
    258     showEmptyContentPlaceholder: function(message, hideToolbarItem)
    259     {
    260         console.assert(message);
    261 
    262         if (this._emptyContentPlaceholderElement.parentNode && this._emptyContentPlaceholderMessageElement.textContent === message)
    263             return;
    264 
    265         this._emptyContentPlaceholderMessageElement.textContent = message;
    266         this.element.appendChild(this._emptyContentPlaceholderElement);
    267 
    268         this._hideToolbarItemWhenEmpty = hideToolbarItem || false;
    269         this._updateToolbarItemVisibility();
    270         this._updateContentOverflowShadowVisibility();
    271     },
    272 
    273     hideEmptyContentPlaceholder: function()
    274     {
    275         if (!this._emptyContentPlaceholderElement.parentNode)
    276             return;
    277 
    278         this._emptyContentPlaceholderElement.parentNode.removeChild(this._emptyContentPlaceholderElement);
    279 
    280         this._hideToolbarItemWhenEmpty = false;
    281         this._updateToolbarItemVisibility();
    282         this._updateContentOverflowShadowVisibility();
    283     },
    284 
    285     updateEmptyContentPlaceholder: function(message)
    286     {
    287         this._updateToolbarItemVisibility();
    288 
    289         if (!this._contentTreeOutline.children.length) {
    290             // No tree elements, so no results.
    291             this.showEmptyContentPlaceholder(message);
    292         } else if (!this._emptyFilterResults) {
    293             // There are tree elements, and not all of them are hidden by the filter.
    294             this.hideEmptyContentPlaceholder();
    295         }
    296     },
    297 
    298     updateFilter: function()
    299     {
    300         this._updateFilter();
    301     },
    302 
    303     hasCustomFilters: function()
    304     {
    305         // Implemented by subclasses if needed.
    306         return false;
    307     },
    308 
    309     matchTreeElementAgainstCustomFilters: function(treeElement)
    310     {
    311         // Implemented by subclasses if needed.
    312         return true;
    313     },
    314 
    315     matchTreeElementAgainstFilterFunctions: function(treeElement)
    316     {
    317         for (var filterFunction of this._filterFunctions) {
    318             if (filterFunction(treeElement))
    319                 return true;
    320         }
    321         return false;
    322     },
    323 
    324     applyFiltersToTreeElement: function(treeElement)
    325     {
    326         if (!this._filterBar.hasActiveFilters() && !this.hasCustomFilters()) {
    327             // No filters, so make everything visible.
    328             treeElement.hidden = false;
    329 
    330             // If this tree element was expanded during filtering, collapse it again.
    331             if (treeElement.expanded && treeElement.__wasExpandedDuringFiltering) {
    332                 delete treeElement.__wasExpandedDuringFiltering;
    333                 treeElement.collapse();
    334             }
    335 
    336             return;
    337         }
    338 
    339         var filterableData = treeElement.filterableData || {};
    340 
    341         var matchedBuiltInFilters = false;
    342 
    343         var self = this;
    344         function matchTextFilter(inputs)
    345         {
    346             if (!inputs || !self._textFilterRegex)
    347                 return true;
    348 
    349             // Convert to a single item array if needed.
    350             if (!(inputs instanceof Array))
    351                 inputs = [inputs];
    352 
    353             // Loop over all the inputs and try to match them.
    354             for (var input of inputs) {
    355                 if (!input)
    356                     continue;
    357                 if (self._textFilterRegex.test(input)) {
    358                     matchedBuiltInFilters = true;
    359                     return true;
    360                 }
    361             }
    362 
    363             // No inputs matched.
    364             return false;
    365         }
    366 
    367         function makeVisible()
    368         {
    369             // Make this element visible.
    370             treeElement.hidden = false;
    371 
    372             // Make the ancestors visible and expand them.
    373             var currentAncestor = treeElement.parent;
    374             while (currentAncestor && !currentAncestor.root) {
    375                 currentAncestor.hidden = false;
    376 
    377                 // Only expand if the built-in filters matched, not custom filters.
    378                 if (matchedBuiltInFilters && !currentAncestor.expanded) {
    379                     currentAncestor.__wasExpandedDuringFiltering = true;
    380                     currentAncestor.expand();
    381                 }
    382 
    383                 currentAncestor = currentAncestor.parent;
    384             }
    385         }
    386 
    387         if (matchTextFilter(filterableData.text) && this.matchTreeElementAgainstFilterFunctions(treeElement) && this.matchTreeElementAgainstCustomFilters(treeElement)) {
    388             // Make this element visible since it matches.
    389             makeVisible();
    390 
    391             // If this tree element didn't match a built-in filter and was expanded earlier during filtering, collapse it again.
    392             if (!matchedBuiltInFilters && treeElement.expanded && treeElement.__wasExpandedDuringFiltering) {
    393                 delete treeElement.__wasExpandedDuringFiltering;
    394                 treeElement.collapse();
    395             }
    396 
    397             return;
    398         }
    399 
    400         // Make this element invisible since it does not match.
    401         treeElement.hidden = true;
    402     },
    403 
    404     show: function()
    405     {
    406         if (!this.parentSidebar)
    407             return;
    408 
    409         WebInspector.SidebarPanel.prototype.show.call(this);
    410 
    411         this.contentTreeOutlineElement.focus();
    412     },
    413 
    414     shown: function()
    415     {
    416         WebInspector.SidebarPanel.prototype.shown.call(this);
    417 
    418         this._updateContentOverflowShadowVisibility();
    419 
    420         // Force the navigation item to be visible. This makes sure it is
    421         // always visible when the panel is shown.
    422         this.toolbarItem.hidden = false;
    423     },
    424 
    425     hidden: function()
    426     {
    427         WebInspector.SidebarPanel.prototype.hidden.call(this);
    428 
    429         this._updateToolbarItemVisibility();
    430     },
    431 
    432     // Private
    433    
    434     _updateContentOverflowShadowVisibilitySoon: function()
    435     {
    436         if (this._updateContentOverflowShadowVisibilityIdentifier)
    437             return;
    438 
    439         this._updateContentOverflowShadowVisibilityIdentifier = setTimeout(this._updateContentOverflowShadowVisibility.bind(this), 0);
    440     },
    441 
    442     _updateContentOverflowShadowVisibility: function()
    443     {
    444         delete this._updateContentOverflowShadowVisibilityIdentifier;
    445 
    446         var scrollHeight = this.contentElement.scrollHeight;
    447         var offsetHeight = this.contentElement.offsetHeight;
    448 
    449         if (scrollHeight < offsetHeight) {
    450             if (this._topOverflowShadowElement)
    451                 this._topOverflowShadowElement.style.opacity = 0;
    452             this._bottomOverflowShadowElement.style.opacity = 0;
    453             return;
    454         }
    455 
    456         if (WebInspector.Platform.isLegacyMacOS)
    457             const edgeThreshold = 10;
    458         else
    459             const edgeThreshold = 1;
    460 
    461         var scrollTop = this.contentElement.scrollTop;
    462 
    463         var topCoverage = Math.min(scrollTop, edgeThreshold);
    464         var bottomCoverage = Math.max(0, (offsetHeight + scrollTop) - (scrollHeight - edgeThreshold));
    465 
    466         if (this._topOverflowShadowElement)
    467             this._topOverflowShadowElement.style.opacity = (topCoverage / edgeThreshold).toFixed(1);
    468         this._bottomOverflowShadowElement.style.opacity = (1 - (bottomCoverage / edgeThreshold)).toFixed(1);
    469     },
    470 
    471     _updateToolbarItemVisibility: function()
    472     {
    473         // Hide the navigation item if requested or auto-hiding and we are not visible and we are empty.
    474         var shouldHide = ((this._hideToolbarItemWhenEmpty || this._autoHideToolbarItemWhenEmpty) && !this.selected && !this._contentTreeOutline.children.length);
    475         this.toolbarItem.hidden = shouldHide;
    476     },
    477 
    478     _checkForEmptyFilterResults: function()
    479     {
    480         // No tree elements, so don't touch the empty content placeholder.
    481         if (!this._contentTreeOutline.children.length)
    482             return;
    483 
    484         // Iterate over all the top level tree elements. If any are visible, return early.
    485         var currentTreeElement = this._contentTreeOutline.children[0];
    486         while (currentTreeElement) {
    487             if (!currentTreeElement.hidden) {
    488                 // Not hidden, so hide any empty content message.
    489                 this.hideEmptyContentPlaceholder();
    490                 this._emptyFilterResults = false;
    491                 return;
    492             }
    493 
    494             currentTreeElement = currentTreeElement.nextSibling;
    495         }
    496 
    497         // All top level tree elements are hidden, so filtering hid everything. Show a message.
    498         this.showEmptyContentPlaceholder(WebInspector.UIString("No Filter Results"));
    499         this._emptyFilterResults = true;
    500     },
    501 
    502     _filterDidChange: function()
    503     {
    504         this._updateFilter();
    505     },
    506 
    507     _updateFilter: function()
    508     {
    509         var selectedTreeElement = this._contentTreeOutline.selectedTreeElement;
    510         var selectionWasHidden = selectedTreeElement && selectedTreeElement.hidden;
    511 
    512         var filters = this._filterBar.filters;
    513         this._textFilterRegex = simpleGlobStringToRegExp(filters.text, "i");
    514         this._filtersSetting.value = filters;
    515         this._filterFunctions = filters.functions;
    516 
    517         // Don't populate if we don't have any active filters.
    518         // We only need to populate when a filter needs to reveal.
    519         var dontPopulate = !this._filterBar.hasActiveFilters();
    520 
    521         // Update the whole tree.
    522         var currentTreeElement = this._contentTreeOutline.children[0];
    523         while (currentTreeElement && !currentTreeElement.root) {
    524             this.applyFiltersToTreeElement(currentTreeElement);
    525             currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, dontPopulate);
    526         }
    527 
    528         this._checkForEmptyFilterResults();
    529         this._updateContentOverflowShadowVisibility();
    530 
    531         // Filter may have hidden the selected resource in the timeline view, which should now notify its listeners.
    532         if (selectedTreeElement && selectedTreeElement.hidden !== selectionWasHidden) {
    533             var currentContentView = WebInspector.contentBrowser.currentContentView;
    534             if (currentContentView instanceof WebInspector.TimelineRecordingContentView && typeof currentContentView.currentTimelineView.filterUpdated === "function")
    535                 currentContentView.currentTimelineView.filterUpdated();
    536         }
    537     },
    538 
    539     _treeElementAddedOrChanged: function(treeElement)
    540     {
    541         // Don't populate if we don't have any active filters.
    542         // We only need to populate when a filter needs to reveal.
    543         var dontPopulate = !this._filterBar.hasActiveFilters();
    544 
    545         // Apply the filters to the tree element and its descendants.
    546         var currentTreeElement = treeElement;
    547         while (currentTreeElement && !currentTreeElement.root) {
    548             this.applyFiltersToTreeElement(currentTreeElement);
    549             currentTreeElement = currentTreeElement.traverseNextTreeElement(false, treeElement, dontPopulate);
    550         }
    551 
    552         this._checkForEmptyFilterResults();
    553         this._updateContentOverflowShadowVisibilitySoon();
    554 
    555         if (this.selected)
    556             this._checkElementsForPendingViewStateCookie(treeElement);
    557     },
    558 
    559     _treeElementExpandedOrCollapsed: function(treeElement)
    560     {
    561         this._updateContentOverflowShadowVisibility();
    562     },
    563 
    564     _generateStyleRulesIfNeeded: function()
    565     {
    566         if (WebInspector.NavigationSidebarPanel._styleElement)
    567             return;
    568 
    569         WebInspector.NavigationSidebarPanel._styleElement = document.createElement("style");
    570 
    571         const maximumSidebarTreeDepth = 32;
    572         const baseLeftPadding = 5; // Matches the padding in NavigationSidebarPanel.css for the item class. Keep in sync.
    573         const depthPadding = 10;
    574 
    575         var styleText = "";
    576         var childrenSubstring = "";
    577         for (var i = 1; i <= maximumSidebarTreeDepth; ++i) {
    578             // Keep all the elements at the same depth once the maximum is reached.
    579             childrenSubstring += i === maximumSidebarTreeDepth ? " .children" : " > .children";
    580             styleText += "." + WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementStyleClassName + childrenSubstring + " > .item { ";
    581             styleText += "padding-left: " + (baseLeftPadding + (depthPadding * i)) + "px; }\n";
    582         }
    583 
    584         WebInspector.NavigationSidebarPanel._styleElement.textContent = styleText;
    585 
    586         document.head.appendChild(WebInspector.NavigationSidebarPanel._styleElement);
    587     },
    588 
    589     _generateDisclosureTrianglesIfNeeded: function()
    590     {
    591         if (WebInspector.NavigationSidebarPanel._generatedDisclosureTriangles)
    592             return;
    593 
    594         // Set this early instead of in _generateDisclosureTriangle because we don't want multiple panels that are
    595         // created at the same time to duplicate the work (even though it would be harmless.)
    596         WebInspector.NavigationSidebarPanel._generatedDisclosureTriangles = true;
    597 
    598         var specifications = {};
    599 
    600         if (WebInspector.Platform.isLegacyMacOS) {
    601             specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleNormalCanvasIdentifierSuffix] = {
    602                 fillColor: [112, 126, 139],
    603                 shadowColor: [255, 255, 255, 0.8],
    604                 shadowOffsetX: 0,
    605                 shadowOffsetY: 1,
    606                 shadowBlur: 0
    607             };
    608 
    609             specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleSelectedCanvasIdentifierSuffix] = {
    610                 fillColor: [255, 255, 255],
    611                 shadowColor: [61, 91, 110, 0.8],
    612                 shadowOffsetX: 0,
    613                 shadowOffsetY: 1,
    614                 shadowBlur: 2
    615             };
    616         } else {
    617             specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleNormalCanvasIdentifierSuffix] = {
    618                 fillColor: [140, 140, 140]
    619             };
    620 
    621             specifications[WebInspector.NavigationSidebarPanel.DisclosureTriangleSelectedCanvasIdentifierSuffix] = {
    622                 fillColor: [255, 255, 255]
    623             };
    624         }
    625 
    626         generateColoredImagesForCSS("Images/DisclosureTriangleSmallOpen.svg", specifications, 13, 13, WebInspector.NavigationSidebarPanel.DisclosureTriangleOpenCanvasIdentifier);
    627         generateColoredImagesForCSS("Images/DisclosureTriangleSmallClosed.svg", specifications, 13, 13, WebInspector.NavigationSidebarPanel.DisclosureTriangleClosedCanvasIdentifier);
    628     },
    629 
    630     _checkForOldResources: function(event)
    631     {
    632         if (this._checkForOldResourcesTimeoutIdentifier)
    633             return;
    634 
    635         function delayedWork()
    636         {
    637             delete this._checkForOldResourcesTimeoutIdentifier;
    638 
    639             var contentTreeOutline = this.contentTreeOutlineToAutoPrune;
    640 
    641             // Check all the ResourceTreeElements at the top level to make sure their Resource still has a parentFrame in the frame hierarchy.
    642             // If the parentFrame is no longer in the frame hierarchy we know it was removed due to a navigation or some other page change and
    643             // we should remove the issues for that resource.
    644             for (var i = contentTreeOutline.children.length - 1; i >= 0; --i) {
    645                 var treeElement = contentTreeOutline.children[i];
    646                 if (!(treeElement instanceof WebInspector.ResourceTreeElement))
    647                     continue;
    648 
    649                 var resource = treeElement.resource;
    650                 if (!resource.parentFrame || resource.parentFrame.isDetached())
    651                     contentTreeOutline.removeChildAtIndex(i, true, true);
    652             }
    653 
    654             if (typeof this._updateEmptyContentPlaceholder === "function")
    655                 this._updateEmptyContentPlaceholder();
    656         }
    657 
    658         // Check on a delay to coalesce multiple calls to _checkForOldResources.
    659         this._checkForOldResourcesTimeoutIdentifier = setTimeout(delayedWork.bind(this), 0);
    660     },
    661 
    662     _isTreeElementWithoutRepresentedObject: function(treeElement)
    663     {
    664         return treeElement instanceof WebInspector.FolderTreeElement
    665             || treeElement instanceof WebInspector.DatabaseHostTreeElement
    666             || typeof treeElement.representedObject === "string"
    667             || treeElement.representedObject instanceof String;
    668     },
    669 
    670     _checkOutlinesForPendingViewStateCookie: function(matchTypeOnly)
    671     {
    672         if (!this._pendingViewStateCookie)
    673             return;
    674 
    675         var visibleTreeElements = [];
    676         this._visibleContentTreeOutlines.forEach(function(outline) {
    677             var currentTreeElement = outline.hasChildren ? outline.children[0] : null;
    678             while (currentTreeElement) {
    679                 visibleTreeElements.push(currentTreeElement);
    680                 currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
    681             }
    682         });
    683 
    684         return this._checkElementsForPendingViewStateCookie(visibleTreeElements, matchTypeOnly);
    685     },
    686 
    687     _checkElementsForPendingViewStateCookie: function(treeElements, matchTypeOnly)
    688     {
    689         if (!this._pendingViewStateCookie)
    690             return;
    691 
    692         var cookie = this._pendingViewStateCookie;
    693 
    694         function treeElementMatchesCookie(treeElement)
    695         {
    696             if (this._isTreeElementWithoutRepresentedObject(treeElement))
    697                 return false;
    698 
    699             var representedObject = treeElement.representedObject;
    700             if (!representedObject)
    701                 return false;
    702 
    703             var typeIdentifier = cookie[WebInspector.TypeIdentifierCookieKey];
    704             if (typeIdentifier !== representedObject.constructor.TypeIdentifier)
    705                 return false;
    706 
    707             if (matchTypeOnly)
    708                 return true;
    709 
    710             var candidateObjectCookie = {};
    711             if (representedObject.saveIdentityToCookie)
    712                 representedObject.saveIdentityToCookie(candidateObjectCookie);
    713 
    714             var candidateCookieKeys = Object.keys(candidateObjectCookie);
    715             return candidateCookieKeys.length && candidateCookieKeys.every(function valuesMatchForKey(key) {
    716                 return candidateObjectCookie[key] === cookie[key];
    717             });
    718         }
    719 
    720         if (!(treeElements instanceof Array))
    721             treeElements = [treeElements];
    722 
    723         var matchedElement = null;
    724         treeElements.some(function(element) {
    725             if (treeElementMatchesCookie.call(this, element)) {
    726                 matchedElement = element;
    727                 return true;
    728             }
    729         }, this);
    730 
    731         if (matchedElement) {
    732             matchedElement.revealAndSelect();
    733 
    734             delete this._pendingViewStateCookie;
    735 
    736             // Delay clearing the restoringState flag until the next runloop so listeners
    737             // checking for it in this runloop still know state was being restored.
    738             setTimeout(function() {
    739                 delete this._restoringState;
    740             }.bind(this));
    741 
    742             if (this._finalAttemptToRestoreViewStateTimeout) {
    743                 clearTimeout(this._finalAttemptToRestoreViewStateTimeout);
    744                 delete this._finalAttemptToRestoreViewStateTimeout;
    745             }
    746         }
    747     }
    748 };
  • trunk/Source/WebInspectorUI/UserInterface/Views/ProbeDetailsSidebarPanel.js

    r176080 r182041  
    11/*
     2 * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
    23 * Copyright (C) 2013 University of Washington. All rights reserved.
    3  * Copyright (C) 2014 Apple Inc. All rights reserved.
    44 *
    55 * Redistribution and use in source and binary forms, with or without
     
    2525 */
    2626
    27 WebInspector.ProbeDetailsSidebarPanel = function()
     27WebInspector.ProbeDetailsSidebarPanel = class ProbeDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
    2828{
    29     WebInspector.DetailsSidebarPanel.call(this, "probe", WebInspector.UIString("Probes"), WebInspector.UIString("Probes"), "Images/NavigationItemProbes.svg", "6");
     29    constructor()
     30    {
     31        super("probe", WebInspector.UIString("Probes"), WebInspector.UIString("Probes"), "Images/NavigationItemProbes.svg", "6");
    3032
    31     WebInspector.probeManager.addEventListener(WebInspector.ProbeManager.Event.ProbeSetAdded, this._probeSetAdded, this);
    32     WebInspector.probeManager.addEventListener(WebInspector.ProbeManager.Event.ProbeSetRemoved, this._probeSetRemoved, this);
     33        WebInspector.probeManager.addEventListener(WebInspector.ProbeManager.Event.ProbeSetAdded, this._probeSetAdded, this);
     34        WebInspector.probeManager.addEventListener(WebInspector.ProbeManager.Event.ProbeSetRemoved, this._probeSetRemoved, this);
    3335
    34     this._probeSetSections = new Map;
    35     this._inspectedProbeSets = [];
     36        this._probeSetSections = new Map;
     37        this._inspectedProbeSets = [];
    3638
    37     // Initialize sidebar sections for probe sets that already exist.
    38     for (var probeSet of WebInspector.probeManager.probeSets)
    39         this._probeSetAdded(probeSet);
    40 };
    41 
    42 WebInspector.ProbeDetailsSidebarPanel.OffsetSectionsStyleClassName  = "offset-sections";
    43 
    44 WebInspector.ProbeDetailsSidebarPanel.prototype = {
    45     constructor: WebInspector.ProbeDetailsSidebarPanel,
    46     __proto__: WebInspector.DetailsSidebarPanel.prototype,
     39        // Initialize sidebar sections for probe sets that already exist.
     40        for (var probeSet of WebInspector.probeManager.probeSets)
     41            this._probeSetAdded(probeSet);
     42    }
    4743
    4844    // Public
     
    5147    {
    5248        return this._inspectedProbeSets.slice();
    53     },
     49    }
    5450
    5551    set inspectedProbeSets(newProbeSets)
     
    6662            this.contentElement.appendChild(shownSection.element);
    6763        }
    68     },
     64    }
    6965
    70     inspect: function(objects)
     66    inspect(objects)
    7167    {
    7268        if (!(objects instanceof Array))
     
    9490
    9591        return !!this._inspectedProbeSets.length;
    96     },
     92    }
    9793
    9894    // Private
    9995
    100     _probeSetAdded: function(probeSetOrEvent)
     96    _probeSetAdded(probeSetOrEvent)
    10197    {
    10298        var probeSet;
     
    109105        var newSection = new WebInspector.ProbeSetDetailsSection(probeSet);
    110106        this._probeSetSections.set(probeSet, newSection);
    111     },
     107    }
    112108
    113109
    114     _probeSetRemoved: function(event)
     110    _probeSetRemoved(event)
    115111    {
    116112        var probeSet = event.data.probeSet;
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceDetailsSidebarPanel.js

    r181185 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.ResourceDetailsSidebarPanel = function()
     26WebInspector.ResourceDetailsSidebarPanel = class ResourceDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
    2727{
    28     WebInspector.DetailsSidebarPanel.call(this, "resource-details", WebInspector.UIString("Resource"), WebInspector.UIString("Resource"), "Images/NavigationItemFile.svg", "1");
    29 
    30     this.element.classList.add(WebInspector.ResourceDetailsSidebarPanel.StyleClassName);
    31 
    32     this._resource = null;
    33 
    34     this._typeMIMETypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("MIME Type"));
    35     this._typeResourceTypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Resource Type"));
    36 
    37     this._typeSection = new WebInspector.DetailsSection("resource-type", WebInspector.UIString("Type"));
    38     this._typeSection.groups = [new WebInspector.DetailsSectionGroup([this._typeMIMETypeRow, this._typeResourceTypeRow])];
    39 
    40     this._locationFullURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Full URL"));
    41     this._locationSchemeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Scheme"));
    42     this._locationHostRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Host"));
    43     this._locationPortRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Port"));
    44     this._locationPathRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Path"));
    45     this._locationQueryStringRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Query String"));
    46     this._locationFragmentRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Fragment"));
    47     this._locationFilenameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Filename"));
    48     this._initiatorRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Initiator"));
    49 
    50     var firstGroup = [this._locationFullURLRow];
    51     var secondGroup = [this._locationSchemeRow, this._locationHostRow, this._locationPortRow, this._locationPathRow,
    52         this._locationQueryStringRow, this._locationFragmentRow, this._locationFilenameRow];
    53     var thirdGroup = [this._initiatorRow];
    54 
    55     this._fullURLGroup = new WebInspector.DetailsSectionGroup(firstGroup);
    56     this._locationURLComponentsGroup = new WebInspector.DetailsSectionGroup(secondGroup);
    57     this._initiatorGroup = new WebInspector.DetailsSectionGroup(thirdGroup);
    58 
    59     this._locationSection = new WebInspector.DetailsSection("resource-location", WebInspector.UIString("Location"), [this._fullURLGroup, this._locationURLComponentsGroup, this._initiatorGroup]);
    60 
    61     this._queryParametersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Query Parameters"));
    62     this._queryParametersSection = new WebInspector.DetailsSection("resource-query-parameters", WebInspector.UIString("Query Parameters"));
    63     this._queryParametersSection.groups = [new WebInspector.DetailsSectionGroup([this._queryParametersRow])];
    64 
    65     this._requestDataSection = new WebInspector.DetailsSection("resource-request-data", WebInspector.UIString("Request Data"));
    66 
    67     this._requestMethodRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Method"));
    68     this._cachedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Cached"));
    69 
    70     this._statusTextRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Status"));
    71     this._statusCodeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Code"));
    72 
    73     this._encodedSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Encoded"));
    74     this._decodedSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Decoded"));
    75     this._transferSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Transfered"));
    76 
    77     this._compressedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compressed"));
    78     this._compressionRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compression"));
    79 
    80     var requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._cachedRow]);
    81     var statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
    82     var sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
    83     var compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
    84 
    85     this._requestAndResponseSection = new WebInspector.DetailsSection("resource-request-response", WebInspector.UIString("Request & Response"), [requestGroup, statusGroup, sizeGroup, compressionGroup]);
    86 
    87     this._requestHeadersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Request Headers"));
    88     this._requestHeadersSection = new WebInspector.DetailsSection("resource-request-headers", WebInspector.UIString("Request Headers"));
    89     this._requestHeadersSection.groups = [new WebInspector.DetailsSectionGroup([this._requestHeadersRow])];
    90 
    91     this._responseHeadersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Response Headers"));
    92     this._responseHeadersSection = new WebInspector.DetailsSection("resource-response-headers", WebInspector.UIString("Response Headers"));
    93     this._responseHeadersSection.groups = [new WebInspector.DetailsSectionGroup([this._responseHeadersRow])];
    94 
    95     // Rows for the "Image Size" section.
    96     this._imageWidthRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Width"));
    97     this._imageHeightRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Height"));
    98 
    99     // "Image Size" section where we display intrinsic metrics for image resources.
    100     this._imageSizeSection = new WebInspector.DetailsSection("resource-type", WebInspector.UIString("Image Size"));
    101     this._imageSizeSection.groups = [new WebInspector.DetailsSectionGroup([this._imageWidthRow, this._imageHeightRow])];
    102 
    103     this.contentElement.appendChild(this._typeSection.element);
    104     this.contentElement.appendChild(this._locationSection.element);
    105     this.contentElement.appendChild(this._requestAndResponseSection.element);
    106     this.contentElement.appendChild(this._requestHeadersSection.element);
    107     this.contentElement.appendChild(this._responseHeadersSection.element);
    108 };
    109 
    110 WebInspector.ResourceDetailsSidebarPanel.StyleClassName = "resource";
    111 
    112 WebInspector.ResourceDetailsSidebarPanel.prototype = {
    113     constructor: WebInspector.ResourceDetailsSidebarPanel,
    114     __proto__: WebInspector.DetailsSidebarPanel.prototype,
     28    constructor()
     29    {
     30        super("resource-details", WebInspector.UIString("Resource"), WebInspector.UIString("Resource"), "Images/NavigationItemFile.svg", "1");
     31
     32        this.element.classList.add("resource");
     33
     34        this._resource = null;
     35
     36        this._typeMIMETypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("MIME Type"));
     37        this._typeResourceTypeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Resource Type"));
     38
     39        this._typeSection = new WebInspector.DetailsSection("resource-type", WebInspector.UIString("Type"));
     40        this._typeSection.groups = [new WebInspector.DetailsSectionGroup([this._typeMIMETypeRow, this._typeResourceTypeRow])];
     41
     42        this._locationFullURLRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Full URL"));
     43        this._locationSchemeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Scheme"));
     44        this._locationHostRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Host"));
     45        this._locationPortRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Port"));
     46        this._locationPathRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Path"));
     47        this._locationQueryStringRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Query String"));
     48        this._locationFragmentRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Fragment"));
     49        this._locationFilenameRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Filename"));
     50        this._initiatorRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Initiator"));
     51
     52        var firstGroup = [this._locationFullURLRow];
     53        var secondGroup = [this._locationSchemeRow, this._locationHostRow, this._locationPortRow, this._locationPathRow,
     54            this._locationQueryStringRow, this._locationFragmentRow, this._locationFilenameRow];
     55        var thirdGroup = [this._initiatorRow];
     56
     57        this._fullURLGroup = new WebInspector.DetailsSectionGroup(firstGroup);
     58        this._locationURLComponentsGroup = new WebInspector.DetailsSectionGroup(secondGroup);
     59        this._initiatorGroup = new WebInspector.DetailsSectionGroup(thirdGroup);
     60
     61        this._locationSection = new WebInspector.DetailsSection("resource-location", WebInspector.UIString("Location"), [this._fullURLGroup, this._locationURLComponentsGroup, this._initiatorGroup]);
     62
     63        this._queryParametersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Query Parameters"));
     64        this._queryParametersSection = new WebInspector.DetailsSection("resource-query-parameters", WebInspector.UIString("Query Parameters"));
     65        this._queryParametersSection.groups = [new WebInspector.DetailsSectionGroup([this._queryParametersRow])];
     66
     67        this._requestDataSection = new WebInspector.DetailsSection("resource-request-data", WebInspector.UIString("Request Data"));
     68
     69        this._requestMethodRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Method"));
     70        this._cachedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Cached"));
     71
     72        this._statusTextRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Status"));
     73        this._statusCodeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Code"));
     74
     75        this._encodedSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Encoded"));
     76        this._decodedSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Decoded"));
     77        this._transferSizeRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Transfered"));
     78
     79        this._compressedRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compressed"));
     80        this._compressionRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Compression"));
     81
     82        var requestGroup = new WebInspector.DetailsSectionGroup([this._requestMethodRow, this._cachedRow]);
     83        var statusGroup = new WebInspector.DetailsSectionGroup([this._statusTextRow, this._statusCodeRow]);
     84        var sizeGroup = new WebInspector.DetailsSectionGroup([this._encodedSizeRow, this._decodedSizeRow, this._transferSizeRow]);
     85        var compressionGroup = new WebInspector.DetailsSectionGroup([this._compressedRow, this._compressionRow]);
     86
     87        this._requestAndResponseSection = new WebInspector.DetailsSection("resource-request-response", WebInspector.UIString("Request & Response"), [requestGroup, statusGroup, sizeGroup, compressionGroup]);
     88
     89        this._requestHeadersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Request Headers"));
     90        this._requestHeadersSection = new WebInspector.DetailsSection("resource-request-headers", WebInspector.UIString("Request Headers"));
     91        this._requestHeadersSection.groups = [new WebInspector.DetailsSectionGroup([this._requestHeadersRow])];
     92
     93        this._responseHeadersRow = new WebInspector.DetailsSectionDataGridRow(null, WebInspector.UIString("No Response Headers"));
     94        this._responseHeadersSection = new WebInspector.DetailsSection("resource-response-headers", WebInspector.UIString("Response Headers"));
     95        this._responseHeadersSection.groups = [new WebInspector.DetailsSectionGroup([this._responseHeadersRow])];
     96
     97        // Rows for the "Image Size" section.
     98        this._imageWidthRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Width"));
     99        this._imageHeightRow = new WebInspector.DetailsSectionSimpleRow(WebInspector.UIString("Height"));
     100
     101        // "Image Size" section where we display intrinsic metrics for image resources.
     102        this._imageSizeSection = new WebInspector.DetailsSection("resource-type", WebInspector.UIString("Image Size"));
     103        this._imageSizeSection.groups = [new WebInspector.DetailsSectionGroup([this._imageWidthRow, this._imageHeightRow])];
     104
     105        this.contentElement.appendChild(this._typeSection.element);
     106        this.contentElement.appendChild(this._locationSection.element);
     107        this.contentElement.appendChild(this._requestAndResponseSection.element);
     108        this.contentElement.appendChild(this._requestHeadersSection.element);
     109        this.contentElement.appendChild(this._responseHeadersSection.element);
     110    }
    115111
    116112    // Public
    117113
    118     inspect: function(objects)
     114    inspect(objects)
    119115    {
    120116        // Convert to a single item array if needed.
     
    140136
    141137        return !!this._resource;
    142     },
     138    }
    143139
    144140    get resource()
    145141    {
    146142        return this._resource;
    147     },
     143    }
    148144
    149145    set resource(resource)
     
    177173
    178174        this.needsRefresh();
    179     },
    180 
    181     refresh: function()
     175    }
     176
     177    refresh()
    182178    {
    183179        if (!this._resource)
     
    193189        this._refreshImageSizeSection();
    194190        this._refreshRequestDataSection();
    195     },
     191    }
    196192
    197193    // Private
    198194
    199     _refreshURL: function()
     195    _refreshURL()
    200196    {
    201197        if (!this._resource)
     
    239235                queryParametersSectionElement.parentNode.removeChild(queryParametersSectionElement);
    240236        }
    241     },
    242 
    243     _refreshResourceType: function()
     237    }
     238
     239    _refreshResourceType()
    244240    {
    245241        if (!this._resource)
     
    247243
    248244        this._typeResourceTypeRow.value = WebInspector.Resource.displayNameForType(this._resource.type);
    249     },
    250 
    251     _refreshMIMEType: function()
     245    }
     246
     247    _refreshMIMEType()
    252248    {
    253249        if (!this._resource)
     
    255251
    256252        this._typeMIMETypeRow.value = this._resource.mimeType;
    257     },
    258 
    259     _refreshRequestAndResponse: function()
     253    }
     254
     255    _refreshRequestAndResponse()
    260256    {
    261257        var resource = this._resource;
     
    265261        // If we don't have a value, we set an em-dash to keep the row from hiding.
    266262        // This keeps the UI from shifting around as data comes in.
    267         const emDash = "\u2014";
     263        var emDash = "\u2014";
    268264
    269265        this._requestMethodRow.value = resource.requestMethod || emDash;
     
    276272        this._refreshResponseHeaders();
    277273        this._refreshCompressed();
    278     },
    279 
    280     _valueForSize: function(size)
     274    }
     275
     276    _valueForSize(size)
    281277    {
    282278        // If we don't have a value, we set an em-dash to keep the row from hiding.
    283279        // This keeps the UI from shifting around as data comes in.
    284         const emDash = "\u2014";
     280        var emDash = "\u2014";
    285281        return size > 0 ? Number.bytesToString(size) : emDash;
    286     },
    287 
    288     _refreshCompressed: function()
     282    }
     283
     284    _refreshCompressed()
    289285    {
    290286        this._compressedRow.value = this._resource.compressed ? WebInspector.UIString("Yes") : WebInspector.UIString("No");
    291287        this._compressionRow.value = this._resource.compressed ? WebInspector.UIString("%.2f\u00d7").format(this._resource.size / this._resource.encodedSize) : null;
    292     },
    293 
    294     _refreshDecodedSize: function()
     288    }
     289
     290    _refreshDecodedSize()
    295291    {
    296292        if (!this._resource)
     
    301297
    302298        this._refreshCompressed();
    303     },
    304 
    305     _refreshTransferSize: function()
     299    }
     300
     301    _refreshTransferSize()
    306302    {
    307303        if (!this._resource)
     
    312308
    313309        this._refreshCompressed();
    314     },
    315 
    316     _refreshRequestHeaders: function()
     310    }
     311
     312    _refreshRequestHeaders()
    317313    {
    318314        if (!this._resource)
     
    320316
    321317        this._requestHeadersRow.dataGrid = this._createNameValueDataGrid(this._resource.requestHeaders);
    322     },
    323 
    324     _refreshResponseHeaders: function()
     318    }
     319
     320    _refreshResponseHeaders()
    325321    {
    326322        if (!this._resource)
     
    328324
    329325        this._responseHeadersRow.dataGrid = this._createNameValueDataGrid(this._resource.responseHeaders);
    330     },
    331 
    332     _createNameValueDataGrid: function(data)
     326    }
     327
     328    _createNameValueDataGrid(data)
    333329    {
    334330        if (!data || data instanceof Array ? !data.length : isEmptyObject(data))
     
    346342
    347343            var node = new WebInspector.DataGridNode({name: nodeValue.name, value: nodeValue.value || ""}, false);
    348             node.selectable = true;
    349344            dataGrid.appendChild(node);
    350345        }
     
    375370
    376371        return dataGrid;
    377     },
    378 
    379     _refreshImageSizeSection: function()
     372    }
     373
     374    _refreshImageSizeSection()
    380375    {
    381376        var resource = this._resource;
     
    400395            this._imageHeightRow.value = WebInspector.UIString("%fpx").format(size.height);
    401396        }.bind(this));
    402     },
    403 
    404     _goToRequestDataClicked: function()
     397    }
     398
     399    _goToRequestDataClicked()
    405400    {
    406401        WebInspector.resourceSidebarPanel.showResourceRequest(this._resource);
    407     },
    408 
    409     _refreshRequestDataSection: function()
     402    }
     403
     404    _refreshRequestDataSection()
    410405    {
    411406        var resource = this._resource;
  • trunk/Source/WebInspectorUI/UserInterface/Views/ResourceSidebarPanel.js

    r181452 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.ResourceSidebarPanel = function() {
    27     WebInspector.NavigationSidebarPanel.call(this, "resource", WebInspector.UIString("Resources"), "Images/NavigationItemStorage.svg", "1", true, false, true);
    28 
    29     var searchElement = document.createElement("div");
    30     searchElement.classList.add("search-bar");
    31     this.element.appendChild(searchElement);
    32 
    33     this._inputElement = document.createElement("input");
    34     this._inputElement.type = "search";
    35     this._inputElement.spellcheck = false;
    36     this._inputElement.addEventListener("search", this._searchFieldChanged.bind(this));
    37     this._inputElement.addEventListener("input", this._searchFieldInput.bind(this));
    38     this._inputElement.setAttribute("results", 5);
    39     this._inputElement.setAttribute("autosave", "inspector-search");
    40     this._inputElement.setAttribute("placeholder", WebInspector.UIString("Search Resource Content"));
    41     searchElement.appendChild(this._inputElement);
    42 
    43     this.filterBar.placeholder = WebInspector.UIString("Filter Resource List");
    44 
    45     this._waitingForInitialMainFrame = true;
    46     this._lastSearchedPageSetting = new WebInspector.Setting("last-searched-page", null);
    47 
    48     this._searchQuerySetting = new WebInspector.Setting("search-sidebar-query", "");
    49     this._inputElement.value = this._searchQuerySetting.value;
    50 
    51     this._searchKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl | WebInspector.KeyboardShortcut.Modifier.Shift, "F", this._focusSearchField.bind(this));
    52 
    53     this._localStorageRootTreeElement = null;
    54     this._sessionStorageRootTreeElement = null;
    55 
    56     this._databaseRootTreeElement = null;
    57     this._databaseHostTreeElementMap = {};
    58 
    59     this._indexedDatabaseRootTreeElement = null;
    60     this._indexedDatabaseHostTreeElementMap = {};
    61 
    62     this._cookieStorageRootTreeElement = null;
    63 
    64     this._applicationCacheRootTreeElement = null;
    65     this._applicationCacheURLTreeElementMap = {};
    66 
    67     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.CookieStorageObjectWasAdded, this._cookieStorageObjectWasAdded, this);
    68     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasAdded, this._domStorageObjectWasAdded, this);
    69     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasInspected, this._domStorageObjectWasInspected, this);
    70     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasAdded, this._databaseWasAdded, this);
    71     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasInspected, this._databaseWasInspected, this);
    72     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.IndexedDatabaseWasAdded, this._indexedDatabaseWasAdded, this);
    73     WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.Cleared, this._storageCleared, this);
    74 
    75     WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, this._frameManifestAdded, this);
    76     WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestRemoved, this._frameManifestRemoved, this);
    77 
    78     WebInspector.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);
    79     WebInspector.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.FrameWasAdded, this._frameWasAdded, this);
    80 
    81     WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.DOMNodeWasInspected, this._domNodeWasInspected, this);
    82 
    83     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, this._scriptWasAdded, this);
    84     WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
    85 
    86     WebInspector.notifications.addEventListener(WebInspector.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
    87 
    88     this._resourcesContentTreeOutline = this.contentTreeOutline;
    89     this._searchContentTreeOutline = this.createContentTreeOutline();
    90 
    91     this._resourcesContentTreeOutline.onselect = this._treeElementSelected.bind(this);
    92     this._searchContentTreeOutline.onselect = this._treeElementSelected.bind(this);
    93 
    94     this._resourcesContentTreeOutline.includeSourceMapResourceChildren = true;
    95 
    96     if (WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript)
    97         this._resourcesContentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
    98 };
    99 
    100 WebInspector.ResourceSidebarPanel.prototype = {
    101     constructor: WebInspector.ResourceSidebarPanel,
     26WebInspector.ResourceSidebarPanel = class ResourceSidebarPanel extends WebInspector.NavigationSidebarPanel
     27{
     28    constructor()
     29    {
     30        super("resource", WebInspector.UIString("Resources"), "Images/NavigationItemStorage.svg", "1", true, false, true);
     31
     32        var searchElement = document.createElement("div");
     33        searchElement.classList.add("search-bar");
     34        this.element.appendChild(searchElement);
     35
     36        this._inputElement = document.createElement("input");
     37        this._inputElement.type = "search";
     38        this._inputElement.spellcheck = false;
     39        this._inputElement.addEventListener("search", this._searchFieldChanged.bind(this));
     40        this._inputElement.addEventListener("input", this._searchFieldInput.bind(this));
     41        this._inputElement.setAttribute("results", 5);
     42        this._inputElement.setAttribute("autosave", "inspector-search");
     43        this._inputElement.setAttribute("placeholder", WebInspector.UIString("Search Resource Content"));
     44        searchElement.appendChild(this._inputElement);
     45
     46        this.filterBar.placeholder = WebInspector.UIString("Filter Resource List");
     47
     48        this._waitingForInitialMainFrame = true;
     49        this._lastSearchedPageSetting = new WebInspector.Setting("last-searched-page", null);
     50
     51        this._searchQuerySetting = new WebInspector.Setting("search-sidebar-query", "");
     52        this._inputElement.value = this._searchQuerySetting.value;
     53
     54        this._searchKeyboardShortcut = new WebInspector.KeyboardShortcut(WebInspector.KeyboardShortcut.Modifier.CommandOrControl | WebInspector.KeyboardShortcut.Modifier.Shift, "F", this._focusSearchField.bind(this));
     55
     56        this._localStorageRootTreeElement = null;
     57        this._sessionStorageRootTreeElement = null;
     58
     59        this._databaseRootTreeElement = null;
     60        this._databaseHostTreeElementMap = {};
     61
     62        this._indexedDatabaseRootTreeElement = null;
     63        this._indexedDatabaseHostTreeElementMap = {};
     64
     65        this._cookieStorageRootTreeElement = null;
     66
     67        this._applicationCacheRootTreeElement = null;
     68        this._applicationCacheURLTreeElementMap = {};
     69
     70        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.CookieStorageObjectWasAdded, this._cookieStorageObjectWasAdded, this);
     71        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasAdded, this._domStorageObjectWasAdded, this);
     72        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DOMStorageObjectWasInspected, this._domStorageObjectWasInspected, this);
     73        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasAdded, this._databaseWasAdded, this);
     74        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.DatabaseWasInspected, this._databaseWasInspected, this);
     75        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.IndexedDatabaseWasAdded, this._indexedDatabaseWasAdded, this);
     76        WebInspector.storageManager.addEventListener(WebInspector.StorageManager.Event.Cleared, this._storageCleared, this);
     77
     78        WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestAdded, this._frameManifestAdded, this);
     79        WebInspector.applicationCacheManager.addEventListener(WebInspector.ApplicationCacheManager.Event.FrameManifestRemoved, this._frameManifestRemoved, this);
     80
     81        WebInspector.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);
     82        WebInspector.frameResourceManager.addEventListener(WebInspector.FrameResourceManager.Event.FrameWasAdded, this._frameWasAdded, this);
     83
     84        WebInspector.domTreeManager.addEventListener(WebInspector.DOMTreeManager.Event.DOMNodeWasInspected, this._domNodeWasInspected, this);
     85
     86        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptAdded, this._scriptWasAdded, this);
     87        WebInspector.debuggerManager.addEventListener(WebInspector.DebuggerManager.Event.ScriptsCleared, this._scriptsCleared, this);
     88
     89        WebInspector.notifications.addEventListener(WebInspector.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
     90
     91        this._resourcesContentTreeOutline = this.contentTreeOutline;
     92        this._searchContentTreeOutline = this.createContentTreeOutline();
     93
     94        this._resourcesContentTreeOutline.onselect = this._treeElementSelected.bind(this);
     95        this._searchContentTreeOutline.onselect = this._treeElementSelected.bind(this);
     96
     97        this._resourcesContentTreeOutline.includeSourceMapResourceChildren = true;
     98
     99        if (WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript)
     100            this._resourcesContentTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
     101    }
    102102
    103103    // Public
    104104
    105     showDefaultContentView: function()
     105    showDefaultContentView()
    106106    {
    107107        if (WebInspector.frameResourceManager.mainFrame) {
     
    113113        if (firstTreeElement)
    114114            firstTreeElement.revealAndSelect();
    115     },
     115    }
    116116
    117117    get contentTreeOutlineToAutoPrune()
    118118    {
    119119        return this._searchContentTreeOutline;
    120     },
    121 
    122     showMainFrame: function(nodeToSelect, preventFocusChange)
     120    }
     121
     122    showMainFrame(nodeToSelect, preventFocusChange)
    123123    {
    124124        WebInspector.contentBrowser.showContentViewForRepresentedObject(WebInspector.frameResourceManager.mainFrame);
    125     },
    126 
    127     showMainFrameDOMTree: function(nodeToSelect, preventFocusChange)
     125    }
     126
     127    showMainFrameDOMTree(nodeToSelect, preventFocusChange)
    128128    {
    129129        var contentView = WebInspector.contentBrowser.contentViewForRepresentedObject(WebInspector.frameResourceManager.mainFrame);
    130130        contentView.showDOMTree(nodeToSelect, preventFocusChange);
    131131        WebInspector.contentBrowser.showContentView(contentView);
    132     },
    133 
    134     showMainFrameSourceCode: function()
     132    }
     133
     134    showMainFrameSourceCode()
    135135    {
    136136        var contentView = WebInspector.contentBrowser.contentViewForRepresentedObject(WebInspector.frameResourceManager.mainFrame);
    137137        contentView.showSourceCode();
    138138        WebInspector.contentBrowser.showContentView(contentView);
    139     },
    140 
    141     showContentFlowDOMTree: function(contentFlow, nodeToSelect, preventFocusChange)
     139    }
     140
     141    showContentFlowDOMTree(contentFlow, nodeToSelect, preventFocusChange)
    142142    {
    143143        var contentView = WebInspector.contentBrowser.contentViewForRepresentedObject(contentFlow);
     
    145145            contentView.selectAndRevealDOMNode(nodeToSelect, preventFocusChange);
    146146        WebInspector.contentBrowser.showContentView(contentView);
    147     },
    148 
    149     showSourceCodeForFrame: function(frameIdentifier, revealAndSelectTreeElement)
     147    }
     148
     149    showSourceCodeForFrame(frameIdentifier, revealAndSelectTreeElement)
    150150    {
    151151        delete this._frameIdentifierToShowSourceCodeWhenAvailable;
     
    169169        if (revealAndSelectTreeElement)
    170170            this.treeElementForRepresentedObject(frame).revealAndSelect(true, true, true, true);
    171     },
    172 
    173     showSourceCode: function(sourceCode, positionToReveal, textRangeToSelect, forceUnformatted)
     171    }
     172
     173    showSourceCode(sourceCode, positionToReveal, textRangeToSelect, forceUnformatted)
    174174    {
    175175        console.assert(!positionToReveal || positionToReveal instanceof WebInspector.SourceCodePosition, positionToReveal);
     
    187187        var cookie = positionToReveal ? {lineNumber: positionToReveal.lineNumber, columnNumber: positionToReveal.columnNumber} : {};
    188188        WebInspector.contentBrowser.showContentViewForRepresentedObject(representedObject, cookie);
    189     },
    190 
    191     showSourceCodeLocation: function(sourceCodeLocation)
     189    }
     190
     191    showSourceCodeLocation(sourceCodeLocation)
    192192    {
    193193        this.showSourceCode(sourceCodeLocation.displaySourceCode, sourceCodeLocation.displayPosition());
    194     },
    195 
    196     showOriginalUnformattedSourceCodeLocation: function(sourceCodeLocation)
     194    }
     195
     196    showOriginalUnformattedSourceCodeLocation(sourceCodeLocation)
    197197    {
    198198        this.showSourceCode(sourceCodeLocation.sourceCode, sourceCodeLocation.position(), undefined, true);
    199     },
    200 
    201     showOriginalOrFormattedSourceCodeLocation: function(sourceCodeLocation)
     199    }
     200
     201    showOriginalOrFormattedSourceCodeLocation(sourceCodeLocation)
    202202    {
    203203        this.showSourceCode(sourceCodeLocation.sourceCode, sourceCodeLocation.formattedPosition());
    204     },
    205 
    206     showSourceCodeTextRange: function(sourceCodeTextRange)
     204    }
     205
     206    showSourceCodeTextRange(sourceCodeTextRange)
    207207    {
    208208        var textRangeToSelect = sourceCodeTextRange.displayTextRange;
    209209        this.showSourceCode(sourceCodeTextRange.displaySourceCode, textRangeToSelect.startPosition(), textRangeToSelect);
    210     },
    211 
    212     showOriginalOrFormattedSourceCodeTextRange: function(sourceCodeTextRange)
     210    }
     211
     212    showOriginalOrFormattedSourceCodeTextRange(sourceCodeTextRange)
    213213    {
    214214        var textRangeToSelect = sourceCodeTextRange.formattedTextRange;
    215215        this.showSourceCode(sourceCodeTextRange.sourceCode, textRangeToSelect.startPosition(), textRangeToSelect);
    216     },
    217 
    218     showResource: function(resource)
     216    }
     217
     218    showResource(resource)
    219219    {
    220220        WebInspector.contentBrowser.showContentViewForRepresentedObject(resource.isMainResource() ? resource.parentFrame : resource);
    221     },
    222 
    223     showResourceRequest: function(resource)
     221    }
     222
     223    showResourceRequest(resource)
    224224    {
    225225        var contentView = WebInspector.contentBrowser.contentViewForRepresentedObject(resource.isMainResource() ? resource.parentFrame : resource);
     
    237237
    238238        WebInspector.contentBrowser.showContentView(contentView);
    239     },
    240 
    241     treeElementForRepresentedObject: function(representedObject)
     239    }
     240
     241    treeElementForRepresentedObject(representedObject)
    242242    {
    243243        // A custom implementation is needed for this since the frames are populated lazily.
     
    306306
    307307        return scriptTreeElement;
    308     },
    309 
    310     performSearch: function(searchTerm)
     308    }
     309
     310    performSearch(searchTerm)
    311311    {
    312312        // Before performing a new search, clear the old search.
     
    516516        if (!window.DOMAgent && !window.PageAgent)
    517517            updateEmptyContentPlaceholderSoon.call(this);
    518     },
     518    }
    519519
    520520    // Private
    521521
    522     _showResourcesContentTreeOutline: function()
     522    _showResourcesContentTreeOutline()
    523523    {
    524524        this.filterBar.placeholder = WebInspector.UIString("Filter Resource List");
    525525        this.contentTreeOutline = this._resourcesContentTreeOutline;
    526     },
    527 
    528     _showSearchContentTreeOutline: function()
     526    }
     527
     528    _showSearchContentTreeOutline()
    529529    {
    530530        this.filterBar.placeholder = WebInspector.UIString("Filter Search Results");
    531531        this.contentTreeOutline = this._searchContentTreeOutline;
    532     },
    533 
    534     _searchFieldChanged: function(event)
     532    }
     533
     534    _searchFieldChanged(event)
    535535    {
    536536        this.performSearch(event.target.value);
    537     },
    538 
    539     _searchFieldInput: function(event)
     537    }
     538
     539    _searchFieldInput(event)
    540540    {
    541541        // If the search field is cleared, immediately clear the search results tree outline.
    542542        if (!event.target.value.length && this.contentTreeOutline === this._searchContentTreeOutline)
    543543            this.performSearch("");
    544     },
    545 
    546     _searchTreeElementForResource: function(resource)
     544    }
     545
     546    _searchTreeElementForResource(resource)
    547547    {
    548548        var resourceTreeElement = this._searchContentTreeOutline.getCachedTreeElement(resource);
     
    556556
    557557        return resourceTreeElement;
    558     },
    559 
    560     _searchTreeElementForScript: function(script)
     558    }
     559
     560    _searchTreeElementForScript(script)
    561561    {
    562562        var scriptTreeElement = this._searchContentTreeOutline.getCachedTreeElement(script);
     
    570570
    571571        return scriptTreeElement;
    572     },
    573 
    574     _focusSearchField: function(keyboardShortcut, event)
     572    }
     573
     574    _focusSearchField(keyboardShortcut, event)
    575575    {
    576576        this.show();
    577577
    578578        this._inputElement.select();
    579     },
    580 
    581     _mainFrameDidChange: function(event)
     579    }
     580
     581    _mainFrameDidChange(event)
    582582    {
    583583        if (this._mainFrameTreeElement) {
     
    617617        // Search for whatever is in the input field. This was populated with the last used search term.
    618618        this.performSearch(this._inputElement.value);
    619     },
    620 
    621     _mainFrameMainResourceDidChange: function(event)
     619    }
     620
     621    _mainFrameMainResourceDidChange(event)
    622622    {
    623623        var wasShowingResourceSidebar = this.selected;
     
    656656        // before those listeners do their work might cause the content of the old page to show instead of the new page.
    657657        setTimeout(delayedWork.bind(this), 0);
    658     },
    659 
    660     _frameWasAdded: function(event)
     658    }
     659
     660    _frameWasAdded(event)
    661661    {
    662662        if (!this._frameIdentifierToShowSourceCodeWhenAvailable)
     
    668668
    669669        this.showSourceCodeForFrame(frame.id, true);
    670     },
    671 
    672     _scriptWasAdded: function(event)
     670    }
     671
     672    _scriptWasAdded(event)
    673673    {
    674674        var script = event.data.script;
     
    716716            parentFolderTreeElement.appendChild(scriptTreeElement);
    717717        }
    718     },
    719 
    720     _scriptsCleared: function(event)
     718    }
     719
     720    _scriptsCleared(event)
    721721    {
    722722        if (this._extensionScriptsFolderTreeElement) {
     
    737737            this._anonymousScriptsFolderTreeElement = null;
    738738        }
    739     },
    740 
    741     _scriptsToSearch: function(event)
     739    }
     740
     741    _scriptsToSearch(event)
    742742    {
    743743        var nonResourceScripts = [];
     
    764764
    765765        return nonResourceScripts;
    766     },
    767 
    768     _treeElementSelected: function(treeElement, selectedByUser)
     766    }
     767
     768    _treeElementSelected(treeElement, selectedByUser)
    769769    {
    770770        if (treeElement instanceof WebInspector.FolderTreeElement || treeElement instanceof WebInspector.DatabaseHostTreeElement ||
     
    789789        else if (treeElement.representedObject instanceof WebInspector.SourceCodeSearchMatchObject)
    790790            this.showOriginalOrFormattedSourceCodeTextRange(treeElement.representedObject.sourceCodeTextRange);
    791     },
    792 
    793     _domNodeWasInspected: function(event)
     791    }
     792
     793    _domNodeWasInspected(event)
    794794    {
    795795        this.showMainFrameDOMTree(event.data.node);
    796     },
    797 
    798     _domStorageObjectWasAdded: function(event)
     796    }
     797
     798    _domStorageObjectWasAdded(event)
    799799    {
    800800        var domStorage = event.data.domStorage;
     
    805805        else
    806806            this._sessionStorageRootTreeElement = this._addStorageChild(storageElement, this._sessionStorageRootTreeElement, WebInspector.UIString("Session Storage"));
    807     },
    808 
    809     _domStorageObjectWasInspected: function(event)
     807    }
     808
     809    _domStorageObjectWasInspected(event)
    810810    {
    811811        var domStorage = event.data.domStorage;
    812812        var treeElement = this.treeElementForRepresentedObject(domStorage);
    813813        treeElement.revealAndSelect(true);
    814     },
    815 
    816     _databaseWasAdded: function(event)
     814    }
     815
     816    _databaseWasAdded(event)
    817817    {
    818818        var database = event.data.database;
     
    827827        var databaseElement = new WebInspector.DatabaseTreeElement(database);
    828828        this._databaseHostTreeElementMap[database.host].appendChild(databaseElement);
    829     },
    830 
    831     _databaseWasInspected: function(event)
     829    }
     830
     831    _databaseWasInspected(event)
    832832    {
    833833        var database = event.data.database;
    834834        var treeElement = this.treeElementForRepresentedObject(database);
    835835        treeElement.revealAndSelect(true);
    836     },
    837 
    838     _indexedDatabaseWasAdded: function(event)
     836    }
     837
     838    _indexedDatabaseWasAdded(event)
    839839    {
    840840        var indexedDatabase = event.data.indexedDatabase;
     
    849849        var indexedDatabaseElement = new WebInspector.IndexedDatabaseTreeElement(indexedDatabase);
    850850        this._indexedDatabaseHostTreeElementMap[indexedDatabase.host].appendChild(indexedDatabaseElement);
    851     },
    852 
    853     _cookieStorageObjectWasAdded: function(event)
     851    }
     852
     853    _cookieStorageObjectWasAdded(event)
    854854    {
    855855        console.assert(event.data.cookieStorage instanceof WebInspector.CookieStorageObject);
     
    857857        var cookieElement = new WebInspector.CookieStorageTreeElement(event.data.cookieStorage);
    858858        this._cookieStorageRootTreeElement = this._addStorageChild(cookieElement, this._cookieStorageRootTreeElement, WebInspector.UIString("Cookies"));
    859     },
    860 
    861     _frameManifestAdded: function(event)
     859    }
     860
     861    _frameManifestAdded(event)
    862862    {
    863863        var frameManifest = event.data.frameManifest;
     
    873873        var frameCacheElement = new WebInspector.ApplicationCacheFrameTreeElement(frameManifest);
    874874        this._applicationCacheURLTreeElementMap[manifestURL].appendChild(frameCacheElement);
    875     },
    876 
    877     _frameManifestRemoved: function(event)
     875    }
     876
     877    _frameManifestRemoved(event)
    878878    {
    879879         // FIXME: Implement this.
    880     },
    881 
    882     _compareTreeElements: function(a, b)
     880    }
     881
     882    _compareTreeElements(a, b)
    883883    {
    884884        // Always sort the main frame element first.
     
    892892
    893893        return (a.mainTitle || "").localeCompare(b.mainTitle || "");
    894     },
    895 
    896     _addStorageChild: function(childElement, parentElement, folderName)
     894    }
     895
     896    _addStorageChild(childElement, parentElement, folderName)
    897897    {
    898898        if (!parentElement) {
     
    924924
    925925        return parentElement;
    926     },
    927 
    928     _storageCleared: function(event)
     926    }
     927
     928    _storageCleared(event)
    929929    {
    930930        // Close all DOM and cookie storage content views since the main frame has navigated and all storages are cleared.
     
    962962        this._applicationCacheRootTreeElement = null;
    963963        this._applicationCacheURLTreeElementMap = {};
    964     },
    965 
    966     _extraDomainsActivated: function()
     964    }
     965
     966    _extraDomainsActivated()
    967967    {
    968968        if (WebInspector.debuggableType === WebInspector.DebuggableType.JavaScript)
     
    970970    }
    971971};
    972 
    973 WebInspector.ResourceSidebarPanel.prototype.__proto__ = WebInspector.NavigationSidebarPanel.prototype;
  • trunk/Source/WebInspectorUI/UserInterface/Views/ScopeChainDetailsSidebarPanel.js

    r181704 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.ScopeChainDetailsSidebarPanel = function()
     26WebInspector.ScopeChainDetailsSidebarPanel = class ScopeChainDetailsSidebarPanel extends WebInspector.DetailsSidebarPanel
    2727{
    28     WebInspector.DetailsSidebarPanel.call(this, "scope-chain", WebInspector.UIString("Scope Chain"), WebInspector.UIString("Scope Chain"), "Images/NavigationItemVariable.svg", "5");
    29 
    30     this._callFrame = null;
    31 
    32     // Update on console prompt eval as objects in the scope chain may have changed.
    33     WebInspector.runtimeManager.addEventListener(WebInspector.RuntimeManager.Event.DidEvaluate, this.needsRefresh, this);
    34 };
    35 
    36 WebInspector.ScopeChainDetailsSidebarPanel.autoExpandProperties = new Set;
    37 
    38 WebInspector.ScopeChainDetailsSidebarPanel.prototype = {
    39     constructor: WebInspector.ScopeChainDetailsSidebarPanel,
    40     __proto__: WebInspector.DetailsSidebarPanel.prototype,
     28    constructor()
     29    {
     30        super("scope-chain", WebInspector.UIString("Scope Chain"), WebInspector.UIString("Scope Chain"), "Images/NavigationItemVariable.svg", "5");
     31
     32        this._callFrame = null;
     33
     34        // Update on console prompt eval as objects in the scope chain may have changed.
     35        WebInspector.runtimeManager.addEventListener(WebInspector.RuntimeManager.Event.DidEvaluate, this.needsRefresh, this);
     36    }
    4137
    4238    // Public
     
    6157
    6258        return !!this.callFrame;
    63     },
     59    }
    6460
    6561    get callFrame()
    6662    {
    6763        return this._callFrame;
    68     },
     64    }
    6965
    7066    set callFrame(callFrame)
     
    7672
    7773        this.needsRefresh();
    78     },
     74    }
    7975
    8076    refresh()
     
    182178        // if the debugger is paused in code that was executed from the console. The console will be waiting for
    183179        // the result of the execution and without a timeout we would never update the scope variables.
    184         var delay = WebInspector.ScopeChainDetailsSidebarPanel.autoExpandProperties.size === 0 ? 50 : 250;
     180        var delay = WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.size === 0 ? 50 : 250;
    185181        var timeout = setTimeout(delayedWork.bind(this), delay);
    186182
     
    188184        // until after all the pending asynchronous requests are completed. This prevents severe flashing while stepping.
    189185        InspectorBackend.runAfterPendingDispatches(delayedWork.bind(this));
    190     },
     186    }
    191187
    192188    _propertyPathIdentifierForTreeElement(identifier, objectPropertyTreeElement)
     
    200196
    201197        return identifier + "-" + propertyPath.fullPath;
    202     },
     198    }
    203199
    204200    _objectTreeAddHandler(identifier, treeElement)
     
    208204            return;
    209205
    210         if (WebInspector.ScopeChainDetailsSidebarPanel.autoExpandProperties.has(propertyPathIdentifier))
     206        if (WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.has(propertyPathIdentifier))
    211207            treeElement.expand();
    212     },
     208    }
    213209
    214210    _objectTreeExpandHandler(identifier, treeElement)
     
    218214            return;
    219215
    220         WebInspector.ScopeChainDetailsSidebarPanel.autoExpandProperties.add(propertyPathIdentifier);
    221     },
     216        WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.add(propertyPathIdentifier);
     217    }
    222218
    223219    _objectTreeCollapseHandler(identifier, treeElement)
     
    227223            return;
    228224
    229         WebInspector.ScopeChainDetailsSidebarPanel.autoExpandProperties.delete(propertyPathIdentifier);
     225        WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties.delete(propertyPathIdentifier);
    230226    }
    231227};
     228
     229WebInspector.ScopeChainDetailsSidebarPanel._autoExpandProperties = new Set;
  • trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js

    r181903 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.Sidebar = function(element, side, sidebarPanels, role, label) {
    27     // FIXME: Convert this to a WebInspector.Object subclass, and call super().
    28     // WebInspector.Object.call(this);
    29 
    30     console.assert(!side || side === WebInspector.Sidebar.Sides.Left || side === WebInspector.Sidebar.Sides.Right);
    31     this._side = side || WebInspector.Sidebar.Sides.Left;
    32 
    33     this._element = element || document.createElement("div");
    34     this._element.classList.add(WebInspector.Sidebar.StyleClassName);
    35     this._element.classList.add(WebInspector.Sidebar.CollapsedStyleClassName);
    36     this._element.classList.add(this._side);
    37 
    38     this._element.setAttribute("role", role || "group");
    39     if (label)
    40         this._element.setAttribute("aria-label", label);
    41 
    42     this._resizer = new WebInspector.Resizer(WebInspector.Resizer.RuleOrientation.Vertical, this);
    43     this._element.insertBefore(this._resizer.element, this._element.firstChild);
    44 
    45     this._sidebarPanels = [];
    46 
    47     if (sidebarPanels) {
    48         for (var i = 0; i < sidebarPanels.length; ++i)
    49             this.addSidebarPanel(sidebarPanels[i]);
    50     }
    51 };
    52 
    53 // FIXME: Move to a WebInspector.Object subclass and we can remove this.
    54 WebInspector.Object.deprecatedAddConstructorFunctions(WebInspector.Sidebar);
    55 
    56 WebInspector.Sidebar.StyleClassName = "sidebar";
    57 WebInspector.Sidebar.CollapsedStyleClassName = "collapsed";
    58 WebInspector.Sidebar.AbsoluteMinimumWidth = 200;
    59 
    60 WebInspector.Sidebar.Sides = {};
    61 WebInspector.Sidebar.Sides.Right = "right";
    62 WebInspector.Sidebar.Sides.Left = "left";
    63 
    64 WebInspector.Sidebar.Event = {
    65     SidebarPanelSelected: "sidebar-sidebar-panel-selected",
    66     CollapsedStateDidChange: "sidebar-sidebar-collapsed-state-did-change",
    67     WidthDidChange: "sidebar-width-did-change",
    68 };
    69 
    70 WebInspector.Sidebar.prototype = {
    71     constructor: WebInspector.Sidebar,
     26WebInspector.Sidebar = class Sidebar extends WebInspector.Object
     27{
     28    constructor(element, side, sidebarPanels, role, label)
     29    {
     30        super();
     31
     32        console.assert(!side || side === WebInspector.Sidebar.Sides.Left || side === WebInspector.Sidebar.Sides.Right);
     33        this._side = side || WebInspector.Sidebar.Sides.Left;
     34
     35        this._element = element || document.createElement("div");
     36        this._element.classList.add("sidebar");
     37        this._element.classList.add(WebInspector.Sidebar.CollapsedStyleClassName);
     38        this._element.classList.add(this._side);
     39
     40        this._element.setAttribute("role", role || "group");
     41        if (label)
     42            this._element.setAttribute("aria-label", label);
     43
     44        this._resizer = new WebInspector.Resizer(WebInspector.Resizer.RuleOrientation.Vertical, this);
     45        this._element.insertBefore(this._resizer.element, this._element.firstChild);
     46
     47        this._sidebarPanels = [];
     48
     49        if (sidebarPanels) {
     50            for (var i = 0; i < sidebarPanels.length; ++i)
     51                this.addSidebarPanel(sidebarPanels[i]);
     52        }
     53    }
    7254
    7355    // Public
    7456
    75     addSidebarPanel: function(sidebarPanel)
     57    addSidebarPanel(sidebarPanel)
    7658    {
    7759        console.assert(sidebarPanel instanceof WebInspector.SidebarPanel);
     
    9173
    9274        return sidebarPanel;
    93     },
    94 
    95     removeSidebarPanel: function(sidebarPanelOrIdentifierOrIndex, index)
     75    }
     76
     77    removeSidebarPanel(sidebarPanelOrIdentifierOrIndex, index)
    9678    {
    9779        var sidebarPanel = this.findSidebarPanel(sidebarPanelOrIdentifierOrIndex);
     
    11496
    11597        return sidebarPanel;
    116     },
     98    }
    11799
    118100    get selectedSidebarPanel()
    119101    {
    120102        return this._selectedSidebarPanel || null;
    121     },
     103    }
    122104
    123105    set selectedSidebarPanel(sidebarPanelOrIdentifierOrIndex)
     
    150132
    151133        this.dispatchEventToListeners(WebInspector.Sidebar.Event.SidebarPanelSelected);
    152     },
     134    }
    153135
    154136    get minimumWidth()
    155137    {
    156138        return WebInspector.Sidebar.AbsoluteMinimumWidth;
    157     },
     139    }
    158140
    159141    get maximumWidth()
     
    162144        // available space for the sibling elements.
    163145        return Math.round(window.innerWidth / 3);
    164     },
     146    }
    165147
    166148    get width()
    167149    {
    168150        return this._element.offsetWidth;
    169     },
     151    }
    170152
    171153    set width(newWidth)
     
    182164
    183165        this.dispatchEventToListeners(WebInspector.Sidebar.Event.WidthDidChange);
    184     },
     166    }
    185167
    186168    get collapsed()
    187169    {
    188170        return this._element.classList.contains(WebInspector.Sidebar.CollapsedStyleClassName);
    189     },
     171    }
    190172
    191173    set collapsed(flag)
     
    212194        this.dispatchEventToListeners(WebInspector.Sidebar.Event.CollapsedStateDidChange);
    213195        this.dispatchEventToListeners(WebInspector.Sidebar.Event.WidthDidChange);
    214     },
     196    }
    215197
    216198    get sidebarPanels()
    217199    {
    218200        return this._sidebarPanels;
    219     },
     201    }
    220202
    221203    get element()
    222204    {
    223205        return this._element;
    224     },
     206    }
    225207
    226208    get side()
    227209    {
    228210        return this._side;
    229     },
    230 
    231     findSidebarPanel: function(sidebarPanelOrIdentifierOrIndex)
     211    }
     212
     213    findSidebarPanel(sidebarPanelOrIdentifierOrIndex)
    232214    {
    233215        var sidebarPanel = null;
     
    248230
    249231        return sidebarPanel;
    250     },
     232    }
    251233
    252234    // Protected
    253235
    254     resizerDragStarted: function(resizer)
     236    resizerDragStarted(resizer)
    255237    {
    256238        this._widthBeforeResize = this.width;
    257     },
    258 
    259     resizerDragging: function(resizer, positionDelta)
     239    }
     240
     241    resizerDragging(resizer, positionDelta)
    260242    {
    261243        if (this._side === WebInspector.Sidebar.Sides.Left)
     
    265247        this.width = newWidth;
    266248        this.collapsed = (newWidth < (this.minimumWidth / 2));
    267     },
    268 
    269     resizerDragEnded: function(resizer)
     249    }
     250
     251    resizerDragEnded(resizer)
    270252    {
    271253        delete this._widthBeforeResize;
    272     },
     254    }
    273255
    274256    // Private
    275257
    276     _navigationItemSelected: function(event)
     258    _navigationItemSelected(event)
    277259    {
    278260        this.selectedSidebarPanel = event.target.selectedNavigationItem ? event.target.selectedNavigationItem.identifier : null;
     
    280262};
    281263
    282 WebInspector.Sidebar.prototype.__proto__ = WebInspector.Object.prototype;
     264WebInspector.Sidebar.CollapsedStyleClassName = "collapsed";
     265WebInspector.Sidebar.AbsoluteMinimumWidth = 200;
     266
     267WebInspector.Sidebar.Sides = {
     268    Right: "right",
     269    Left: "left"
     270};
     271
     272WebInspector.Sidebar.Event = {
     273    SidebarPanelSelected: "sidebar-panel-selected",
     274    CollapsedStateDidChange: "sidebar-collapsed-state-did-change",
     275    WidthDidChange: "sidebar-width-did-change",
     276};
  • trunk/Source/WebInspectorUI/UserInterface/Views/SidebarPanel.js

    r181769 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.SidebarPanel = function(identifier, displayName, showToolTip, hideToolTip, image, element, role, label)
     26WebInspector.SidebarPanel = class SidebarPanel extends WebInspector.Object
    2727{
    28     // FIXME: Convert this to a WebInspector.Object subclass, and call super().
    29     // WebInspector.Object.call(this);
     28    constructor(identifier, displayName, showToolTip, hideToolTip, image, element, role, label)
     29    {
     30        super();
    3031
    31     this._identifier = identifier;
     32        this._identifier = identifier;
    3233
    33     this._toolbarItem = new WebInspector.ActivateButtonToolbarItem(identifier, showToolTip, hideToolTip, displayName, image, null, "tab");
    34     this._toolbarItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this.toggle, this);
    35     this._toolbarItem.enabled = false;
     34        this._toolbarItem = new WebInspector.ActivateButtonToolbarItem(identifier, showToolTip, hideToolTip, displayName, image, null, "tab");
     35        this._toolbarItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this.toggle, this);
     36        this._toolbarItem.enabled = false;
    3637
    37     this._element = element || document.createElement("div");
    38     this._element.classList.add(WebInspector.SidebarPanel.StyleClassName);
    39     this._element.classList.add(identifier);
     38        this._element = element || document.createElement("div");
     39        this._element.classList.add("panel");
     40        this._element.classList.add(identifier);
    4041
    41     this._element.setAttribute("role", role || "group");
    42     this._element.setAttribute("aria-label", label || displayName);
     42        this._element.setAttribute("role", role || "group");
     43        this._element.setAttribute("aria-label", label || displayName);
    4344
    44     this._contentElement = document.createElement("div");
    45     this._contentElement.className = WebInspector.SidebarPanel.ContentElementStyleClassName;
    46     this._element.appendChild(this._contentElement);
    47 };
    48 
    49 WebInspector.SidebarPanel.StyleClassName = "panel";
    50 WebInspector.SidebarPanel.SelectedStyleClassName = "selected";
    51 WebInspector.SidebarPanel.ContentElementStyleClassName = "content";
    52 
    53 WebInspector.SidebarPanel.prototype = {
    54     constructor: WebInspector.SidebarPanel,
    55     __proto__: WebInspector.Object.prototype,
     45        this._contentElement = document.createElement("div");
     46        this._contentElement.className = "content";
     47        this._element.appendChild(this._contentElement);
     48    }
    5649
    5750    // Public
     
    6053    {
    6154        return this._identifier;
    62     },
     55    }
    6356
    6457    get toolbarItem()
    6558    {
    6659        return this._toolbarItem;
    67     },
     60    }
    6861
    6962    get element()
    7063    {
    7164        return this._element;
    72     },
     65    }
    7366
    7467    get contentElement()
    7568    {
    7669        return this._contentElement;
    77     },
     70    }
    7871
    7972    get visible()
    8073    {
    8174        return this.selected && this._parentSidebar && !this._parentSidebar.collapsed;
    82     },
     75    }
    8376
    8477    get selected()
    8578    {
    8679        return this._element.classList.contains(WebInspector.SidebarPanel.SelectedStyleClassName);
    87     },
     80    }
    8881
    8982    set selected(flag)
     
    9386        else
    9487            this._element.classList.remove(WebInspector.SidebarPanel.SelectedStyleClassName);
    95     },
     88    }
    9689
    9790    get parentSidebar()
    9891    {
    9992        return this._parentSidebar;
    100     },
     93    }
    10194
    102     show: function()
     95    show()
    10396    {
    10497        if (!this._parentSidebar)
     
    107100        this._parentSidebar.collapsed = false;
    108101        this._parentSidebar.selectedSidebarPanel = this;
    109     },
     102    }
    110103
    111     hide: function()
     104    hide()
    112105    {
    113106        if (!this._parentSidebar)
     
    116109        this._parentSidebar.collapsed = true;
    117110        this._parentSidebar.selectedSidebarPanel = null;
    118     },
     111    }
    119112
    120     toggle: function()
     113    toggle()
    121114    {
    122115        if (this.visible)
     
    124117        else
    125118            this.show();
    126     },
     119    }
    127120
    128     added: function()
     121    added()
    129122    {
    130123        console.assert(this._parentSidebar);
    131124        this._toolbarItem.enabled = true;
    132125        this._toolbarItem.activated = this.visible;
    133     },
     126    }
    134127
    135     removed: function()
     128    removed()
    136129    {
    137130        console.assert(!this._parentSidebar);
    138131        this._toolbarItem.enabled = false;
    139132        this._toolbarItem.activated = false;
    140     },
     133    }
    141134
    142     willRemove: function()
     135    willRemove()
    143136    {
    144137        // Implemented by subclasses.
    145     },
     138    }
    146139
    147     shown: function()
     140    shown()
    148141    {
    149142        // Implemented by subclasses.
    150     },
     143    }
    151144
    152     hidden: function()
     145    hidden()
    153146    {
    154147        // Implemented by subclasses.
    155     },
     148    }
    156149
    157     widthDidChange: function()
     150    widthDidChange()
    158151    {
    159152        // Implemented by subclasses.
    160     },
     153    }
    161154
    162     visibilityDidChange: function()
     155    visibilityDidChange()
    163156    {
    164157        this._toolbarItem.activated = this.visible;
    165158    }
    166159};
     160
     161WebInspector.SidebarPanel.SelectedStyleClassName = "selected";
  • trunk/Source/WebInspectorUI/UserInterface/Views/TimelineSidebarPanel.js

    r181626 r182041  
    11/*
    2  * Copyright (C) 2013 Apple Inc. All rights reserved.
     2 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    2424 */
    2525
    26 WebInspector.TimelineSidebarPanel = function()
     26WebInspector.TimelineSidebarPanel = class TimelineSidebarPanel extends WebInspector.NavigationSidebarPanel
    2727{
    28     WebInspector.NavigationSidebarPanel.call(this, "timeline", WebInspector.UIString("Timelines"), "Images/NavigationItemStopwatch.svg", "2");
    29 
    30     this._timelineEventsTitleBarElement = document.createElement("div");
    31     this._timelineEventsTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TitleBarStyleClass);
    32     this._timelineEventsTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TimelineEventsTitleBarStyleClass);
    33     this.element.insertBefore(this._timelineEventsTitleBarElement, this.element.firstChild);
    34 
    35     this.contentTreeOutlineLabel = "";
    36 
    37     this._timelinesContentContainerElement = document.createElement("div");
    38     this._timelinesContentContainerElement.classList.add(WebInspector.TimelineSidebarPanel.TimelinesContentContainerStyleClass);
    39     this.element.insertBefore(this._timelinesContentContainerElement, this.element.firstChild);
    40 
    41     this._displayedRecording = null;
    42     this._displayedContentView = null;
    43 
    44     // Maintain an invisible tree outline containing tree elements for all recordings.
    45     // The visible recording's tree element is selected when the content view changes.
    46     this._recordingTreeElementMap = new Map;
    47     this._recordingsTreeOutline = this.createContentTreeOutline(true, true);
    48     this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
    49     this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
    50     this._recordingsTreeOutline.onselect = this._recordingsTreeElementSelected.bind(this);
    51     this._timelinesContentContainerElement.appendChild(this._recordingsTreeOutline.element);
    52 
    53     // Maintain a tree outline with tree elements for each timeline of the selected recording.
    54     this._timelinesTreeOutline = this.createContentTreeOutline(true, true);
    55     this._timelinesTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
    56     this._timelinesTreeOutline.onselect = this._timelinesTreeElementSelected.bind(this);
    57     this._timelinesContentContainerElement.appendChild(this._timelinesTreeOutline.element);
    58 
    59     this._timelineTreeElementMap = new Map;
    60 
    61     var timelinesTitleBarElement = document.createElement("div");
    62     timelinesTitleBarElement.textContent = WebInspector.UIString("Timelines");
    63     timelinesTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TitleBarStyleClass);
    64     timelinesTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TimelinesTitleBarStyleClass);
    65     this.element.insertBefore(timelinesTitleBarElement, this.element.firstChild);
    66 
    67     var statusBarElement = this._statusBarElement = document.createElement("div");
    68     statusBarElement.classList.add(WebInspector.TimelineSidebarPanel.StatusBarStyleClass);
    69     this.element.insertBefore(statusBarElement, this.element.firstChild);
    70 
    71     this._recordGlyphElement = document.createElement("div");
    72     this._recordGlyphElement.className = WebInspector.TimelineSidebarPanel.RecordGlyphStyleClass;
    73     this._recordGlyphElement.addEventListener("mouseover", this._recordGlyphMousedOver.bind(this));
    74     this._recordGlyphElement.addEventListener("mouseout", this._recordGlyphMousedOut.bind(this));
    75     this._recordGlyphElement.addEventListener("click", this._recordGlyphClicked.bind(this));
    76     statusBarElement.appendChild(this._recordGlyphElement);
    77 
    78     this._recordStatusElement = document.createElement("div");
    79     this._recordStatusElement.className = WebInspector.TimelineSidebarPanel.RecordStatusStyleClass;
    80     statusBarElement.appendChild(this._recordStatusElement);
    81 
    82     WebInspector.showReplayInterfaceSetting.addEventListener(WebInspector.Setting.Event.Changed, this._updateReplayInterfaceVisibility, this);
    83 
    84     // We always create a navigation bar; its visibility is controlled by WebInspector.showReplayInterfaceSetting.
    85     this._navigationBar = new WebInspector.NavigationBar;
    86     this.element.appendChild(this._navigationBar.element);
    87 
    88     var toolTip = WebInspector.UIString("Begin Capturing");
    89     var altToolTip = WebInspector.UIString("End Capturing");
    90     this._replayCaptureButtonItem = new WebInspector.ActivateButtonNavigationItem("replay-capture", toolTip, altToolTip, "Images/Circle.svg", 16, 16);
    91     this._replayCaptureButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._replayCaptureButtonClicked, this);
    92     this._replayCaptureButtonItem.enabled = true;
    93     this._navigationBar.addNavigationItem(this._replayCaptureButtonItem);
    94 
    95     var pauseImage, resumeImage;
    96     if (WebInspector.Platform.isLegacyMacOS) {
    97         pauseImage = {src: "Images/Legacy/Pause.svg", width: 16, height: 16};
    98         resumeImage = {src: "Images/Legacy/Resume.svg", width: 16, height: 16};
    99     } else {
    100         pauseImage = {src: "Images/Pause.svg", width: 15, height: 15};
    101         resumeImage = {src: "Images/Resume.svg", width: 15, height: 15};
    102     }
    103 
    104     toolTip = WebInspector.UIString("Start Playback");
    105     altToolTip = WebInspector.UIString("Pause Playback");
    106     this._replayPauseResumeButtonItem = new WebInspector.ToggleButtonNavigationItem("replay-pause-resume", toolTip, altToolTip, resumeImage.src, pauseImage.src, pauseImage.width, pauseImage.height, true);
    107     this._replayPauseResumeButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._replayPauseResumeButtonClicked, this);
    108     this._replayPauseResumeButtonItem.enabled = false;
    109     this._navigationBar.addNavigationItem(this._replayPauseResumeButtonItem);
    110 
    111     WebInspector.replayManager.addEventListener(WebInspector.ReplayManager.Event.CaptureStarted, this._captureStarted, this);
    112     WebInspector.replayManager.addEventListener(WebInspector.ReplayManager.Event.CaptureStopped, this._captureStopped, this);
    113 
    114     this._statusBarElement.oncontextmenu = this._contextMenuNavigationBarOrStatusBar.bind(this);
    115     this._navigationBar.element.oncontextmenu = this._contextMenuNavigationBarOrStatusBar.bind(this);
    116     this._updateReplayInterfaceVisibility();
    117 
    118     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.RecordingCreated, this._recordingCreated, this);
    119     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.RecordingLoaded, this._recordingLoaded, this);
    120 
    121     WebInspector.contentBrowser.addEventListener(WebInspector.ContentBrowser.Event.CurrentContentViewDidChange, this._contentBrowserCurrentContentViewDidChange, this);
    122     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
    123     WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     28    constructor()
     29    {
     30        super("timeline", WebInspector.UIString("Timelines"), "Images/NavigationItemStopwatch.svg", "2");
     31
     32        this._timelineEventsTitleBarElement = document.createElement("div");
     33        this._timelineEventsTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TitleBarStyleClass);
     34        this._timelineEventsTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TimelineEventsTitleBarStyleClass);
     35        this.element.insertBefore(this._timelineEventsTitleBarElement, this.element.firstChild);
     36
     37        this.contentTreeOutlineLabel = "";
     38
     39        this._timelinesContentContainerElement = document.createElement("div");
     40        this._timelinesContentContainerElement.classList.add(WebInspector.TimelineSidebarPanel.TimelinesContentContainerStyleClass);
     41        this.element.insertBefore(this._timelinesContentContainerElement, this.element.firstChild);
     42
     43        this._displayedRecording = null;
     44        this._displayedContentView = null;
     45
     46        // Maintain an invisible tree outline containing tree elements for all recordings.
     47        // The visible recording's tree element is selected when the content view changes.
     48        this._recordingTreeElementMap = new Map;
     49        this._recordingsTreeOutline = this.createContentTreeOutline(true, true);
     50        this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
     51        this._recordingsTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.ContentTreeOutlineElementHiddenStyleClassName);
     52        this._recordingsTreeOutline.onselect = this._recordingsTreeElementSelected.bind(this);
     53        this._timelinesContentContainerElement.appendChild(this._recordingsTreeOutline.element);
     54
     55        // Maintain a tree outline with tree elements for each timeline of the selected recording.
     56        this._timelinesTreeOutline = this.createContentTreeOutline(true, true);
     57        this._timelinesTreeOutline.element.classList.add(WebInspector.NavigationSidebarPanel.HideDisclosureButtonsStyleClassName);
     58        this._timelinesTreeOutline.onselect = this._timelinesTreeElementSelected.bind(this);
     59        this._timelinesContentContainerElement.appendChild(this._timelinesTreeOutline.element);
     60
     61        this._timelineTreeElementMap = new Map;
     62
     63        var timelinesTitleBarElement = document.createElement("div");
     64        timelinesTitleBarElement.textContent = WebInspector.UIString("Timelines");
     65        timelinesTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TitleBarStyleClass);
     66        timelinesTitleBarElement.classList.add(WebInspector.TimelineSidebarPanel.TimelinesTitleBarStyleClass);
     67        this.element.insertBefore(timelinesTitleBarElement, this.element.firstChild);
     68
     69        var statusBarElement = this._statusBarElement = document.createElement("div");
     70        statusBarElement.classList.add(WebInspector.TimelineSidebarPanel.StatusBarStyleClass);
     71        this.element.insertBefore(statusBarElement, this.element.firstChild);
     72
     73        this._recordGlyphElement = document.createElement("div");
     74        this._recordGlyphElement.className = WebInspector.TimelineSidebarPanel.RecordGlyphStyleClass;
     75        this._recordGlyphElement.addEventListener("mouseover", this._recordGlyphMousedOver.bind(this));
     76        this._recordGlyphElement.addEventListener("mouseout", this._recordGlyphMousedOut.bind(this));
     77        this._recordGlyphElement.addEventListener("click", this._recordGlyphClicked.bind(this));
     78        statusBarElement.appendChild(this._recordGlyphElement);
     79
     80        this._recordStatusElement = document.createElement("div");
     81        this._recordStatusElement.className = WebInspector.TimelineSidebarPanel.RecordStatusStyleClass;
     82        statusBarElement.appendChild(this._recordStatusElement);
     83
     84        WebInspector.showReplayInterfaceSetting.addEventListener(WebInspector.Setting.Event.Changed, this._updateReplayInterfaceVisibility, this);
     85
     86        // We always create a navigation bar; its visibility is controlled by WebInspector.showReplayInterfaceSetting.
     87        this._navigationBar = new WebInspector.NavigationBar;
     88        this.element.appendChild(this._navigationBar.element);
     89
     90        var toolTip = WebInspector.UIString("Begin Capturing");
     91        var altToolTip = WebInspector.UIString("End Capturing");
     92        this._replayCaptureButtonItem = new WebInspector.ActivateButtonNavigationItem("replay-capture", toolTip, altToolTip, "Images/Circle.svg", 16, 16);
     93        this._replayCaptureButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._replayCaptureButtonClicked, this);
     94        this._replayCaptureButtonItem.enabled = true;
     95        this._navigationBar.addNavigationItem(this._replayCaptureButtonItem);
     96
     97        var pauseImage, resumeImage;
     98        if (WebInspector.Platform.isLegacyMacOS) {
     99            pauseImage = {src: "Images/Legacy/Pause.svg", width: 16, height: 16};
     100            resumeImage = {src: "Images/Legacy/Resume.svg", width: 16, height: 16};
     101        } else {
     102            pauseImage = {src: "Images/Pause.svg", width: 15, height: 15};
     103            resumeImage = {src: "Images/Resume.svg", width: 15, height: 15};
     104        }
     105
     106        toolTip = WebInspector.UIString("Start Playback");
     107        altToolTip = WebInspector.UIString("Pause Playback");
     108        this._replayPauseResumeButtonItem = new WebInspector.ToggleButtonNavigationItem("replay-pause-resume", toolTip, altToolTip, resumeImage.src, pauseImage.src, pauseImage.width, pauseImage.height, true);
     109        this._replayPauseResumeButtonItem.addEventListener(WebInspector.ButtonNavigationItem.Event.Clicked, this._replayPauseResumeButtonClicked, this);
     110        this._replayPauseResumeButtonItem.enabled = false;
     111        this._navigationBar.addNavigationItem(this._replayPauseResumeButtonItem);
     112
     113        WebInspector.replayManager.addEventListener(WebInspector.ReplayManager.Event.CaptureStarted, this._captureStarted, this);
     114        WebInspector.replayManager.addEventListener(WebInspector.ReplayManager.Event.CaptureStopped, this._captureStopped, this);
     115
     116        this._statusBarElement.oncontextmenu = this._contextMenuNavigationBarOrStatusBar.bind(this);
     117        this._navigationBar.element.oncontextmenu = this._contextMenuNavigationBarOrStatusBar.bind(this);
     118        this._updateReplayInterfaceVisibility();
     119
     120        WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.RecordingCreated, this._recordingCreated, this);
     121        WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.RecordingLoaded, this._recordingLoaded, this);
     122
     123        WebInspector.contentBrowser.addEventListener(WebInspector.ContentBrowser.Event.CurrentContentViewDidChange, this._contentBrowserCurrentContentViewDidChange, this);
     124        WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStarted, this._capturingStarted, this);
     125        WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.Event.CapturingStopped, this._capturingStopped, this);
     126    }
     127
     128    // Public
     129
     130    shown()
     131    {
     132        WebInspector.NavigationSidebarPanel.prototype.shown.call(this);
     133
     134        if (this._displayedContentView)
     135            WebInspector.contentBrowser.showContentView(this._displayedContentView);
     136    }
     137
     138    showDefaultContentView()
     139    {
     140        if (this._displayedContentView)
     141            this.showTimelineOverview();
     142    }
     143
     144    get hasSelectedElement()
     145    {
     146        return !!this._contentTreeOutline.selectedTreeElement || !!this._recordingsTreeOutline.selectedTreeElement;
     147    }
     148
     149    treeElementForRepresentedObject(representedObject)
     150    {
     151        if (representedObject instanceof WebInspector.TimelineRecording)
     152            return this._recordingTreeElementMap.get(representedObject);
     153
     154        // This fails if the timeline does not belong to the selected recording.
     155        if (representedObject instanceof WebInspector.Timeline) {
     156            var foundTreeElement = this._timelineTreeElementMap.get(representedObject);
     157            if (foundTreeElement)
     158                return foundTreeElement;
     159        }
     160
     161        // The main resource is used as the representedObject instead of Frame in our tree.
     162        if (representedObject instanceof WebInspector.Frame)
     163            representedObject = representedObject.mainResource;
     164
     165        var foundTreeElement = this.contentTreeOutline.getCachedTreeElement(representedObject);
     166        if (foundTreeElement)
     167            return foundTreeElement;
     168
     169        // Look for TreeElements loosely based on represented objects that can contain the represented
     170        // object we are really looking for. This allows a SourceCodeTimelineTreeElement or a
     171        // TimelineRecordTreeElement to stay selected when the Resource it represents is showing.
     172
     173        function looselyCompareRepresentedObjects(candidateTreeElement)
     174        {
     175            if (!candidateTreeElement)
     176                return false;
     177
     178            var candidateRepresentedObject = candidateTreeElement.representedObject;
     179            if (candidateRepresentedObject instanceof WebInspector.SourceCodeTimeline) {
     180                if (candidateRepresentedObject.sourceCode === representedObject)
     181                    return true;
     182                return false;
     183            } else if (candidateRepresentedObject instanceof WebInspector.Timeline && representedObject instanceof WebInspector.Timeline) {
     184                // Reopen to the same timeline, even if a different parent recording is currently shown.
     185                if (candidateRepresentedObject.type === representedObject.type)
     186                    return true;
     187                return false;
     188            }
     189
     190            if (candidateRepresentedObject instanceof WebInspector.TimelineRecord) {
     191                if (!candidateRepresentedObject.sourceCodeLocation)
     192                    return false;
     193                if (candidateRepresentedObject.sourceCodeLocation.sourceCode === representedObject)
     194                    return true;
     195                return false;
     196            }
     197
     198            if (candidateRepresentedObject instanceof WebInspector.ProfileNode)
     199                return false;
     200
     201            console.error("Unknown TreeElement", candidateTreeElement);
     202            return false;
     203        }
     204
     205        // Check the selected tree element first so we don't need to do a longer search and it is
     206        // likely to be the best candidate for the current view.
     207        if (looselyCompareRepresentedObjects(this.contentTreeOutline.selectedTreeElement))
     208            return this.contentTreeOutline.selectedTreeElement;
     209
     210        var currentTreeElement = this._contentTreeOutline.children[0];
     211        while (currentTreeElement && !currentTreeElement.root) {
     212            if (looselyCompareRepresentedObjects(currentTreeElement))
     213                return currentTreeElement;
     214            currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
     215        }
     216
     217        return null;
     218    }
     219
     220    get contentTreeOutlineLabel()
     221    {
     222        return this._timelineEventsTitleBarElement.textContent;
     223    }
     224
     225    set contentTreeOutlineLabel(label)
     226    {
     227        label = label || WebInspector.UIString("Timeline Events");
     228
     229        this._timelineEventsTitleBarElement.textContent = label;
     230        this.filterBar.placeholder = WebInspector.UIString("Filter %s").format(label);
     231    }
     232
     233    showTimelineOverview()
     234    {
     235        if (this._timelinesTreeOutline.selectedTreeElement)
     236            this._timelinesTreeOutline.selectedTreeElement.deselect();
     237
     238        this._displayedContentView.showOverviewTimelineView();
     239        WebInspector.contentBrowser.showContentView(this._displayedContentView);
     240    }
     241
     242    showTimelineViewForTimeline(timeline)
     243    {
     244        console.assert(timeline instanceof WebInspector.Timeline, timeline);
     245        console.assert(this._timelineTreeElementMap.has(timeline), "Cannot show timeline because it does not belong to the shown recording.", timeline);
     246
     247        // Defer showing the relevant timeline to the onselect handler of the timelines tree element.
     248        var wasSelectedByUser = true;
     249        var shouldSuppressOnSelect = false;
     250        this._timelineTreeElementMap.get(timeline).select(true, wasSelectedByUser, shouldSuppressOnSelect, true);
     251    }
     252
     253    // Protected
     254
     255    updateFilter()
     256    {
     257        WebInspector.NavigationSidebarPanel.prototype.updateFilter.call(this);
     258
     259        this._displayedContentView.filterDidChange();
     260    }
     261
     262    hasCustomFilters()
     263    {
     264        return true;
     265    }
     266
     267    matchTreeElementAgainstCustomFilters(treeElement)
     268    {
     269        if (!this._displayedContentView)
     270            return true;
     271
     272        return this._displayedContentView.matchTreeElementAgainstCustomFilters(treeElement);
     273    }
     274
     275    canShowDifferentContentView()
     276    {
     277        return !this.restoringState || !this._restoredShowingTimelineRecordingContentView;
     278    }
     279
     280    saveStateToCookie(cookie)
     281    {
     282        console.assert(cookie);
     283
     284        cookie[WebInspector.TimelineSidebarPanel.ShowingTimelineRecordingContentViewCookieKey] = WebInspector.contentBrowser.currentContentView instanceof WebInspector.TimelineRecordingContentView;
     285
     286        var selectedTreeElement = this._timelinesTreeOutline.selectedTreeElement;
     287        if (selectedTreeElement)
     288            cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey] = selectedTreeElement.representedObject.type;
     289        else
     290            cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey] = WebInspector.TimelineSidebarPanel.OverviewTimelineIdentifierCookieValue;
     291
     292        super.saveStateToCookie(cookie);
     293    }
     294
     295    restoreStateFromCookie(cookie, relaxedMatchDelay)
     296    {
     297        console.assert(cookie);
     298
     299        // The _displayedContentView is not ready on initial load, so delay the restore.
     300        // This matches the delayed work in the WebInspector.TimelineSidebarPanel constructor.
     301        if (!this._displayedContentView) {
     302            setTimeout(this.restoreStateFromCookie.bind(this, cookie, relaxedMatchDelay), 0);
     303            return;
     304        }
     305
     306        this._restoredShowingTimelineRecordingContentView = cookie[WebInspector.TimelineSidebarPanel.ShowingTimelineRecordingContentViewCookieKey];
     307
     308        var selectedTimelineViewIdentifier = cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey];
     309        if (!selectedTimelineViewIdentifier || selectedTimelineViewIdentifier === WebInspector.TimelineSidebarPanel.OverviewTimelineIdentifierCookieValue)
     310            this.showTimelineOverview();
     311        else if (this._displayedRecording.timelines.has(selectedTimelineViewIdentifier))
     312            this.showTimelineViewForTimeline(this._displayedRecording.timelines.get(selectedTimelineViewIdentifier));
     313        else
     314            this.showTimelineOverview();
     315
     316        // Don't call NavigationSidebarPanel.restoreStateFromCookie, because it tries to match based
     317        // on type only as a last resort. This would cause the first recording to be reselected on reload.
     318    }
     319
     320    // Private
     321
     322    _recordingsTreeElementSelected(treeElement, selectedByUser)
     323    {
     324        console.assert(treeElement.representedObject instanceof WebInspector.TimelineRecording);
     325        console.assert(!selectedByUser, "Recording tree elements should be hidden and only programmatically selectable.");
     326
     327        this._recordingSelected(treeElement.representedObject);
     328
     329        // Deselect or re-select the timeline tree element for the timeline view being displayed.
     330        var currentTimelineView = this._displayedContentView.currentTimelineView;
     331        if (currentTimelineView && currentTimelineView.representedObject instanceof WebInspector.Timeline) {
     332            var wasSelectedByUser = false; // This is a simulated selection.
     333            var shouldSuppressOnSelect = false;
     334            this._timelineTreeElementMap.get(currentTimelineView.representedObject).select(true, wasSelectedByUser, shouldSuppressOnSelect, true);
     335        } else if (this._timelinesTreeOutline.selectedTreeElement)
     336            this._timelinesTreeOutline.selectedTreeElement.deselect();
     337
     338        this.updateFilter();
     339    }
     340
     341    _timelinesTreeElementSelected(treeElement, selectedByUser)
     342    {
     343        console.assert(this._timelineTreeElementMap.get(treeElement.representedObject) === treeElement, treeElement);
     344
     345        // If not selected by user, then this selection merely synced the tree element with the content view's contents.
     346        if (!selectedByUser) {
     347            console.assert(this._displayedContentView.currentTimelineView.representedObject === treeElement.representedObject);
     348            return;
     349        }
     350
     351        var timeline = treeElement.representedObject;
     352        console.assert(timeline instanceof WebInspector.Timeline, timeline);
     353        console.assert(this._displayedRecording.timelines.get(timeline.type) === timeline, timeline);
     354
     355        this._displayedContentView.showTimelineViewForTimeline(timeline);
     356        WebInspector.contentBrowser.showContentView(this._displayedContentView);
     357    }
     358
     359    _contentBrowserCurrentContentViewDidChange(event)
     360    {
     361        var didShowTimelineRecordingContentView = WebInspector.contentBrowser.currentContentView instanceof WebInspector.TimelineRecordingContentView;
     362        this.element.classList.toggle(WebInspector.TimelineSidebarPanel.TimelineRecordingContentViewShowingStyleClass, didShowTimelineRecordingContentView);
     363    }
     364
     365    _capturingStarted(event)
     366    {
     367        this._recordStatusElement.textContent = WebInspector.UIString("Recording");
     368        this._recordGlyphElement.classList.add(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingStyleClass);
     369    }
     370
     371    _capturingStopped(event)
     372    {
     373        this._recordStatusElement.textContent = "";
     374        this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingStyleClass);
     375    }
     376
     377    _recordingCreated(event)
     378    {
     379        var recording = event.data.recording;
     380        console.assert(recording instanceof WebInspector.TimelineRecording, recording);
     381
     382        var recordingTreeElement = new WebInspector.GeneralTreeElement(WebInspector.TimelineSidebarPanel.StopwatchIconStyleClass, recording.displayName, null, recording);
     383        this._recordingTreeElementMap.set(recording, recordingTreeElement);
     384        this._recordingsTreeOutline.appendChild(recordingTreeElement);
     385
     386        this._recordingCountChanged();
     387    }
     388
     389    _recordingCountChanged()
     390    {
     391        var previousTreeElement = null;
     392        for (var treeElement of this._recordingTreeElementMap.values()) {
     393            if (previousTreeElement) {
     394                previousTreeElement.nextSibling = treeElement;
     395                treeElement.previousSibling = previousTreeElement;
     396            }
     397
     398            previousTreeElement = treeElement;
     399        }
     400    }
     401
     402    _recordingSelected(recording)
     403    {
     404        console.assert(recording instanceof WebInspector.TimelineRecording, recording);
     405
     406        var oldRecording = this._displayedRecording || null;
     407        if (oldRecording) {
     408            oldRecording.removeEventListener(WebInspector.TimelineRecording.Event.TimelineAdded, this._timelineAdded, this);
     409            oldRecording.removeEventListener(WebInspector.TimelineRecording.Event.TimelineRemoved, this._timelineRemoved, this);
     410
     411            // Destroy tree elements in one operation to avoid unnecessary fixups.
     412            this._timelinesTreeOutline.removeChildren();
     413            this._timelineTreeElementMap.clear();
     414        }
     415
     416        this._displayedRecording = recording;
     417        this._displayedRecording.addEventListener(WebInspector.TimelineRecording.Event.TimelineAdded, this._timelineAdded, this);
     418        this._displayedRecording.addEventListener(WebInspector.TimelineRecording.Event.TimelineRemoved, this._timelineRemoved, this);
     419
     420        for (var timeline of recording.timelines.values())
     421            this._timelineAdded(timeline);
     422
     423        this._displayedContentView = WebInspector.contentBrowser.contentViewForRepresentedObject(this._displayedRecording);
     424        if (this.selected)
     425            WebInspector.contentBrowser.showContentView(this._displayedContentView);
     426    }
     427
     428    _recordingLoaded(event)
     429    {
     430        this._recordingSelected(WebInspector.timelineManager.activeRecording);
     431    }
     432
     433    _timelineAdded(timelineOrEvent)
     434    {
     435        var timeline = timelineOrEvent;
     436        if (!(timeline instanceof WebInspector.Timeline))
     437            timeline = timelineOrEvent.data.timeline;
     438
     439        console.assert(timeline instanceof WebInspector.Timeline, timeline);
     440        console.assert(!this._timelineTreeElementMap.has(timeline), timeline);
     441
     442        var timelineTreeElement = new WebInspector.GeneralTreeElement([timeline.iconClassName, WebInspector.TimelineSidebarPanel.LargeIconStyleClass], timeline.displayName, null, timeline);
     443        var tooltip = WebInspector.UIString("Close %s timeline view").format(timeline.displayName);
     444        wrappedSVGDocument(platformImagePath("CloseLarge.svg"), WebInspector.TimelineSidebarPanel.CloseButtonStyleClass, tooltip, function(element) {
     445            var button = new WebInspector.TreeElementStatusButton(element);
     446            button.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this.showTimelineOverview, this);
     447            timelineTreeElement.status = button.element;
     448        }.bind(this));
     449        this._timelinesTreeOutline.appendChild(timelineTreeElement);
     450        this._timelineTreeElementMap.set(timeline, timelineTreeElement);
     451
     452        this._timelineCountChanged();
     453    }
     454
     455    _timelineRemoved(event)
     456    {
     457        var timeline = event.data.timeline;
     458        console.assert(timeline instanceof WebInspector.Timeline, timeline);
     459        console.assert(this._timelineTreeElementMap.has(timeline), timeline);
     460
     461        var timelineTreeElement = this._timelineTreeElementMap.take(timeline);
     462        var shouldSuppressOnDeselect = false;
     463        var shouldSuppressSelectSibling = true;
     464        this._timelinesTreeOutline.removeChild(timelineTreeElement, shouldSuppressOnDeselect, shouldSuppressSelectSibling);
     465        this._timelineTreeElementMap.delete(timeline);
     466
     467        this._timelineCountChanged();
     468    }
     469
     470    _timelineCountChanged()
     471    {
     472        var previousTreeElement = null;
     473        for (var treeElement of this._timelineTreeElementMap.values()) {
     474            if (previousTreeElement) {
     475                previousTreeElement.nextSibling = treeElement;
     476                treeElement.previousSibling = previousTreeElement;
     477            }
     478
     479            previousTreeElement = treeElement;
     480        }
     481
     482        var timelineHeight = 36;
     483        var eventTitleBarOffset = 51;
     484        var contentElementOffset = 74;
     485        var timelineCount = this._displayedRecording.timelines.size;
     486        this._timelinesContentContainerElement.style.height = (timelineHeight * timelineCount) + "px";
     487        this._timelineEventsTitleBarElement.style.top = (timelineHeight * timelineCount + eventTitleBarOffset) + "px";
     488        this.contentElement.style.top = (timelineHeight * timelineCount + contentElementOffset) + "px";
     489    }
     490
     491    _recordGlyphMousedOver(event)
     492    {
     493        this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
     494
     495        if (WebInspector.timelineManager.isCapturing())
     496            this._recordStatusElement.textContent = WebInspector.UIString("Stop Recording");
     497        else
     498            this._recordStatusElement.textContent = WebInspector.UIString("Start Recording");
     499    }
     500
     501    _recordGlyphMousedOut(event)
     502    {
     503        this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
     504
     505        if (WebInspector.timelineManager.isCapturing())
     506            this._recordStatusElement.textContent = WebInspector.UIString("Recording");
     507        else
     508            this._recordStatusElement.textContent = "";
     509    }
     510
     511    _recordGlyphClicked(event)
     512    {
     513        // Add forced class to prevent the glyph from showing a confusing status after click.
     514        this._recordGlyphElement.classList.add(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
     515
     516        var shouldCreateRecording = event.shiftKey;
     517
     518        if (WebInspector.timelineManager.isCapturing())
     519            WebInspector.timelineManager.stopCapturing();
     520        else {
     521            WebInspector.timelineManager.startCapturing(shouldCreateRecording);
     522            // Show the timeline to which events will be appended.
     523            this._recordingLoaded();
     524        }
     525    }
     526
     527    // These methods are only used when ReplayAgent is available.
     528
     529    _updateReplayInterfaceVisibility()
     530    {
     531        var shouldShowReplayInterface = window.ReplayAgent && WebInspector.showReplayInterfaceSetting.value;
     532
     533        this._statusBarElement.classList.toggle(WebInspector.TimelineSidebarPanel.HiddenStyleClassName, shouldShowReplayInterface);
     534        this._navigationBar.element.classList.toggle(WebInspector.TimelineSidebarPanel.HiddenStyleClassName, !shouldShowReplayInterface);
     535    }
     536
     537    _contextMenuNavigationBarOrStatusBar()
     538    {
     539        if (!window.ReplayAgent)
     540            return;
     541
     542        function toggleReplayInterface() {
     543            WebInspector.showReplayInterfaceSetting.value = !WebInspector.showReplayInterfaceSetting.value;
     544        }
     545
     546        var contextMenu = new WebInspector.ContextMenu(event);
     547        if (WebInspector.showReplayInterfaceSetting.value)
     548            contextMenu.appendItem(WebInspector.UIString("Hide Replay Controls"), toggleReplayInterface);
     549        else
     550            contextMenu.appendItem(WebInspector.UIString("Show Replay Controls"), toggleReplayInterface);
     551        contextMenu.show();
     552    }
     553
     554    _replayCaptureButtonClicked()
     555    {
     556        if (!this._replayCaptureButtonItem.activated) {
     557            WebInspector.replayManager.startCapturing();
     558            WebInspector.timelineManager.startCapturing();
     559
     560            // De-bounce further presses until the backend has begun capturing.
     561            this._replayCaptureButtonItem.activated = true;
     562            this._replayCaptureButtonItem.enabled = false;
     563        } else {
     564            WebInspector.replayManager.stopCapturing();
     565            WebInspector.timelineManager.stopCapturing();
     566
     567            this._replayCaptureButtonItem.enabled = false;
     568        }
     569    }
     570
     571    _replayPauseResumeButtonClicked()
     572    {
     573        if (this._replayPauseResumeButtonItem.toggled)
     574            WebInspector.replayManager.pausePlayback();
     575        else
     576            WebInspector.replayManager.replayToCompletion();
     577    }
     578
     579    _captureStarted()
     580    {
     581        this._replayCaptureButtonItem.enabled = true;
     582    }
     583
     584    _captureStopped()
     585    {
     586        this._replayCaptureButtonItem.activated = false;
     587        this._replayPauseResumeButtonItem.enabled = true;
     588    }
     589
     590    _playbackStarted()
     591    {
     592        this._replayPauseResumeButtonItem.toggled = true;
     593    }
     594
     595    _playbackPaused()
     596    {
     597        this._replayPauseResumeButtonItem.toggled = false;
     598    }
    124599};
    125600
     
    146621WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey = "timeline-sidebar-panel-selected-timeline-view-identifier";
    147622WebInspector.TimelineSidebarPanel.OverviewTimelineIdentifierCookieValue = "overview";
    148 
    149 WebInspector.TimelineSidebarPanel.prototype = {
    150     constructor: WebInspector.TimelineSidebarPanel,
    151     __proto__: WebInspector.NavigationSidebarPanel.prototype,
    152 
    153     // Public
    154 
    155     shown: function()
    156     {
    157         WebInspector.NavigationSidebarPanel.prototype.shown.call(this);
    158 
    159         if (this._displayedContentView)
    160             WebInspector.contentBrowser.showContentView(this._displayedContentView);
    161     },
    162 
    163     showDefaultContentView: function()
    164     {
    165         if (this._displayedContentView)
    166             this.showTimelineOverview();
    167     },
    168 
    169     get hasSelectedElement()
    170     {
    171         return !!this._contentTreeOutline.selectedTreeElement || !!this._recordingsTreeOutline.selectedTreeElement;
    172     },
    173 
    174     treeElementForRepresentedObject: function(representedObject)
    175     {
    176         if (representedObject instanceof WebInspector.TimelineRecording)
    177             return this._recordingTreeElementMap.get(representedObject);
    178 
    179         // This fails if the timeline does not belong to the selected recording.
    180         if (representedObject instanceof WebInspector.Timeline) {
    181             var foundTreeElement = this._timelineTreeElementMap.get(representedObject);
    182             if (foundTreeElement)
    183                 return foundTreeElement;
    184         }
    185 
    186         // The main resource is used as the representedObject instead of Frame in our tree.
    187         if (representedObject instanceof WebInspector.Frame)
    188             representedObject = representedObject.mainResource;
    189 
    190         var foundTreeElement = this.contentTreeOutline.getCachedTreeElement(representedObject);
    191         if (foundTreeElement)
    192             return foundTreeElement;
    193 
    194         // Look for TreeElements loosely based on represented objects that can contain the represented
    195         // object we are really looking for. This allows a SourceCodeTimelineTreeElement or a
    196         // TimelineRecordTreeElement to stay selected when the Resource it represents is showing.
    197 
    198         function looselyCompareRepresentedObjects(candidateTreeElement)
    199         {
    200             if (!candidateTreeElement)
    201                 return false;
    202 
    203             var candidateRepresentedObject = candidateTreeElement.representedObject;
    204             if (candidateRepresentedObject instanceof WebInspector.SourceCodeTimeline) {
    205                 if (candidateRepresentedObject.sourceCode === representedObject)
    206                     return true;
    207                 return false;
    208             } else if (candidateRepresentedObject instanceof WebInspector.Timeline && representedObject instanceof WebInspector.Timeline) {
    209                 // Reopen to the same timeline, even if a different parent recording is currently shown.
    210                 if (candidateRepresentedObject.type === representedObject.type)
    211                     return true;
    212                 return false;
    213             }
    214 
    215             if (candidateRepresentedObject instanceof WebInspector.TimelineRecord) {
    216                 if (!candidateRepresentedObject.sourceCodeLocation)
    217                     return false;
    218                 if (candidateRepresentedObject.sourceCodeLocation.sourceCode === representedObject)
    219                     return true;
    220                 return false;
    221             }
    222 
    223             if (candidateRepresentedObject instanceof WebInspector.ProfileNode)
    224                 return false;
    225 
    226             console.error("Unknown TreeElement", candidateTreeElement);
    227             return false;
    228         }
    229 
    230         // Check the selected tree element first so we don't need to do a longer search and it is
    231         // likely to be the best candidate for the current view.
    232         if (looselyCompareRepresentedObjects(this.contentTreeOutline.selectedTreeElement))
    233             return this.contentTreeOutline.selectedTreeElement;
    234 
    235         var currentTreeElement = this._contentTreeOutline.children[0];
    236         while (currentTreeElement && !currentTreeElement.root) {
    237             if (looselyCompareRepresentedObjects(currentTreeElement))
    238                 return currentTreeElement;
    239             currentTreeElement = currentTreeElement.traverseNextTreeElement(false, null, false);
    240         }
    241 
    242         return null;
    243     },
    244 
    245     get contentTreeOutlineLabel()
    246     {
    247         return this._timelineEventsTitleBarElement.textContent;
    248     },
    249 
    250     set contentTreeOutlineLabel(label)
    251     {
    252         label = label || WebInspector.UIString("Timeline Events");
    253 
    254         this._timelineEventsTitleBarElement.textContent = label;
    255         this.filterBar.placeholder = WebInspector.UIString("Filter %s").format(label);
    256     },
    257 
    258     showTimelineOverview: function()
    259     {
    260         if (this._timelinesTreeOutline.selectedTreeElement)
    261             this._timelinesTreeOutline.selectedTreeElement.deselect();
    262 
    263         this._displayedContentView.showOverviewTimelineView();
    264         WebInspector.contentBrowser.showContentView(this._displayedContentView);
    265     },
    266 
    267     showTimelineViewForTimeline: function(timeline)
    268     {
    269         console.assert(timeline instanceof WebInspector.Timeline, timeline);
    270         console.assert(this._timelineTreeElementMap.has(timeline), "Cannot show timeline because it does not belong to the shown recording.", timeline);
    271 
    272         // Defer showing the relevant timeline to the onselect handler of the timelines tree element.
    273         const wasSelectedByUser = true;
    274         const shouldSuppressOnSelect = false;
    275         this._timelineTreeElementMap.get(timeline).select(true, wasSelectedByUser, shouldSuppressOnSelect, true);
    276     },
    277 
    278     // Protected
    279 
    280     updateFilter: function()
    281     {
    282         WebInspector.NavigationSidebarPanel.prototype.updateFilter.call(this);
    283 
    284         this._displayedContentView.filterDidChange();
    285     },
    286 
    287     hasCustomFilters: function()
    288     {
    289         return true;
    290     },
    291 
    292     matchTreeElementAgainstCustomFilters: function(treeElement)
    293     {
    294         if (!this._displayedContentView)
    295             return true;
    296 
    297         return this._displayedContentView.matchTreeElementAgainstCustomFilters(treeElement);
    298     },
    299 
    300     canShowDifferentContentView: function()
    301     {
    302         return !this.restoringState || !this._restoredShowingTimelineRecordingContentView;
    303     },
    304 
    305     saveStateToCookie: function(cookie)
    306     {
    307         console.assert(cookie);
    308 
    309         cookie[WebInspector.TimelineSidebarPanel.ShowingTimelineRecordingContentViewCookieKey] = WebInspector.contentBrowser.currentContentView instanceof WebInspector.TimelineRecordingContentView;
    310 
    311         var selectedTreeElement = this._timelinesTreeOutline.selectedTreeElement;
    312         if (selectedTreeElement)
    313             cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey] = selectedTreeElement.representedObject.type;
    314         else
    315             cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey] = WebInspector.TimelineSidebarPanel.OverviewTimelineIdentifierCookieValue;
    316 
    317         WebInspector.NavigationSidebarPanel.prototype.saveStateToCookie.call(this, cookie);
    318     },
    319 
    320     restoreStateFromCookie: function(cookie, relaxedMatchDelay)
    321     {
    322         console.assert(cookie);
    323 
    324         // The _displayedContentView is not ready on initial load, so delay the restore.
    325         // This matches the delayed work in the WebInspector.TimelineSidebarPanel constructor.
    326         if (!this._displayedContentView) {
    327             setTimeout(this.restoreStateFromCookie.bind(this, cookie, relaxedMatchDelay), 0);
    328             return;
    329         }
    330 
    331         this._restoredShowingTimelineRecordingContentView = cookie[WebInspector.TimelineSidebarPanel.ShowingTimelineRecordingContentViewCookieKey];
    332 
    333         var selectedTimelineViewIdentifier = cookie[WebInspector.TimelineSidebarPanel.SelectedTimelineViewIdentifierCookieKey];
    334         if (!selectedTimelineViewIdentifier || selectedTimelineViewIdentifier === WebInspector.TimelineSidebarPanel.OverviewTimelineIdentifierCookieValue)
    335             this.showTimelineOverview();
    336         else if (this._displayedRecording.timelines.has(selectedTimelineViewIdentifier))
    337             this.showTimelineViewForTimeline(this._displayedRecording.timelines.get(selectedTimelineViewIdentifier));
    338         else
    339             this.showTimelineOverview();
    340 
    341         // Don't call NavigationSidebarPanel.restoreStateFromCookie, because it tries to match based
    342         // on type only as a last resort. This would cause the first recording to be reselected on reload.
    343     },
    344 
    345     // Private
    346 
    347     _recordingsTreeElementSelected: function(treeElement, selectedByUser)
    348     {
    349         console.assert(treeElement.representedObject instanceof WebInspector.TimelineRecording);
    350         console.assert(!selectedByUser, "Recording tree elements should be hidden and only programmatically selectable.");
    351 
    352         this._recordingSelected(treeElement.representedObject);
    353 
    354         // Deselect or re-select the timeline tree element for the timeline view being displayed.
    355         var currentTimelineView = this._displayedContentView.currentTimelineView;
    356         if (currentTimelineView && currentTimelineView.representedObject instanceof WebInspector.Timeline) {
    357             const wasSelectedByUser = false; // This is a simulated selection.
    358             const shouldSuppressOnSelect = false;
    359             this._timelineTreeElementMap.get(currentTimelineView.representedObject).select(true, wasSelectedByUser, shouldSuppressOnSelect, true);
    360         } else if (this._timelinesTreeOutline.selectedTreeElement)
    361             this._timelinesTreeOutline.selectedTreeElement.deselect();
    362 
    363         this.updateFilter();
    364     },
    365 
    366     _timelinesTreeElementSelected: function(treeElement, selectedByUser)
    367     {
    368         console.assert(this._timelineTreeElementMap.get(treeElement.representedObject) === treeElement, treeElement);
    369 
    370         // If not selected by user, then this selection merely synced the tree element with the content view's contents.
    371         if (!selectedByUser) {
    372             console.assert(this._displayedContentView.currentTimelineView.representedObject === treeElement.representedObject);
    373             return;
    374         }
    375 
    376         var timeline = treeElement.representedObject;
    377         console.assert(timeline instanceof WebInspector.Timeline, timeline);
    378         console.assert(this._displayedRecording.timelines.get(timeline.type) === timeline, timeline);
    379 
    380         this._displayedContentView.showTimelineViewForTimeline(timeline);
    381         WebInspector.contentBrowser.showContentView(this._displayedContentView);
    382     },
    383 
    384     _contentBrowserCurrentContentViewDidChange: function(event)
    385     {
    386         var didShowTimelineRecordingContentView = WebInspector.contentBrowser.currentContentView instanceof WebInspector.TimelineRecordingContentView;
    387         this.element.classList.toggle(WebInspector.TimelineSidebarPanel.TimelineRecordingContentViewShowingStyleClass, didShowTimelineRecordingContentView);
    388     },
    389 
    390     _capturingStarted: function(event)
    391     {
    392         this._recordStatusElement.textContent = WebInspector.UIString("Recording");
    393         this._recordGlyphElement.classList.add(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingStyleClass);
    394     },
    395 
    396     _capturingStopped: function(event)
    397     {
    398         this._recordStatusElement.textContent = "";
    399         this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingStyleClass);
    400     },
    401 
    402     _recordingCreated: function(event)
    403     {
    404         var recording = event.data.recording;
    405         console.assert(recording instanceof WebInspector.TimelineRecording, recording);
    406 
    407         var recordingTreeElement = new WebInspector.GeneralTreeElement(WebInspector.TimelineSidebarPanel.StopwatchIconStyleClass, recording.displayName, null, recording);
    408         this._recordingTreeElementMap.set(recording, recordingTreeElement);
    409         this._recordingsTreeOutline.appendChild(recordingTreeElement);
    410 
    411         this._recordingCountChanged();
    412     },
    413 
    414     _recordingCountChanged: function()
    415     {
    416         var previousTreeElement = null;
    417         for (var treeElement of this._recordingTreeElementMap.values()) {
    418             if (previousTreeElement) {
    419                 previousTreeElement.nextSibling = treeElement;
    420                 treeElement.previousSibling = previousTreeElement;
    421             }
    422 
    423             previousTreeElement = treeElement;
    424         }
    425     },
    426 
    427     _recordingSelected: function(recording)
    428     {
    429         console.assert(recording instanceof WebInspector.TimelineRecording, recording);
    430 
    431         var oldRecording = this._displayedRecording || null;
    432         if (oldRecording) {
    433             oldRecording.removeEventListener(WebInspector.TimelineRecording.Event.TimelineAdded, this._timelineAdded, this);
    434             oldRecording.removeEventListener(WebInspector.TimelineRecording.Event.TimelineRemoved, this._timelineRemoved, this);
    435 
    436             // Destroy tree elements in one operation to avoid unnecessary fixups.
    437             this._timelinesTreeOutline.removeChildren();
    438             this._timelineTreeElementMap.clear();
    439         }
    440 
    441         this._displayedRecording = recording;
    442         this._displayedRecording.addEventListener(WebInspector.TimelineRecording.Event.TimelineAdded, this._timelineAdded, this);
    443         this._displayedRecording.addEventListener(WebInspector.TimelineRecording.Event.TimelineRemoved, this._timelineRemoved, this);
    444 
    445         for (var timeline of recording.timelines.values())
    446             this._timelineAdded(timeline);
    447 
    448         this._displayedContentView = WebInspector.contentBrowser.contentViewForRepresentedObject(this._displayedRecording);
    449         if (this.selected)
    450             WebInspector.contentBrowser.showContentView(this._displayedContentView);
    451     },
    452 
    453     _recordingLoaded: function(event)
    454     {
    455         this._recordingSelected(WebInspector.timelineManager.activeRecording);
    456     },
    457 
    458     _timelineAdded: function(timelineOrEvent)
    459     {
    460         var timeline = timelineOrEvent;
    461         if (!(timeline instanceof WebInspector.Timeline))
    462             timeline = timelineOrEvent.data.timeline;
    463 
    464         console.assert(timeline instanceof WebInspector.Timeline, timeline);
    465         console.assert(!this._timelineTreeElementMap.has(timeline), timeline);
    466 
    467         var timelineTreeElement = new WebInspector.GeneralTreeElement([timeline.iconClassName, WebInspector.TimelineSidebarPanel.LargeIconStyleClass], timeline.displayName, null, timeline);
    468         const tooltip = WebInspector.UIString("Close %s timeline view").format(timeline.displayName);
    469         wrappedSVGDocument(platformImagePath("CloseLarge.svg"), WebInspector.TimelineSidebarPanel.CloseButtonStyleClass, tooltip, function(element) {
    470             var button = new WebInspector.TreeElementStatusButton(element);
    471             button.addEventListener(WebInspector.TreeElementStatusButton.Event.Clicked, this.showTimelineOverview, this);
    472             timelineTreeElement.status = button.element;
    473         }.bind(this));
    474         this._timelinesTreeOutline.appendChild(timelineTreeElement);
    475         this._timelineTreeElementMap.set(timeline, timelineTreeElement);
    476 
    477         this._timelineCountChanged();
    478     },
    479 
    480     _timelineRemoved: function(event)
    481     {
    482         var timeline = event.data.timeline;
    483         console.assert(timeline instanceof WebInspector.Timeline, timeline);
    484         console.assert(this._timelineTreeElementMap.has(timeline), timeline);
    485 
    486         var timelineTreeElement = this._timelineTreeElementMap.take(timeline);
    487         const shouldSuppressOnDeselect = false;
    488         const shouldSuppressSelectSibling = true;
    489         this._timelinesTreeOutline.removeChild(timelineTreeElement, shouldSuppressOnDeselect, shouldSuppressSelectSibling);
    490         this._timelineTreeElementMap.delete(timeline);
    491 
    492         this._timelineCountChanged();
    493     },
    494 
    495     _timelineCountChanged: function()
    496     {
    497         var previousTreeElement = null;
    498         for (var treeElement of this._timelineTreeElementMap.values()) {
    499             if (previousTreeElement) {
    500                 previousTreeElement.nextSibling = treeElement;
    501                 treeElement.previousSibling = previousTreeElement;
    502             }
    503 
    504             previousTreeElement = treeElement;
    505         }
    506 
    507         const timelineHeight = 36;
    508         const eventTitleBarOffset = 51;
    509         const contentElementOffset = 74;
    510         var timelineCount = this._displayedRecording.timelines.size;
    511         this._timelinesContentContainerElement.style.height = (timelineHeight * timelineCount) + "px";
    512         this._timelineEventsTitleBarElement.style.top = (timelineHeight * timelineCount + eventTitleBarOffset) + "px";
    513         this.contentElement.style.top = (timelineHeight * timelineCount + contentElementOffset) + "px";
    514     },
    515 
    516     _recordGlyphMousedOver: function(event)
    517     {
    518         this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
    519 
    520         if (WebInspector.timelineManager.isCapturing())
    521             this._recordStatusElement.textContent = WebInspector.UIString("Stop Recording");
    522         else
    523             this._recordStatusElement.textContent = WebInspector.UIString("Start Recording");
    524     },
    525 
    526     _recordGlyphMousedOut: function(event)
    527     {
    528         this._recordGlyphElement.classList.remove(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
    529 
    530         if (WebInspector.timelineManager.isCapturing())
    531             this._recordStatusElement.textContent = WebInspector.UIString("Recording");
    532         else
    533             this._recordStatusElement.textContent = "";
    534     },
    535 
    536     _recordGlyphClicked: function(event)
    537     {
    538         // Add forced class to prevent the glyph from showing a confusing status after click.
    539         this._recordGlyphElement.classList.add(WebInspector.TimelineSidebarPanel.RecordGlyphRecordingForcedStyleClass);
    540 
    541         var shouldCreateRecording = event.shiftKey;
    542 
    543         if (WebInspector.timelineManager.isCapturing())
    544             WebInspector.timelineManager.stopCapturing();
    545         else {
    546             WebInspector.timelineManager.startCapturing(shouldCreateRecording);
    547             // Show the timeline to which events will be appended.
    548             this._recordingLoaded();
    549         }
    550     },
    551 
    552     // These methods are only used when ReplayAgent is available.
    553 
    554     _updateReplayInterfaceVisibility: function()
    555     {
    556         var shouldShowReplayInterface = window.ReplayAgent && WebInspector.showReplayInterfaceSetting.value;
    557 
    558         this._statusBarElement.classList.toggle(WebInspector.TimelineSidebarPanel.HiddenStyleClassName, shouldShowReplayInterface);
    559         this._navigationBar.element.classList.toggle(WebInspector.TimelineSidebarPanel.HiddenStyleClassName, !shouldShowReplayInterface);
    560     },
    561 
    562     _contextMenuNavigationBarOrStatusBar: function()
    563     {
    564         if (!window.ReplayAgent)
    565             return;
    566 
    567         function toggleReplayInterface() {
    568             WebInspector.showReplayInterfaceSetting.value = !WebInspector.showReplayInterfaceSetting.value;
    569         }
    570 
    571         var contextMenu = new WebInspector.ContextMenu(event);
    572         if (WebInspector.showReplayInterfaceSetting.value)
    573             contextMenu.appendItem(WebInspector.UIString("Hide Replay Controls"), toggleReplayInterface);
    574         else
    575             contextMenu.appendItem(WebInspector.UIString("Show Replay Controls"), toggleReplayInterface);
    576         contextMenu.show();
    577     },
    578 
    579     _replayCaptureButtonClicked: function()
    580     {
    581         if (!this._replayCaptureButtonItem.activated) {
    582             WebInspector.replayManager.startCapturing();
    583             WebInspector.timelineManager.startCapturing();
    584 
    585             // De-bounce further presses until the backend has begun capturing.
    586             this._replayCaptureButtonItem.activated = true;
    587             this._replayCaptureButtonItem.enabled = false;
    588         } else {
    589             WebInspector.replayManager.stopCapturing();
    590             WebInspector.timelineManager.stopCapturing();
    591 
    592             this._replayCaptureButtonItem.enabled = false;
    593         }
    594     },
    595 
    596     _replayPauseResumeButtonClicked: function()
    597     {
    598         if (this._replayPauseResumeButtonItem.toggled)
    599             WebInspector.replayManager.pausePlayback();
    600         else
    601             WebInspector.replayManager.replayToCompletion();
    602     },
    603 
    604     _captureStarted: function()
    605     {
    606         this._replayCaptureButtonItem.enabled = true;
    607     },
    608 
    609     _captureStopped: function()
    610     {
    611         this._replayCaptureButtonItem.activated = false;
    612         this._replayPauseResumeButtonItem.enabled = true;
    613     },
    614 
    615     _playbackStarted: function()
    616     {
    617         this._replayPauseResumeButtonItem.toggled = true;
    618     },
    619 
    620     _playbackPaused: function()
    621     {
    622         this._replayPauseResumeButtonItem.toggled = false;
    623     }
    624 };
Note: See TracChangeset for help on using the changeset viewer.