From cfffcad1b8f658eef5d1103c1782f5c3ba3e0c9b Mon Sep 17 00:00:00 2001 From: Peng Xiao Date: Mon, 6 Nov 2023 18:09:48 +0800 Subject: [PATCH] fix(core): adapt blob in sqlite for svg type (#4845) --- packages/frontend/workspace/package.json | 1 + .../workspace/src/blob/cloud-blob-storage.ts | 1 + .../workspace/src/blob/sqlite-blob-storage.ts | 11 +++++++++- packages/frontend/workspace/src/blob/util.ts | 9 ++++++++ yarn.lock | 21 +++++++++++++++++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 packages/frontend/workspace/src/blob/util.ts diff --git a/packages/frontend/workspace/package.json b/packages/frontend/workspace/package.json index c56e643cbc..3784720435 100644 --- a/packages/frontend/workspace/package.json +++ b/packages/frontend/workspace/package.json @@ -23,6 +23,7 @@ "@toeverything/hooks": "workspace:*", "@toeverything/y-indexeddb": "workspace:*", "async-call-rpc": "^6.3.1", + "is-svg": "^5.0.0", "jotai": "^2.4.3", "js-base64": "^3.7.5", "ky": "^1.0.1", diff --git a/packages/frontend/workspace/src/blob/cloud-blob-storage.ts b/packages/frontend/workspace/src/blob/cloud-blob-storage.ts index d44dd8ec00..44ef6c05db 100644 --- a/packages/frontend/workspace/src/blob/cloud-blob-storage.ts +++ b/packages/frontend/workspace/src/blob/cloud-blob-storage.ts @@ -24,6 +24,7 @@ export const createCloudBlobStorage = (workspaceId: string): BlobStorage => { // status not in the range 200-299 return null; } + // todo: shall we add svg type here if it is missing? return res.blob(); }); }, diff --git a/packages/frontend/workspace/src/blob/sqlite-blob-storage.ts b/packages/frontend/workspace/src/blob/sqlite-blob-storage.ts index 47c60e79bb..fafe15995c 100644 --- a/packages/frontend/workspace/src/blob/sqlite-blob-storage.ts +++ b/packages/frontend/workspace/src/blob/sqlite-blob-storage.ts @@ -1,6 +1,8 @@ import { assertExists } from '@blocksuite/global/utils'; import type { BlobStorage } from '@blocksuite/store'; +import { isSvgBuffer } from './util'; + export const createSQLiteStorage = (workspaceId: string): BlobStorage => { const apis = window.apis; assertExists(apis); @@ -8,7 +10,14 @@ export const createSQLiteStorage = (workspaceId: string): BlobStorage => { crud: { get: async (key: string) => { const buffer = await apis.db.getBlob(workspaceId, key); - return buffer ? new Blob([buffer]) : null; + if (buffer) { + const isSVG = isSvgBuffer(buffer); + // for svg blob, we need to explicitly set the type to image/svg+xml + return isSVG + ? new Blob([buffer], { type: 'image/svg+xml' }) + : new Blob([buffer]); + } + return null; }, set: async (key: string, value: Blob) => { await apis.db.addBlob( diff --git a/packages/frontend/workspace/src/blob/util.ts b/packages/frontend/workspace/src/blob/util.ts new file mode 100644 index 0000000000..2ad3400803 --- /dev/null +++ b/packages/frontend/workspace/src/blob/util.ts @@ -0,0 +1,9 @@ +import isSvg from 'is-svg'; + +// this has a overhead of converting to string for testing if it is svg. +// is there a more performant way? +export function isSvgBuffer(buffer: Uint8Array) { + const decoder = new TextDecoder('utf-8'); + const str = decoder.decode(buffer); + return isSvg(str); +} diff --git a/yarn.lock b/yarn.lock index 188e05c365..44436bc1af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -864,6 +864,7 @@ __metadata: "@types/ws": "npm:^8.5.7" async-call-rpc: "npm:^6.3.1" fake-indexeddb: "npm:^5.0.0" + is-svg: "npm:^5.0.0" jotai: "npm:^2.4.3" js-base64: "npm:^3.7.5" ky: "npm:^1.0.1" @@ -20626,6 +20627,17 @@ __metadata: languageName: node linkType: hard +"fast-xml-parser@npm:^4.1.3": + version: 4.3.2 + resolution: "fast-xml-parser@npm:4.3.2" + dependencies: + strnum: "npm:^1.0.5" + bin: + fxparser: src/cli/cli.js + checksum: cb3d9ad7d5508e7ec1e6ee4b4753f659c7b7c93c3eb76439cb03072532d07521d53a7e35f243b490dce3fcc16519415bf1f99c6a1004a6de1dccd3d3647c336f + languageName: node + linkType: hard + "fastest-levenshtein@npm:^1.0.12": version: 1.0.16 resolution: "fastest-levenshtein@npm:1.0.16" @@ -23429,6 +23441,15 @@ __metadata: languageName: node linkType: hard +"is-svg@npm:^5.0.0": + version: 5.0.0 + resolution: "is-svg@npm:5.0.0" + dependencies: + fast-xml-parser: "npm:^4.1.3" + checksum: cd3b0810a005440613e9e7752b3ca4639760fbfb0d79af5275b9639670526dd05c501c89edc63ce16c6ff4d568348485db4299f4bae1131cbd260fce6943abea + languageName: node + linkType: hard + "is-text-path@npm:^1.0.1": version: 1.0.1 resolution: "is-text-path@npm:1.0.1"