@samitouri / QOS-React-2 / commits / 95bd6c8f63

Added export to web shell and removed 'downloads' API permission

Brian Vaughn committed May 22, 2019 at 06:46 UTC 95bd6c8f6390ac3826ec472f41732a461e226cf6
7 files changed +28 -42
shells/browser/chrome/manifest.json
-1
@@ -44,7 +44,6 @@
44 "permissions": [
45 "<all_urls>",
46 "background",
47 - "downloads",
47 "tabs",
48 "file:///*",
49 "http://*/*",
shells/browser/firefox/manifest.json
-1
@@ -46,7 +46,6 @@
46
47 "permissions": [
48 "<all_urls>",
49 - "downloads",
49 "activeTab",
50 "tabs",
51 "file:///*",
shells/browser/shared/src/background.js
-11
@@ -110,17 +110,6 @@ chrome.runtime.onMessage.addListener((request, sender) => {
110 setIconAndPopup(reactBuildType, sender.tab.id);
111 }
112
113 - if (request.exportFile) {
114 - let { contents, filename } = request;
115 - if (!Array.isArray(contents)) {
116 - contents = [contents];
117 - }
118 -
119 - const blob = new Blob(contents, { type: 'text/plain' });
120 - const url = URL.createObjectURL(blob);
121 - chrome.downloads.download({ filename, saveAs: true, url });
122 - }
123 -
113 if (request.captureScreenshot) {
114 const { commitIndex, rootID } = request;
115 try {
shells/browser/shared/src/main.js
-8
@@ -85,13 +85,6 @@ function createPanelIfReactLoaded() {
85 localStorage.setItem(LOCAL_STORAGE_SUPPORTS_PROFILING_KEY, 'true');
86 chrome.devtools.inspectedWindow.eval('window.location.reload();');
87 });
88 - bridge.addListener('exportFile', ({ contents, filename }) => {
89 - chrome.runtime.sendMessage({
90 - exportFile: true,
91 - contents,
92 - filename,
93 - });
94 - });
88 bridge.addListener('captureScreenshot', ({ commitIndex, rootID }) => {
89 chrome.runtime.sendMessage(
90 {
@@ -124,7 +117,6 @@ function createPanelIfReactLoaded() {
117 store = new Store(bridge, {
118 isProfiling,
119 supportsCaptureScreenshots: true,
127 - supportsFileDownloads: browserName === 'Chrome',
120 supportsReloadAndProfile: true,
121 supportsProfiling,
122 });
src/devtools/store.js
-10
@@ -45,7 +45,6 @@ const LOCAL_STORAGE_COLLAPSE_ROOTS_BY_DEFAULT_KEY =
45 type Config = {|
46 isProfiling?: boolean,
47 supportsCaptureScreenshots?: boolean,
48 - supportsFileDownloads?: boolean,
48 supportsReloadAndProfile?: boolean,
49 supportsProfiling?: boolean,
50 |};
@@ -99,7 +98,6 @@ export default class Store extends EventEmitter {
98 // These options may be initially set by a confiugraiton option when constructing the Store.
99 // In the case of "supportsProfiling", the option may be updated based on the injected renderers.
100 _supportsCaptureScreenshots: boolean = false;
102 - _supportsFileDownloads: boolean = false;
101 _supportsProfiling: boolean = false;
102 _supportsReloadAndProfile: boolean = false;
103
@@ -127,7 +125,6 @@ export default class Store extends EventEmitter {
125
126 const {
127 supportsCaptureScreenshots,
130 - supportsFileDownloads,
128 supportsProfiling,
129 supportsReloadAndProfile,
130 } = config;
@@ -137,9 +134,6 @@ export default class Store extends EventEmitter {
134 localStorage.getItem(LOCAL_STORAGE_CAPTURE_SCREENSHOTS_KEY) ===
135 'true';
136 }
140 - if (supportsFileDownloads) {
141 - this._supportsFileDownloads = true;
142 - }
137 if (supportsProfiling) {
138 this._supportsProfiling = true;
139 }
@@ -309,10 +303,6 @@ export default class Store extends EventEmitter {
303 return this._supportsCaptureScreenshots;
304 }
305
312 - get supportsFileDownloads(): boolean {
313 - return this._supportsFileDownloads;
314 - }
315 -
306 get supportsProfiling(): boolean {
307 return this._supportsProfiling;
308 }
src/devtools/views/Profiler/ProfilingImportExportButtons.js
+12 -11
@@ -10,6 +10,7 @@ import {
10 prepareProfilingDataExport,
11 prepareProfilingDataFrontendFromExport,
12 } from './utils';
13 +import { downloadFile } from '../utils';
14
15 import styles from './ProfilingImportExportButtons.css';
16
@@ -34,8 +35,10 @@ export default function ProfilingImportExportButtons() {
35 profilerStore.profilingData
36 );
37
37 - // TODO (profarc) Generate anchor "download" tag and click it
38 - console.log('profilingDataExport:', profilingDataExport);
38 + downloadFile(
39 + 'profile-data.json',
40 + JSON.stringify(profilingDataExport, null, 2)
41 + );
42 }
43 }, [rootID, profilerStore.profilingData]);
44
@@ -95,15 +98,13 @@ export default function ProfilingImportExportButtons() {
98 >
99 <ButtonIcon type="import" />
100 </Button>
98 - {store.supportsFileDownloads && (
99 - <Button
100 - disabled={isProfiling || !profilerStore.hasProfilingData}
101 - onClick={downloadData}
102 - title="Save profile..."
103 - >
104 - <ButtonIcon type="export" />
105 - </Button>
106 - )}
101 + <Button
102 + disabled={isProfiling || !profilerStore.hasProfilingData}
103 + onClick={downloadData}
104 + title="Save profile..."
105 + >
106 + <ButtonIcon type="export" />
107 + </Button>
108 </Fragment>
109 );
110 }
src/devtools/views/utils.js
+16
@@ -146,3 +146,19 @@ export function serializeHooksForCopy(hooks: HooksTree | null): string {
146 return '';
147 }
148 }
149 +
150 +export function downloadFile(filename: string, text: string): void {
151 + const element = document.createElement('a');
152 + element.setAttribute(
153 + 'href',
154 + 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)
155 + );
156 + element.setAttribute('download', filename);
157 +
158 + element.style.display = 'none';
159 + ((document.body: any): HTMLBodyElement).appendChild(element);
160 +
161 + element.click();
162 +
163 + ((document.body: any): HTMLBodyElement).removeChild(element);
164 +}