Skip to content

Commit

Permalink
Merge pull request Urigo#1348 from kamilkisiela/chore/templates-runtime
Browse files Browse the repository at this point in the history
[WIP] chore(templates): Move common things to angular-templates-runtime
  • Loading branch information
Urigo committed May 1, 2016
2 parents b3ab343 + edaea0e commit 9705d23
Show file tree
Hide file tree
Showing 11 changed files with 186 additions and 460 deletions.
26 changes: 9 additions & 17 deletions packages/angular-blaze-templates-compiler/package.js
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
Package.describe({
name: "angular-blaze-templates-compiler",
summary: "Compile angular templates into the template cache for .ng extensions",
version: "0.0.1",
git: "https://github.com/Urigo/angular-meteor.git",
name: 'angular-blaze-templates-compiler',
summary: 'Compile angular templates into the template cache for .ng extensions',
version: '0.0.1',
git: 'https://github.com/Urigo/angular-meteor.git',
documentation: null
});

Package.registerBuildPlugin({
name: "compileNGTemplate",
name: 'compileNGTemplate',
sources: [
"plugin/ng-caching-html-compiler.js",
"plugin/ng-html-scanner.js",
"plugin/ng-template-compiler.js",
"plugin/ng-annotate.js"
'plugin/ng-caching-html-compiler.js',
'plugin/ng-template-compiler.js',
'plugin/ng-annotate.js'
],
use: [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
'[email protected]'
],
npmDependencies : {
'cheerio': '0.19.0',
'html-minifier' : '0.6.9',
'uglify-js': '2.4.24',
'ng-annotate': '0.15.4'
}
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
NgCachingHtmlCompiler = class NgCachingHtmlCompiler extends CachingHtmlCompiler {
compileOneFile(inputFile) {
const contents = inputFile.getContentsAsString();
var packagePrefix = '';
let packagePrefix = '';

if (inputFile.getPackageName()) {
packagePrefix += '/packages/' + inputFile.getPackageName() + '/';
packagePrefix += `/packages/${inputFile.getPackageName()}/`;
}

const inputPath = packagePrefix + inputFile.getPathInPackage();
try {
const tags = this.tagScannerFunc({
sourceName: inputPath,
contents: contents,
tagNames: ["body", "head", "template"]
tagNames: ['body', 'head', 'template']
});

return this.tagHandlerFunc(tags);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,114 +1,5 @@
var htmlMinifier = Npm.require('html-minifier');

Plugin.registerCompiler({
extensions: ['ng.html'],
archMatching: 'web',
isTemplate: true
}, () => new NgCachingHtmlCompiler("angular", 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 if (this.tag.tagName === 'template') {
var contents = minifyHtml(this.tag.contents);

this.results.js += wrapAngularTemplate(this.tag.attribs.id, 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);
}
}

var minifyHtml = function(html) {
// Just parse the html to make sure it is correct before minifying
HTMLTools.parseFragment(html);

return htmlMinifier.minify(html, {
collapseWhitespace : true,
conservativeCollapse : true,
minifyCSS : true,
minifyJS : true,
processScripts : ['text/template']
});
};

function wrapAngularTemplate(id, contents) {
return "angular.module('angular-meteor').run(['$templateCache', function($templateCache) { $templateCache.put('" +
id + "'," + JSON.stringify(contents) + ");}]);";
}
}, () => new NgCachingHtmlCompiler('angular', AngularTemplates.scanner, AngularTemplates.handler));
4 changes: 4 additions & 0 deletions packages/angular-templates-runtime/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
AngularTemplates = {
scanner: HtmlScan.init,
handler: StaticHtmlTagHandler.init
};
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
scanHtmlForTags = function (options) {
const scan = new HtmlScan(options);
return scan.getTags();
};

/**
* Scan an HTML file for top-level tags and extract their contents. Pass them to
* a tag handler (an object with a handleTag method)
Expand All @@ -11,7 +6,7 @@ scanHtmlForTags = function (options) {
* top-level tags, which are allowed to have attributes,
* and ignores top-level HTML comments.
*/
class HtmlScan {
HtmlScan = class HtmlScan {
/**
* Initialize and run a scan of a single file
* @param {String} sourceName The filename, used in errors only
Expand Down Expand Up @@ -197,3 +192,8 @@ class HtmlScan {
return this.tags;
}
}

HtmlScan.init = function (options) {
const scan = new HtmlScan(options);
return scan.getTags();
};
117 changes: 117 additions & 0 deletions packages/angular-templates-runtime/ng-template-compiler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
var htmlMinifier = Npm.require('html-minifier');
// 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();
}

StaticHtmlTagHandler = 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 if (this.tag.tagName === 'template') {
var contents = minifyHtml(this.tag.contents);

this.results.js += wrapAngularTemplate(this.tag.attribs.id, 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);
}
}

var minifyHtml = function(html) {
// Just parse the html to make sure it is correct before minifying
HTMLTools.parseFragment(html);

return htmlMinifier.minify(html, {
collapseWhitespace : true,
conservativeCollapse : true,
minifyCSS : true,
minifyJS : true,
processScripts : ['text/template']
});
};

function wrapAngularTemplate(id, contents) {
return "angular.module('angular-templates').run(['$templateCache', function($templateCache) { $templateCache.put('" +
id + "'," + JSON.stringify(contents) + ");}]);";
}

StaticHtmlTagHandler.init = function(tags) {
var handler = new StaticHtmlTagHandler();

tags.forEach((tag) => {
handler.addTagToResults(tag);
});

return handler.getResults();
}
40 changes: 40 additions & 0 deletions packages/angular-templates-runtime/package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Package.describe({
name: 'angular-templates-runtime',
summary: 'Compile angular templates into the template cache',
version: '0.0.1',
git: 'https://github.com/Urigo/angular-meteor.git',
documentation: null
});

Npm.depends({
'html-minifier' : '0.6.9',
'uglify-js': '2.4.24',
'cheerio': '0.19.0' // why do we keep it?
});

Package.onUse(function(api) {
api.versionsFrom('[email protected]');

api.use([
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
], 'server');

api.imply([
'[email protected]',
'[email protected]',
'[email protected]'
], 'server');

api.addFiles([
'ng-html-scanner.js',
'ng-template-compiler.js',
'index.js'
], 'server');

api.export([
'AngularTemplates'
], 'server');
});
14 changes: 2 additions & 12 deletions packages/angular-templates/package.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,11 @@ Package.registerBuildPlugin({
name: 'compileNGTemplate',
sources: [
'plugin/ng-caching-html-compiler.js',
'plugin/ng-html-scanner.js',
'plugin/ng-template-compiler.js'
],
use: [
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]',
'[email protected]'
],
npmDependencies : {
'cheerio': '0.19.0',
'html-minifier' : '0.6.9',
'uglify-js': '2.4.24'
}
'[email protected]'
]
});

Package.onUse(function(api) {
Expand Down
Loading

0 comments on commit 9705d23

Please sign in to comment.