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
+}