mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
1. Make a package called `static-html` that just compiles `<head>` and `<body>` tags inside `.html` files. Much like templating but without the templates. 2. Refactor `templating` to avoid duplicating code. Split out code that would be shared between `templating` and `static-html` into a new `templating-tools` package. These tools could also be used to simplify implementation of other build plugins, like `simple:markdown-templating`. This also has the added benefit of moving as much code as humanly possible out of the `templating` package, so that it can be reused in other packages. 1. `templating-tools` package and its README 2. `static-html` package and its README 3. `caching-html-compiler` is not new code; it is just code factored out of the batch plugin version of `templating`, but the README and some comments are new. 1. `tools/tests/static-html.js` tests static html and error handling 2. `templating-tools/html-scanner-tests.js` tests `scanHtmlForTags` and `compileTagsWithSpacebars` together. All unit tests pass on this branch.
91 lines
2.3 KiB
JavaScript
91 lines
2.3 KiB
JavaScript
Plugin.registerCompiler({
|
|
extensions: ['html'],
|
|
archMatching: 'web',
|
|
isTemplate: true
|
|
}, () => new CachingHtmlCompiler("static-html", TemplatingTools.scanHtmlForTags, compileTagsToStaticHtml));
|
|
|
|
// Same API as TutorialTools.compileTagsWithSpacebars, but instead of compiling
|
|
// with Spacebars, it just returns static HTML
|
|
function compileTagsToStaticHtml(tags) {
|
|
var handler = new StaticHtmlTagHandler();
|
|
|
|
tags.forEach((tag) => {
|
|
handler.addTagToResults(tag);
|
|
});
|
|
|
|
return handler.getResults();
|
|
};
|
|
|
|
class StaticHtmlTagHandler {
|
|
constructor() {
|
|
this.results = {
|
|
head: '',
|
|
body: '',
|
|
js: '',
|
|
bodyAttrs: {}
|
|
};
|
|
}
|
|
|
|
getResults() {
|
|
return this.results;
|
|
}
|
|
|
|
addTagToResults(tag) {
|
|
this.tag = tag;
|
|
|
|
// do we have 1 or more attributes?
|
|
const hasAttribs = ! _.isEmpty(this.tag.attribs);
|
|
|
|
if (this.tag.tagName === "head") {
|
|
if (hasAttribs) {
|
|
this.throwCompileError("Attributes on <head> not supported");
|
|
}
|
|
|
|
this.results.head += this.tag.contents;
|
|
return;
|
|
}
|
|
|
|
|
|
// <body> or <template>
|
|
|
|
try {
|
|
if (this.tag.tagName === "body") {
|
|
this.addBodyAttrs(this.tag.attribs);
|
|
|
|
// We may be one of many `<body>` tags.
|
|
this.results.body += this.tag.contents;
|
|
} else {
|
|
this.throwCompileError("Expected <head> or <body> tag", this.tag.tagStartIndex);
|
|
}
|
|
} catch (e) {
|
|
if (e.scanner) {
|
|
// The error came from Spacebars
|
|
this.throwCompileError(e.message, this.tag.contentsStartIndex + e.offset);
|
|
} else {
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
|
|
addBodyAttrs(attrs) {
|
|
Object.keys(attrs).forEach((attr) => {
|
|
const val = attrs[attr];
|
|
|
|
// This check is for conflicting body attributes in the same file;
|
|
// we check across multiple files in caching-html-compiler using the
|
|
// attributes on results.bodyAttrs
|
|
if (this.results.bodyAttrs.hasOwnProperty(attr) && this.results.bodyAttrs[attr] !== val) {
|
|
this.throwCompileError(
|
|
`<body> declarations have conflicting values for the '${attr}' attribute.`);
|
|
}
|
|
|
|
this.results.bodyAttrs[attr] = val;
|
|
});
|
|
}
|
|
|
|
throwCompileError(message, overrideIndex) {
|
|
TemplatingTools.throwCompileError(this.tag, message, overrideIndex);
|
|
}
|
|
}
|
|
|