[cleanup] Use `ContentData` in `Workspace.FileManager.FileManager`.
Bug: 425280773
Change-Id: I0099f26a088452285ff88b80088e8c1a948f9798
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/6651078
Commit-Queue: Benedikt Meurer <[email protected]>
Reviewed-by: Simon Zünd <[email protected]>
Auto-Submit: Benedikt Meurer <[email protected]>
Commit-Queue: Simon Zünd <[email protected]>
diff --git a/front_end/models/bindings/FileUtils.ts b/front_end/models/bindings/FileUtils.ts
index a6a55b5..8536f0a 100644
--- a/front_end/models/bindings/FileUtils.ts
+++ b/front_end/models/bindings/FileUtils.ts
@@ -30,6 +30,7 @@
import type * as Common from '../../core/common/common.js';
import type * as Platform from '../../core/platform/platform.js';
+import * as TextUtils from '../text_utils/text_utils.js';
import * as Workspace from '../workspace/workspace.js';
export interface ChunkedReader {
@@ -223,8 +224,8 @@
this.#closed = false;
this.#writeCallbacks = [];
this.#fileName = fileName;
- const saveResponse =
- await Workspace.FileManager.FileManager.instance().save(this.#fileName, '', true, false /* isBase64 */);
+ const saveResponse = await Workspace.FileManager.FileManager.instance().save(
+ this.#fileName, TextUtils.ContentData.EMPTY_TEXT_CONTENT_DATA, /* forceSaveAs=*/ true);
if (saveResponse) {
Workspace.FileManager.FileManager.instance().addEventListener(
Workspace.FileManager.Events.APPENDED_TO_URL, this.onAppendDone, this);
diff --git a/front_end/models/persistence/PersistenceAction.test.ts b/front_end/models/persistence/PersistenceAction.test.ts
index 4b33f53..9dab33e 100644
--- a/front_end/models/persistence/PersistenceAction.test.ts
+++ b/front_end/models/persistence/PersistenceAction.test.ts
@@ -32,13 +32,13 @@
sinon.stub(event, 'target').value(document);
const contextMenu = new UI.ContextMenu.ContextMenu(event);
const menuProvider = new Persistence.PersistenceActions.ContextMenuProvider();
+ const contentData = new TextUtils.ContentData.ContentData('AGFzbQEAAAA=', true, 'image/webp');
const contentProvider: TextUtils.ContentProvider.ContentProvider = {
contentURL: () => urlString`https://example.com/sample.webp`,
contentType: () => Common.ResourceType.resourceTypes
.Document, // Navigating a tab to an image will result in a document type for images.
- requestContent: () => Promise.resolve({isEncoded: true, content: 'AGFzbQEAAAA='}),
- requestContentData: () =>
- Promise.resolve(new TextUtils.ContentData.ContentData('AGFzbQEAAAA=', true, 'image/webp')),
+ requestContent: () => Promise.resolve({isEncoded: true, content: contentData.base64}),
+ requestContentData: () => Promise.resolve(contentData),
searchInContent: () => assert.fail('Not implemented'),
};
@@ -51,7 +51,9 @@
contextMenu.invokeHandler(saveItem.id());
assert.deepEqual(await expectCall(saveStub), [
- urlString`https://example.com/sample.webp`, 'AGFzbQEAAAA=', true /* forceSaveAs */, true, /* isBase64 */
+ urlString`https://example.com/sample.webp`,
+ contentData,
+ /* forceSaveAs=*/ true,
]);
});
@@ -83,8 +85,10 @@
contextMenu.invokeHandler(saveItem.id());
- assert.deepEqual(await expectCall(saveStub), [
- urlString`https://example.com/sample.wasm`, 'AQIDBA==', true /* forceSaveAs */, true, /* isBase64 */
- ]);
+ const args = await expectCall(saveStub);
+ assert.lengthOf(args, 3);
+ assert.strictEqual(args[0], urlString`https://example.com/sample.wasm`);
+ assert.strictEqual(args[1].base64, 'AQIDBA==');
+ assert.isTrue(args[2]);
});
});
diff --git a/front_end/models/persistence/PersistenceActions.ts b/front_end/models/persistence/PersistenceActions.ts
index 390e900..bde8512 100644
--- a/front_end/models/persistence/PersistenceActions.ts
+++ b/front_end/models/persistence/PersistenceActions.ts
@@ -9,7 +9,7 @@
import * as SDK from '../../core/sdk/sdk.js';
import * as UI from '../../ui/legacy/legacy.js';
import * as Bindings from '../bindings/bindings.js';
-import type * as TextUtils from '../text_utils/text_utils.js';
+import * as TextUtils from '../text_utils/text_utils.js';
import * as Workspace from '../workspace/workspace.js';
import {NetworkPersistenceManager} from './NetworkPersistenceManager.js';
@@ -48,6 +48,11 @@
overrideSourceMappedFileExplanation: '‘{PH1}’ is a source mapped file and cannot be overridden.',
/**
* @description An error message shown in the DevTools console after the user clicked "Save as" in
+ * the context menu of a page resource.
+ */
+ saveFailed: 'Failed to save file to disk.',
+ /**
+ * @description An error message shown in the DevTools console after the user clicked "Save as" in
* the context menu of a WebAssembly file.
*/
saveWasmFailed: 'Unable to save WASM module to disk. Most likely the module is too large.',
@@ -66,22 +71,27 @@
(contentProvider).commitWorkingCopy();
}
const url = contentProvider.contentURL();
- let content: TextUtils.ContentProvider.DeferredContent;
+ let contentData: TextUtils.ContentData.ContentData;
const maybeScript = getScript(contentProvider);
if (maybeScript?.isWasm()) {
try {
- const byteCode = await maybeScript.getWasmBytecode();
- const base64 = await Common.Base64.encode(byteCode);
- content = {isEncoded: true, content: base64};
+ const base64 = await maybeScript.getWasmBytecode().then(Common.Base64.encode);
+ contentData = new TextUtils.ContentData.ContentData(base64, /* isBase64=*/ true, 'application/wasm');
} catch (e) {
console.error(`Unable to convert WASM byte code for ${url} to base64. Not saving to disk`, e.stack);
Common.Console.Console.instance().error(i18nString(UIStrings.saveWasmFailed), /* show=*/ false);
return;
}
} else {
- content = await contentProvider.requestContent();
+ const contentDataOrError = await contentProvider.requestContentData();
+ if (TextUtils.ContentData.ContentData.isError(contentDataOrError)) {
+ console.error(`Failed to retrieve content for ${url}: ${contentDataOrError}`);
+ Common.Console.Console.instance().error(i18nString(UIStrings.saveFailed), /* show=*/ false);
+ return;
+ }
+ contentData = contentDataOrError;
}
- await Workspace.FileManager.FileManager.instance().save(url, content.content ?? '', true, content.isEncoded);
+ await Workspace.FileManager.FileManager.instance().save(url, contentData, /* forceSaveAs=*/ true);
Workspace.FileManager.FileManager.instance().close(url);
}
diff --git a/front_end/models/workspace/FileManager.ts b/front_end/models/workspace/FileManager.ts
index 5333f95..f09bcc6 100644
--- a/front_end/models/workspace/FileManager.ts
+++ b/front_end/models/workspace/FileManager.ts
@@ -31,6 +31,7 @@
import * as Common from '../../core/common/common.js';
import * as Host from '../../core/host/host.js';
import type * as Platform from '../../core/platform/platform.js';
+import type * as TextUtils from '../text_utils/text_utils.js';
let fileManagerInstance: FileManager|null;
@@ -65,13 +66,14 @@
*/
save(
url: Platform.DevToolsPath.RawPathString|Platform.DevToolsPath.UrlString,
- content: string,
+ contentData: TextUtils.ContentData.ContentData,
forceSaveAs: boolean,
- isBase64: boolean,
): Promise<SaveCallbackParam|null> {
// Remove this url from the saved URLs while it is being saved.
const result = new Promise<SaveCallbackParam|null>(resolve => this.#saveCallbacks.set(url, resolve));
- Host.InspectorFrontendHost.InspectorFrontendHostInstance.save(url, content, forceSaveAs, isBase64);
+ const {isTextContent} = contentData;
+ const content = isTextContent ? contentData.text : contentData.base64;
+ Host.InspectorFrontendHost.InspectorFrontendHostInstance.save(url, content, forceSaveAs, !isTextContent);
return result;
}