Skip to content

Commit 43b2a6a

Browse files
committed
feat: update jscard package result: extract template and json while keeping sourcemap
Signed-off-by: lileirjyb <[email protected]>
1 parent 5381aef commit 43b2a6a

File tree

22 files changed

+1277
-538
lines changed

22 files changed

+1277
-538
lines changed

packages/hap-compiler/src/style/process.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ function processImport(csscode, dir, log, depList) {
141141
* @param {String} filePath - 文件路径
142142
* @param {Array} depFiles - 使用到的资源集合
143143
*/
144-
function processSingleClass(rule, jsonStyle, ruleResult, log, filePath, depFiles) {
144+
function processSingleClass(rule, jsonStyle, ruleResult, log, filePath, depFiles, options) {
145145
rule.declarations.forEach(function (declaration) {
146146
const subType = declaration.type
147147

packages/hap-compiler/src/style/validator.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2672,7 +2672,7 @@ function validate(name, value, options) {
26722672
const validator = validatorMap[name]
26732673

26742674
if (typeof validator === 'function') {
2675-
if (typeof value !== 'function') {
2675+
if (typeof value !== 'function' && value.indexOf('function') < 0) {
26762676
if (mightReferlocalResource(name)) {
26772677
result = validator(value, options)
26782678
} else {

packages/hap-compiler/src/template/exp.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ function trimhtml(str) {
3535
* @param isLite is lite card
3636
* @returns {*}
3737
*/
38-
function transExpr(expContent, toFunc, isLite) {
38+
function transExpr(expContent, toFunc, isLite, isCard) {
3939
let ret
4040
const trimExpContent = expContent.trim()
4141
if (!textParser.isExpr(trimExpContent)) {
@@ -64,8 +64,12 @@ function transExpr(expContent, toFunc, isLite) {
6464
ret = ret.join(' + ')
6565
if (toFunc !== false) {
6666
try {
67-
/* eslint-disable no-eval */
68-
ret = eval('(function () {return ' + ret + '})')
67+
if (isCard) {
68+
ret = 'function () {return ' + ret + '}'
69+
} else {
70+
/* eslint-disable no-eval */
71+
ret = eval('(function () {return ' + ret + '})')
72+
}
6973
/* eslint-enable no-eval */
7074
} catch (err) {
7175
err.isExpressionError = true

packages/hap-compiler/src/template/index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,15 @@ function traverse(node, output, previousNode, conditionList, options) {
128128
if (name.match(/^model:/)) {
129129
// 解析model指令,model指令格式:model:name="{{youName}}"
130130
validator.checkModel(name, value, output, node, locationInfo, options)
131+
if (output.isCard) {
132+
throw new Error('卡片不支持 model 指令')
133+
}
131134
} else if (name.match(/^dir:/)) {
132135
// 解析自定义指令,自定义指令格式:dir:指令名称="{{data}}"
133136
validator.checkCustomDirective(name, value, output, node)
137+
if (output.isCard) {
138+
throw new Error('卡片不支持自定义指令')
139+
}
134140
} else {
135141
// 其余为普通属性
136142
validator.checkAttr(name, value, output, node.tagName, locationInfo, options)
@@ -362,7 +368,13 @@ function parse(source, options) {
362368
{ treeAdapter: parse5.treeAdapters.default, locationInfo: true },
363369
options.filePath
364370
)
365-
const output = { result: {}, log: [], depFiles: [], isLite: !!options.lite }
371+
const output = {
372+
result: {},
373+
log: [],
374+
depFiles: [],
375+
isCard: !!options.card,
376+
isLite: !!options.lite
377+
}
366378

367379
// 模板为空或解析失败
368380
/* istanbul ignore if */

packages/hap-compiler/src/template/validator.js

Lines changed: 84 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,7 +1420,13 @@ function checkTagName(node, output, options = {}) {
14201420
*/
14211421
function checkId(id, output) {
14221422
if (id) {
1423-
output.result.id = exp.isExpr(id) ? exp(id, true, output.isLite) : id
1423+
const isLite = output.isLite
1424+
const isCard = output.isCard
1425+
output.result.id = exp.isExpr(id) ? exp(id, true, isLite, isCard) : id
1426+
output.result.idExpr = true
1427+
if (isCard && !isLite) {
1428+
output.result.idRaw = id
1429+
}
14241430
}
14251431
}
14261432

@@ -1456,7 +1462,8 @@ function checkClass(className, output) {
14561462
let classList = []
14571463

14581464
className = className.trim()
1459-
1465+
const isLite = output.isLite
1466+
const isCard = output.isCard
14601467
if (className) {
14611468
let start = 0
14621469
let end = 0
@@ -1477,7 +1484,6 @@ function checkClass(className, output) {
14771484
}
14781485
segs.push(className.slice(start)) // trailing static classes
14791486

1480-
const isLite = output.isLite
14811487
classList = segs.reduce((list, seg) => {
14821488
if (exp.isExpr(seg)) {
14831489
hasBinding = true
@@ -1500,14 +1506,19 @@ function checkClass(className, output) {
15001506
err.expression = className
15011507
throw err
15021508
}
1503-
output.result.class = className
15041509
output.result.classList = classList
15051510
} else if (hasBinding) {
1506-
const code = '(function () {return [' + classList.join(', ') + ']})'
15071511
try {
1508-
/* eslint-disable no-eval */
1509-
output.result.classList = eval(code)
1510-
/* eslint-enable no-eval */
1512+
let code = ''
1513+
if (isCard) {
1514+
code = 'function () {return [' + classList.join(', ') + ']}'
1515+
output.result.classList = code
1516+
} else {
1517+
code = '(function () {return [' + classList.join(', ') + ']})'
1518+
/* eslint-disable no-eval */
1519+
output.result.classList = eval(code)
1520+
/* eslint-enable no-eval */
1521+
}
15111522
} catch (err) {
15121523
err.isExpressionError = true
15131524
err.expression = className
@@ -1520,6 +1531,12 @@ function checkClass(className, output) {
15201531
)
15211532
}
15221533
}
1534+
if (isCard) {
1535+
output.result.class = className
1536+
if (!isLite) {
1537+
output.result.classListRaw = className
1538+
}
1539+
}
15231540
}
15241541

15251542
/**
@@ -1532,9 +1549,11 @@ function checkClass(className, output) {
15321549
*/
15331550
function checkStyle(cssText, output, locationInfo, options) {
15341551
let style = {}
1552+
let styleRaw = {}
15351553
const log = output.log
15361554
if (cssText) {
15371555
const isLite = output.isLite
1556+
const isCard = output.isCard
15381557
if (exp.singleExpr(cssText)) {
15391558
// 检测是否嵌套{{}}
15401559
const incText = exp.removeExprffix(cssText)
@@ -1545,9 +1564,12 @@ function checkStyle(cssText, output, locationInfo, options) {
15451564
reason: 'ERROR: style 属性不能嵌套多层{{}}'
15461565
})
15471566
} else {
1548-
style = exp(cssText, true, isLite)
1567+
style = exp(cssText, true, isLite, isCard)
15491568
}
15501569
output.result.style = style
1570+
if (isCard && !isLite) {
1571+
output.result.styleRaw = cssText
1572+
}
15511573
return
15521574
}
15531575
// 如果是 a: {{}}; b: {{}};, 则分解处理
@@ -1563,13 +1585,18 @@ function checkStyle(cssText, output, locationInfo, options) {
15631585
k = pair[0].trim()
15641586
k = hyphenedToCamelCase(k)
15651587
v = pair[1].trim()
1566-
v = exp(v, true, isLite) // 处理值表达式
1588+
1589+
const valueRaw = v
1590+
v = exp(v, true, isLite, isCard) // 处理值表达式
15671591
vResult = styler.validateDelaration(k, v, options)
15681592
v = vResult.value
15691593
v.forEach((t) => {
15701594
// 如果校验成功,则保存转换后的属性值
15711595
if (isValidValue(t.v) || typeof t.v === 'function') {
15721596
style[t.n] = t.v
1597+
if (isCard && !isLite) {
1598+
styleRaw[t.n] = valueRaw
1599+
}
15731600
}
15741601
})
15751602
if (vResult.log) {
@@ -1590,6 +1617,9 @@ function checkStyle(cssText, output, locationInfo, options) {
15901617
}
15911618
}
15921619
output.result.style = style
1620+
if (isCard && !isLite) {
1621+
output.result.styleRaw = styleRaw
1622+
}
15931623
}
15941624
}
15951625

@@ -1604,9 +1634,14 @@ function checkIs(value, output, locationInfo) {
16041634
if (value) {
16051635
// 如果没有,补充上{{}}
16061636
value = exp.addExprffix(value)
1637+
const isLite = output.isLite
1638+
const isCard = output.isCard
16071639

16081640
// 将表达式转换为function
1609-
output.result.is = exp(value, true, output.isLite)
1641+
output.result.is = exp(value, true, isLite, isCard)
1642+
if (isCard && !isLite) {
1643+
output.result.isRaw = value
1644+
}
16101645
} else {
16111646
log.push({
16121647
line: locationInfo.line || 1,
@@ -1628,6 +1663,7 @@ function checkIf(value, output, not, locationInfo, conditionList) {
16281663
// 如果没有,补充上{{}}
16291664
value = exp.addExprffix(value)
16301665
const isLite = output.isLite
1666+
const isCard = output.isCard
16311667
if (not) {
16321668
value = '{{' + buildConditionExp(conditionList) + '}}'
16331669
} else {
@@ -1636,7 +1672,10 @@ function checkIf(value, output, not, locationInfo, conditionList) {
16361672
conditionList.push(`${value.substr(2, value.length - 4)}`)
16371673
}
16381674
// 将表达式转换为function
1639-
output.result.shown = isLite ? value : exp(value, true)
1675+
output.result.shown = isLite ? value : exp(value, true, isLite, isCard)
1676+
if (isCard && !isLite) {
1677+
output.result.shownRaw = value
1678+
}
16401679
} else {
16411680
if (!not) {
16421681
log.push({
@@ -1674,11 +1713,15 @@ function checkElif(value, cond, output, locationInfo, conditionList) {
16741713
value = exp.addExprffix(value)
16751714
cond = exp.addExprffix(cond)
16761715
const isLite = output.isLite
1716+
const isCard = output.isCard
16771717
newcond =
16781718
'{{(' + value.substr(2, value.length - 4) + ') && ' + buildConditionExp(conditionList) + '}}'
16791719

16801720
// 将表达式转换为function
1681-
output.result.shown = isLite ? newcond : exp(newcond)
1721+
output.result.shown = isLite ? newcond : exp(newcond, true, isLite, isCard)
1722+
if (isCard && !isLite) {
1723+
output.result.shownRaw = newcond
1724+
}
16821725
conditionList.push(`${value.substr(2, value.length - 4)}`)
16831726
} else {
16841727
log.push({
@@ -1719,12 +1762,15 @@ function checkFor(value, output, locationInfo) {
17191762
value = '{{' + value + '}}'
17201763

17211764
const isLite = output.isLite
1722-
let repeat
1765+
const isCard = output.isCard
1766+
let repeat, repeatRaw
17231767
if (!key && !val) {
1724-
repeat = exp(value, true, isLite)
1768+
repeat = exp(value, true, isLite, isCard)
1769+
repeatRaw = value
17251770
} else {
17261771
// 如果指定key,value
1727-
repeat = { exp: exp(value, true, isLite) }
1772+
repeat = { exp: exp(value, true, isLite, isCard) }
1773+
repeatRaw = { expRaw: value }
17281774
if (key) {
17291775
repeat.key = key
17301776
}
@@ -1733,6 +1779,9 @@ function checkFor(value, output, locationInfo) {
17331779
}
17341780
}
17351781
output.result.repeat = repeat
1782+
if (isCard && !isLite) {
1783+
output.result.repeatRaw = repeatRaw
1784+
}
17361785
} else {
17371786
log.push({
17381787
line: locationInfo.line || 1,
@@ -1775,11 +1824,15 @@ function checkEvent(name, value, output) {
17751824
value = '{{' + funcName + '(' + params.join(',') + ')}}'
17761825
try {
17771826
// 将事件转换为函数对象
1778-
/* eslint-disable no-eval */
1779-
value = output.isLite
1780-
? value
1781-
: eval('(function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '})')
1782-
/* eslint-enable no-eval */
1827+
if (output.isCard) {
1828+
value = 'function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '}'
1829+
} else if (!output.isLite) {
1830+
/* eslint-disable no-eval */
1831+
value = eval(
1832+
'(function (evt) { return ' + exp(value, false).replace('this.evt', 'evt') + '})'
1833+
)
1834+
/* eslint-enable no-eval */
1835+
}
17831836
} catch (err) {
17841837
err.isExpressionError = true
17851838
err.expression = originValue
@@ -1809,7 +1862,7 @@ function checkCustomDirective(name, value, output, node) {
18091862
output.result.directives = output.result.directives || []
18101863
output.result.directives.push({
18111864
name: dirName,
1812-
value: exp.isExpr(value) ? exp(value, true, output.isLite) : value
1865+
value: exp.isExpr(value) ? exp(value, true, output.isLite, output.isCard) : value
18131866
})
18141867
}
18151868

@@ -1840,8 +1893,13 @@ function checkAttr(name, value, output, tagName, locationInfo, options) {
18401893
value = resolvePath(value, options.filePath)
18411894
output.depFiles.push(value)
18421895
}
1896+
const isLite = output.isLite
1897+
const isCard = output.isCard
18431898
output.result.attr = output.result.attr || {}
1844-
output.result.attr[hyphenedToCamelCase(name)] = exp(value, true, output.isLite)
1899+
output.result.attr[hyphenedToCamelCase(name)] = exp(value, true, isLite, isCard)
1900+
if (isCard && !isLite) {
1901+
output.result.attr[hyphenedToCamelCase(name) + 'Raw'] = value
1902+
}
18451903
if (name === 'value' && tagName === 'text') {
18461904
output.log.push({
18471905
line: locationInfo.line,
@@ -1982,6 +2040,9 @@ function hasIfOrFor(nodes) {
19822040
return flag
19832041
}
19842042

2043+
/**
2044+
* 检查class数组是否为常量和变量混合的方式,如 "clazz1 {{myClass}}"
2045+
*/
19852046
function isValidClassArray(arr) {
19862047
const filterArr = arr.filter((clazz) => clazz.length > 0)
19872048

0 commit comments

Comments
 (0)