Skip to content

Commit d3ea9ce

Browse files
xakdogmichael-ciniawsky
authored andcommitted
feat(index): scopes
1 parent ade7fe2 commit d3ea9ce

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

lib/index.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const merge = require('lodash.merge')
33
const cloneDeep = require('lodash.clonedeep')
44
const parseAndReplace = require('./expression_parser')
55

6-
let delimiters, unescapeDelimiters, delimiterRegex, unescapeDelimiterRegex, conditionals, loops, options
6+
let delimiters, unescapeDelimiters, delimiterRegex, unescapeDelimiterRegex, conditionals, loops, scopes, options
77

88
module.exports = function PostHTMLExpressions (_options = {}) {
99
options = _options
@@ -19,6 +19,7 @@ module.exports = function PostHTMLExpressions (_options = {}) {
1919

2020
// conditional and loop options
2121
conditionals = options.conditionalTags || ['if', 'elseif', 'else']
22+
scopes = options.scopeTags || ['scope']
2223
loops = options.loopTags || ['each']
2324

2425
// kick off the parsing
@@ -60,7 +61,7 @@ function walk (opts, nodes) {
6061
}
6162

6263
// if the node has content, recurse (unless it's a loop, handled later)
63-
if (node.content && node.tag !== loops[0]) {
64+
if (node.content && node.tag !== loops[0] && node.tag !== scopes[0]) {
6465
node.content = walk(opts, node.content)
6566
}
6667

@@ -159,6 +160,27 @@ function walk (opts, nodes) {
159160
return m
160161
}
161162

163+
// parse scopes
164+
if (node.tag === scopes[0]) {
165+
console.log('scopes found')
166+
// handle syntax error
167+
if (!(node.attrs && node.attrs.with)) {
168+
throw new Error(`the "${scopes[0]}" tag must have a "with" attribute`)
169+
}
170+
171+
const target = vm.runInContext(node.attrs.with, ctx)
172+
173+
// handle additional syntax errors
174+
if (typeof target !== 'object' || Array.isArray(target)) {
175+
throw new Error('You must provide an object to make scope')
176+
}
177+
178+
m.push(executeScoped(target, node))
179+
180+
// return directly out of the loop, which will skip the "each" tag
181+
return m
182+
}
183+
162184
// return the node
163185
m.push(node)
164186
return m
@@ -248,10 +270,19 @@ function executeLoop (loopParams, p1, p2, node) {
248270
const scopedLocals = {}
249271
scopedLocals[loopParams[0]] = p1
250272
if (loopParams[1]) scopedLocals[loopParams[1]] = p2
273+
274+
return executeScoped(scopedLocals, node)
275+
}
276+
277+
/**
278+
* Runs walk function with arbitrary set of local variables
279+
*/
280+
function executeScoped (scopedLocals, node) {
251281
// merge nondestructively into existing locals
252282
const scopedOptions = merge(cloneDeep(options), { locals: scopedLocals })
253283
// walk through the contents and run replacements with modified options
254284
// we need to clone the node because the normal operation modifies
255285
// the node directly
256286
return walk(scopedOptions, cloneDeep(node.content))
257287
}
288+

0 commit comments

Comments
 (0)