UNPKG

grunt-angular-templates

Version:

Grunt build task to concatenate & register your AngularJS templates in the $templateCache

216 lines (180 loc) 5.52 kB
/* * grunt-angular-templates * https://github.com/ericclemmons/grunt-angular-templates * * Copyright (c) 2013 Eric Clemmons * Licensed under the MIT license. */ 'use strict'; var minify = require('html-minifier').minify; var Url = require('url'); /** * Angular Template Compiler * @param {Object} grunt Grunt global variable * @param {Object} options Task options * @param {String} cwd Determines if paths are relative or not * @return {Object} */ var Compiler = function(grunt, options, cwd, expanded) { /** * Wrap individual cache registration script in bootstrap function * * @param {String} script Multiline string of `$templateCache.put(...)` * @return {String} Final template aggregate script */ this.bootstrap = function(module, script) { return options.bootstrap(module, script, options); }; /** * Wrap HTML template in `$templateCache.put(...)` * @param {String} template Multiline HTML template string * @param {String} url URL to act as template ID * @return {String} Template wrapped in `$templateCache.put(...)` */ this.cache = function(template, url, prefix) { var path = prefix; // Force trailing slash if (path.length) { path = path.replace(/\/?$/, '/'); } if(cwd && expanded){ var cwdRegExp = new RegExp('^' + cwd + '\/?'); url = url.replace(cwdRegExp, ''); } // Append formatted URL path += Url.format( Url.parse( url.replace(/\\/g, '/') ) ); return "\n $templateCache.put('" + path + "',\n " + template + "\n );\n"; }; /** * Convert list of files into Javascript that caches their contents * @param {String} module Module name * @param {Array} files List of files relative to `cwd` * @return {String} Final template aggregate script */ this.compile = function(module, files) { var paths = files.map(this.path).filter(function(path) { if (!grunt.file.exists(path)) { grunt.log.warn('Template "' + path + '" not found.'); return false; } return true; }); var script = " 'use strict';" + grunt.util.linefeed; script += paths .map(this.load) .map(this.minify) .map(function(source, i) { return this.customize(source, paths[i]); }.bind(this)) .map(this.stringify) .map(function(string, i) { return this.cache(string, this.url(files[i]), options.prefix); }.bind(this)) .map(grunt.util.normalizelf) .join(grunt.util.linefeed) ; return this.bootstrap(module, script); }; /** * Customize template source * @param {String} source Possibly minified template source * @param {String} path Path to template file * @return {String} */ this.customize = function(source, path) { if (typeof options.source === 'function') { return options.source(source, path, options); } return source; }; /** * Load template path * @param {String} path Template path * @return {String} Template source */ this.load = function(path) { return grunt.file.read(path); }; /** * Run template source through htmlmin * @param {String} source Template source * @return {String} Minified template */ this.minify = function(source) { if (options.htmlmin && Object.keys(options.htmlmin).length) { try { grunt.verbose.writeln('Minifying file: ' +source); source = minify(source, options.htmlmin); } catch (err) { grunt.log.error(err + '\n\n' + source + '\n\n'); } } return source; }; /** * Get static or dynamic module name from file. * @param {String} file File name * @return {String} */ this.module = function(file) { if (typeof options.module === 'function') { return options.module(file, options); } return options.module; }; /** * Group files into individual modules * @param {Array} files Files * @return {Object} Key/Value pair of module + files */ this.modules = function(files) { var modules = {}; files.forEach(function(file) { var module = this.module(file); if (!modules[module]) { modules[module] = []; } modules[module].push(file); }, this); return modules; }; /** * Get path to template file on filesystem * @param {String} file Name of file relative to `cwd` * @return {String} Template path */ this.path = function(file) { if (cwd && !expanded) { return cwd + '/' + file; } return file; }; /** * Convert template source Javascript-friendly lines * @param {String} source Template source * @return {String} */ this.stringify = function(source) { return source.split(/^/gm).map(function(line) { var quote = options.quotes === 'single' ? '\'' : '"'; line = line.replace(/\\/g, '\\\\'); line = line.replace(/\n/g, '\\n'); line = line.replace(/\r/g, '\\r'); var quoteRegExp = new RegExp(quote, 'g'); line = line.replace(quoteRegExp, '\\' + quote); return quote + line + quote; }).join(' +\n ') || '""'; }; /** * Convert file name to URL * @param {String} file File name * @return {String} URL */ this.url = function(file) { if (typeof options.url === 'function') { return options.url(file, options); } return file; }; }; module.exports = Compiler;