This is an automated email from the ASF dual-hosted git repository.
wangzx pushed a commit to branch gh-pages
in repository https://gitbox.apache.org/repos/asf/echarts-examples.git
The following commit(s) were added to refs/heads/gh-pages by this push:
new b8b00b39 feat: use deflate to compress code string by default
b8b00b39 is described below
commit b8b00b39e68eb9a9dc32e75660035793f7bb6a72
Author: plainheart <[email protected]>
AuthorDate: Mon Nov 10 22:57:26 2025 +0800
feat: use deflate to compress code string by default
---
package-lock.json | 90 ++++++-------
package.json | 7 +-
src/common/helper.js | 45 ++++++-
src/common/store.js | 18 ++-
src/dep/uint8array-polyfill.js | 283 +++++++++++++++++++++++++++++++++++++++++
src/editor/Preview.vue | 7 +-
6 files changed, 387 insertions(+), 63 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 635fc1ea..ec57685f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,13 +12,14 @@
"@lang/object-visualizer": "^4.2.0",
"codesandbox": "^2.2.3",
"compare-versions": "^6.1.1",
+ "fflate": "^0.8.2",
"lodash": "^4.17.21",
"lz-string": "^1.5.0",
- "nanoid": "^5.0.9",
+ "nanoid": "^5.1.6",
"prettier": "^2.7.1",
"resize-detector": "^0.3.0",
- "rimraf": "^6.0.1",
- "semver": "^7.6.2",
+ "rimraf": "^6.1.0",
+ "semver": "^7.7.3",
"sucrase": "^3.35.0",
"vanilla-lazyload": "^17.8.3",
"vue-i18n": "^8.18.2",
@@ -101,6 +102,7 @@
"version": "7.11.1",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.10.4",
"@babel/generator": "^7.11.0",
@@ -2119,6 +2121,7 @@
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.12.0.tgz",
"integrity":
"sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==",
"dev": true,
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2167,6 +2170,7 @@
"version": "6.12.6",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
@@ -2909,6 +2913,7 @@
"url": "https://github.com/sponsors/ai"
}
],
+ "peer": true,
"dependencies": {
"caniuse-lite": "^1.0.30001629",
"electron-to-chromium": "^1.4.796",
@@ -3054,26 +3059,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/caniuse-lite": {
- "version": "1.0.30001636",
- "resolved":
"https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz",
- "integrity":
"sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ]
- },
"node_modules/capture-stack-trace": {
"version": "1.0.1",
"license": "MIT",
@@ -4295,7 +4280,8 @@
"resolved":
"https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1464554.tgz",
"integrity":
"sha512-CAoP3lYfwAGQTaAXYvA6JZR0fjGUb7qec1qf4mToyoH2TZgUFeIqYcjh6f9jNuhHfuZiEdH+PONHYrLhRQX6aw==",
"dev": true,
- "license": "BSD-3-Clause"
+ "license": "BSD-3-Clause",
+ "peer": true
},
"node_modules/dir-glob": {
"version": "3.0.1",
@@ -5173,6 +5159,12 @@
"pend": "~1.2.0"
}
},
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity":
"sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "license": "MIT"
+ },
"node_modules/file-loader": {
"version": "6.2.0",
"dev": true,
@@ -7231,15 +7223,16 @@
}
},
"node_modules/nanoid": {
- "version": "5.0.9",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.0.9.tgz",
- "integrity":
"sha512-Aooyr6MXU6HpvvWXKoVoXwKMs/KyVakWwg7xQfv5/S/RIgJMy0Ifa45H9qqYy7pTCszrHzP21Uk4PZq2HpEM8Q==",
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-5.1.6.tgz",
+ "integrity":
"sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
+ "license": "MIT",
"bin": {
"nanoid": "bin/nanoid.js"
},
@@ -7248,10 +7241,11 @@
}
},
"node_modules/napi-build-utils": {
- "version": "1.0.2",
- "resolved":
"https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity":
"sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
- "dev": true
+ "version": "2.0.0",
+ "resolved":
"https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+ "integrity":
"sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/neo-async": {
"version": "2.6.2",
@@ -8348,17 +8342,18 @@
}
},
"node_modules/prebuild-install": {
- "version": "7.1.1",
- "resolved":
"https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity":
"sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+ "version": "7.1.3",
+ "resolved":
"https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+ "integrity":
"sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
+ "napi-build-utils": "^2.0.0",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
@@ -9119,12 +9114,13 @@
}
},
"node_modules/rimraf": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
- "integrity":
"sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.1.0.tgz",
+ "integrity":
"sha512-DxdlA1bdNzkZK7JiNWH+BAx1x4tEJWoTofIopFo6qWUU94jYrFZ0ubY05TqH3nWPJ1nKa1JWVFDINZ3fnrle/A==",
+ "license": "BlueOak-1.0.0",
"dependencies": {
- "glob": "^11.0.0",
- "package-json-from-dist": "^1.0.0"
+ "glob": "^11.0.3",
+ "package-json-from-dist": "^1.0.1"
},
"bin": {
"rimraf": "dist/esm/bin.mjs"
@@ -9315,9 +9311,9 @@
}
},
"node_modules/semver": {
- "version": "7.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
- "integrity":
"sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
+ "version": "7.7.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
+ "integrity":
"sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -10352,6 +10348,7 @@
"version": "4.1.3",
"dev": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -10657,7 +10654,8 @@
},
"node_modules/vue": {
"version": "2.6.14",
- "license": "MIT"
+ "license": "MIT",
+ "peer": true
},
"node_modules/vue-hot-reload-api": {
"version": "2.3.4",
@@ -10749,6 +10747,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz",
"integrity":
"sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==",
"dev": true,
+ "peer": true,
"dependencies": {
"@types/estree": "^1.0.5",
"@webassemblyjs/ast": "^1.12.1",
@@ -10888,6 +10887,7 @@
"version": "4.3.1",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/info": "^1.2.1",
@@ -11344,4 +11344,4 @@
"license": "0BSD"
}
}
-}
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 45e96242..2f708ea0 100644
--- a/package.json
+++ b/package.json
@@ -69,13 +69,14 @@
"@lang/object-visualizer": "^4.2.0",
"codesandbox": "^2.2.3",
"compare-versions": "^6.1.1",
+ "fflate": "^0.8.2",
"lodash": "^4.17.21",
"lz-string": "^1.5.0",
- "nanoid": "^5.0.9",
+ "nanoid": "^5.1.6",
"prettier": "^2.7.1",
"resize-detector": "^0.3.0",
- "rimraf": "^6.0.1",
- "semver": "^7.6.2",
+ "rimraf": "^6.1.0",
+ "semver": "^7.7.3",
"sucrase": "^3.35.0",
"vanilla-lazyload": "^17.8.3",
"vue-i18n": "^8.18.2",
diff --git a/src/common/helper.js b/src/common/helper.js
index ea7d3f01..b72d8925 100644
--- a/src/common/helper.js
+++ b/src/common/helper.js
@@ -1,6 +1,11 @@
import { store } from './store';
import { getScriptURLs } from './config';
-import { compressToBase64, decompressFromBase64 } from 'lz-string';
+import * as lz from 'lz-string';
+import * as fflate from 'fflate';
+import {
+ uint8ArrayToBase64,
+ base64ToUint8Array
+} from '../dep/uint8array-polyfill';
const promisesCache = {};
@@ -94,27 +99,57 @@ export function formatCode(code) {
});
}
-export function compressStr(str) {
+export function compressStrLZString(str) {
if (!str || !(str = str.trim())) {
return;
}
- return compressToBase64(str)
+ return lz
+ .compressToBase64(str)
.replace(/\+/g, '-') // Convert '+' to '-'
.replace(/\//g, '_') // Convert '/' to '_'
.replace(/=+$/, ''); // Remove ending '='
}
-export function decompressStr(str) {
+export function decompressStrLZString(str) {
if (!str || !(str = str.trim())) {
return;
}
- return decompressFromBase64(
+ return lz.decompressFromBase64(
str
.replace(/\-/g, '+') // Convert '-' to '+'
.replace(/_/g, '/') // Convert '_' to '/'
);
}
+export function compressStrDeflate(str) {
+ if (!str || !(str = str.trim())) {
+ return Promise.resolve();
+ }
+ const uint8Array = fflate.deflateSync(fflate.strToU8(str), {
+ level: 9,
+ mem: 12
+ });
+ return uint8Array.toBase64
+ ? uint8Array.toBase64({
+ alphabet: 'base64url',
+ omitPadding: true
+ })
+ : uint8ArrayToBase64(uint8Array, {
+ alphabet: 'base64url',
+ omitPadding: true
+ });
+}
+
+export function decompressStrDeflate(str) {
+ if (!str || !(str = str.trim())) {
+ return Promise.resolve();
+ }
+ const uint8Array = Uint8Array.fromBase64
+ ? Uint8Array.fromBase64(str, { alphabet: 'base64url' })
+ : base64ToUint8Array(str, { alphabet: 'base64url' }).bytes;
+ return fflate.strFromU8(fflate.inflateSync(uint8Array));
+}
+
export function isTrustedOpener() {
try {
return (
diff --git a/src/common/store.js b/src/common/store.js
index c9088265..f596a7d0 100644
--- a/src/common/store.js
+++ b/src/common/store.js
@@ -3,8 +3,9 @@ import { CDN_ROOT, URL_PARAMS } from '../common/config';
import CHART_LIST from '../data/chart-list-data';
import CHART_LIST_GL from '../data/chart-list-data-gl';
import {
- compressStr,
- decompressStr,
+ compressStrDeflate,
+ decompressStrDeflate,
+ decompressStrLZString,
decodeBase64,
isTrustedOpener
} from './helper';
@@ -95,7 +96,7 @@ export const CODE_CHANGED_FLAG = '__CODE_CHANGED__';
export function saveExampleCodeToLocal() {
localStorage.setItem(
LOCAL_EXAMPLE_CODE_STORE_KEY,
- compressStr(
+ compressStrDeflate(
JSON.stringify({
code: store.sourceCode,
codeModified: store.initialCode !== store.sourceCode,
@@ -108,7 +109,7 @@ export function saveExampleCodeToLocal() {
export function loadExampleCodeFromLocal() {
try {
return JSON.parse(
- decompressStr(localStorage.getItem(LOCAL_EXAMPLE_CODE_STORE_KEY))
+ decompressStrDeflate(localStorage.getItem(LOCAL_EXAMPLE_CODE_STORE_KEY))
);
} catch (e) {
return null;
@@ -137,9 +138,12 @@ export function loadExampleCode() {
// PENDING fallback to `c` if the decompressed code is not available?
// TODO: auto-detect the encoder type?
code =
- URL_PARAMS.enc === 'base64'
- ? decodeBase64(code)
- : decompressStr(code);
+ URL_PARAMS.enc === 'deflate'
+ ? decompressStrDeflate(code)
+ ? URL_PARAMS.enc === 'base64'
+ : decodeBase64(code)
+ : // for backward compatibility
+ decompressStrLZString(code);
// not considered as shared code if it's opened by echarts website
like echarts-doc
store.isSharedCode = !isTrustedOpener() && !!code;
// clear the opener
diff --git a/src/dep/uint8array-polyfill.js b/src/dep/uint8array-polyfill.js
new file mode 100644
index 00000000..6e3e890e
--- /dev/null
+++ b/src/dep/uint8array-polyfill.js
@@ -0,0 +1,283 @@
+// Source from
https://github.com/tc39/proposal-arraybuffer-base64/blob/main/playground/polyfill-core.mjs
+
+let base64Characters =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+let base64UrlCharacters =
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
+
+let tag = Object.getOwnPropertyDescriptor(
+ Object.getPrototypeOf(Uint8Array.prototype),
+ Symbol.toStringTag
+).get;
+function checkUint8Array(arg) {
+ let kind;
+ try {
+ kind = tag.call(arg);
+ } catch {
+ throw new TypeError('not a Uint8Array');
+ }
+ if (kind !== 'Uint8Array') {
+ throw new TypeError('not a Uint8Array');
+ }
+}
+
+function assert(condition, message) {
+ if (!condition) {
+ throw new Error(`Assert failed: ${message}`);
+ }
+}
+
+function getOptions(options) {
+ if (typeof options === 'undefined') {
+ return Object.create(null);
+ }
+ if (options && typeof options === 'object') {
+ return options;
+ }
+ throw new TypeError('options is not object');
+}
+
+export function uint8ArrayToBase64(arr, options) {
+ checkUint8Array(arr);
+ let opts = getOptions(options);
+ let alphabet = opts.alphabet;
+ if (typeof alphabet === 'undefined') {
+ alphabet = 'base64';
+ }
+ if (alphabet !== 'base64' && alphabet !== 'base64url') {
+ throw new TypeError(
+ 'expected alphabet to be either "base64" or "base64url"'
+ );
+ }
+ let omitPadding = !!opts.omitPadding;
+
+ if ('detached' in arr.buffer && arr.buffer.detached) {
+ throw new TypeError('toBase64 called on array backed by detached buffer');
+ }
+
+ let lookup = alphabet === 'base64' ? base64Characters : base64UrlCharacters;
+ let result = '';
+
+ let i = 0;
+ for (; i + 2 < arr.length; i += 3) {
+ let triplet = (arr[i] << 16) + (arr[i + 1] << 8) + arr[i + 2];
+ result +=
+ lookup[(triplet >> 18) & 63] +
+ lookup[(triplet >> 12) & 63] +
+ lookup[(triplet >> 6) & 63] +
+ lookup[triplet & 63];
+ }
+ if (i + 2 === arr.length) {
+ let triplet = (arr[i] << 16) + (arr[i + 1] << 8);
+ result +=
+ lookup[(triplet >> 18) & 63] +
+ lookup[(triplet >> 12) & 63] +
+ lookup[(triplet >> 6) & 63] +
+ (omitPadding ? '' : '=');
+ } else if (i + 1 === arr.length) {
+ let triplet = arr[i] << 16;
+ result +=
+ lookup[(triplet >> 18) & 63] +
+ lookup[(triplet >> 12) & 63] +
+ (omitPadding ? '' : '==');
+ }
+ return result;
+}
+
+function decodeBase64Chunk(chunk, throwOnExtraBits) {
+ let actualChunkLength = chunk.length;
+ if (actualChunkLength < 4) {
+ chunk += actualChunkLength === 2 ? 'AA' : 'A';
+ }
+
+ let map = new Map(base64Characters.split('').map((c, i) => [c, i]));
+
+ let c1 = chunk[0];
+ let c2 = chunk[1];
+ let c3 = chunk[2];
+ let c4 = chunk[3];
+
+ let triplet =
+ (map.get(c1) << 18) +
+ (map.get(c2) << 12) +
+ (map.get(c3) << 6) +
+ map.get(c4);
+
+ let chunkBytes = [(triplet >> 16) & 255, (triplet >> 8) & 255, triplet &
255];
+
+ if (actualChunkLength === 2) {
+ if (throwOnExtraBits && chunkBytes[1] !== 0) {
+ throw new SyntaxError('extra bits');
+ }
+ return [chunkBytes[0]];
+ } else if (actualChunkLength === 3) {
+ if (throwOnExtraBits && chunkBytes[2] !== 0) {
+ throw new SyntaxError('extra bits');
+ }
+ return [chunkBytes[0], chunkBytes[1]];
+ }
+ return chunkBytes;
+}
+
+function skipAsciiWhitespace(string, index) {
+ for (; index < string.length; ++index) {
+ if (!/[\u0009\u000A\u000C\u000D\u0020]/.test(string[index])) {
+ break;
+ }
+ }
+ return index;
+}
+
+function fromBase64(string, alphabet, lastChunkHandling, maxLength) {
+ debugger;
+ if (maxLength === 0) {
+ return { read: 0, bytes: [], error: null };
+ }
+
+ let read = 0;
+ let bytes = [];
+ let chunk = '';
+
+ let index = 0;
+ while (true) {
+ index = skipAsciiWhitespace(string, index);
+ if (index === string.length) {
+ if (chunk.length > 0) {
+ if (lastChunkHandling === 'stop-before-partial') {
+ return { bytes, read, error: null };
+ } else if (lastChunkHandling === 'loose') {
+ if (chunk.length === 1) {
+ let error = new SyntaxError(
+ 'malformed padding: exactly one additional character'
+ );
+ return { bytes, read, error };
+ }
+ bytes.push(...decodeBase64Chunk(chunk, false));
+ } else {
+ assert(lastChunkHandling === 'strict');
+ let error = new SyntaxError('missing padding');
+ return { bytes, read, error };
+ }
+ }
+ return { bytes, read: string.length, error: null };
+ }
+ let char = string[index];
+ ++index;
+ if (char === '=') {
+ if (chunk.length < 2) {
+ let error = new SyntaxError('padding is too early');
+ return { bytes, read, error };
+ }
+ index = skipAsciiWhitespace(string, index);
+ if (chunk.length === 2) {
+ if (index === string.length) {
+ if (lastChunkHandling === 'stop-before-partial') {
+ // two characters then `=` then EOS: this is, technically, a
partial chunk
+ return { bytes, read, error: null };
+ }
+ let error = new SyntaxError('malformed padding - only one =');
+ return { bytes, read, error };
+ }
+ if (string[index] === '=') {
+ ++index;
+ index = skipAsciiWhitespace(string, index);
+ }
+ }
+ if (index < string.length) {
+ let error = new SyntaxError('unexpected character after padding');
+ return { bytes, read, error };
+ }
+ bytes.push(...decodeBase64Chunk(chunk, lastChunkHandling === 'strict'));
+ assert(bytes.length <= maxLength);
+ return { bytes, read: string.length, error: null };
+ }
+ if (alphabet === 'base64url') {
+ if (char === '+' || char === '/') {
+ let error = new SyntaxError(
+ `unexpected character ${JSON.stringify(char)}`
+ );
+ return { bytes, read, error };
+ } else if (char === '-') {
+ char = '+';
+ } else if (char === '_') {
+ char = '/';
+ }
+ }
+ if (!base64Characters.includes(char)) {
+ let error = new SyntaxError(
+ `unexpected character ${JSON.stringify(char)}`
+ );
+ return { bytes, read, error };
+ }
+ let remainingBytes = maxLength - bytes.length;
+ if (
+ (remainingBytes === 1 && chunk.length === 2) ||
+ (remainingBytes === 2 && chunk.length === 3)
+ ) {
+ // special case: we can fit exactly the number of bytes currently
represented by chunk, so we were just checking for `=`
+ return { bytes, read, error: null };
+ }
+
+ chunk += char;
+ if (chunk.length === 4) {
+ bytes.push(...decodeBase64Chunk(chunk, false));
+ chunk = '';
+ read = index;
+ assert(bytes.length <= maxLength);
+ if (bytes.length === maxLength) {
+ return { bytes, read, error: null };
+ }
+ }
+ }
+}
+
+export const base64ToUint8Array = function (string, options, into) {
+ let opts = getOptions(options);
+ let alphabet = opts.alphabet;
+ if (typeof alphabet === 'undefined') {
+ alphabet = 'base64';
+ }
+ if (alphabet !== 'base64' && alphabet !== 'base64url') {
+ throw new TypeError(
+ 'expected alphabet to be either "base64" or "base64url"'
+ );
+ }
+ let lastChunkHandling = opts.lastChunkHandling;
+ if (typeof lastChunkHandling === 'undefined') {
+ lastChunkHandling = 'loose';
+ }
+ if (!['loose', 'strict', 'stop-before-partial'].includes(lastChunkHandling))
{
+ throw new TypeError(
+ 'expected lastChunkHandling to be either "loose", "strict", or
"stop-before-partial"'
+ );
+ }
+ if (into && 'detached' in into.buffer && into.buffer.detached) {
+ throw new TypeError(
+ 'toBase64Into called on array backed by detached buffer'
+ );
+ }
+
+ let maxLength = into ? into.length : 2 ** 53 - 1;
+
+ let { bytes, read, error } = fromBase64(
+ string,
+ alphabet,
+ lastChunkHandling,
+ maxLength
+ );
+ if (error && !into) {
+ throw error;
+ }
+
+ bytes = new Uint8Array(bytes);
+ if (into && bytes.length > 0) {
+ assert(bytes.length <= into.length);
+ into.set(bytes);
+ }
+
+ if (error) {
+ throw error;
+ }
+
+ return { read, bytes };
+};
diff --git a/src/editor/Preview.vue b/src/editor/Preview.vue
index 6fd8175b..9373b86c 100644
--- a/src/editor/Preview.vue
+++ b/src/editor/Preview.vue
@@ -155,7 +155,7 @@ import {
isValidPRVersion
} from '../common/store';
import { getScriptURLs, URL_PARAMS } from '../common/config';
-import { compressStr } from '../common/helper';
+import { compressStrDeflate } from '../common/helper';
import { createSandbox } from './sandbox';
import debounce from 'lodash/debounce';
import { download } from './downloadExample';
@@ -499,8 +499,9 @@ export default {
getSharableURL(raw) {
const params = {};
if (store.initialCode !== store.sourceCode) {
- params.code = compressStr(store.sourceCode);
- params.enc = null;
+ params.code = compressStrDeflate(store.sourceCode);
+ // explicitly mark as deflate encoded for backward compatibility
+ params.enc = 'deflate';
}
return getURL(
{
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]