Web Inspector: Canvas: no obvious way of switching to the overview when viewing an...
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Apr 2019 20:31:02 +0000 (20:31 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Apr 2019 20:31:02 +0000 (20:31 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197178
<rdar://problem/50106641>

Reviewed by Timothy Hatcher.

Expand the idea of "imported" recordings to include "saved" recordings, ones whose
underlying <canvas> was destroyed.

* UserInterface/Views/CanvasTabContentView.js:
(WI.CanvasTabContentView):
(WI.CanvasTabContentView.prototype.attached):
(WI.CanvasTabContentView.prototype._removeCanvas):
(WI.CanvasTabContentView.prototype._addRecording):
(WI.CanvasTabContentView.prototype._handleRecordingSavedOrStopped): Added.
(WI.CanvasTabContentView.prototype.initialLayout): Deleted.
(WI.CanvasTabContentView.prototype._recordingImportedOrStopped): Deleted.
Make the "Saved Recordings" folder a child of the "Overview" so that the "Overview" path
component is always visible/clickable.

* UserInterface/Views/CanvasOverviewContentView.js:
(WI.CanvasOverviewContentView):
(WI.CanvasOverviewContentView.prototype.contentViewAdded):
(WI.CanvasOverviewContentView.prototype.attached):
(WI.CanvasOverviewContentView.prototype.detached):
(WI.CanvasOverviewContentView.prototype._addSavedRecording): Added.
(WI.CanvasOverviewContentView.prototype._handleRecordingSaved): Added.
(WI.CanvasOverviewContentView.prototype._handleSavedRecordingClicked): Added.
* UserInterface/Views/CanvasOverviewContentView.css:
(.content-view.canvas-overview .content-view.canvas.saved-recordings): Added.
(.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline): Added.
(.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline > .item.recording > .icon): Added.
Add a card for "Saved Recordings" that mimics the style of regular canvas cards.

* UserInterface/Controllers/CanvasManager.js:
(WI.CanvasManager):
(WI.CanvasManager.prototype.get savedRecordings): Added.
(WI.CanvasManager.prototype.async processJSON):
(WI.CanvasManager.prototype.disable):
(WI.CanvasManager.prototype._removeCanvas):
(WI.CanvasManager.prototype.get importedRecordings): Deleted.

* Localizations/en.lproj/localizedStrings.js:

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

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js
Source/WebInspectorUI/UserInterface/Views/CanvasOverviewContentView.css
Source/WebInspectorUI/UserInterface/Views/CanvasOverviewContentView.js
Source/WebInspectorUI/UserInterface/Views/CanvasTabContentView.js

index 2ddb9ce..d41e808 100644 (file)
@@ -1,3 +1,49 @@
+2019-04-23  Devin Rousso  <drousso@apple.com>
+
+        Web Inspector: Canvas: no obvious way of switching to the overview when viewing an imported recording
+        https://bugs.webkit.org/show_bug.cgi?id=197178
+        <rdar://problem/50106641>
+
+        Reviewed by Timothy Hatcher.
+
+        Expand the idea of "imported" recordings to include "saved" recordings, ones whose
+        underlying <canvas> was destroyed.
+
+        * UserInterface/Views/CanvasTabContentView.js:
+        (WI.CanvasTabContentView):
+        (WI.CanvasTabContentView.prototype.attached):
+        (WI.CanvasTabContentView.prototype._removeCanvas):
+        (WI.CanvasTabContentView.prototype._addRecording):
+        (WI.CanvasTabContentView.prototype._handleRecordingSavedOrStopped): Added.
+        (WI.CanvasTabContentView.prototype.initialLayout): Deleted.
+        (WI.CanvasTabContentView.prototype._recordingImportedOrStopped): Deleted.
+        Make the "Saved Recordings" folder a child of the "Overview" so that the "Overview" path
+        component is always visible/clickable.
+
+        * UserInterface/Views/CanvasOverviewContentView.js:
+        (WI.CanvasOverviewContentView):
+        (WI.CanvasOverviewContentView.prototype.contentViewAdded):
+        (WI.CanvasOverviewContentView.prototype.attached):
+        (WI.CanvasOverviewContentView.prototype.detached):
+        (WI.CanvasOverviewContentView.prototype._addSavedRecording): Added.
+        (WI.CanvasOverviewContentView.prototype._handleRecordingSaved): Added.
+        (WI.CanvasOverviewContentView.prototype._handleSavedRecordingClicked): Added.
+        * UserInterface/Views/CanvasOverviewContentView.css:
+        (.content-view.canvas-overview .content-view.canvas.saved-recordings): Added.
+        (.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline): Added.
+        (.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline > .item.recording > .icon): Added.
+        Add a card for "Saved Recordings" that mimics the style of regular canvas cards.
+
+        * UserInterface/Controllers/CanvasManager.js:
+        (WI.CanvasManager):
+        (WI.CanvasManager.prototype.get savedRecordings): Added.
+        (WI.CanvasManager.prototype.async processJSON):
+        (WI.CanvasManager.prototype.disable):
+        (WI.CanvasManager.prototype._removeCanvas):
+        (WI.CanvasManager.prototype.get importedRecordings): Deleted.
+
+        * Localizations/en.lproj/localizedStrings.js:
+
 2019-04-22  Devin Rousso  <drousso@apple.com>
 
         Web Inspector: REGRESSION: Sources: auto-continue breakpoint triangle is incorrectly positioned
index c68e704..51a6e85 100644 (file)
@@ -562,7 +562,6 @@ localizedStrings["Immediate Pause Requested"] = "Immediate Pause Requested";
 localizedStrings["Import"] = "Import";
 localizedStrings["Imported"] = "Imported";
 localizedStrings["Imported - %s"] = "Imported - %s";
-localizedStrings["Imported Recordings"] = "Imported Recordings";
 localizedStrings["Imported \u2014 %s"] = "Imported \u2014 %s";
 localizedStrings["Incomplete"] = "Incomplete";
 localizedStrings["Indent width:"] = "Indent width:";
@@ -879,6 +878,7 @@ localizedStrings["Save File"] = "Save File";
 localizedStrings["Save Image"] = "Save Image";
 localizedStrings["Save Selected"] = "Save Selected";
 localizedStrings["Save configuration"] = "Save configuration";
+localizedStrings["Saved Recordings"] = "Saved Recordings";
 localizedStrings["Saved States"] = "Saved States";
 localizedStrings["Scheduling:"] = "Scheduling:";
 localizedStrings["Scheme"] = "Scheme";
index a480c1d..88766ce 100644 (file)
@@ -34,7 +34,7 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         this._enabled = false;
         this._canvasIdentifierMap = new Map;
         this._shaderProgramIdentifierMap = new Map;
-        this._importedRecordings = new Set;
+        this._savedRecordings = new Set;
 
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
     }
@@ -63,7 +63,7 @@ WI.CanvasManager = class CanvasManager extends WI.Object
 
     // Public
 
-    get importedRecordings() { return this._importedRecordings; }
+    get savedRecordings() { return this._savedRecordings; }
 
     get canvases()
     {
@@ -96,9 +96,9 @@ WI.CanvasManager = class CanvasManager extends WI.Object
             filename = filename.substring(0, extensionStart);
         recording.createDisplayName(filename);
 
-        this._importedRecordings.add(recording);
+        this._savedRecordings.add(recording);
 
-        this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingImported, {recording, initiatedByUser: true});
+        this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingSaved, {recording, imported: true, initiatedByUser: true});
     }
 
     enable()
@@ -122,7 +122,7 @@ WI.CanvasManager = class CanvasManager extends WI.Object
 
         this._canvasIdentifierMap.clear();
         this._shaderProgramIdentifierMap.clear();
-        this._importedRecordings.clear();
+        this._savedRecordings.clear();
 
         this._enabled = false;
     }
@@ -277,6 +277,8 @@ WI.CanvasManager = class CanvasManager extends WI.Object
         for (let recording of canvas.recordingCollection) {
             recording.source = null;
             recording.createDisplayName(recording.displayName);
+            this._savedRecordings.add(recording);
+            this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingSaved, {recording});
         }
 
         this.dispatchEventToListeners(WI.CanvasManager.Event.CanvasRemoved, {canvas});
@@ -301,5 +303,5 @@ WI.CanvasManager = class CanvasManager extends WI.Object
 WI.CanvasManager.Event = {
     CanvasAdded: "canvas-manager-canvas-was-added",
     CanvasRemoved: "canvas-manager-canvas-was-removed",
-    RecordingImported: "canvas-manager-recording-imported",
+    RecordingSaved: "canvas-manager-recording-saved",
 };
index 7844d0d..9fb82c7 100644 (file)
     -webkit-padding-start: 4px;
 }
 
+.content-view.canvas-overview .content-view.canvas.saved-recordings {
+    height: 340px;
+}
+
+.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline {
+    overflow-y: scroll;
+}
+
+.content-view.canvas-overview .content-view.canvas.saved-recordings .tree-outline > .item.recording > .icon {
+    content: url(../Images/Recording.svg);
+}
+
 .navigation-bar > .item.canvas-recording-auto-capture > label {
     display: flex;
     align-items: center;
index fd64ae2..ded3cb8 100644 (file)
@@ -77,6 +77,9 @@ WI.CanvasOverviewContentView = class CanvasOverviewContentView extends WI.Collec
 
         importNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this);
         this._importButtonNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleImportButtonNavigationItemClicked, this);
+
+        this._savedRecordingsContentView = null;
+        this._savedRecordingsTreeOutline = null;
     }
 
     // Static
@@ -107,6 +110,12 @@ WI.CanvasOverviewContentView = class CanvasOverviewContentView extends WI.Collec
         contentView.element.addEventListener("mouseenter", this._contentViewMouseEnter);
         contentView.element.addEventListener("mouseleave", this._contentViewMouseLeave);
 
+        if (this._savedRecordingsContentView) {
+            // Ensure that the imported recordings are always last.
+            this.removeSubview(this._savedRecordingsContentView);
+            this.addSubview(this._savedRecordingsContentView);
+        }
+
         this._updateNavigationItems();
     }
 
@@ -125,10 +134,19 @@ WI.CanvasOverviewContentView = class CanvasOverviewContentView extends WI.Collec
         WI.settings.showImageGrid.addEventListener(WI.Setting.Event.Changed, this._updateShowImageGrid, this);
         WI.settings.canvasRecordingAutoCaptureEnabled.addEventListener(WI.Setting.Event.Changed, this._handleCanvasRecordingAutoCaptureEnabledChanged, this);
         WI.settings.canvasRecordingAutoCaptureFrameCount.addEventListener(WI.Setting.Event.Changed, this._handleCanvasRecordingAutoCaptureFrameCountChanged, this);
+
+        WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingSaved, this._handleRecordingSaved, this);
+
+        if (this._savedRecordingsTreeOutline)
+            this._savedRecordingsTreeOutline.removeChildren();
+        for (let recording of WI.canvasManager.savedRecordings)
+            this._addSavedRecording(recording);
     }
 
     detached()
     {
+        WI.canvasManager.removeEventListener(null, null, this);
+
         WI.settings.canvasRecordingAutoCaptureFrameCount.removeEventListener(null, null, this);
         WI.settings.canvasRecordingAutoCaptureEnabled.removeEventListener(null, null, this);
         WI.settings.showImageGrid.removeEventListener(null, null, this);
@@ -261,6 +279,32 @@ WI.CanvasOverviewContentView = class CanvasOverviewContentView extends WI.Collec
         return frameCount;
     }
 
+    _addSavedRecording(recording)
+    {
+        console.assert(!recording.source);
+
+        if (!this._savedRecordingsContentView) {
+            this._savedRecordingsContentView = new WI.ContentView;
+            this._savedRecordingsContentView.element.classList.add("canvas", "saved-recordings");
+            this.addSubview(this._savedRecordingsContentView);
+
+            let header = this._savedRecordingsContentView.element.appendChild(document.createElement("header"));
+            header.textContent = WI.UIString("Saved Recordings");
+        }
+
+        if (!this._savedRecordingsTreeOutline) {
+            const selectable = false;
+            this._savedRecordingsTreeOutline = new WI.TreeOutline(selectable);
+            this._savedRecordingsTreeOutline.addEventListener(WI.TreeOutline.Event.ElementClicked, this._handleSavedRecordingClicked, this);
+            this._savedRecordingsContentView.element.appendChild(this._savedRecordingsTreeOutline.element);
+        }
+
+        const subtitle = null;
+        let recordingTreeElement = new WI.GeneralTreeElement(["recording"], recording.displayName, subtitle, recording);
+        recordingTreeElement.selectable = false;
+        this._savedRecordingsTreeOutline.appendChild(recordingTreeElement);
+    }
+
     _handleRecordingAutoCaptureInput(event)
     {
         let frameCount = this._updateRecordingAutoCaptureInputElementSize();
@@ -292,4 +336,14 @@ WI.CanvasOverviewContentView = class CanvasOverviewContentView extends WI.Collec
     {
         WI.FileUtilities.importJSON((result) => WI.canvasManager.processJSON(result));
     }
+
+    _handleRecordingSaved(event)
+    {
+        this._addSavedRecording(event.data.recording);
+    }
+
+    _handleSavedRecordingClicked(event)
+    {
+        WI.showRepresentedObject(event.data.treeElement.representedObject);
+    }
 };
index b0fb128..fb79b53 100644 (file)
@@ -44,9 +44,9 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
         this._overviewTreeElement = new WI.GeneralTreeElement("canvas-overview", WI.UIString("Overview"), null, this._canvasCollection);
         this._canvasTreeOutline.appendChild(this._overviewTreeElement);
 
-        this._importedRecordingsTreeElement = new WI.FolderTreeElement(WI.UIString("Imported Recordings"), WI.RecordingCollection);
-        this._importedRecordingsTreeElement.hidden = true;
-        this._canvasTreeOutline.appendChild(this._importedRecordingsTreeElement);
+        this._savedRecordingsTreeElement = new WI.FolderTreeElement(WI.UIString("Saved Recordings"), WI.RecordingCollection);
+        this._savedRecordingsTreeElement.hidden = true;
+        this._overviewTreeElement.appendChild(this._savedRecordingsTreeElement);
 
         this._recordShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.Space, this._handleSpace.bind(this));
         this._recordShortcut.implicitlyPreventsDefault = false;
@@ -145,26 +145,14 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
 
     // Protected
 
-    initialLayout()
-    {
-        super.initialLayout();
-
-        const options = {
-            suppressShowRecording: true,
-        };
-
-        for (let recording of WI.canvasManager.importedRecordings)
-            this._addRecording(recording, options);
-    }
-
     attached()
     {
         super.attached();
 
         WI.canvasManager.addEventListener(WI.CanvasManager.Event.CanvasAdded, this._handleCanvasAdded, this);
         WI.canvasManager.addEventListener(WI.CanvasManager.Event.CanvasRemoved, this._handleCanvasRemoved, this);
-        WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingImported, this._recordingImportedOrStopped, this);
-        WI.Canvas.addEventListener(WI.Canvas.Event.RecordingStopped, this._recordingImportedOrStopped, this);
+        WI.canvasManager.addEventListener(WI.CanvasManager.Event.RecordingSaved, this._handleRecordingSavedOrStopped, this);
+        WI.Canvas.addEventListener(WI.Canvas.Event.RecordingStopped, this._handleRecordingSavedOrStopped, this);
 
         let canvases = WI.canvasManager.canvases;
 
@@ -177,6 +165,10 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
             if (!this._canvasCollection.has(canvas))
                 this._addCanvas(canvas);
         }
+
+        this._savedRecordingsTreeElement.removeChildren();
+        for (let recording of WI.canvasManager.savedRecordings)
+            this._addRecording(recording, {suppressShowRecording: true});
     }
 
     detached()
@@ -213,13 +205,6 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
 
         this._canvasCollection.remove(canvas);
 
-        const options = {
-            suppressShowRecording: true,
-        };
-
-        for (let recording of canvas.recordingCollection)
-            this._addRecording(recording, options);
-
         let currentContentView = this.contentBrowser.currentContentView;
         if (currentContentView instanceof WI.CanvasContentView)
             WI.showRepresentedObject(this._canvasCollection);
@@ -229,6 +214,8 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
         let navigationSidebarPanel = this.navigationSidebarPanel;
         if (navigationSidebarPanel instanceof WI.CanvasSidebarPanel && navigationSidebarPanel.visible)
             navigationSidebarPanel.updateRepresentedObjects();
+
+        this.showDetailsSidebarPanels();
     }
 
     _addRecording(recording, options = {})
@@ -236,8 +223,8 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
         if (!recording.source) {
             const subtitle = null;
             let recordingTreeElement = new WI.GeneralTreeElement(["recording"], recording.displayName, subtitle, recording);
-            this._importedRecordingsTreeElement.hidden = false;
-            this._importedRecordingsTreeElement.appendChild(recordingTreeElement);
+            this._savedRecordingsTreeElement.hidden = false;
+            this._savedRecordingsTreeElement.appendChild(recordingTreeElement);
         }
 
         if (!options.suppressShowRecording)
@@ -269,16 +256,16 @@ WI.CanvasTabContentView = class CanvasTabContentView extends WI.ContentBrowserTa
         this.showRepresentedObject(representedObject);
     }
 
-    _recordingImportedOrStopped(event)
+    _handleRecordingSavedOrStopped(event)
     {
-        let {recording, initiatedByUser} = event.data;
+        let {recording, initiatedByUser, imported} = event.data;
         if (!recording)
             return;
 
         let options = {};
 
         // Always show imported recordings.
-        if (recording.source)
+        if (recording.source || !imported)
             options.suppressShowRecording = !initiatedByUser || this.contentBrowser.currentRepresentedObjects.some((representedObject) => representedObject instanceof WI.Recording);
 
         this._addRecording(recording, options);