@@ -1420,7 +1420,13 @@ function checkTagName(node, output, options = {}) {
1420
1420
*/
1421
1421
function checkId ( id , output ) {
1422
1422
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
+ }
1424
1430
}
1425
1431
}
1426
1432
@@ -1456,7 +1462,8 @@ function checkClass(className, output) {
1456
1462
let classList = [ ]
1457
1463
1458
1464
className = className . trim ( )
1459
-
1465
+ const isLite = output . isLite
1466
+ const isCard = output . isCard
1460
1467
if ( className ) {
1461
1468
let start = 0
1462
1469
let end = 0
@@ -1477,7 +1484,6 @@ function checkClass(className, output) {
1477
1484
}
1478
1485
segs . push ( className . slice ( start ) ) // trailing static classes
1479
1486
1480
- const isLite = output . isLite
1481
1487
classList = segs . reduce ( ( list , seg ) => {
1482
1488
if ( exp . isExpr ( seg ) ) {
1483
1489
hasBinding = true
@@ -1500,14 +1506,19 @@ function checkClass(className, output) {
1500
1506
err . expression = className
1501
1507
throw err
1502
1508
}
1503
- output . result . class = className
1504
1509
output . result . classList = classList
1505
1510
} else if ( hasBinding ) {
1506
- const code = '(function () {return [' + classList . join ( ', ' ) + ']})'
1507
1511
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
+ }
1511
1522
} catch ( err ) {
1512
1523
err . isExpressionError = true
1513
1524
err . expression = className
@@ -1520,6 +1531,12 @@ function checkClass(className, output) {
1520
1531
)
1521
1532
}
1522
1533
}
1534
+ if ( isCard ) {
1535
+ output . result . class = className
1536
+ if ( ! isLite ) {
1537
+ output . result . classListRaw = className
1538
+ }
1539
+ }
1523
1540
}
1524
1541
1525
1542
/**
@@ -1532,9 +1549,11 @@ function checkClass(className, output) {
1532
1549
*/
1533
1550
function checkStyle ( cssText , output , locationInfo , options ) {
1534
1551
let style = { }
1552
+ let styleRaw = { }
1535
1553
const log = output . log
1536
1554
if ( cssText ) {
1537
1555
const isLite = output . isLite
1556
+ const isCard = output . isCard
1538
1557
if ( exp . singleExpr ( cssText ) ) {
1539
1558
// 检测是否嵌套{{}}
1540
1559
const incText = exp . removeExprffix ( cssText )
@@ -1545,9 +1564,12 @@ function checkStyle(cssText, output, locationInfo, options) {
1545
1564
reason : 'ERROR: style 属性不能嵌套多层{{}}'
1546
1565
} )
1547
1566
} else {
1548
- style = exp ( cssText , true , isLite )
1567
+ style = exp ( cssText , true , isLite , isCard )
1549
1568
}
1550
1569
output . result . style = style
1570
+ if ( isCard && ! isLite ) {
1571
+ output . result . styleRaw = cssText
1572
+ }
1551
1573
return
1552
1574
}
1553
1575
// 如果是 a: {{}}; b: {{}};, 则分解处理
@@ -1563,13 +1585,18 @@ function checkStyle(cssText, output, locationInfo, options) {
1563
1585
k = pair [ 0 ] . trim ( )
1564
1586
k = hyphenedToCamelCase ( k )
1565
1587
v = pair [ 1 ] . trim ( )
1566
- v = exp ( v , true , isLite ) // 处理值表达式
1588
+
1589
+ const valueRaw = v
1590
+ v = exp ( v , true , isLite , isCard ) // 处理值表达式
1567
1591
vResult = styler . validateDelaration ( k , v , options )
1568
1592
v = vResult . value
1569
1593
v . forEach ( ( t ) => {
1570
1594
// 如果校验成功,则保存转换后的属性值
1571
1595
if ( isValidValue ( t . v ) || typeof t . v === 'function' ) {
1572
1596
style [ t . n ] = t . v
1597
+ if ( isCard && ! isLite ) {
1598
+ styleRaw [ t . n ] = valueRaw
1599
+ }
1573
1600
}
1574
1601
} )
1575
1602
if ( vResult . log ) {
@@ -1590,6 +1617,9 @@ function checkStyle(cssText, output, locationInfo, options) {
1590
1617
}
1591
1618
}
1592
1619
output . result . style = style
1620
+ if ( isCard && ! isLite ) {
1621
+ output . result . styleRaw = styleRaw
1622
+ }
1593
1623
}
1594
1624
}
1595
1625
@@ -1604,9 +1634,14 @@ function checkIs(value, output, locationInfo) {
1604
1634
if ( value ) {
1605
1635
// 如果没有,补充上{{}}
1606
1636
value = exp . addExprffix ( value )
1637
+ const isLite = output . isLite
1638
+ const isCard = output . isCard
1607
1639
1608
1640
// 将表达式转换为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
+ }
1610
1645
} else {
1611
1646
log . push ( {
1612
1647
line : locationInfo . line || 1 ,
@@ -1628,6 +1663,7 @@ function checkIf(value, output, not, locationInfo, conditionList) {
1628
1663
// 如果没有,补充上{{}}
1629
1664
value = exp . addExprffix ( value )
1630
1665
const isLite = output . isLite
1666
+ const isCard = output . isCard
1631
1667
if ( not ) {
1632
1668
value = '{{' + buildConditionExp ( conditionList ) + '}}'
1633
1669
} else {
@@ -1636,7 +1672,10 @@ function checkIf(value, output, not, locationInfo, conditionList) {
1636
1672
conditionList . push ( `${ value . substr ( 2 , value . length - 4 ) } ` )
1637
1673
}
1638
1674
// 将表达式转换为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
+ }
1640
1679
} else {
1641
1680
if ( ! not ) {
1642
1681
log . push ( {
@@ -1674,11 +1713,15 @@ function checkElif(value, cond, output, locationInfo, conditionList) {
1674
1713
value = exp . addExprffix ( value )
1675
1714
cond = exp . addExprffix ( cond )
1676
1715
const isLite = output . isLite
1716
+ const isCard = output . isCard
1677
1717
newcond =
1678
1718
'{{(' + value . substr ( 2 , value . length - 4 ) + ') && ' + buildConditionExp ( conditionList ) + '}}'
1679
1719
1680
1720
// 将表达式转换为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
+ }
1682
1725
conditionList . push ( `${ value . substr ( 2 , value . length - 4 ) } ` )
1683
1726
} else {
1684
1727
log . push ( {
@@ -1719,12 +1762,15 @@ function checkFor(value, output, locationInfo) {
1719
1762
value = '{{' + value + '}}'
1720
1763
1721
1764
const isLite = output . isLite
1722
- let repeat
1765
+ const isCard = output . isCard
1766
+ let repeat , repeatRaw
1723
1767
if ( ! key && ! val ) {
1724
- repeat = exp ( value , true , isLite )
1768
+ repeat = exp ( value , true , isLite , isCard )
1769
+ repeatRaw = value
1725
1770
} else {
1726
1771
// 如果指定key,value
1727
- repeat = { exp : exp ( value , true , isLite ) }
1772
+ repeat = { exp : exp ( value , true , isLite , isCard ) }
1773
+ repeatRaw = { expRaw : value }
1728
1774
if ( key ) {
1729
1775
repeat . key = key
1730
1776
}
@@ -1733,6 +1779,9 @@ function checkFor(value, output, locationInfo) {
1733
1779
}
1734
1780
}
1735
1781
output . result . repeat = repeat
1782
+ if ( isCard && ! isLite ) {
1783
+ output . result . repeatRaw = repeatRaw
1784
+ }
1736
1785
} else {
1737
1786
log . push ( {
1738
1787
line : locationInfo . line || 1 ,
@@ -1775,11 +1824,15 @@ function checkEvent(name, value, output) {
1775
1824
value = '{{' + funcName + '(' + params . join ( ',' ) + ')}}'
1776
1825
try {
1777
1826
// 将事件转换为函数对象
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
+ }
1783
1836
} catch ( err ) {
1784
1837
err . isExpressionError = true
1785
1838
err . expression = originValue
@@ -1809,7 +1862,7 @@ function checkCustomDirective(name, value, output, node) {
1809
1862
output . result . directives = output . result . directives || [ ]
1810
1863
output . result . directives . push ( {
1811
1864
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
1813
1866
} )
1814
1867
}
1815
1868
@@ -1840,8 +1893,13 @@ function checkAttr(name, value, output, tagName, locationInfo, options) {
1840
1893
value = resolvePath ( value , options . filePath )
1841
1894
output . depFiles . push ( value )
1842
1895
}
1896
+ const isLite = output . isLite
1897
+ const isCard = output . isCard
1843
1898
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
+ }
1845
1903
if ( name === 'value' && tagName === 'text' ) {
1846
1904
output . log . push ( {
1847
1905
line : locationInfo . line ,
@@ -1982,6 +2040,9 @@ function hasIfOrFor(nodes) {
1982
2040
return flag
1983
2041
}
1984
2042
2043
+ /**
2044
+ * 检查class数组是否为常量和变量混合的方式,如 "clazz1 {{myClass}}"
2045
+ */
1985
2046
function isValidClassArray ( arr ) {
1986
2047
const filterArr = arr . filter ( ( clazz ) => clazz . length > 0 )
1987
2048
0 commit comments