forked from vuejs/core
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcompileStyleAttrs.ts
More file actions
94 lines (86 loc) · 2.86 KB
/
compileStyleAttrs.ts
File metadata and controls
94 lines (86 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import {
AttributeNode,
BindingMetadata,
createRoot,
createSimpleExpression,
createTransformContext,
DirectiveNode,
NodeTypes,
processExpression,
SimpleExpressionNode
} from "@vue/compiler-core";
import {ScriptCompileContext} from "../script/context";
export const CE_STYLE_ATTRS_HELPER = `useCEStyleAttrs`
export function genCEStyleAttrs( ctx: ScriptCompileContext){
const ceStyleAttrs = ctx.descriptor.ceStyleAttrs
let code = ''
for (let i = 0; i < ceStyleAttrs.length; i++) {
const ceStyleAttr = ceStyleAttrs[i]
code = `${code}${doGenStyleAttrsCode(ceStyleAttr, ctx.bindingMetadata)},\n`
}
return `_${CE_STYLE_ATTRS_HELPER}(_ctx => ([\n${code}]))`
}
function doGenStyleAttrsCode(
attrs: Array<AttributeNode | DirectiveNode>,
bindings: BindingMetadata,
){
const attrsExp = genAttrsFromList(attrs)
const exp = createSimpleExpression(attrsExp, false)
const context = createTransformContext(createRoot([]), {
prefixIdentifiers: true,
inline: true,
bindingMetadata: bindings.__isScriptSetup === false ? undefined : bindings
})
const transformed = processExpression(exp, context)
return transformed.type === NodeTypes.SIMPLE_EXPRESSION
? transformed.content
: transformed.children
.map(c => {
return typeof c === 'string'
? c
: (c as SimpleExpressionNode).content
})
.join('')
}
function genAttrsFromList(attrs: Array<AttributeNode | DirectiveNode>,){
let code = ' {\n'
let keySet = new Set<string>()
for (let i = 0; i < attrs.length; i++) {
const attr = attrs[i]
if(attr.type === 6){
const key = `"${attr.name}"`
if(keySet.has(key)) continue
const val = `${(attr as AttributeNode).value ? (attr as AttributeNode).value?.content : 'undefined'}`
code = code + ` ${key}: ${val},\n`
keySet.add(key)
} else if(attr.type === 7){
const arg = (attr as DirectiveNode).arg! as SimpleExpressionNode
const key = !arg.isStatic ? `[${arg.content}]` : `"${arg.content}"`
if(keySet.has(key)) continue
code = code + ` ${key}: ${((attr as DirectiveNode).exp! as SimpleExpressionNode).content},\n`
keySet.add(key)
}
}
code = code + ' }'
return code
}
// TODO normal script
// TODO 兼容 useCSSvars
// TODO unit test
/*
const __sfc__ = {};
import { openBlock as _openBlock, createElementBlock as _createElementBlock, defineCustomElement as _defineCustomElement } from "vue"
function render(_ctx, _cache) {
return (_openBlock(), _createElementBlock("h1", null, " app "))
}
__sfc__.render = render
__sfc__.__file = "src/App.vue"
export default customElements.define(name, _defineCustomElement(constructor), options);
*/
// :id="{ id: msg3, 'other-attr': msg }"
// id="{ id: msg3, 'other-attr': msg }"
// .id="{ id: msg3, 'other-attr': msg }"
// v-bind:src="msg2s"
// v-bind:[msg]="msg2"
// :[msg]="msg2"
// :xlink:special="msg3"