From 7c8a9035876d933f322625b909149d356367559f Mon Sep 17 00:00:00 2001 From: lilei946 Date: Mon, 15 Jun 2026 16:17:10 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E5=A2=9E=E5=8A=A0=E5=85=AC?= =?UTF-8?q?=E6=8E=A7=E7=BB=84=E4=BB=B6=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lilei946 --- packages/hap-compiler/src/style/validator.js | 48 ++++++- .../hap-compiler/src/template/validator.js | 134 +++++++++++++++++- 2 files changed, 176 insertions(+), 6 deletions(-) diff --git a/packages/hap-compiler/src/style/validator.js b/packages/hap-compiler/src/style/validator.js index 9720ffa3..7cd10227 100755 --- a/packages/hap-compiler/src/style/validator.js +++ b/packages/hap-compiler/src/style/validator.js @@ -2648,8 +2648,28 @@ const validatorMap = { backgroundPosition: validator.backgroundPosition, display: validator.display, visibility: makeEnumValidator(['visible', 'hidden']), - objectFit: makeEnumValidator(['fill', 'contain', 'cover', 'none', 'scale-down', 'fit-start', 'fit-end', 'cover-start', 'cover-end']), - altObjectFit: makeEnumValidator(['fill', 'contain', 'cover', 'none', 'scale-down', 'fit-start', 'fit-end', 'cover-start', 'cover-end']), + objectFit: makeEnumValidator([ + 'fill', + 'contain', + 'cover', + 'none', + 'scale-down', + 'fit-start', + 'fit-end', + 'cover-start', + 'cover-end' + ]), + altObjectFit: makeEnumValidator([ + 'fill', + 'contain', + 'cover', + 'none', + 'scale-down', + 'fit-start', + 'fit-end', + 'cover-start', + 'cover-end' + ]), // text lines: validator.integer, color: validator.color, @@ -2712,7 +2732,29 @@ const validatorMap = { themeTrackColor: makeEnumValidator(themeColors), themeSelectedColor: makeEnumValidator(themeColors), themeBlockColor: makeEnumValidator(themeColors), */ - letterSpacing: validator.letterSpacing + letterSpacing: validator.letterSpacing, + // legacy card styles + textWeight: validator.fontWeight, + textSize: validator.length, + fillet: validator.length, + lineColor: validator.color, + lineWidth: validator.length, + faceColor: validator.color, + titleColor: validator.color, + titleSize: validator.length, + titleStyle: validator.fontWeight, + itemColor: validator.color, + itemSize: validator.length, + selectItemColor: validator.color, + unitStyle: validator.fontWeight, + unitColor: validator.color, + size: validator.length, + bgBeginColor: validator.color, + bgEndColor: validator.color, + ringBeginColor: validator.color, + ringEndColor: validator.color, + thumbBeginColor: validator.color, + thumbEndColor: validator.color } /** diff --git a/packages/hap-compiler/src/template/validator.js b/packages/hap-compiler/src/template/validator.js index 0f04b77c..cd6900ee 100644 --- a/packages/hap-compiler/src/template/validator.js +++ b/packages/hap-compiler/src/template/validator.js @@ -217,7 +217,15 @@ const tagNatives = { }, web: { atomic: true, - events: ['pagestart', 'pagefinish', 'titlereceive', 'error', 'message', 'progress', 'intercepturl'], + events: [ + 'pagestart', + 'pagefinish', + 'titlereceive', + 'error', + 'message', + 'progress', + 'intercepturl' + ], attrs: { src: {}, trustedurl: {}, @@ -233,7 +241,7 @@ const tagNatives = { supportzoom: { enum: ['true', 'false'] }, - intercepturl:{} + intercepturl: {} } }, list: { @@ -354,6 +362,20 @@ const tagNatives = { textContent: true, atomic: true }, + vbutton: { + supportCard: true, + textContent: true, + atomic: true, + attrs: { + enablecolor: {}, + enableanim: {}, + animtype: {}, + loading: {}, + drawtype: {}, + text: {}, + disable: {} + } + }, refresh: { attrs: { offset: { @@ -577,6 +599,68 @@ const tagNatives = { }, events: ['change', 'columnchange', 'cancel'] }, + vcustompicker: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + mode: {}, + defaultvalue: {}, + itemcycle: {}, + visibleitemcount: {} + }, + events: ['change'] + }, + vtimepicker: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + defaultvalue: {}, + itemcycle: {}, + visibleitemcount: {} + }, + events: ['change'] + }, + vdatepicker: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + defaultvalue: {}, + itemcycle: {}, + yearrange: {}, + visibleitemcount: {} + }, + events: ['change'] + }, + vdatepicker2: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + defaultvalue: {}, + itemcycle: {}, + yearrange: {}, + visibleitemcount: {} + }, + events: ['change'] + }, + vcalendardatepicker: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + defaultvalue: {}, + yearrange: {} + }, + events: ['change'] + }, switch: { supportCard: true, selfClosing: true, @@ -588,6 +672,50 @@ const tagNatives = { }, events: ['change'] }, + vswitch: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + checked: {}, + blurmaterial: {}, + disable: {}, + loading: {} + }, + events: ['change'] + }, + vcheckbox: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + text: {}, + checked: {}, + groupid: {}, + type: {}, + tickcolor: {}, + framecolor: {}, + fillcolor: {}, + checkstatus: {} + }, + events: ['change'] + }, + vradiobutton: { + supportCard: true, + selfClosing: true, + atomic: true, + empty: true, + attrs: { + text: {}, + checked: {}, + groupid: {}, + radiocolor: {}, + framecolor: {} + }, + events: ['change'] + }, textarea: { supportCard: true, atomic: true, @@ -1328,7 +1456,7 @@ function checkTagName(node, output, options = {}) { log.push({ line: location.line || 1, column: location.col || 1, - reason: 'WARN: 组件 `' + tagName + '` 不支持属性 `' + item + reason: 'WARN: 组件 `' + tagName + '` 不支持属性 `' + item + '`' }) } } From aff9d784e885426121c9c42715fd7cd5be0fb362 Mon Sep 17 00:00:00 2001 From: lilei946 Date: Mon, 29 Jun 2026 14:27:35 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20image=E7=BB=84=E4=BB=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81symbolcode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lilei946 --- packages/hap-compiler/src/template/validator.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/hap-compiler/src/template/validator.js b/packages/hap-compiler/src/template/validator.js index cd6900ee..807ba337 100644 --- a/packages/hap-compiler/src/template/validator.js +++ b/packages/hap-compiler/src/template/validator.js @@ -181,6 +181,7 @@ const tagNatives = { attrs: { src: {}, alt: {}, + symbolcode: {}, enablenightmode: { enum: ['true', 'false'] }, From ec1409bb62278d1d0108cd8d8c77a439f208b5a9 Mon Sep 17 00:00:00 2001 From: lilei946 Date: Wed, 22 Jul 2026 17:14:36 +0800 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8D=A1=E7=89=87?= =?UTF-8?q?=E5=90=8D=E7=A7=B0=E6=8F=90=E5=8F=96=E6=97=B6=E6=AD=A3=E5=88=99?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E7=A2=B0=E6=92=9E=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lilei946 --- .../src/plugins/card-script-handle-plugin.js | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/packages/hap-packager/src/plugins/card-script-handle-plugin.js b/packages/hap-packager/src/plugins/card-script-handle-plugin.js index 76bdbbbc..89752170 100644 --- a/packages/hap-packager/src/plugins/card-script-handle-plugin.js +++ b/packages/hap-packager/src/plugins/card-script-handle-plugin.js @@ -199,27 +199,35 @@ const prodUtils = { if (templateFileName === `${compPath}.template.json`) { templatePath = CARD_ENTRY } - const uniquePlaceHolder = `_START_PLACE_HOLDER_TEMPLATE_${templateFileName}_${templatePath}_END_` + // 用_做分隔符容易与开发者卡片路径冲突造成匹配失效,使用[]序列化,碰撞概率更低 + const payload = JSON.stringify([templateFileName, templatePath]) + const uniquePlaceHolder = `_START_PLACE_HOLDER_TEMPLATE_${payload}_END_` path.replaceWith(t.stringLiteral(uniquePlaceHolder)) }, replaceStyleStr(path, styleStr, cssFileName, pathSrc) { const compPath = this.getCompPath(styleStr, pathSrc) const styleObjId = getStyleObjectId(compPath) - const uniquePlaceHolder = `_START_PLACE_HOLDER_CSS_${cssFileName}_${styleObjId}_END_` + const payload = JSON.stringify([cssFileName, styleObjId]) + const uniquePlaceHolder = `_START_PLACE_HOLDER_CSS_${payload}_END_` path.replaceWith(t.stringLiteral(uniquePlaceHolder)) }, replacePlaceHolder(code) { - // 正则表达式匹配_idX_valY_place_holder_格式的字符串 - const regexTemplate = /["'`]_START_PLACE_HOLDER_TEMPLATE_([^\s]+?)_([^\s]+?)_END_["'`]/g + // 正则表达式匹配 JSON 序列化的占位符 + const regexTemplate = /["'`]_START_PLACE_HOLDER_TEMPLATE_(.+?)_END_["'`]/g // 替换 template 的 placeholder - code = code.replace(regexTemplate, function (match, templateFileName, templatePath) { + code = code.replace(regexTemplate, function (match, payload) { + // generate 会对字符串中的 " 转义为 \",需先还原 + const unescaped = payload.replace(/\\"/g, '"') + const [templateFileName, templatePath] = JSON.parse(unescaped) return `$json_require$("${templateFileName}",{"componentPath":"${templatePath}"})` }) - const regexCss = /["'`]_START_PLACE_HOLDER_CSS_([^\s]+?)_([^\s]+?)_END_["'`]/g + const regexCss = /["'`]_START_PLACE_HOLDER_CSS_(.+?)_END_["'`]/g // 替换 css 的 placeholder - code = code.replace(regexCss, function (match, cssFileName, styleObjId) { + code = code.replace(regexCss, function (match, payload) { + const unescaped = payload.replace(/\\"/g, '"') + const [cssFileName, styleObjId] = JSON.parse(unescaped) return JSON.stringify({ '@info': { styleObjectId: styleObjId }, extracted: true, From ca2742cd6cb4182e168e9207d95f40c7abe9c7f0 Mon Sep 17 00:00:00 2001 From: lilei946 Date: Mon, 10 Aug 2026 11:33:56 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20=E8=BD=BB=E5=8D=A1=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E4=BC=A0=E9=80=92=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lilei946 --- .../hap-compiler/src/template/validator.js | 47 ++++++++++--------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/packages/hap-compiler/src/template/validator.js b/packages/hap-compiler/src/template/validator.js index 807ba337..89566f47 100644 --- a/packages/hap-compiler/src/template/validator.js +++ b/packages/hap-compiler/src/template/validator.js @@ -1998,12 +1998,12 @@ function checkEvent(name, value, output, options) { // 如果表达式形式为XXX(xxxx) const paramsMatch = value.match(/(.*)\((.*)\)/) if (paramsMatch) { - if (options.lite) { - const err = new Error('轻卡不支持带参数的事件') - err.isExpressionError = true - err.expression = value - throw err - } + // if (options.lite) { + // const err = new Error('轻卡不支持带参数的事件') + // err.isExpressionError = true + // err.expression = value + // throw err + // } const funcName = paramsMatch[1] let params = paramsMatch[2] // 解析','分隔的参数 @@ -2017,22 +2017,25 @@ function checkEvent(name, value, output, options) { // 否则默认有一个参数'$evt' params = ['evt'] } - value = '{{' + funcName + '(' + params.join(',') + ')}}' - try { - // 将事件转换为函数对象 - if (options.newJSCard) { - value = 'function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '}' - } else { - /* eslint-disable no-eval */ - value = eval( - '(function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '})' - ) - /* eslint-enable no-eval */ + value = funcName + '(' + params.join(',') + ')' + if (!options.lite) { + value = '{{' + value + '}}' + try { + // 将事件转换为函数对象 + if (options.newJSCard) { + value = 'function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '}' + } else { + /* eslint-disable no-eval */ + value = eval( + '(function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '})' + ) + /* eslint-enable no-eval */ + } + } catch (err) { + err.isExpressionError = true + err.expression = originValue + throw err } - } catch (err) { - err.isExpressionError = true - err.expression = originValue - throw err } } output.result.events = output.result.events || {} @@ -2290,4 +2293,4 @@ export default { isNotTextContentAtomic, isExpr: exp.isExpr, parseText: exp.parseText -} +} \ No newline at end of file From e9d655a84b582645690645afd370edb09e00728e Mon Sep 17 00:00:00 2001 From: lilei946 Date: Mon, 10 Aug 2026 11:34:37 +0800 Subject: [PATCH 5/5] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81followcorner?= =?UTF-8?q?=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: lilei946 --- packages/hap-compiler/src/template/validator.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/hap-compiler/src/template/validator.js b/packages/hap-compiler/src/template/validator.js index 89566f47..3f355cc3 100644 --- a/packages/hap-compiler/src/template/validator.js +++ b/packages/hap-compiler/src/template/validator.js @@ -94,6 +94,9 @@ const tagCommon = { }, overflow: { enum: ['visible', 'hidden'] + }, + followcorner: { + enum: ['true', 'false'] } }, children: ['block', 'slot', 'component'], // 通用控制组件