From 0c071609d7b511c3e3585a1bde33ee23d56f4b1d Mon Sep 17 00:00:00 2001 From: qiang Date: Mon, 10 Jan 2022 12:16:58 +0800 Subject: [PATCH] fix(mp): string express with escape quote --- .../__tests__/compiler-mp-weixin.spec.js | 18 +++++++++++ .../uni-template-compiler/lib/constants.js | 4 ++- .../lib/script/traverse/data/attrs.js | 10 ++++-- .../lib/script/traverse/index.js | 8 ++++- .../lib/script/traverse/visitor.js | 14 +++++++-- packages/uni-template-compiler/lib/util.js | 31 ++++++++++++++++++- 6 files changed, 77 insertions(+), 8 deletions(-) diff --git a/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js index 44ae404f7..4e39263a5 100644 --- a/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js +++ b/packages/uni-template-compiler/__tests__/compiler-mp-weixin.spec.js @@ -54,6 +54,24 @@ describe('mp:compiler-mp-weixin', () => { ) }) + it('generate string express with escape quote', () => { + assertCodegen( + ``, + '', + `with(this){var a0=text+"'";$mp.data=Object.assign({},{$root:{a0:a0}})}` + ) + assertCodegen( + `{{text+'\\''}}`, + '{{$root.t0}}', + `with(this){var t0=text+"'";$mp.data=Object.assign({},{$root:{t0:t0}})}` + ) + assertCodegen( + `{{text+"\\""}}`, + '{{$root.t0}}', + `with(this){var t0=text+"\\"";$mp.data=Object.assign({},{$root:{t0:t0}})}` + ) + }) + it('generate named scoped slot', () => { assertCodegen( '', diff --git a/packages/uni-template-compiler/lib/constants.js b/packages/uni-template-compiler/lib/constants.js index af0ea8ca2..bc38a000a 100644 --- a/packages/uni-template-compiler/lib/constants.js +++ b/packages/uni-template-compiler/lib/constants.js @@ -117,6 +117,7 @@ module.exports = { PREFIX_CLASS: 'c', PREFIX_STYLE: 's', PREFIX_EVENT: 'e', + PREFIX_TEXT: 't', IDENTIFIER_FOR: '__$$for$$__', IDENTIFIER_ATTR: '__$$attr$$__', IDENTIFIER_METHOD: '__$$method$$__', @@ -124,5 +125,6 @@ module.exports = { IDENTIFIER_CLASS: '__$$class$$__', IDENTIFIER_STYLE: '__$$style$$__', IDENTIFIER_EVENT: '__$$event$$__', - IDENTIFIER_GLOBAL: '__$$global$$__' + IDENTIFIER_GLOBAL: '__$$global$$__', + IDENTIFIER_TEXT: '__$$text$$__' } diff --git a/packages/uni-template-compiler/lib/script/traverse/data/attrs.js b/packages/uni-template-compiler/lib/script/traverse/data/attrs.js index 10c0c18c1..b4b7fad01 100644 --- a/packages/uni-template-compiler/lib/script/traverse/data/attrs.js +++ b/packages/uni-template-compiler/lib/script/traverse/data/attrs.js @@ -3,18 +3,24 @@ const { } = require('../../../constants') const { - isSimpleObjectExpression + isSimpleObjectExpression, + hasEscapeQuote } = require('../../../util') const getMemberExpr = require('../member-expr') +function checkObjectExpression (path) { + return path.isObjectExpression() && !isSimpleObjectExpression(path.node) +} + module.exports = function processAttrs (paths, path, state, isComponent, tagName) { const attrsPath = paths.attrs if (attrsPath) { attrsPath.get('value.properties').forEach(propertyPath => { const valuePath = propertyPath.get('value') // 对于简单的ObjectExpression不再单独处理,改为在转换temlplte时用()包裹(微信、QQ) - if (valuePath.isObjectExpression() && !isSimpleObjectExpression(valuePath.node)) { + // 属性中包含转义引号时部分小程序平台报错或显示异常 + if (checkObjectExpression(valuePath) || hasEscapeQuote(valuePath)) { valuePath.replaceWith(getMemberExpr(path, IDENTIFIER_ATTR, valuePath.node, state)) } }) diff --git a/packages/uni-template-compiler/lib/script/traverse/index.js b/packages/uni-template-compiler/lib/script/traverse/index.js index 723ccb6bb..a07b1bfff 100644 --- a/packages/uni-template-compiler/lib/script/traverse/index.js +++ b/packages/uni-template-compiler/lib/script/traverse/index.js @@ -12,6 +12,7 @@ const { IDENTIFIER_STYLE, IDENTIFIER_EVENT, IDENTIFIER_GLOBAL, + IDENTIFIER_TEXT, PREFIX_ATTR, PREFIX_GLOBAL, PREFIX_METHOD, @@ -19,7 +20,8 @@ const { PREFIX_FOR, PREFIX_CLASS, PREFIX_STYLE, - PREFIX_EVENT + PREFIX_EVENT, + PREFIX_TEXT } = require('../../constants') const { @@ -63,6 +65,10 @@ function reIdentifier (identifierArray) { [IDENTIFIER_ATTR]: { prefix: PREFIX_ATTR, id: 0 + }, + [IDENTIFIER_TEXT]: { + prefix: PREFIX_TEXT, + id: 0 } } // TODO order diff --git a/packages/uni-template-compiler/lib/script/traverse/visitor.js b/packages/uni-template-compiler/lib/script/traverse/visitor.js index 5868959d7..572149fe7 100644 --- a/packages/uni-template-compiler/lib/script/traverse/visitor.js +++ b/packages/uni-template-compiler/lib/script/traverse/visitor.js @@ -11,7 +11,8 @@ const { METHOD_RESOLVE_SCOPED_SLOTS, IDENTIFIER_FILTER, IDENTIFIER_METHOD, - IDENTIFIER_GLOBAL + IDENTIFIER_GLOBAL, + IDENTIFIER_TEXT } = require('../../constants') const { @@ -22,7 +23,8 @@ const { hasOwn, hyphenate, traverseFilter, - getComponentName + getComponentName, + hasEscapeQuote } = require('../../util') const traverseData = require('./data') @@ -186,7 +188,13 @@ module.exports = { break case METHOD_TO_STRING: { - const stringNodes = path.node.arguments[0] + const stringPath = path.get('arguments.0') + if (hasEscapeQuote(stringPath)) { + // 属性中包含转义引号时部分小程序平台报错或显示异常 + // TODO 简单情况翻转外层引号 + stringPath.replaceWith(getMemberExpr(path, IDENTIFIER_TEXT, stringPath.node, this)) + } + const stringNodes = stringPath.node stringNodes.$toString = true path.replaceWith(stringNodes) } diff --git a/packages/uni-template-compiler/lib/util.js b/packages/uni-template-compiler/lib/util.js index 99a3103c1..081c12589 100644 --- a/packages/uni-template-compiler/lib/util.js +++ b/packages/uni-template-compiler/lib/util.js @@ -232,6 +232,34 @@ function isSimpleObjectExpression (node) { }) => !t.isIdentifier(key) || !(t.isIdentifier(value) || t.isStringLiteral(value) || t.isBooleanLiteral(value) || t.isNumericLiteral(value) || t.isNullLiteral(value))) } +/** + * 是否包含转义引号 + * @param {*} path + * @returns {boolean} + */ +function hasEscapeQuote (path) { + let has = false + function hasEscapeQuote (node) { + const quote = node.extra ? node.extra.raw[0] : '"' + if (node.value.includes(quote)) { + return true + } + } + if (path.isStringLiteral()) { + return hasEscapeQuote(path.node) + } else { + path.traverse({ + noScope: true, + StringLiteral (path) { + if (hasEscapeQuote(path.node)) { + has = true + path.stop() + } + } + }) + } + return has +} module.exports = { hasOwn, @@ -263,5 +291,6 @@ module.exports = { }), processMemberExpression, getForIndexIdentifier, - isSimpleObjectExpression + isSimpleObjectExpression, + hasEscapeQuote } -- GitLab