Add Download button to right click menu
We need a way for users to export data, since it can't be selected and
copied all at once.
video: https://www.youtube.com/watch?v=v7KAKXj41yY&feature=youtu.be
example json: files.tedm.io/devtools_download_example.json
Bug: 711793
Change-Id: I653a1ec6e77b6fdca54a2f958e3c479e9aa89566
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2327241
Commit-Queue: Ted Meyer <[email protected]>
Reviewed-by: Mathias Bynens <[email protected]>
diff --git a/front_end/media/MainView.js b/front_end/media/MainView.js
index 538ed15..db2c787 100644
--- a/front_end/media/MainView.js
+++ b/front_end/media/MainView.js
@@ -61,6 +61,113 @@
}
/**
+ * @implements TriggerHandler
+ */
+class PlayerDataCollection {
+ constructor() {
+ // Map<Protocol.Media.PlayerProperty>
+ this._properties = {};
+
+ this._messages = [];
+ this._events = [];
+ this._errors = [];
+ }
+
+ /**
+ * @override
+ * @param {!Protocol.Media.PlayerProperty} property
+ */
+ onProperty(property) {
+ this._properties[property.name] = property.value;
+ }
+
+ /**
+ * @override
+ * @param {!Protocol.Media.PlayerError} error */
+ onError(error) {
+ this._errors.push(error);
+ }
+
+ /**
+ * @override
+ * @param {!Protocol.Media.PlayerMessage} message
+ */
+ onMessage(message) {
+ this._messages.push(message);
+ }
+
+ /**
+ * @override
+ * @param {!PlayerEvent} event
+ */
+ onEvent(event) {
+ this._events.push(event);
+ }
+
+ export() {
+ return {'properties': this._properties, 'messages': this._messages, 'events': this._events, 'errors': this._errors};
+ }
+}
+
+/**
+ * @implements TriggerDispatcher
+ */
+class PlayerDataDownloadManager {
+ constructor() {
+ // Map<string, PlayerDataCollection>
+ this._playerDataCollection = new Map();
+ }
+
+ addPlayer(playerID) {
+ this._playerDataCollection.set(playerID, new PlayerDataCollection());
+ }
+
+ /**
+ * @override
+ * @param {string} playerID
+ * @param {!Protocol.Media.PlayerProperty} property
+ */
+ onProperty(playerID, property) {
+ this._playerDataCollection.get(playerID).onProperty(property);
+ }
+
+ /**
+ * @override
+ * @param {string} playerID
+ * @param {!Protocol.Media.PlayerError} error
+ */
+ onError(playerID, error) {
+ this._playerDataCollection.get(playerID).onError(error);
+ }
+
+ /**
+ * @override
+ * @param {string} playerID
+ * @param {!Protocol.Media.PlayerMessage} message
+ */
+ onMessage(playerID, message) {
+ this._playerDataCollection.get(playerID).onMessage(message);
+ }
+
+ /**
+ * @override
+ * @param {string} playerID
+ * @param {!PlayerEvent} event
+ */
+ onEvent(playerID, event) {
+ this._playerDataCollection.get(playerID).onEvent(event);
+ }
+
+ exportPlayerData(playerID) {
+ return this._playerDataCollection.get(playerID).export();
+ }
+
+ deletePlayer(playerID) {
+ this._playerDataCollection.delete(playerID);
+ }
+}
+
+/**
* @implements {SDK.SDKModel.SDKModelObserver<!Media.MediaModel>}
* @implements TriggerDispatcher
*/
@@ -75,6 +182,8 @@
// Map<string>
this._deletedPlayers = new Set();
+ this._downloadStore = new PlayerDataDownloadManager();
+
this._sidebar = new PlayerListView(this);
this._sidebar.show(this.panelSidebarElement());
@@ -158,6 +267,7 @@
_onPlayerCreated(playerID) {
this._sidebar.addMediaElementItem(playerID);
this._detailPanels.set(playerID, new PlayerDetailView());
+ this._downloadStore.addPlayer(playerID);
}
/**
@@ -214,6 +324,7 @@
return;
}
this._sidebar.onProperty(playerID, property);
+ this._downloadStore.onProperty(playerID, property);
this._detailPanels.get(playerID).onProperty(property);
}
@@ -227,6 +338,7 @@
return;
}
this._sidebar.onError(playerID, error);
+ this._downloadStore.onError(playerID, error);
this._detailPanels.get(playerID).onError(error);
}
@@ -240,6 +352,7 @@
return;
}
this._sidebar.onMessage(playerID, message);
+ this._downloadStore.onMessage(playerID, message);
this._detailPanels.get(playerID).onMessage(message);
}
@@ -253,6 +366,7 @@
return;
}
this._sidebar.onEvent(playerID, event);
+ this._downloadStore.onEvent(playerID, event);
this._detailPanels.get(playerID).onEvent(event);
}
@@ -274,5 +388,15 @@
this._deletedPlayers.add(playerID);
this._detailPanels.delete(playerID);
this._sidebar.deletePlayer(playerID);
+ this._downloadStore.deletePlayer(playerID);
+ }
+
+ exportPlayerData(playerID) {
+ const dump = this._downloadStore.exportPlayerData(playerID);
+ const uriContent = 'data:application/octet-stream,' + encodeURIComponent(JSON.stringify(dump, null, 2));
+ const anchor = document.createElement('a');
+ anchor.href = uriContent;
+ anchor.download = playerID + '.json';
+ anchor.click();
}
}