Skip to content

Commit

Permalink
Merge 83316c3 into 894afc4
Browse files Browse the repository at this point in the history
  • Loading branch information
mbland committed Jan 6, 2024
2 parents 894afc4 + 83316c3 commit 3ff1429
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 7 deletions.
6 changes: 2 additions & 4 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
* obtain one at https://mozilla.org/MPL/2.0/.
*/

import PartialCollector from './partial-collector.js'
import collectPartials from './partials.js'
import { createFilter } from '@rollup/pluginutils'
import Handlebars from 'handlebars'

Expand Down Expand Up @@ -125,13 +125,11 @@ export default class PluginImpl {
const ast = Handlebars.parse(code, opts)
const compiled = Handlebars.precompile(ast, opts)
const { code: tmpl = compiled, map: srcMap } = compiled
const collector = new PartialCollector()
collector.accept(ast)

const beforeTmpl = [
IMPORT_HANDLEBARS,
IMPORT_HELPERS,
...collector.partials.map(p => `import '${this.#partialPath(p, id)}'`),
...collectPartials(ast).map(p => `import '${this.#partialPath(p, id)}'`),
'export const RawTemplate = Handlebars.template('
]
const afterTmpl = [
Expand Down
22 changes: 20 additions & 2 deletions lib/partial-collector.js → lib/partials.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import Handlebars from 'handlebars'
* Collects the names of partial templates from a Handlebars template
* @see https://github.com/handlebars-lang/handlebars.js/blob/master/docs/compiler-api.md
*/
export default class PartialCollector extends Handlebars.Visitor {
class PartialCollector extends Handlebars.Visitor {
partials = []

PartialStatement(partial) {
Expand All @@ -55,5 +55,23 @@ export default class PartialCollector extends Handlebars.Visitor {
return super.PartialBlockStatement(partial)
}

collect(n) { if (n.type === 'PathExpression') this.partials.push(n.original) }
collect(n) {
if (n.type === 'PathExpression' && n.original !== '@partial-block') {
this.partials.push(n.original)
}
}
}

/**
* Returns the partial names parsed from a Handlebars template
* @see https://handlebarsjs.com/guide/partials.html
* @see https://github.com/handlebars-lang/handlebars.js/blob/master/docs/compiler-api.md
* @param {object} ast - abstract syntax tree for a Handlebars template returned
* by Handlebars.parse()
* @returns {string[]} - a list of partial names parsed from the template
*/
export default function collectPartials(ast) {
const collector = new PartialCollector()
collector.accept(ast)
return collector.partials
}
2 changes: 1 addition & 1 deletion test/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import { describe, expect, test } from 'vitest'
import HandlebarsPrecompiler from '../index.js'
import { PLUGIN_NAME } from '../lib/index.js'
import { describe, expect, test } from 'vitest'

const PLUGIN_ID = `\0${PLUGIN_NAME}`

Expand Down
74 changes: 74 additions & 0 deletions test/partials.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/

import collectPartials from '../lib/partials.js'
import Handlebars from 'handlebars'
import { describe, expect, test } from 'vitest'

describe('collectPartials', () => {
/**
* Returns the partial names parsed from a Handlebars template
* @param {string} s - Handlebars template strin to parse
* @returns {string[]} - a list of partial names parsed from the template
*/
const partials = (s) => collectPartials(Handlebars.parse(s, {}))

describe('parses', () => {
test('regular partials', () => {
const s = '{{ foo }}{{> bar }}{{ baz }}{{> quux }}{{ xyzzy }}{{> plugh }}'

expect(partials(s))
.toEqual(['bar', 'quux', 'plugh'])
})

test('partials with contexts or parameters', () => {
expect(partials('{{> foo bar}}{{> baz quux=xyzzy }}'))
.toEqual(['foo', 'baz'])
})

test('block partials', () => {
expect(partials('{{#> foo }}bar{{>baz}}quux{{/foo}}'))
.toEqual(['foo', 'baz'])
})
})

describe('ignores', () => {
test('dynamic partials', () => {
expect(partials('{{> foo }}{{> (lookup . ignored) }}{{> bar }}'))
.toEqual(['foo', 'bar'])
})

test('@partial-block', () => {
expect(partials('Some text {{> @partial-block }}'))
.toEqual([])
})

test('inline partials', () => {
// Examples from:
// - https://handlebarsjs.com/guide/partials.html#inline-partials
const s = [
'{{#*inline "myPartial"}}',
' My Content',
'{{/inline}}',
'{{#each people}}',
' {{> myPartial}}',
'{{/each}}',
'',
'{{#> layout}}',
' {{#*inline "nav"}}',
' My Nav',
' {{/inline}}',
' {{#*inline "content"}}',
' My Content',
' {{/inline}}',
'{{/layout}}'
].join('\n')

expect(partials(s))
.toEqual(['myPartial', 'layout'])
})
})
})

0 comments on commit 3ff1429

Please sign in to comment.