Title: [223322] trunk/Source/WebInspectorUI
Revision
223322
Author
[email protected]
Date
2017-10-14 12:05:16 -0700 (Sat, 14 Oct 2017)

Log Message

Web Inspector: Canvas tab: recordings should have a unique name
https://bugs.webkit.org/show_bug.cgi?id=178188
<rdar://problem/34943364>

Reviewed by Devin Rousso.

* Localizations/en.lproj/localizedStrings.js:
New format string "Recording %d".

* UserInterface/Base/FileUtilities.js:
(WI.loadDataFromFile):
Pass chosen filename to callback.

* UserInterface/Controllers/CanvasManager.js:
(WI.CanvasManager.prototype.recordingFinished):
Create a unique name for the recording.

* UserInterface/Models/Recording.js:
(WI.Recording):
(WI.Recording.fromPayload):
(WI.Recording.prototype.get displayName):
(WI.Recording.prototype.createDisplayName):

* UserInterface/Views/RecordingContentView.js:
(WI.RecordingContentView.prototype.get saveData):
Use encodeURI so that special characters can be used in filenames, and
to be consistent with other `saveData` implementations.

* UserInterface/Views/RecordingNavigationSidebarPanel.js:
(WI.RecordingNavigationSidebarPanel.prototype.set recording):
(WI.RecordingNavigationSidebarPanel.prototype._importNavigationItemClicked):
Drive-by fix: wait until actions are resolved before updating UI.

* UserInterface/Views/RecordingTabContentView.js:
(WI.RecordingTabContentView.prototype._navigationSidebarImport):
Try to use the imported filename as the recording name. If the name
collides with that of another imported recording, append a unique suffix.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (223321 => 223322)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-10-14 19:05:16 UTC (rev 223322)
@@ -1,3 +1,43 @@
+2017-10-14  Matt Baker  <[email protected]>
+
+        Web Inspector: Canvas tab: recordings should have a unique name
+        https://bugs.webkit.org/show_bug.cgi?id=178188
+        <rdar://problem/34943364>
+
+        Reviewed by Devin Rousso.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        New format string "Recording %d".
+
+        * UserInterface/Base/FileUtilities.js:
+        (WI.loadDataFromFile):
+        Pass chosen filename to callback.
+
+        * UserInterface/Controllers/CanvasManager.js:
+        (WI.CanvasManager.prototype.recordingFinished):
+        Create a unique name for the recording.
+
+        * UserInterface/Models/Recording.js:
+        (WI.Recording):
+        (WI.Recording.fromPayload):
+        (WI.Recording.prototype.get displayName):
+        (WI.Recording.prototype.createDisplayName):
+
+        * UserInterface/Views/RecordingContentView.js:
+        (WI.RecordingContentView.prototype.get saveData):
+        Use encodeURI so that special characters can be used in filenames, and
+        to be consistent with other `saveData` implementations.
+
+        * UserInterface/Views/RecordingNavigationSidebarPanel.js:
+        (WI.RecordingNavigationSidebarPanel.prototype.set recording):
+        (WI.RecordingNavigationSidebarPanel.prototype._importNavigationItemClicked):
+        Drive-by fix: wait until actions are resolved before updating UI.
+
+        * UserInterface/Views/RecordingTabContentView.js:
+        (WI.RecordingTabContentView.prototype._navigationSidebarImport):
+        Try to use the imported filename as the recording name. If the name
+        collides with that of another imported recording, append a unique suffix.
+
 2017-10-14  Devin Rousso  <[email protected]>
 
         Web Inspector: provide a way to enable/disable event listeners

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -708,6 +708,7 @@
 localizedStrings["Reasons for compositing:"] = "Reasons for compositing:";
 localizedStrings["Recently Closed Tabs"] = "Recently Closed Tabs";
 localizedStrings["Recording"] = "Recording";
+localizedStrings["Recording %d"] = "Recording %d";
 localizedStrings["Recording Timeline Data"] = "Recording Timeline Data";
 localizedStrings["Recording error: %s"] = "Recording error: %s";
 localizedStrings["Reference Issue"] = "Reference Issue";

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/FileUtilities.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Base/FileUtilities.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/FileUtilities.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -76,11 +76,12 @@
             return;
         }
 
+        let file = inputElement.files[0];
         let reader = new FileReader;
         reader.addEventListener("loadend", (event) => {
-            callback(reader.result);
+            callback(reader.result, file.name);
         });
-        reader.readAsText(inputElement.files[0]);
+        reader.readAsText(file);
     });
     inputElement.click();
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/CanvasManager.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -158,9 +158,11 @@
         if (!canvas)
             return;
 
-        let recording = recordingPayload ? WI.Recording.fromPayload(recordingPayload) : null;
-        if (recording)
+        let recording = recordingPayload ? WI.Recording.fromPayload(recordingPayload) : null
+        if (recording) {
             recording.source = canvas;
+            recording.createDisplayName();
+        }
 
         this.dispatchEventToListeners(WI.CanvasManager.Event.RecordingStopped, {canvas, recording});
     }

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/Recording.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Models/Recording.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/Recording.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -32,6 +32,7 @@
         this._initialState = initialState;
         this._frames = frames;
         this._data = data;
+        this._displayName = WI.UIString("Recording");
 
         this._swizzle = [];
         this._source = null;
@@ -63,12 +64,10 @@
         });
     }
 
-    // Static
-
     static fromPayload(payload)
     {
         if (typeof payload !== "object" || payload === null)
-            payload = {};
+            return null;
 
         if (isNaN(payload.version) || payload.version <= 0)
             return null;
@@ -165,6 +164,7 @@
 
     // Public
 
+    get displayName() { return this._displayName; }
     get type() { return this._type; }
     get initialState() { return this._initialState; }
     get frames() { return this._frames; }
@@ -175,6 +175,33 @@
     get source() { return this._source; }
     set source(source) { this._source = source; }
 
+    createDisplayName(suggestedName)
+    {
+        let recordingNameSet;
+        if (this._source) {
+            recordingNameSet = this._source[WI.Recording.CanvasRecordingNamesSymbol];
+            if (!recordingNameSet)
+                this._source[WI.Recording.CanvasRecordingNamesSymbol] = recordingNameSet = new Set;
+        } else
+            recordingNameSet = WI.Recording._importedRecordingNameSet;
+
+        let name;
+        if (suggestedName) {
+            name = suggestedName;
+            let duplicateNumber = 2;
+            while (recordingNameSet.has(name))
+                name = `${suggestedName} (${duplicateNumber++})`;
+        } else {
+            let recordingNumber = 1;
+            do {
+                name = WI.UIString("Recording %d").format(recordingNumber++);
+            } while (recordingNameSet.has(name));
+        }
+
+        recordingNameSet.add(name);
+        this._displayName = name;
+    }
+
     async swizzle(index, type)
     {
         if (typeof this._swizzle[index] !== "object")
@@ -282,6 +309,10 @@
     }
 };
 
+WI.Recording._importedRecordingNameSet = new Set;
+
+WI.Recording.CanvasRecordingNamesSymbol = Symbol("canvas-recording-names");
+
 WI.Recording.Type = {
     Canvas2D: "canvas-2d",
     CanvasWebGL: "canvas-webgl",

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingContentView.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -148,8 +148,12 @@
 
     get saveData()
     {
+        let filename = this.representedObject.displayName;
+        if (!filename.endsWith(".json"))
+            filename += ".json";
+
         return {
-            url: "web-inspector:///Recording.json",
+            url: "web-inspector:///" + encodeURI(filename),
             content: JSON.stringify(this.representedObject.toJSON()),
             forceSaveAs: true,
         };

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingNavigationSidebarPanel.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingNavigationSidebarPanel.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingNavigationSidebarPanel.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -56,36 +56,39 @@
 
         this._recording = recording;
 
-        if (this._recording) {
-            this._recording.actions.then((actions) => {
-                this.contentTreeOutline.element.dataset.indent = Number.countDigits(actions.length);
+        this.updateEmptyContentPlaceholder(WI.UIString("No Recording Data"));
 
-                if (actions[0] instanceof WI.RecordingInitialStateAction)
-                    this.contentTreeOutline.appendChild(new WI.RecordingActionTreeElement(actions[0], 0, this._recording.type));
+        if (!this._recording) {
+            if (this._exportButton)
+                this._exportButton.disabled = true;
+            return;
+        }
 
-                let cumulativeActionIndex = 1;
-                this._recording.frames.forEach((frame, frameIndex) => {
-                    let folder = new WI.FolderTreeElement(WI.UIString("Frame %d").format((frameIndex + 1).toLocaleString()));
-                    this.contentTreeOutline.appendChild(folder);
+        this._recording.actions.then((actions) => {
+            this.contentTreeOutline.element.dataset.indent = Number.countDigits(actions.length);
 
-                    for (let i = 0; i < frame.actions.length; ++i)
-                        folder.appendChild(new WI.RecordingActionTreeElement(frame.actions[i], cumulativeActionIndex + i, this._recording.type));
+            if (actions[0] instanceof WI.RecordingInitialStateAction)
+                this.contentTreeOutline.appendChild(new WI.RecordingActionTreeElement(actions[0], 0, this._recording.type));
 
-                    if (frame.incomplete)
-                        folder.subtitle = WI.UIString("Incomplete");
+            let cumulativeActionIndex = 1;
+            this._recording.frames.forEach((frame, frameIndex) => {
+                let folder = new WI.FolderTreeElement(WI.UIString("Frame %d").format((frameIndex + 1).toLocaleString()));
+                this.contentTreeOutline.appendChild(folder);
 
-                    if (this._recording.frames.length === 1)
-                        folder.expand();
+                for (let i = 0; i < frame.actions.length; ++i)
+                    folder.appendChild(new WI.RecordingActionTreeElement(frame.actions[i], cumulativeActionIndex + i, this._recording.type));
 
-                    cumulativeActionIndex += frame.actions.length;
-                });
+                if (frame.incomplete)
+                    folder.subtitle = WI.UIString("Incomplete");
+
+                if (this._recording.frames.length === 1)
+                    folder.expand();
+
+                cumulativeActionIndex += frame.actions.length;
             });
-        }
 
-        this.updateEmptyContentPlaceholder(WI.UIString("No Recording Data"));
-
-        if (this._exportButton)
-            this._exportButton.disabled = !this.contentTreeOutline.children.length;
+            this._exportButton.disabled = !actions.length;
+        });
     }
 
     updateActionIndex(index, options = {})
@@ -174,7 +177,7 @@
 
     _importNavigationItemClicked(event)
     {
-        WI.loadDataFromFile((data) => {
+        WI.loadDataFromFile((data, filename) => {
             if (!data)
                 return;
 
@@ -186,7 +189,7 @@
                 return;
             }
 
-            this.dispatchEventToListeners(WI.RecordingNavigationSidebarPanel.Event.Import, {payload});
+            this.dispatchEventToListeners(WI.RecordingNavigationSidebarPanel.Event.Import, {payload, filename});
         });
     }
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RecordingTabContentView.js (223321 => 223322)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RecordingTabContentView.js	2017-10-14 18:56:32 UTC (rev 223321)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RecordingTabContentView.js	2017-10-14 19:05:16 UTC (rev 223322)
@@ -162,12 +162,19 @@
 
     _navigationSidebarImport(event)
     {
-        let recording = WI.Recording.fromPayload(event.data.payload);
+        let {filename, payload} = event.data;
+        let recording = WI.Recording.fromPayload(payload);
         if (!recording) {
             WI.Recording.synthesizeError(WI.UIString("unsupported version."));
             return;
         }
 
+        let extensionStart = filename.lastIndexOf(".");
+        if (extensionStart !== -1)
+            filename = filename.substring(0, extensionStart);
+
+        recording.createDisplayName(filename);
+
         this.showRepresentedObject(recording);
     }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to