├── .gitignore ├── LICENSE ├── README.md ├── examples ├── dist │ └── .gitkeep ├── gulpfile.js └── templates │ ├── test.tpl.html │ ├── test2.tpl.html │ └── test3.tpl.html ├── index.js ├── lib ├── adapters │ ├── angular.js │ └── javascript.js ├── compile.js └── utils.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | lib-cov 2 | *.seed 3 | *.log 4 | *.csv 5 | *.dat 6 | *.out 7 | *.pid 8 | *.gz 9 | 10 | pids 11 | logs 12 | results 13 | 14 | .idea/** 15 | 16 | npm-debug.log 17 | node_modules 18 | examples/dist/*.* 19 | !.gitkeep -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 xvfeng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gulp-html2js 2 | ============ 3 | 4 | [![NPM version][npm-image]][npm-url] 5 | [![Downloads][downloads-image]][downloads-url] 6 | 7 | Gulp plugin for converting AngularJS templates to JavaScript 8 | 9 | See more from [grunt-html2js](https://github.com/karlgoldstein/grunt-html2js) 10 | 11 | 12 | ## Install 13 | Install with [npm](https://npmjs.org/package/gulp-html2js) 14 | `npm install --save-dev gulp-html2js` 15 | 16 | ## Usage 17 | 18 | ### Angular 19 | 20 | ```javascript 21 | var gulp = require('gulp'); 22 | var html2js = require('gulp-html2js'); 23 | 24 | gulp.task('default', function () { 25 | gulp.src('templates/*.html') 26 | .pipe(html2js('angular.js', { 27 | adapter: 'angular', 28 | base: 'templates', 29 | name: 'angular-demo' 30 | })) 31 | .pipe(gulp.dest('dist/')); 32 | }); 33 | ``` 34 | 35 | ### Vanilla 36 | 37 | ```javascript 38 | var gulp = require('gulp'); 39 | var html2js = require('gulp-html2js'); 40 | 41 | gulp.task('default', function () { 42 | gulp.src('templates/*.html') 43 | .pipe(html2js('js-demo.js', { 44 | adapter: 'javascript', 45 | base: 'templates', 46 | name: 'js-demo' 47 | })) 48 | .pipe(gulp.dest('dist/')); 49 | }); 50 | ``` 51 | 52 | ## Available options 53 | * base - project source path default to "." 54 | * quoteChar - default to " 55 | * indentString - default to " " (two spaces) 56 | * target (coffee support to be added) 57 | * useStrict - default to false 58 | * name - module name 59 | 60 | ## LICENSE 61 | 62 | (MIT License) 63 | 64 | Copyright (c) 2015 Fraserxu 65 | 66 | [npm-image]: https://img.shields.io/npm/v/gulp-html2js.svg?style=flat-square 67 | [npm-url]: https://npmjs.org/package/gulp-html2js 68 | [downloads-image]: http://img.shields.io/npm/dm/gulp-html2js.svg?style=flat-square 69 | [downloads-url]: https://npmjs.org/package/gulp-html2js 70 | -------------------------------------------------------------------------------- /examples/dist/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fraserxu/gulp-html2js/a09dea5ca88babddb42aed8805ccb199e5e79270/examples/dist/.gitkeep -------------------------------------------------------------------------------- /examples/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var html2js = require('../'); 3 | 4 | gulp.task('default', function () { 5 | gulp.src('templates/*.html') 6 | .pipe(html2js('js-demo.js', { 7 | adapter: 'javascript', 8 | name: 'demo', 9 | base: 'templates' 10 | })) 11 | .pipe(gulp.dest('dist/')); 12 | 13 | gulp.src('templates/*.html') 14 | .pipe(html2js('angular.js', { 15 | adapter: 'angular', 16 | name: 'angular-demo' 17 | })) 18 | .pipe(gulp.dest('dist/')); 19 | }); 20 | -------------------------------------------------------------------------------- /examples/templates/test.tpl.html: -------------------------------------------------------------------------------- 1 | Testing01... -------------------------------------------------------------------------------- /examples/templates/test2.tpl.html: -------------------------------------------------------------------------------- 1 | Testing02... -------------------------------------------------------------------------------- /examples/templates/test3.tpl.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 | Lorem ipsum 6 | 7 | 8 | 9 |
-------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var through = require('through2'); 4 | var path = require('path'); 5 | var gutil = require('gulp-util'); 6 | var htmlToJs = require('./lib/compile'); 7 | var PluginError = gutil.PluginError; 8 | var File = gutil.File; 9 | var PLUGIN_NAME = 'gulp-html2js'; 10 | 11 | // file can be a vinyl file object or a string 12 | // when a string it will construct a new one 13 | module.exports = function (file, opt) { 14 | if (!file) { 15 | throw new PluginError(PLUGIN_NAME, 'Missing file option for gulp-html-to-js'); 16 | } 17 | var opt = opt || {}; 18 | opt.base = opt.base || '.' 19 | opt.quoteChar = opt.quoteChar || '"' 20 | opt.indentString = opt.indentString || ' ' 21 | opt.target = opt.target || '' 22 | opt.htmlmin = opt.htmlmin || {} 23 | opt.useStrict = opt.useStrict || false 24 | opt.outputModuleName = opt.outputModuleName || false; 25 | opt.separator = gutil.linefeed; 26 | 27 | var _module, 28 | latestFile, 29 | latestMod; 30 | 31 | return through.obj(function (file, enc, cb) { 32 | // ignore empty files 33 | if (file.isNull()) { 34 | cb(); 35 | return; 36 | } 37 | if (!latestMod || file.stat && file.stat.mtime > latestMod) { 38 | latestFile = file; 39 | latestMod = file.stat && file.stat.mtime; 40 | } 41 | 42 | // we don't do streams (yet) 43 | if (file.isStream()) { 44 | this.emit('error', new PluginError(PLUGIN_NAME, 'Streaming not supported')); 45 | cb(); 46 | return; 47 | } 48 | // construct concat instance 49 | if (!_module) { 50 | _module = new htmlToJs(opt); 51 | } 52 | // add file to concat instance 53 | _module.add(file.path, file.contents.toString()); 54 | cb(); 55 | }, function (cb) { 56 | // no files passed in, no file goes out 57 | if (!latestFile || !_module) { 58 | cb(); 59 | return; 60 | } 61 | 62 | 63 | var joinedFile; 64 | 65 | // if file opt was a file path 66 | // clone everything from the latest file 67 | if (typeof file === 'string') { 68 | joinedFile = latestFile.clone({contents: false}); 69 | joinedFile.path = path.join(latestFile.base, file); 70 | } else { 71 | joinedFile = new File(file); 72 | } 73 | 74 | joinedFile.contents = _module.content; 75 | this.push(joinedFile); 76 | cb(); 77 | }); 78 | }; 79 | -------------------------------------------------------------------------------- /lib/adapters/angular.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | function NGAdapter(opt) { 3 | this.opt = opt || {}; 4 | this.opt.name = opt.name || '_html_'; 5 | this.contentParts = []; 6 | this.separator = new Buffer(opt.separator); 7 | }; 8 | 9 | NGAdapter.prototype.getHeader = function () { 10 | return '//HEAD ' + "\n" + 11 | '(function(app) {' + "\n" + 12 | 'try { app = angular.module("' + this.opt.name + '"); }' + "\n" + 13 | 'catch(err) { app = angular.module("' + this.opt.name + '", []); }' + "\n" + 14 | 'app.run(["$templateCache", function($templateCache) {' + "\n" + 15 | '"use strict";' + "\n"; 16 | }; 17 | 18 | NGAdapter.prototype.getFile = function (file, content) { 19 | return '$templateCache.put("' + file + '","' + this.escapeContent(content) + '")' + "\n"; 20 | }; 21 | 22 | NGAdapter.prototype.getFooter = function () { 23 | return '}]);' + "\n" + '})();'; 24 | }; 25 | NGAdapter.prototype.escapeContent = function (content) { 26 | var quoteChar = '"'; 27 | var indentString = " "; 28 | var bsRegexp = new RegExp('\\\\', 'g'); 29 | var quoteRegexp = new RegExp('\\' + quoteChar, 'g'); 30 | var nlReplace = '\\n' + quoteChar + ' +\n' + indentString + indentString + quoteChar; 31 | return content.replace(bsRegexp, '\\\\').replace(quoteRegexp, '\\' + quoteChar).replace(/\r?\n/g, nlReplace); 32 | } 33 | module.exports = NGAdapter; 34 | -------------------------------------------------------------------------------- /lib/adapters/javascript.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | function JSAdapter(opt) { 3 | this.opt = opt || {}; 4 | this.opt.name = opt.name || '_html_'; 5 | this.lineOffset = 0; 6 | this.contentParts = []; 7 | this.separator = new Buffer(opt.separator); 8 | }; 9 | 10 | JSAdapter.prototype.getHeader = function () { 11 | return '//HEAD ' + "\n" + 12 | 'window["' + this.opt.name + '"] = {};' + "\n"; 13 | }; 14 | 15 | JSAdapter.prototype.getFile = function (file, content) { 16 | return 'window["' + this.opt.name + '"]["' + file + '"] = "' + (Buffer.isBuffer(content) ? content : new Buffer(this.escapeContent(content))) + '"; ' + "\n"; 17 | }; 18 | 19 | JSAdapter.prototype.getFooter = function () { 20 | return "// END "; 21 | }; 22 | JSAdapter.prototype.escapeContent = function (content) { 23 | var quoteChar = '"'; 24 | var indentString = " "; 25 | var bsRegexp = new RegExp('\\\\', 'g'); 26 | var quoteRegexp = new RegExp('\\' + quoteChar, 'g'); 27 | var nlReplace = '\\n' + quoteChar + ' +\n' + indentString + indentString + quoteChar; 28 | return content.replace(bsRegexp, '\\\\').replace(quoteRegexp, '\\' + quoteChar).replace(/\r?\n/g, nlReplace); 29 | } 30 | module.exports = JSAdapter; -------------------------------------------------------------------------------- /lib/compile.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var NGAdapter = require('./adapters/angular') 3 | var JSAdapter = require('./adapters/javascript') 4 | 5 | var normalizePath = function (p) { 6 | return path.sep !== '/' ? p.replace(/\\/g, '/') : p; 7 | } 8 | 9 | function html2js(opt) { 10 | this.opt = opt || {}; 11 | this.opt.base = this.opt.base || './'; 12 | this.adapter; 13 | this.contentParts = []; 14 | this.separator = new Buffer(opt.separator || ','); 15 | this.getAdapter(); 16 | } 17 | html2js.prototype.add = function (filePath, content) { 18 | filePath = filePath && normalizePath(filePath); 19 | 20 | var filePath = normalizePath(path.relative(this.opt.base, filePath)) 21 | 22 | if (typeof this.opt.rename === 'function') { 23 | filePath = this.opt.rename(filePath) 24 | } 25 | 26 | if (this.contentParts.length) { 27 | this.contentParts.push(this.separator); 28 | } 29 | 30 | this.contentParts.push(new Buffer(this.adapter.getFile(filePath, content))); 31 | }; 32 | html2js.prototype.getAdapter = function () { 33 | 34 | if (this.adapter) return this.adapter; 35 | 36 | switch (this.opt.adapter) { 37 | case 'angular': 38 | default: 39 | this.adapter = new NGAdapter(this.opt); 40 | break; 41 | case 'javascript': 42 | this.adapter = new JSAdapter(this.opt); 43 | break; 44 | } 45 | this.contentParts = [new Buffer(this.adapter.getHeader())]; 46 | return this.adapter; 47 | } 48 | 49 | Object.defineProperty(html2js.prototype, 'content', { 50 | get: function () { 51 | this.contentParts.push(new Buffer(this.adapter.getFooter())); 52 | return Buffer.concat(this.contentParts); 53 | } 54 | }); 55 | module.exports = html2js; -------------------------------------------------------------------------------- /lib/utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This part comes from grunt library. 3 | * See more from https://github.com/gruntjs/grunt/tree/master/lib/grunt 4 | * 5 | * Copyright (c) 2013 "Cowboy" Ben Alman 6 | * Licensed under the MIT license. 7 | * https://github.com/gruntjs/grunt/blob/master/LICENSE-MIT 8 | */ 9 | 10 | var gutil = require('gulp-util') 11 | var fs = require('fs') 12 | var path = require('path') 13 | 14 | var utils = module.exports = {} 15 | 16 | // What "kind" is a value? 17 | // I really need to rework https://github.com/cowboy/javascript-getclass 18 | var kindsOf = {} 19 | 'Number String Boolean Function RegExp Array Date Error'.split(' ').forEach(function(k) { 20 | kindsOf['[object ' + k + ']'] = k.toLowerCase() 21 | }) 22 | utils.kindOf = function(value) { 23 | // Null or undefined. 24 | if (value == null) { return String(value) } 25 | // Everything else. 26 | return kindsOf[kindsOf.toString.call(value)] || 'object' 27 | } 28 | 29 | // The line feed char for the current system. 30 | utils.linefeed = process.platform === 'win32' ? '\r\n' : '\n' 31 | 32 | // Normalize linefeeds in a string. 33 | utils.normalizelf = function(str) { 34 | return str.replace(/\r\n|\n/g, utils.linefeed) 35 | } 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-html2js", 3 | "version": "0.4.2", 4 | "description": "Gulp plugin for converting AngularJS templates to JavaScript", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/fraserxu/gulp-html2js.git" 9 | }, 10 | "keywords": [ 11 | "gulpplugin" 12 | ], 13 | "author": "fraserxu", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/fraserxu/gulp-html2js/issues" 17 | }, 18 | "devDependencies": { 19 | "gulp": "^3.6.0", 20 | "gulp-concat": "^2.6.0" 21 | }, 22 | "dependencies": { 23 | "gulp-util": "~2.2.0", 24 | "html-minifier": "~0.6.7", 25 | "map-stream": "^0.1.0", 26 | "through2": "^2.0.0" 27 | } 28 | } 29 | --------------------------------------------------------------------------------