From d3d7edd144f42947b04c169294f9732bc869cc4b Mon Sep 17 00:00:00 2001 From: Maiz Date: Mon, 18 Jul 2022 20:29:48 +0800 Subject: [PATCH 01/18] fix(Log): Fix `window.onerror` missing line breaks. --- CHANGELOG.md | 5 +++++ CHANGELOG_CN.md | 5 +++++ package.json | 2 +- src/log/default.ts | 11 ++++++----- src/log/logValue.svelte | 2 +- 5 files changed, 18 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffe748b8..833e840d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ English | [简体中文](./CHANGELOG_CN.md) +## 3.14.7 (2022-07-??) + +- `Fix(Log)` Fix `window.onerror` missing line breaks. + + ## 3.14.6 (2022-04-14) - `Fix(Log)` Fix logs lost tracking when adding a new vConsole after destroying the old one. diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 5d0299a5..011f19d5 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -1,5 +1,10 @@ [English](./CHANGELOG.md) | 简体中文 +## 3.14.7 (2022-07-??) + +- `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 + + ## 3.14.6 (2022-04-14) - `Fix(Log)` 修复当销毁后再次初始化 vConsole 时失去追踪 logs 的问题。 diff --git a/package.json b/package.json index cefb417a..e62a1fa9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vconsole", - "version": "3.14.6", + "version": "3.14.7-rc", "description": "A lightweight, extendable front-end developer tool for mobile web page.", "homepage": "https://github.com/Tencent/vConsole", "files": [ diff --git a/src/log/default.ts b/src/log/default.ts index 538f8be0..e025fe3b 100644 --- a/src/log/default.ts +++ b/src/log/default.ts @@ -48,17 +48,18 @@ export class VConsoleDefaultPlugin extends VConsoleLogPlugin { this.onErrorHandler = this.onErrorHandler ? this.onErrorHandler : (event) => { let msg = event.message; if (event.filename) { - msg += '\n' + event.filename.replace(location.origin, ''); - } - if (event.lineno || event.colno) { - msg += ':' + event.lineno + ':' + event.colno; + msg += '\\n\\t' + event.filename.replace(location.origin, ''); + if (event.lineno || event.colno) { + msg += ':' + event.lineno + ':' + event.colno; + } } // print error stack info const hasStack = !!event.error && !!event.error.stack; const stackInfo = (hasStack && event.error.stack.toString()) || ''; + msg += '\\n' + stackInfo; this.model.addLog({ type: 'error', - origData: [msg, stackInfo], + origData: [msg], }, { noOrig: true }); }; window.removeEventListener('error', this.onErrorHandler); diff --git a/src/log/logValue.svelte b/src/log/logValue.svelte index e9ae6cb0..cde138c7 100644 --- a/src/log/logValue.svelte +++ b/src/log/logValue.svelte @@ -25,7 +25,7 @@ if (!isInTree && valueType === 'string') { // convert string - dataValue = tool.htmlEncode(dataValue.replace('\\n', '\n').replace('\\t', '\t')); + dataValue = tool.htmlEncode(dataValue.replaceAll('\\n', '\n').replaceAll('\\t', ' ')); } // (window as any)._vcOrigConsole.log('logValue update', origData); From 59b8c087b14677604558d13b58e9e00bd5891ac2 Mon Sep 17 00:00:00 2001 From: Maiz Date: Wed, 20 Jul 2022 19:30:21 +0800 Subject: [PATCH 02/18] docs: update pattern usage. (issue #549) --- doc/tutorial.md | 4 ++-- doc/tutorial_CN.md | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/tutorial.md b/doc/tutorial.md index 4ea27731..d86c6aae 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -127,13 +127,13 @@ console.log('%c FOO', 'font-weight:bold', 'bar'); // FOO bar console.log('%c Foo %c bar', 'color:red'); // Foo %c bar ``` -> Note that only first parameter support `%c` format, and the following parameter(s) will be used as HTML style to fill `%c`, and the remain `%c` or parameters will be shown as normal string. +> Note that only the first parameter support `%c` format, and the `%c` must be followed by a space. The following parameter(s) will be used as HTML style to fill `%c`, and the remain `%c` or parameters will be shown as normal string. --- ### Using string substitutions -Use `%s, %d, %o` to output log with formatting. +Use `%s, %d, %o` to output a log with formatting. The pattern must be followed by a space. - `%s`: Output as a string. Non-string objects will be converted into strings. - `%d`: Output as a number. diff --git a/doc/tutorial_CN.md b/doc/tutorial_CN.md index 7196ee38..8fdc3a3f 100644 --- a/doc/tutorial_CN.md +++ b/doc/tutorial_CN.md @@ -123,7 +123,7 @@ console.log('%c FOO', 'font-weight:bold', 'bar'); // FOO bar console.log('%c Foo %c bar', 'color:red'); // Foo %c bar ``` -> 只有第一个参数支持 `%c` 格式,一旦出现 `%c` 格式,后续的字符串参数将作为 HTML style 样式来替换 `%c`;未被替换的 `%c`、剩余的参数,将作为默认日志照常输出。 +> 只有第一个参数支持 `%c` 格式,且 `%c` 后必须带空格。一旦出现 `%c` 格式,后续的字符串参数将作为 HTML style 样式来替换 `%c`;未被替换的 `%c`、剩余的参数,将作为默认日志照常输出。 --- @@ -131,7 +131,7 @@ console.log('%c Foo %c bar', 'color:red'); // Foo %c bar ### 使用字符串替换 -可使用 `%s, %d, %o` 来格式化输出。 +可使用 `%s, %d, %o` 来格式化输出,关键字后必须带空格。 - `%s`:输出为字符串。非字符串对象会被转换成字符串。 - `%d`:输出为数字。 From f3aaff59e76d422161ba24e3e4f66c7052f2649f Mon Sep 17 00:00:00 2001 From: Maiz Date: Thu, 21 Jul 2022 17:37:07 +0800 Subject: [PATCH 03/18] refactor: use regular expression instead of replaceAll() --- src/log/logValue.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/log/logValue.svelte b/src/log/logValue.svelte index cde138c7..c77ec9e8 100644 --- a/src/log/logValue.svelte +++ b/src/log/logValue.svelte @@ -25,7 +25,7 @@ if (!isInTree && valueType === 'string') { // convert string - dataValue = tool.htmlEncode(dataValue.replaceAll('\\n', '\n').replaceAll('\\t', ' ')); + dataValue = tool.htmlEncode(dataValue.replace(/\\n/g, '\n').replace(/\\t/g, ' ')); } // (window as any)._vcOrigConsole.log('logValue update', origData); From 58dfe8d7534a9b2efe50ec12b739761383b28261 Mon Sep 17 00:00:00 2001 From: maniacata Date: Sat, 27 Aug 2022 20:43:28 +0800 Subject: [PATCH 04/18] build: add option to disable `core-js` polyfill Pass env `no-core-js` to replace `core-js` with a dummy module, decreasing the bundle size by 40k+. --- build/dummy.js | 1 + webpack.config.js | 61 +++++++++++++++++++++++++++-------------------- 2 files changed, 36 insertions(+), 26 deletions(-) create mode 100644 build/dummy.js diff --git a/build/dummy.js b/build/dummy.js new file mode 100644 index 00000000..b1c6ea43 --- /dev/null +++ b/build/dummy.js @@ -0,0 +1 @@ +export default {} diff --git a/webpack.config.js b/webpack.config.js index 38b74ed9..f0daba4a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,6 +9,40 @@ const BuildTarget = ['web', 'wx']; module.exports = (env, argv) => { const isDev = argv.mode === 'development'; const __TARGET__ = BuildTarget.indexOf(env.target) === -1 ? BuildTarget[0] : env.target; + const noCoreJS = !!env['no-core-js'] + // define plugins + const plugins = [ + new Webpack.BannerPlugin({ + banner: [ + 'vConsole v' + pkg.version + ' (' + pkg.homepage + ')', + '', + 'Tencent is pleased to support the open source community by making vConsole available.', + 'Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.', + 'Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at', + 'http://opensource.org/licenses/MIT', + 'Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.', + ].join('\n'), + entryOnly: true, + }), + new Webpack.DefinePlugin({ + __VERSION__: JSON.stringify(pkg.version), + __TARGET__: JSON.stringify(__TARGET__), + }), + ]; + if (isDev) { + plugins.push({ + apply: (compiler) => { + compiler.hooks.done.tap('DeclarationEmitter', () => { + execSync('npm run build:typings'); + }); + }, + }) + } + if (noCoreJS) { + const dummyModulePath = Path.resolve(__dirname, './build/dummy.js'); + plugins.push(new Webpack.NormalModuleReplacementPlugin(/^core-js\/.*/, dummyModulePath)); + } + return { mode: argv.mode, devtool: false, @@ -108,31 +142,6 @@ module.exports = (env, argv) => { watchOptions: { ignored: ['**/node_modules'], }, - plugins: [ - new Webpack.BannerPlugin({ - banner: [ - 'vConsole v' + pkg.version + ' (' + pkg.homepage + ')', - '', - 'Tencent is pleased to support the open source community by making vConsole available.', - 'Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.', - 'Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at', - 'http://opensource.org/licenses/MIT', - 'Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.', - ].join('\n'), - entryOnly: true, - }), - new Webpack.DefinePlugin({ - __VERSION__: JSON.stringify(pkg.version), - __TARGET__: JSON.stringify(__TARGET__), - }), - { - apply: (compiler) => { - compiler.hooks.done.tap('DeclarationEmitter', () => { - if (isDev) return; // only emit declarations in prod mode - execSync('npm run build:typings'); - }); - }, - }, - ], + plugins }; }; From 316a3aad55ab755033197a677686040dabde642b Mon Sep 17 00:00:00 2001 From: maniacata Date: Fri, 9 Sep 2022 16:52:58 +0800 Subject: [PATCH 05/18] fix(log): vc-cmd-clear-btn layout on iOS --- src/log/logCommand.less | 9 +++------ src/log/logCommand.svelte | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/log/logCommand.less b/src/log/logCommand.less index a6dca8e9..637dd795 100644 --- a/src/log/logCommand.less +++ b/src/log/logCommand.less @@ -17,7 +17,8 @@ // input or textarea .vc-cmd-input-wrap { - display: block; + display: flex; + align-items: center; position: relative; height: (28em / @font); margin-right: (40em / @font); @@ -52,12 +53,8 @@ font-size: 1em; } .vc-cmd-clear-btn { - position: absolute; + flex: 1 (40em / @font); text-align: center; - top: 0; - right: 0; - bottom: 0; - width: (40em / @font); line-height: (40em / @font); } .vc-cmd-btn:active, diff --git a/src/log/logCommand.svelte b/src/log/logCommand.svelte index 63bbf961..5fb81491 100644 --- a/src/log/logCommand.svelte +++ b/src/log/logCommand.svelte @@ -236,11 +236,6 @@
- {#if cmdValue.length > 0} -
onTapClearText('cmd')}> - -
- {/if} + {#if cmdValue.length > 0} +
onTapClearText('cmd')}> + +
+ {/if}
@@ -258,15 +258,15 @@
    - {#if filterValue.length > 0} -
    onTapClearText('filter')}> - -
    - {/if} + {#if filterValue.length > 0} +
    onTapClearText('filter')}> + +
    + {/if}
    From 01f621a6890abf7b45ce7c07606c684f959c1c04 Mon Sep 17 00:00:00 2001 From: Maiz Date: Tue, 20 Sep 2022 11:15:00 +0800 Subject: [PATCH 06/18] docs: update changelog --- CHANGELOG.md | 4 +++- CHANGELOG_CN.md | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 833e840d..33b02ba6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,10 @@ English | [简体中文](./CHANGELOG_CN.md) -## 3.14.7 (2022-07-??) +## 3.14.7 (2022-09-??) - `Fix(Log)` Fix `window.onerror` missing line breaks. +- `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) +- `Chore` Add option `env['no-core-js']` to disable core-js polyfill. (PR #562) ## 3.14.6 (2022-04-14) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 011f19d5..844f225a 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -1,8 +1,10 @@ [English](./CHANGELOG.md) | 简体中文 -## 3.14.7 (2022-07-??) +## 3.14.7 (2022-09-??) - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 +- `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) +- `Chore` 添加 `env['no-core-js']` 选项来停用构建时使用 core-js polyfill。 (PR #562) ## 3.14.6 (2022-04-14) From b8f810d0d75a19613a89a79386e004a52183d738 Mon Sep 17 00:00:00 2001 From: Maiz Date: Tue, 20 Sep 2022 11:18:53 +0800 Subject: [PATCH 07/18] Fix(Log): Fix a typo that misjudged circular reference objects. (issue #566) --- CHANGELOG.md | 1 + CHANGELOG_CN.md | 1 + src/lib/tool.ts | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 33b02ba6..b6bf5edf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ English | [简体中文](./CHANGELOG_CN.md) - `Fix(Log)` Fix `window.onerror` missing line breaks. - `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) +- `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) - `Chore` Add option `env['no-core-js']` to disable core-js polyfill. (PR #562) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 844f225a..334f81e5 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -4,6 +4,7 @@ - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 - `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) +- `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) - `Chore` 添加 `env['no-core-js']` 选项来停用构建时使用 core-js polyfill。 (PR #562) diff --git a/src/lib/tool.ts b/src/lib/tool.ts index 7396cdc6..ff4ecb1f 100644 --- a/src/lib/tool.ts +++ b/src/lib/tool.ts @@ -229,7 +229,7 @@ const _safeJSONStringify = (obj, opt: ISafeJSONStringifyOption, _curDepth = 0) = if (isCircular) { if (isArray(obj)) { opt.ret += '(Circular Array)'; - } else if (isObject) { + } else if (isObject(obj)) { opt.ret += `(Circular ${obj.constructor?.name || 'Object'})`; } return; From eb83e696ea9a54c0094d6cbd76cd75c09a9c921c Mon Sep 17 00:00:00 2001 From: chyizheng Date: Tue, 20 Sep 2022 17:19:16 +0800 Subject: [PATCH 08/18] feat: optimize addLog performance --- src/log/log.model.ts | 125 +++++++++++++++++++++++++--------------- src/log/logRow.svelte | 3 +- src/log/logTree.svelte | 1 + src/log/logValue.svelte | 1 + 4 files changed, 82 insertions(+), 48 deletions(-) diff --git a/src/log/log.model.ts b/src/log/log.model.ts index b2e1157b..0283b736 100644 --- a/src/log/log.model.ts +++ b/src/log/log.model.ts @@ -56,6 +56,8 @@ export class VConsoleLogModel extends VConsoleModel { public maxLogNumber: number = 1000; protected logCounter: number = 0; // a counter used to do some tasks on a regular basis protected pluginPattern: RegExp; + protected logQueue: IVConsoleLog[] = []; + protected flushLogScheduled: boolean = false; /** * The original `window.console` methods. @@ -113,7 +115,7 @@ export class VConsoleLogModel extends VConsoleModel { /** * Hook `window.console` with vConsole log method. - * Methods will be hooked only once. + * Methods will be hooked only once. */ public mockConsole() { if (typeof this.origConsole.log === 'function') { @@ -228,7 +230,7 @@ export class VConsoleLogModel extends VConsoleModel { return store; }); } - + /** * Add a vConsole log. */ @@ -249,16 +251,8 @@ export class VConsoleLogModel extends VConsoleModel { // } // log.data = getLogDatasWithFormatting(item?.origData); - // extract pluginId by `[xxx]` format - const pluginId = this._extractPluginIdByLog(log); + this._signalLog(log); - if (this._isRepeatedLog(pluginId, log)) { - this._updateLastLogRepeated(pluginId); - } else { - this._pushLogList(pluginId, log); - this._limitLogListLength(); - } - if (!opt?.noOrig) { // logging to original console this.callOriginalConsole(item.type, ...item.origData); @@ -292,6 +286,54 @@ export class VConsoleLogModel extends VConsoleModel { }, { cmdType: 'output' }); }; + protected _signalLog(log: IVConsoleLog) { + // throttle addLog + if (!this.flushLogScheduled) { + this.flushLogScheduled = true; + window.requestAnimationFrame(() => { + this.flushLogScheduled = false; + this._flushLogs(); + }); + } + this.logQueue.push(log); + } + + protected _flushLogs() { + const logQueue = this.logQueue; + this.logQueue = []; + const pluginLogs: Record = {}; + + // extract pluginId by `[xxx]` format + for (const log of logQueue) { + const pluginId = this._extractPluginIdByLog(log); + + (pluginLogs[pluginId] = pluginLogs[pluginId] || []).push(log); + } + + const pluginIds = Object.keys(plugin;Logs) + for (const pluginId of pluginIds) { + const logs = pluginLogs[pluginId]; + + const store = Store.get(pluginId); + store.update((store) => { + let logList = [...store.logList]; + + for (const log of logs) { + if (this._isRepeatedLog(logList, log)) { + this._updateLastLogRepeated(logList); + } else { + logList.push(log); + } + } + + logList = this._limitLogListLength(logList); + + return { logList }; + }) + } + contentStore.updateTime(); + } + protected _extractPluginIdByLog(log: IVConsoleLog) { // if origData[0] is `[xxx]` format, and `xxx` is a Log plugin id, // then put this log to that plugin, @@ -312,9 +354,8 @@ export class VConsoleLogModel extends VConsoleModel { return pluginId; } - protected _isRepeatedLog(pluginId: string, log: IVConsoleLog) { - const store = Store.getRaw(pluginId); - const lastLog = store.logList[store.logList.length - 1]; + protected _isRepeatedLog(logList: IVConsoleLog[], log: IVConsoleLog) { + const lastLog = logList[logList.length - 1]; if (!lastLog) { return false; } @@ -332,42 +373,32 @@ export class VConsoleLogModel extends VConsoleModel { return isRepeated; } - protected _updateLastLogRepeated(pluginId: string) { - Store.get(pluginId).update((store) => { - const list = store.logList - const last = list[list.length - 1]; - last.repeated = last.repeated ? last.repeated + 1 : 2; - return store; - }); - } - - protected _pushLogList(pluginId: string, log: IVConsoleLog) { - Store.get(pluginId).update((store) => { - store.logList.push(log); - return store; - }); - contentStore.updateTime(); + protected _updateLastLogRepeated(logList: IVConsoleLog[]) { + const last = logList[logList.length - 1]; + const repeated = last.repeated ? last.repeated + 1 : 2; + logList[logList.length - 1] = { + ...last, + repeated, + }; + return logList; } - protected _limitLogListLength() { + protected _limitLogListLength(logList: IVConsoleLog[]): IVConsoleLog[] { // update logList length every N rounds - const N = 10; - this.logCounter++; - if (this.logCounter % N !== 0) { - return; - } - this.logCounter = 0; - - const stores = Store.getAll(); - for (const id in stores) { - stores[id].update((store) => { - if (store.logList.length > this.maxLogNumber - N) { - // delete N more logs for performance - store.logList.splice(0, store.logList.length - this.maxLogNumber + N); - // this.callOriginalConsole('info', 'delete', id, store[id].logList.length); - } - return store; - }); + // const N = 10; + // this.logCounter++; + // if (this.logCounter % N !== 0) { + // return logList; + // } + // this.logCounter = 0; + + const len = logList.length; + const maxLen = this.maxLogNumber; + if (len > maxLen) { + // delete N more logs for performance + // this.callOriginalConsole('info', 'delete', len, len - maxLen); + return logList.slice(len - maxLen, len); } + return logList; } } diff --git a/src/log/logRow.svelte b/src/log/logRow.svelte index 13dbb8c3..1ce270bb 100644 --- a/src/log/logRow.svelte +++ b/src/log/logRow.svelte @@ -1,3 +1,4 @@ + {#if dataKey !== undefined}{tool.getVisibleText(dataKey)}:{/if} - {#if !isInTree && valueType === 'string'} - {@html dataValue} - {:else} - {dataValue} - {/if} + {dataValue} From 164857ebf73a799f54bc8de046561c0aa83c4469 Mon Sep 17 00:00:00 2001 From: Maiz Date: Wed, 21 Sep 2022 20:26:24 +0800 Subject: [PATCH 13/18] Fix(Storage): Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) --- CHANGELOG.md | 1 + CHANGELOG_CN.md | 1 + dev/storage.html | 7 ++++++- src/storage/storage.ts | 14 ++++++++++---- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9db53975..97155fc0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ English | [简体中文](./CHANGELOG_CN.md) - `Fix(Log)` Fix `window.onerror` missing line breaks. - `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) - `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) +- `Fix(Storage)` Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) - `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) - `Chore` Add option `env['no-core-js']` to disable core-js polyfill. (PR #562) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 9e00d271..141df9db 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -6,6 +6,7 @@ - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 - `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) - `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) +- `Fix(Storage)` 修复因设置 `storage.defaultStorages` 导致 Storage 面板排序错误的问题。 (issue #560) - `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) - `Chore` 添加 `env['no-core-js']` 选项来停用构建时使用 core-js polyfill。 (PR #562) diff --git a/dev/storage.html b/dev/storage.html index b7a154be..c9fdb0c5 100644 --- a/dev/storage.html +++ b/dev/storage.html @@ -18,6 +18,7 @@ XSS defaultStorages: clear defaultStorages: add + defaultStorages: update @@ -28,7 +29,7 @@ window.vConsole = new window.VConsole({ // disableLogScrolling: true, storage: { - // defaultStorages: [], + // defaultStorages: ['sessionStorage', 'cookies', 'localStorage'], }, onReady: function() { console.log('vConsole is ready.'); @@ -140,4 +141,8 @@ window.wx = {}; vConsole.setOption('storage.defaultStorages', ['wxStorage', 'localStorage']); } + +function defaultStoragesUpdate() { + vConsole.setOption('storage.defaultStorages', ['localStorage', 'unknownStorage', 'sessionStorage']); +} \ No newline at end of file diff --git a/src/storage/storage.ts b/src/storage/storage.ts index c821486b..95275da3 100644 --- a/src/storage/storage.ts +++ b/src/storage/storage.ts @@ -1,4 +1,5 @@ import { get } from 'svelte/store'; +import { isArray } from '../lib/tool'; import { VConsoleSveltePlugin } from '../lib/sveltePlugin'; import { VConsoleStorageModel, storageStore } from './storage.model'; import { default as StorageComp } from './storage.svelte'; @@ -53,9 +54,14 @@ export class VConsoleStoragePlugin extends VConsoleSveltePlugin { } public onUpdateOption() { - if (typeof this.vConsole.option.storage?.defaultStorages !== 'undefined') { - storageStore.defaultStorages.set(this.vConsole.option.storage?.defaultStorages || []); - this.updateTopBar(); + let defaultStorages = this.vConsole.option.storage?.defaultStorages; + if (isArray(defaultStorages)) { + defaultStorages = defaultStorages.length > 0 ? defaultStorages : ['cookies']; + if (defaultStorages !== get(storageStore.defaultStorages)) { + storageStore.defaultStorages.set(defaultStorages); + storageStore.activedName.set(defaultStorages[0]); + this.updateTopBar(); + } } } @@ -73,7 +79,7 @@ export class VConsoleStoragePlugin extends VConsoleSveltePlugin { data: { name: name, }, - actived: i === 0, + actived: name === get(storageStore.activedName), onClick: (e: PointerEvent, data: { name: string }) => { const activedName = get(storageStore.activedName); if (data.name === activedName) { From 61cc1f4058529a6bfb59bf702040021d08bfb866 Mon Sep 17 00:00:00 2001 From: Maiz Date: Wed, 21 Sep 2022 20:41:15 +0800 Subject: [PATCH 14/18] Fix(Core): Fix intervention error caused by `preventDefault` in `Touch` events. (issue #546) --- CHANGELOG.md | 1 + CHANGELOG_CN.md | 1 + src/core/core.svelte | 6 +++--- src/core/switchButton.svelte | 6 +++--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97155fc0..6fb9e486 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ English | [简体中文](./CHANGELOG_CN.md) - `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) - `Fix(Storage)` Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) - `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) +- `Fix(Core)` Fix intervention error caused by `preventDefault` in `Touch` events. (issue #546) - `Chore` Add option `env['no-core-js']` to disable core-js polyfill. (PR #562) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 141df9db..a8622e39 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -8,6 +8,7 @@ - `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) - `Fix(Storage)` 修复因设置 `storage.defaultStorages` 导致 Storage 面板排序错误的问题。 (issue #560) - `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) +- `Fix(Core)` 修复因 `Touch` 事件中的 `preventDefault` 导致的 intervention 错误。 (issue #546) - `Chore` 添加 `env['no-core-js']` 选项来停用构建时使用 core-js polyfill。 (PR #562) diff --git a/src/core/core.svelte b/src/core/core.svelte index 09c670b4..e894daf8 100644 --- a/src/core/core.svelte +++ b/src/core/core.svelte @@ -293,9 +293,9 @@ class:vc-toggle={showMain} style="{fontSize ? 'font-size:' + fontSize + ';' : ''}" data-theme={theme} - on:touchstart|capture={mockTapEvent.touchStart} - on:touchmove|capture={mockTapEvent.touchMove} - on:touchend|capture={mockTapEvent.touchEnd} + on:touchstart|capture|nonpassive={mockTapEvent.touchStart} + on:touchmove|capture|nonpassive={mockTapEvent.touchMove} + on:touchend|capture|nonpassive={mockTapEvent.touchEnd} > vConsole From 2ea8a8afe5e321a00bf34bffc31721da79b9879c Mon Sep 17 00:00:00 2001 From: Maiz Date: Wed, 21 Sep 2022 21:03:11 +0800 Subject: [PATCH 15/18] Fix(Network): Fix `Fetch` stays in pending status when `window` is proxied. (issue #556) --- CHANGELOG.md | 1 + CHANGELOG_CN.md | 1 + src/network/fetch.proxy.ts | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fb9e486..5585b071 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ English | [简体中文](./CHANGELOG_CN.md) - `Fix(Log)` Fix `window.onerror` missing line breaks. - `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) - `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) +- `Fix(Network)` Fix `Fetch` stays in pending status when `window` is proxied. (issue #556) - `Fix(Storage)` Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) - `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) - `Fix(Core)` Fix intervention error caused by `preventDefault` in `Touch` events. (issue #546) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index a8622e39..f701fcfb 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -6,6 +6,7 @@ - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 - `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) - `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) +- `Fix(Network)` 修复因 `window` 对象被代理导致 `Fetch` 一直为 pending 状态的问题。 (issue #556) - `Fix(Storage)` 修复因设置 `storage.defaultStorages` 导致 Storage 面板排序错误的问题。 (issue #560) - `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) - `Fix(Core)` 修复因 `Touch` 事件中的 `preventDefault` 导致的 intervention 错误。 (issue #546) diff --git a/src/network/fetch.proxy.ts b/src/network/fetch.proxy.ts index 1e1cbd48..f4f06425 100644 --- a/src/network/fetch.proxy.ts +++ b/src/network/fetch.proxy.ts @@ -118,13 +118,13 @@ export class FetchProxyHandler implements ProxyHandler>target.apply(thisArg, argsList)).then(this.afterFetch(item)).catch((e) => { + return (>target.apply(window, argsList)).then(this.afterFetch(item)).catch((e) => { // mock finally item.endTime = Date.now(); item.costTime = item.endTime - (item.startTime || item.endTime); From 9a42c6ebd08d958a6f478b846df6434a11f96ec4 Mon Sep 17 00:00:00 2001 From: Maiz Date: Fri, 23 Sep 2022 18:30:18 +0800 Subject: [PATCH 16/18] Fix(Log|Network): Copy objects or arrays as standard JSON format. (issue #547) --- CHANGELOG.md | 1 + CHANGELOG_CN.md | 1 + src/component/iconCopy.svelte | 7 ++++++- src/lib/tool.ts | 24 ++++++++++++++++++++---- src/log/logRow.svelte | 8 ++++++-- src/network/helper.ts | 4 ++-- 6 files changed, 36 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5585b071..8171a1fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ English | [简体中文](./CHANGELOG_CN.md) - `Fix(Log)` Fix `window.onerror` missing line breaks. - `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) - `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) +- `Fix(Log|Network)` Copy objects or arrays as standard JSON format. (issue #547) - `Fix(Network)` Fix `Fetch` stays in pending status when `window` is proxied. (issue #556) - `Fix(Storage)` Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) - `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index f701fcfb..4563ebe7 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -6,6 +6,7 @@ - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 - `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) - `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) +- `Fix(Log|Network)` 以标准 JSON 格式复制对象或数组。 (issue #547) - `Fix(Network)` 修复因 `window` 对象被代理导致 `Fetch` 一直为 pending 状态的问题。 (issue #556) - `Fix(Storage)` 修复因设置 `storage.defaultStorages` 导致 Storage 面板排序错误的问题。 (issue #560) - `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) diff --git a/src/component/iconCopy.svelte b/src/component/iconCopy.svelte index f7b4c2da..5ee1cb26 100644 --- a/src/component/iconCopy.svelte +++ b/src/component/iconCopy.svelte @@ -15,7 +15,12 @@ text = handler(content) || ''; } else { if (tool.isObject(content) || tool.isArray(content)) { - text = tool.safeJSONStringify(content); + text = tool.safeJSONStringify(content, { + maxDepth: 10, + keyMaxLen: 10000, + pretty: false, + standardJSON: true, + }); } else { text = content; } diff --git a/src/lib/tool.ts b/src/lib/tool.ts index ff4ecb1f..e595bef5 100644 --- a/src/lib/tool.ts +++ b/src/lib/tool.ts @@ -185,6 +185,7 @@ type ISafeJSONStringifyOption = { maxDepth: number, keyMaxLen: number, pretty: boolean, + standardJSON: boolean, circularFinder: (val: any) => any, }; const _safeJSONStringifyCircularFinder = () => { @@ -227,11 +228,13 @@ const _safeJSONStringify = (obj, opt: ISafeJSONStringifyOption, _curDepth = 0) = const isCircular = opt.circularFinder(obj); if (isCircular) { + let circularText = ''; if (isArray(obj)) { - opt.ret += '(Circular Array)'; + circularText = '(Circular Array)'; } else if (isObject(obj)) { - opt.ret += `(Circular ${obj.constructor?.name || 'Object'})`; + circularText = `(Circular ${obj.constructor?.name || 'Object'})`; } + opt.ret += opt.standardJSON ? `"${circularText}"` : circularText; return; } @@ -261,6 +264,8 @@ const _safeJSONStringify = (obj, opt: ISafeJSONStringifyOption, _curDepth = 0) = if (!isArray(obj)) { if (isObject(key) || isArray(key) || isSymbol(key)) { opt.ret += Object.prototype.toString.call(key); + } else if (isString(key) && opt.standardJSON) { + opt.ret += '"' + key + '"'; } else { opt.ret += key; } @@ -294,7 +299,7 @@ const _safeJSONStringify = (obj, opt: ISafeJSONStringifyOption, _curDepth = 0) = } catch (e) { // cannot stringify `value`, use a default text - opt.ret += '(...)'; + opt.ret += opt.standardJSON ? '"(PARSE_ERROR)"' : '(PARSE_ERROR)'; } if (opt.keyMaxLen > 0 && opt.ret.length >= opt.keyMaxLen * 10) { @@ -311,12 +316,23 @@ const _safeJSONStringify = (obj, opt: ISafeJSONStringifyOption, _curDepth = 0) = /** * A safe `JSON.stringify` method. */ -export function safeJSONStringify(obj, opt: { maxDepth?: number, keyMaxLen?: number, pretty?: boolean } = { maxDepth: -1, keyMaxLen: -1, pretty: false, }) { +export function safeJSONStringify(obj, opt: { + maxDepth?: number, + keyMaxLen?: number, + pretty?: boolean, + standardJSON?: boolean, +} = { + maxDepth: -1, + keyMaxLen: -1, + pretty: false, + standardJSON: false, +}) { const option: ISafeJSONStringifyOption = Object.assign({ ret: '', maxDepth: -1, keyMaxLen: -1, pretty: false, + standardJSON: false, circularFinder: _safeJSONStringifyCircularFinder(), }, opt); _safeJSONStringify(obj, option); diff --git a/src/log/logRow.svelte b/src/log/logRow.svelte index 1ce270bb..40d1424f 100644 --- a/src/log/logRow.svelte +++ b/src/log/logRow.svelte @@ -48,8 +48,12 @@ const text: string[] = []; try { for (let i = 0; i < log.data.length; i++) { - // Only copy up to 10 levels of object depth and single key size up to 10KB - text.push(tool.safeJSONStringify(log.data[i].origData, { maxDepth: 10, keyMaxLen: 10000, pretty: false })); + if (tool.isString(log.data[i].origData) || tool.isNumber(log.data[i].origData)) { + text.push(log.data[i].origData); + } else { + // Only copy up to 10 levels of object depth and single key size up to 10KB + text.push(tool.safeJSONStringify(log.data[i].origData, { maxDepth: 10, keyMaxLen: 10000, pretty: false, standardJSON: true })); + } } } catch (e) { // do nothing diff --git a/src/network/helper.ts b/src/network/helper.ts index 91c487c9..9a5b3384 100644 --- a/src/network/helper.ts +++ b/src/network/helper.ts @@ -42,13 +42,13 @@ export const genResonseByResponseType = (responseType: string, response: any) => if (tool.isString(response)) { try { ret = JSON.parse(response); - ret = tool.safeJSONStringify(ret, { maxDepth: 10, keyMaxLen: 10000, pretty: true }); + ret = tool.safeJSONStringify(ret, { maxDepth: 10, keyMaxLen: 10000, pretty: true, standardJSON: true }); } catch (e) { // not a JSON string ret = tool.getStringWithinLength(String(response), 10000); } } else if (tool.isObject(response) || tool.isArray(response)) { - ret = tool.safeJSONStringify(response, { maxDepth: 10, keyMaxLen: 10000, pretty: true }); + ret = tool.safeJSONStringify(response, { maxDepth: 10, keyMaxLen: 10000, pretty: true, standardJSON: true }); } else if (typeof response !== 'undefined') { ret = Object.prototype.toString.call(response); } From 9b2aed8745931b5e58ab1cf7d7bd067745fe54e9 Mon Sep 17 00:00:00 2001 From: Maiz Date: Fri, 23 Sep 2022 18:48:32 +0800 Subject: [PATCH 17/18] chore: use __TARGET__ for no-core-js --- webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index f0daba4a..0ef08d81 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -9,7 +9,7 @@ const BuildTarget = ['web', 'wx']; module.exports = (env, argv) => { const isDev = argv.mode === 'development'; const __TARGET__ = BuildTarget.indexOf(env.target) === -1 ? BuildTarget[0] : env.target; - const noCoreJS = !!env['no-core-js'] + const noCoreJS = !!env['no-core-js'] || __TARGET__ === 'wx'; // define plugins const plugins = [ new Webpack.BannerPlugin({ From 61c70613d48fd6b4358353c58ee638eba7f69d50 Mon Sep 17 00:00:00 2001 From: Maiz Date: Fri, 23 Sep 2022 18:51:08 +0800 Subject: [PATCH 18/18] chore: v3.14.7 --- CHANGELOG.md | 6 +++--- CHANGELOG_CN.md | 6 +++--- package.json | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8171a1fd..c149da54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,16 +1,16 @@ English | [简体中文](./CHANGELOG_CN.md) -## 3.14.7 (2022-09-??) +## 3.14.7 (2022-09-23) - `Perf(Log)` Optimize rendering performance when adding logs. (PR #567) +- `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) +- `Fix(Core)` Fix intervention error caused by `preventDefault` in `Touch` events. (issue #546) - `Fix(Log)` Fix `window.onerror` missing line breaks. - `Fix(Log)` Fix unclickable `vc-cmd-clear-btn` on iOS Safari. (PR #564) - `Fix(Log)` Fix a typo that misjudged circular reference objects. (issue #566) - `Fix(Log|Network)` Copy objects or arrays as standard JSON format. (issue #547) - `Fix(Network)` Fix `Fetch` stays in pending status when `window` is proxied. (issue #556) - `Fix(Storage)` Fix storage pannel sorting error when setting `storage.defaultStorages` option. (issue #560) -- `Fix(Core)` Fix plugin panel sorting error when setting `pluginOrder` option. (issue #559) -- `Fix(Core)` Fix intervention error caused by `preventDefault` in `Touch` events. (issue #546) - `Chore` Add option `env['no-core-js']` to disable core-js polyfill. (PR #562) diff --git a/CHANGELOG_CN.md b/CHANGELOG_CN.md index 4563ebe7..13f89dc6 100644 --- a/CHANGELOG_CN.md +++ b/CHANGELOG_CN.md @@ -1,16 +1,16 @@ [English](./CHANGELOG.md) | 简体中文 -## 3.14.7 (2022-09-??) +## 3.14.7 (2022-09-23) - `Perf(Log)` 优化打印日志时的性能。 (PR #567) +- `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) +- `Fix(Core)` 修复因 `Touch` 事件中的 `preventDefault` 导致的 intervention 错误。 (issue #546) - `Fix(Log)` 修复 `window.onerror` 丢失换行的问题。 - `Fix(Log)` 修复清除命令行按钮在 iOS Safari 中无法点击的问题。 (PR #564) - `Fix(Log)` 修复一处误判循环引用对象的笔误。 (issue #566) - `Fix(Log|Network)` 以标准 JSON 格式复制对象或数组。 (issue #547) - `Fix(Network)` 修复因 `window` 对象被代理导致 `Fetch` 一直为 pending 状态的问题。 (issue #556) - `Fix(Storage)` 修复因设置 `storage.defaultStorages` 导致 Storage 面板排序错误的问题。 (issue #560) -- `Fix(Core)` 修复因设置 `pluginOrder` 导致插件面板排序错误的问题。 (issue #559) -- `Fix(Core)` 修复因 `Touch` 事件中的 `preventDefault` 导致的 intervention 错误。 (issue #546) - `Chore` 添加 `env['no-core-js']` 选项来停用构建时使用 core-js polyfill。 (PR #562) diff --git a/package.json b/package.json index e62a1fa9..32d86826 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vconsole", - "version": "3.14.7-rc", + "version": "3.14.7", "description": "A lightweight, extendable front-end developer tool for mobile web page.", "homepage": "https://github.com/Tencent/vConsole", "files": [