Skip to content

feat: update jscard package result: extract template and json while keeping sourcemap #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 20, 2025
21 changes: 19 additions & 2 deletions packages/hap-compiler/src/style/validator.js
Original file line number Diff line number Diff line change
Expand Up @@ -2656,7 +2656,24 @@ const validatorMap = {
starSecondary: validator.url,
// font
fontSrc: validator.fontSrc,
fontFamily: validator.fontFamily
fontFamily: validator.fontFamily,
themeColor: makeEnumValidator([
'uxCardColorTheme',
'uxCardColorAccent',
'uxCardColorPrimary',
'uxCardColorSecondary',
'uxCardColorSecondaryVariant',
'uxCardColorTertiary',
'uxCardColorQuaternary',
'uxCardColorContainer',
'uxCardBackground',
'uxCardColorHue',
'uxCardColorHueSecondary',
'uxIconColorAccent',
'uxIconColorPrimary',
'uxIconColorSecondary',
'uxIconColorBackground'
])
}

/**
Expand All @@ -2672,7 +2689,7 @@ function validate(name, value, options) {
const validator = validatorMap[name]

if (typeof validator === 'function') {
if (typeof value !== 'function') {
if (typeof value !== 'function' && value.indexOf('function') < 0) {
if (mightReferlocalResource(name)) {
result = validator(value, options)
} else {
Expand Down
10 changes: 7 additions & 3 deletions packages/hap-compiler/src/template/exp.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ function trimhtml(str) {
* @param isLite is lite card
* @returns {*}
*/
function transExpr(expContent, toFunc, isLite) {
function transExpr(expContent, toFunc, isLite, isCard) {
let ret
const trimExpContent = expContent.trim()
if (!textParser.isExpr(trimExpContent)) {
Expand Down Expand Up @@ -64,8 +64,12 @@ function transExpr(expContent, toFunc, isLite) {
ret = ret.join(' + ')
if (toFunc !== false) {
try {
/* eslint-disable no-eval */
ret = eval('(function () {return ' + ret + '})')
if (isCard) {
ret = 'function () {return ' + ret + '}'
} else {
/* eslint-disable no-eval */
ret = eval('(function () {return ' + ret + '})')
}
/* eslint-enable no-eval */
} catch (err) {
err.isExpressionError = true
Expand Down
8 changes: 7 additions & 1 deletion packages/hap-compiler/src/template/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,13 @@ function parse(source, options) {
{ treeAdapter: parse5.treeAdapters.default, locationInfo: true },
options.filePath
)
const output = { result: {}, log: [], depFiles: [], isLite: !!options.lite }
const output = {
result: {},
log: [],
depFiles: [],
isCard: !!options.card,
isLite: !!options.lite
}

// 模板为空或解析失败
/* istanbul ignore if */
Expand Down
175 changes: 124 additions & 51 deletions packages/hap-compiler/src/template/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,16 @@ function genCheckboxModel(node, attrName, value, output) {
${expValue} = checked ? ${trueValueBinding} : ${falseValueBinding}
}`

addAttr(output.result, attrName, eval(`(function() {${attrCheckedCode}})`))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))

const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addAttr(output.result, attrName, `(function() {${attrCheckedCode}})`)
addAttr(output.result, attrName + 'Raw', value)
addHandler(output.result, 'change', `function(evt) {${eventChangeCode}}`)
} else {
addAttr(output.result, attrName, eval(`(function() {${attrCheckedCode}})`))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))
}
return {
attr: { checked: attrCheckedCode },
events: { change: eventChangeCode }
Expand All @@ -125,8 +132,16 @@ function genRadioModel(node, attrName, value, output) {
const attrCheckedCode = `return ${exp(value, false)} === ${valueBinding}`
const eventChangeCode = `${exp(value, false)} = ${valueBinding}`

addAttr(output.result, attrName, eval(`(function() {${attrCheckedCode}})`))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))
const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addAttr(output.result, attrName, `(function() {${attrCheckedCode}})`)
addAttr(output.result, attrName + 'Raw', value)
addHandler(output.result, 'change', `function(evt) {${eventChangeCode}}`)
} else {
addAttr(output.result, attrName, eval(`(function() {${attrCheckedCode}})`))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))
}

return {
attr: { checked: attrCheckedCode },
Expand All @@ -140,11 +155,17 @@ function genRadioModel(node, attrName, value, output) {
* @param {object} output 构建的输出结果
*/
function genSelectModel(value, output) {
addHandler(
output.result,
'change',
eval(`(function(evt) { ${exp(value, false)} = evt.newValue})`)
)
const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addHandler(output.result, 'change', `function(evt) { ${exp(value, false)} = evt.newValue}`)
} else {
addHandler(
output.result,
'change',
eval(`(function(evt) { ${exp(value, false)} = evt.newValue})`)
)
}
}

/**
Expand All @@ -156,10 +177,16 @@ function genSelectModel(value, output) {
*/
function genDefaultModel(attrName, value, output) {
const eventChangeCode = `${exp(value, false)} = evt.target.value`

addAttr(output.result, attrName, exp(value))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))

const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addAttr(output.result, attrName, exp(value, true, isLite, isCard))
addAttr(output.result, attrName + 'Raw', value)
addHandler(output.result, 'change', `function(evt) {${eventChangeCode}}`)
} else {
addAttr(output.result, attrName, exp(value))
addHandler(output.result, 'change', eval(`(function(evt) {${eventChangeCode}})`))
}
return { events: { change: eventChangeCode } }
}

Expand All @@ -176,12 +203,22 @@ function genComponentModel(node, attrName, value, output, locationInfo, options)
// 自定义组件model指令绑定的属性,依然作为普通属性处理
validator.checkAttr(attrName, value, output, node.tagName, locationInfo, options)

// 为自定义组件绑定update:${attrName}事件,接收组件内部emit的update:${attrName}事件
addHandler(
output.result,
`update:${attrName}`,
eval(`(function(evt) { ${exp(value, false)} = evt.detail})`)
)
const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addHandler(
output.result,
`update:${attrName}`,
`function(evt) { ${exp(value, false)} = evt.detail}`
)
} else {
// 为自定义组件绑定update:${attrName}事件,接收组件内部emit的update:${attrName}事件
addHandler(
output.result,
`update:${attrName}`,
eval(`(function(evt) { ${exp(value, false)} = evt.detail})`)
)
}
}

/**
Expand All @@ -196,40 +233,76 @@ function genDynamicModel(node, attrName, value, output, expType) {
const checkboxCode = genCheckboxModel(node, attrName, value, output)
const radioCode = genRadioModel(node, attrName, value, output)
const textCode = genDefaultModel(attrName, value, output)
const isCard = output.isCard
const isLite = output.isLite
if (isCard && !isLite) {
addAttr(output.result, attrName, exp(value, true, isLite, isCard))
addAttr(output.result, attrName + 'Raw', value)

addAttr(output.result, attrName, exp(value))
addAttr(
output.result,
'checked',
`(function() {
if (${expType} === 'checkbox') {
${checkboxCode.attr.checked}
} else if (${expType} === 'radio') {
${radioCode.attr.checked}
} else {
return false
}
})
`
)

addAttr(
output.result,
'checked',
eval(`
(function() {
if (${expType} === 'checkbox') {
${checkboxCode.attr.checked}
} else if (${expType} === 'radio') {
${radioCode.attr.checked}
} else {
return false
}
})
`)
)
addAttr(output.result, 'checkedRaw', value)
addHandler(
output.result,
'change',
`function(evt) {
if (${expType} === 'checkbox') {
${checkboxCode.events.change}
} else if (${expType} === 'radio') {
${radioCode.events.change}
} else {
${textCode.events.change}
}
}`
)
} else {
addAttr(output.result, attrName, exp(value))

addHandler(
output.result,
'change',
eval(`
(function(evt) {
if (${expType} === 'checkbox') {
${checkboxCode.events.change}
} else if (${expType} === 'radio') {
${radioCode.events.change}
} else {
${textCode.events.change}
}
})
`)
)
addAttr(
output.result,
'checked',
eval(`
(function() {
if (${expType} === 'checkbox') {
${checkboxCode.attr.checked}
} else if (${expType} === 'radio') {
${radioCode.attr.checked}
} else {
return false
}
})
`)
)

addHandler(
output.result,
'change',
eval(`
(function(evt) {
if (${expType} === 'checkbox') {
${checkboxCode.events.change}
} else if (${expType} === 'radio') {
${radioCode.events.change}
} else {
${textCode.events.change}
}
})
`)
)
}
}

/**
Expand Down
Loading
Loading