Skip to content

Commit 06cab90

Browse files
committed
fix scope getters
1 parent c25dd53 commit 06cab90

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

src/directives/scope.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { Context } from '../walk'
55
export const createScopedContext = (ctx: Context, data: object): Context => {
66
if (isObject(data)) {
77
const parentScope = ctx.scope
8-
const mergedScope = Object.assign(Object.create(parentScope), data)
8+
const mergedScope = Object.create(parentScope)
9+
Object.defineProperties(mergedScope, Object.getOwnPropertyDescriptors(data))
910
const proxy = new Proxy(mergedScope, {
1011
set(target, key, val, receiver) {
1112
// when setting a property that doesn't exist on current scope,

src/eval.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ export const evaluate = (scope: any, exp: string, el?: Node) => {
55
try {
66
return fn(scope, el)
77
} catch (e) {
8+
if (import.meta.env.DEV) {
9+
console.warn(`Error when evaluating expression "${exp}":`)
10+
}
811
console.error(e)
912
}
1013
}

src/walk.ts

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,16 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
6666

6767
// v-scope
6868
if ((exp = checkAttr(el, 'v-scope')) || exp === '') {
69-
ctx = createScopedContext(ctx, exp ? evaluate(ctx.scope, exp) : {})
69+
const scope = exp ? evaluate(ctx.scope, exp) : {}
70+
ctx = createScopedContext(ctx, scope)
71+
if (scope.$template) {
72+
resolveTemplate(el, scope.$template)
73+
}
7074
}
7175

76+
// process children first before self attrs
77+
walkChildren(el, ctx)
78+
7279
// other directives
7380
let deferredModel
7481
for (const { name, value } of [...el.attributes]) {
@@ -98,19 +105,20 @@ export const walk = (node: Node, ctx: Context): ChildNode | null | void => {
98105
segments.push(`$s(${match[1]})`)
99106
lastIndex = match.index + match[0].length
100107
}
101-
if (lastIndex < data.length - 1) {
108+
if (lastIndex < data.length) {
102109
segments.push(JSON.stringify(data.slice(lastIndex)))
103110
}
104111
applyDirective(node, text, segments.join('+'), ctx)
105112
}
113+
} else if (type === 11) {
114+
walkChildren(node as DocumentFragment, ctx)
106115
}
116+
}
107117

108-
if (type === 1 || type === 11) {
109-
// element or fragment - process children
110-
let child = node.firstChild
111-
while (child) {
112-
child = walk(child, ctx) || child.nextSibling
113-
}
118+
const walkChildren = (node: Element | DocumentFragment, ctx: Context) => {
119+
let child = node.firstChild
120+
while (child) {
121+
child = walk(child, ctx) || child.nextSibling
114122
}
115123
}
116124

@@ -165,3 +173,17 @@ const applyDirective = (
165173
ctx.cleanups.push(cleanup)
166174
}
167175
}
176+
177+
const resolveTemplate = (el: Element, template: string) => {
178+
if (template[0] === '#') {
179+
const templateEl = document.querySelector(template)
180+
if (import.meta.env.DEV && !templateEl) {
181+
console.error(
182+
`template selector ${template} has no matching <template> element.`
183+
)
184+
}
185+
el.appendChild((templateEl as HTMLTemplateElement).content.cloneNode(true))
186+
return
187+
}
188+
el.innerHTML = template
189+
}

0 commit comments

Comments
 (0)