├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── CHANGELOG.md ├── Gruntfile.js ├── app ├── USAGE ├── index.js └── templates │ └── styles │ ├── css │ ├── bootstrap.css │ └── main.css │ ├── sass │ ├── main.sass │ └── main.scss │ └── scss │ └── main.scss ├── common └── index.js ├── constant ├── USAGE └── index.js ├── contributing.md ├── controller ├── USAGE └── index.js ├── decorator ├── USAGE └── index.js ├── directive ├── USAGE └── index.js ├── factory ├── USAGE └── index.js ├── filter ├── USAGE └── index.js ├── main └── index.js ├── package.json ├── provider ├── USAGE └── index.js ├── readme.md ├── route ├── USAGE └── index.js ├── script-base.js ├── service ├── USAGE └── index.js ├── templates ├── coffeescript-min │ ├── app.coffee │ ├── controller.coffee │ ├── decorator.coffee │ ├── directive.coffee │ ├── filter.coffee │ ├── service │ │ ├── constant.coffee │ │ ├── factory.coffee │ │ ├── provider.coffee │ │ ├── service.coffee │ │ └── value.coffee │ └── spec │ │ ├── controller.coffee │ │ ├── directive.coffee │ │ ├── filter.coffee │ │ └── service.coffee ├── coffeescript │ ├── app.coffee │ ├── controller.coffee │ ├── decorator.coffee │ ├── directive.coffee │ ├── filter.coffee │ ├── service │ │ ├── constant.coffee │ │ ├── factory.coffee │ │ ├── provider.coffee │ │ ├── service.coffee │ │ └── value.coffee │ └── spec │ │ ├── controller.coffee │ │ ├── directive.coffee │ │ ├── filter.coffee │ │ └── service.coffee ├── common │ ├── Gruntfile.js │ ├── _bower.json │ ├── _package.json │ ├── gitignore │ ├── index.html │ ├── root │ │ ├── .bowerrc │ │ ├── .editorconfig │ │ ├── .gitattributes │ │ ├── .jshintrc │ │ ├── app │ │ │ ├── .buildignore │ │ │ ├── .htaccess │ │ │ ├── 404.html │ │ │ ├── favicon.ico │ │ │ ├── robots.txt │ │ │ └── views │ │ │ │ └── main.html │ │ └── test │ │ │ ├── .jshintrc │ │ │ └── runner.html │ └── view.html ├── javascript-min │ ├── app.js │ ├── controller.js │ ├── decorator.js │ ├── directive.js │ ├── filter.js │ ├── service │ │ ├── constant.js │ │ ├── factory.js │ │ ├── provider.js │ │ ├── service.js │ │ └── value.js │ └── spec │ │ ├── controller.js │ │ ├── directive.js │ │ ├── filter.js │ │ └── service.js └── javascript │ ├── app.js │ ├── controller.js │ ├── decorator.js │ ├── directive.js │ ├── filter.js │ ├── service │ ├── constant.js │ ├── factory.js │ ├── provider.js │ ├── service.js │ └── value.js │ └── spec │ ├── controller.js │ ├── directive.js │ ├── filter.js │ └── service.js ├── test ├── test-appname-substitution.js └── test-file-creation.js ├── util.js ├── value ├── USAGE └── index.js └── view ├── USAGE └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | test/temp 3 | test/UpperCaseBug 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": false, 5 | "curly": false, 6 | "eqeqeq": true, 7 | "eqnull": true, 8 | "immed": true, 9 | "latedef": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "undef": true, 13 | "strict": false, 14 | "trailing": true, 15 | "smarttabs": true 16 | } 17 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | - '0.8' 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ### v0.5.3 (2015-02-27) 3 | 4 | 5 | ## v0.5.0 (2013-10-17) 6 | 7 | 8 | #### Bug Fixes 9 | 10 | * **app:** 11 | * serve files from correct place ([fe2bad04](http://github.com/yeoman/generator-angular/commit/fe2bad0417b3138fa2788c17abcf7eb5be5f3e91)) 12 | * include bootstrap images for css/scss ([e88dba43](http://github.com/yeoman/generator-angular/commit/e88dba43f2e714d69bca366cade453f49a24b62c), closes [#196](http://github.com/yeoman/generator-angular/issues/196)) 13 | * allow normal javascript to be created ([c8190b55](http://github.com/yeoman/generator-angular/commit/c8190b55284e8c1570cc8fafdc8723250f43829b), closes [#329](http://github.com/yeoman/generator-angular/issues/329), [#316](http://github.com/yeoman/generator-angular/issues/316)) 14 | * conditional include of jquery ([bc1e68e3](http://github.com/yeoman/generator-angular/commit/bc1e68e30450edc16145b934487f6df5eaaddcd8), closes [#362](http://github.com/yeoman/generator-angular/issues/362)) 15 | * **build:** 16 | * remove references to global yeomanConfig ([a0f16e26](http://github.com/yeoman/generator-angular/commit/a0f16e265729586802121c0fe3111f974e5145ec)) 17 | * update to grunt-contrib-connect 0.5.0 ([67c0ebf0](http://github.com/yeoman/generator-angular/commit/67c0ebf081889658a33bc690c530c3c8bc8a2c12)) 18 | * update to grunt-contrib-connect 0.4.0 ([368ad7f9](http://github.com/yeoman/generator-angular/commit/368ad7f9a16be0ee67e5182be581669017788f16)) 19 | * **docs:** fixed typo in readme ([a967907c](http://github.com/yeoman/generator-angular/commit/a967907cf523bac752b3fa9ea6363767d8855162)) 20 | * **generator:** add app modules dependency to app ([a45b71c9](http://github.com/yeoman/generator-angular/commit/a45b71c95c18deb85ff7a1538c0b0744e4faa508), closes [#230](http://github.com/yeoman/generator-angular/issues/230)) 21 | * **templates:** 22 | * Gruntfile indentation ([6f7d17e2](http://github.com/yeoman/generator-angular/commit/6f7d17e2a0f1f7f9f8cac3157beb07b82e8cf400)) 23 | * take out semicolons in coffeescript ([e38124ee](http://github.com/yeoman/generator-angular/commit/e38124eeb369b7741adc263f1763c618a918ee65)) 24 | * correct coffee provider template ([86aefe5d](http://github.com/yeoman/generator-angular/commit/86aefe5da49abe82e054666641f8ee4bdc8d555e)) 25 | * value generator should use value template ([67d0c5ad](http://github.com/yeoman/generator-angular/commit/67d0c5ad5cbc58a2dfcfd8f3db1f45be21afe357)) 26 | * **test:** update tests to match service files ([c30464c3](http://github.com/yeoman/generator-angular/commit/c30464c3a5216169026c23a6fea23d273bd0b948), closes [#338](http://github.com/yeoman/generator-angular/issues/338), [#354](http://github.com/yeoman/generator-angular/issues/354)) 27 | * **views:** correct path for sub views ([0568e744](http://github.com/yeoman/generator-angular/commit/0568e74446c5a8e28d2cea1a9a9a5886be190d7d), closes [#359](http://github.com/yeoman/generator-angular/issues/359)) 28 | 29 | 30 | ## v0.4.0 (2013-08-21) 31 | 32 | 33 | #### Bug Fixes 34 | 35 | * **cli:** fix typo in angular:view generator usage ([d62c2e34](http://github.com/yeoman/generator-angular/commit/d62c2e348bcc61a6794ca23df02b6cce3c79d993)) 36 | * **coffee:** 37 | * remove extraneous commas and returns ([6df875cd](http://github.com/yeoman/generator-angular/commit/6df875cd7167aa4a4e9f98a82d2f7fba98a20b0b)) 38 | * remove the semi-colon from the coffee script templates ([cd46aa88](http://github.com/yeoman/generator-angular/commit/cd46aa88953e60d81dfef64b999f751dc4468ab7)) 39 | * **docs:** 40 | * add decorator generator description ([85f07648](http://github.com/yeoman/generator-angular/commit/85f076485ffabf790fe0b7d55b7e3def3a041a6d)) 41 | * add contributing info to contributing file ([2461aad0](http://github.com/yeoman/generator-angular/commit/2461aad08afe186995d737a1d3dd595c20ec3fb3)) 42 | * **readme:** Remove `yo` installation step ([21f00e50](http://github.com/yeoman/generator-angular/commit/21f00e50571d272d19aea1431177f2d7157ee7be)) 43 | * **templates:** 44 | * removed grunt-karma from deps ([19a796f7](http://github.com/yeoman/generator-angular/commit/19a796f71925b6b33232d8a9a8b4f712de80ec40)) 45 | * classify services registered with .service ([8e1d6fdf](http://github.com/yeoman/generator-angular/commit/8e1d6fdf0d3ef23cf0670512295e03cc0f4516d6)) 46 | * new scope for directive spec ([2753c990](http://github.com/yeoman/generator-angular/commit/2753c990dbdc8efc7a5f245868cd10f15080c140)) 47 | * **test:** Add correct paths to generated files ([1d6f3fbf](http://github.com/yeoman/generator-angular/commit/1d6f3fbfcc315316a44b468418918afaad871f57)) 48 | * **wording:** clarify compass/scss feature prompt ([5521fd73](http://github.com/yeoman/generator-angular/commit/5521fd73d396763568b5e7c08043a82a4e8864a9)) 49 | 50 | 51 | #### Features 52 | 53 | * **build:** 54 | * generate karma 0.10 config ([e1cb2067](http://github.com/yeoman/generator-angular/commit/e1cb206710f54c8bea6ed8870566ac4c3e248b40)) 55 | * add autoprefixer support ([c4dfd61d](http://github.com/yeoman/generator-angular/commit/c4dfd61d860f86a97026d1e5188ab78a87f4e6a1), closes [#317](http://github.com/yeoman/generator-angular/issues/317)) 56 | * switch to use load-grunt-tasks ([4e030c78](http://github.com/yeoman/generator-angular/commit/4e030c78387ec2a60581ff6346b707c98ddb2508)) 57 | * show elapsed time for grunt tasks ([cacdd0fb](http://github.com/yeoman/generator-angular/commit/cacdd0fb5815355f6e35343c53e876352e622180)) 58 | * **coffee:** generate source maps for coffeescript ([38a872b3](http://github.com/yeoman/generator-angular/commit/38a872b31e9ccef1aac76bec330c3490303abdac)) 59 | * **gen:** Change ga.js to analytics.js ([17ae9e63](http://github.com/yeoman/generator-angular/commit/17ae9e63b2d11d271b36282bb34567b716099cb9)) 60 | 61 | 62 | ## v0.3.1 (2013-07-24) 63 | 64 | 65 | #* **Bug Fixes:** 66 | 67 | * **app:** 68 | * order of script inclusions ([9919b2d0](http://github.com/yeoman/generator-angular/commit/9919b2d0bb749cbe5e795608c2b93c3504e3298b), closes [#278](http://github.com/yeoman/generator-angular/issues/278)) 69 | * copy glyphicons for sass ([2c458009](http://github.com/yeoman/generator-angular/commit/2c4580096572678de6212c8592fb553c10b3a4c0), closes [#269](http://github.com/yeoman/generator-angular/issues/269)) 70 | * add jQuery \ into index.html template ([3766b4ff](http://github.com/yeoman/generator-angular/commit/3766b4ffe1b91a647a34577ae529d11c994e3a1d)) 71 | * **docs:** 72 | * fix section explaining generating services ([8b4787c6](http://github.com/yeoman/generator-angular/commit/8b4787c649b918cb2baf78369e86c86156bca2ec)) 73 | * Add explicit instructions for installing yo ([8404c068](http://github.com/yeoman/generator-angular/commit/8404c0687ab582e15b1f46f96da4f7812d641912)) 74 | 75 | 76 | #* **Features:** 77 | 78 | * **app:** 79 | * generate Travis config ([38a4ce9b](http://github.com/yeoman/generator-angular/commit/38a4ce9baa207c49c79b2f3128c2c3637164c011)) 80 | * use checkboxes for module selection ([65fe9d25](http://github.com/yeoman/generator-angular/commit/65fe9d25fdc1f9fa9c24c4858915c2b63b4531cb)) 81 | * add jshintrc for testing folder ([8727288b](http://github.com/yeoman/generator-angular/commit/8727288bcefdb255f3c24cf80ab1c7868b86d044)) 82 | * **build:** add support for svg optimization ([03d63c69](http://github.com/yeoman/generator-angular/commit/03d63c69e8006e563baee0cc4a4ba459e7c13ccd)) 83 | 84 | 85 | ## 0.3.0 (2013-06-26) 86 | 87 | #* **Features:** 88 | 89 | * **decorator:** 90 | * Add decorator template files ([c9f80b3d](http://github.com/yeoman/generator-angular/commit/c9f80b3d)) 91 | * Define creation of decorator at decorator/index.js and added USAGE File ([4c53c1ad](http://github.com/yeoman/generator-angular/commit/4c53c1ad)) 92 | * Add prompt if file already exists ([7d9b862c](http://github.com/yeoman/generator-angular/commit/7d9b862c)) 93 | 94 | * **build:** 95 | * Replace regard with contrib-watch ([edf00565](http://github.com/yeoman/generator-angular/commit/edf00565)) 96 | 97 | #* **Bug Fixes:** 98 | 99 | * **build:** 100 | * bad concatenation of main.css ([4c7e4b29](http://github.com/yeoman/generator-angular/commit/4c7e4b29)) 101 | * Bumped yeoman-generator version for new prompt ([9e899bb2](http://github.com/yeoman/generator-angular/commit/9e899bb2)) 102 | * don't override generated css files ([dd6a0cb1](http://github.com/yeoman/generator-angular/commit/dd6a0cb1)) 103 | * use Usemin for all CSS. ([e6c2fa52](http://github.com/yeoman/generator-angular/commit/e6c2fa52)) 104 | * dropped nospawn option from watch ([02f61f82](http://github.com/yeoman/generator-angular/commit/02f61f82)) 105 | * add svg files to the copy task ([4b897ac8](http://github.com/yeoman/generator-angular/commit/4b897ac8)) 106 | * updated generated dependencies ([cab7c423](http://github.com/yeoman/generator-angular/commit/cab7c423)) 107 | * add httpFontsPath to Gruntfile ([b00deb1a](http://github.com/yeoman/generator-angular/commit/b00deb1a)) 108 | * coffeescript build was empty ([54edc9de](http://github.com/yeoman/generator-angular/commit/54edc9de)) 109 | * add compass task only if compass-flavored bootstrap is selected ([4408413e](http://github.com/yeoman/generator-angular/commit/4408413e)) 110 | 111 | * **app:** 112 | * Bootstrap Compass no prompt on Bootstrap no ([e73ffc49](http://github.com/yeoman/generator-angular/commit/e73ffc49)) 113 | * Use boolean prompts ([da89e70d](http://github.com/yeoman/generator-angular/commit/da89e70d)) 114 | * components to bower_components ([01cee4ba](http://github.com/yeoman/generator-angular/commit/01cee4ba)) 115 | 116 | * **coffee:** syntax for minsafe directives ([62677ec0](http://github.com/yeoman/generator-angular/commit/62677ec0)) 117 | 118 | * **decorator:** 119 | 120 | * removed second dot in warning message ([6a89f8e5](http://github.com/yeoman/generator-angular/commit/6a89f8e5)) 121 | * use [] instead of new Array() to initialize prompts (jsHint) ([360222a6](http://github.com/yeoman/generator-angular/commit/360222a6)) 122 | 123 | * **test:** Updated tests for new prompt ([64e57571](http://github.com/yeoman/generator-angular/commit/64e57571)) 124 | 125 | * **cli:** fix typo in angular:constant generator usage ([6cbb80fd](http://github.com/yeoman/generator-angular/commit/6cbb80fd)) 126 | 127 | 128 | ## v0.2.2 (2013-04-20) 129 | 130 | #* **Features:** 131 | * **build:** Integrate grunt-rev into build process (87bab71) 132 | 133 | * **app:** 134 | 135 | * automatically install dependencies (9f95630) 136 | * add coffee option to Karma generator (e81b624) 137 | 138 | * **misc:** add Grunt support to automate releases and changelogs (9daa50a) 139 | 140 | #* **Bug Fixes:** 141 | * **build:** 142 | 143 | * remove all files except git related on clean (21a0f43) 144 | 145 | * fix Bower error caused by incorrect templates. (0ab5448) 146 | 147 | * Moved duplicate grunt options into own section (3869ca8) 148 | 149 | * grunt-bower-hooks was renamed (3bbaacd) 150 | 151 | * Watch SVG files. Fixes generator-webapp#41 (45fe8ab) 152 | 153 | * display correct message when running npm/bower (3498aa1) 154 | 155 | * add Bootstrap reference when not using Compass (d123897) 156 | 157 | * add SVG files to Grunt rev task. (3c8daab) 158 | 159 | * Changed to shallow copy fonts (1f6b864) 160 | 161 | * Ignore test subfolder (a07627b) 162 | 163 | * finify bootstrap img (263ce61) 164 | 165 | * **coffee:** 166 | 167 | * Fix compiling coffeescript files (71daa7f) 168 | 169 | * fix loading coffeescript tests (9692a21) 170 | 171 | * fix coffeescript directive test (aa2a9c0) 172 | 173 | * rewrite app.coffee file when called with --coffee (0f5256d) 174 | 175 | * **app:** 176 | 177 | * Remove `process.cwd()` from CS detection (3a707f4) 178 | 179 | * use this.env.options.appPath (404c752) 180 | 181 | * use `installDependencies()` method (8369d9a) 182 | 183 | * invoke karma:app with `skip-install` option if defined (7e47dc2) 184 | 185 | * tag closing inconsistency (ref #177) (51bd8d8) 186 | 187 | * **test:** 188 | 189 | * Use $scope in tests instead of {} (58603bd) 190 | 191 | * add Node 0.10 to travis file (60b1ea7) 192 | 193 | * **gen:** 194 | 195 | * Fix controller spec generation (3bb58eb) 196 | 197 | * remove trailing comma in gruntfile. (32afa5a) 198 | 199 | * **readme:** 200 | 201 | * add note to readme about making a node_modules dir until global generators are supported (73a2450) 202 | 203 | * add a note about running commands from the root app folder (f986c77) 204 | 205 | * switched to global generators (18ef336) 206 | 207 | * add note to readme about commit message conventions (d125dd2) 208 | 209 | * Improve readme (8262b93) 210 | 211 | * added documentation of route adding (7c5e03c) 212 | 213 | * Corrected file extension in example (a1149ea) 214 | 215 | * **tests:** skip install on tests (5035d94) 216 | 217 | 218 | ## v0.2.1 (2013-04-07) 219 | 220 | #* **Features:** 221 | * **build:** Integrate grunt-rev into build process (87bab71) 222 | 223 | * **app:** automatically install dependencies (9f95630) 224 | 225 | * **misc:** add Grunt support to automate releases and changelogs (9daa50a) 226 | 227 | 228 | 229 | #* **Bug Fixes:** 230 | * **build:** 231 | 232 | * remove all files except git related on clean (21a0f43) 233 | 234 | * fix Bower error caused by incorrect templates. (0ab5448) 235 | 236 | * Moved duplicate grunt options into own section (3869ca8) 237 | 238 | * grunt-bower-hooks was renamed (3bbaacd) 239 | 240 | * Watch SVG files. Fixes generator-webapp#41 (45fe8ab) 241 | 242 | * **coffee:** 243 | 244 | * Fix compiling coffeescript files (71daa7f) 245 | 246 | * fix loading coffeescript tests (9692a21) 247 | 248 | * fix coffeescript directive test (aa2a9c0) 249 | 250 | * rewrite app.coffee file when called with --coffee (0f5256d) 251 | 252 | * **app:** 253 | 254 | * Remove `process.cwd()` from CS detection (3a707f4) 255 | 256 | * **test:** 257 | 258 | * Use $scope in tests instead of {} (58603bd) 259 | 260 | * **gen:** 261 | 262 | * Fix controller spec generation (3bb58eb) 263 | 264 | * **readme:** 265 | 266 | * add note to readme about making a node_modules dir until global generators are supported (73a2450) 267 | 268 | * add a note about running commands from the root app folder (f986c77) 269 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var markdown = require('marked'); 3 | var semver = require('semver'); 4 | 5 | module.exports = function (grunt) { 6 | require('load-grunt-tasks')(grunt); 7 | 8 | grunt.initConfig({ 9 | pkg: grunt.file.readJSON('package.json'), 10 | changelog: { 11 | options: { 12 | dest: 'CHANGELOG.md', 13 | versionFile: 'package.json' 14 | } 15 | }, 16 | release: { 17 | options: { 18 | commitMessage: '<%= version %>', 19 | tagName: 'v<%= version %>', 20 | bump: false, // we have our own bump 21 | file: 'package.json' 22 | } 23 | }, 24 | stage: { 25 | options: { 26 | files: ['CHANGELOG.md'] 27 | } 28 | } 29 | }); 30 | 31 | grunt.registerTask('bump', 'bump manifest version', function (type) { 32 | var options = this.options({ 33 | file: grunt.config('pkgFile') || 'package.json' 34 | }); 35 | 36 | function setup(file, type) { 37 | var pkg = grunt.file.readJSON(file); 38 | var newVersion = pkg.version = semver.inc(pkg.version, type || 'patch'); 39 | return { 40 | file: file, 41 | pkg: pkg, 42 | newVersion: newVersion 43 | }; 44 | } 45 | 46 | var config = setup(options.file, type); 47 | grunt.file.write(config.file, JSON.stringify(config.pkg, null, ' ') + '\n'); 48 | grunt.log.ok('Version bumped to ' + config.newVersion); 49 | }); 50 | 51 | grunt.registerTask('stage', 'git add files before running the release task', function () { 52 | var files = this.options().files; 53 | grunt.util.spawn({ 54 | cmd: process.platform === 'win32' ? 'git.cmd' : 'git', 55 | args: ['add'].concat(files) 56 | }, grunt.task.current.async()); 57 | }); 58 | 59 | grunt.registerTask('default', ['bump', 'changelog', 'stage', 'release']); 60 | }; 61 | -------------------------------------------------------------------------------- /app/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a default AngularJS app 3 | 4 | Example: 5 | yo angular-ui-router [--coffee] [--minsafe] 6 | 7 | This will create: 8 | Gruntfile.js 9 | bower.json 10 | 11 | app/index.html 12 | app/scripts/your-app-name-here.js 13 | app/scripts/controllers/main.js 14 | app/bower_components/angular/angular.js 15 | app/styles/main.css 16 | app/views/main.html 17 | 18 | test/lib/angular-mocks.js 19 | test/spec/controllers/main.js 20 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var util = require('util'); 4 | var spawn = require('child_process').spawn; 5 | var yeoman = require('yeoman-generator'); 6 | 7 | 8 | var Generator = module.exports = function Generator(args, options) { 9 | yeoman.generators.Base.apply(this, arguments); 10 | this.argument('appname', { type: String, required: false }); 11 | this.appname = this.appname || path.basename(process.cwd()); 12 | 13 | args = ['main']; 14 | 15 | if (typeof this.env.options.appPath === 'undefined') { 16 | try { 17 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 18 | } catch (e) {} 19 | this.env.options.appPath = this.env.options.appPath || 'app'; 20 | } 21 | 22 | this.appPath = this.env.options.appPath; 23 | 24 | if (typeof this.env.options.coffee === 'undefined') { 25 | this.option('coffee'); 26 | 27 | // attempt to detect if user is using CS or not 28 | // if cml arg provided, use that; else look for the existence of cs 29 | if (!this.options.coffee && 30 | this.expandFiles(path.join(this.appPath, '/scripts/**/*.coffee'), {}).length > 0) { 31 | this.options.coffee = true; 32 | } 33 | 34 | this.env.options.coffee = this.options.coffee; 35 | } 36 | 37 | if (typeof this.env.options.minsafe === 'undefined') { 38 | this.option('minsafe'); 39 | this.env.options.minsafe = this.options.minsafe; 40 | args.push('--minsafe'); 41 | } 42 | 43 | this.hookFor('angular-ui-router:common', { 44 | args: args 45 | }); 46 | 47 | this.hookFor('angular-ui-router:main', { 48 | args: args 49 | }); 50 | 51 | this.hookFor('angular-ui-router:controller', { 52 | args: args 53 | }); 54 | 55 | this.hookFor('karma', { 56 | as: 'app', 57 | options: { 58 | options: { 59 | coffee: this.options.coffee, 60 | travis: true, 61 | 'skip-install': this.options['skip-install'] 62 | } 63 | } 64 | }); 65 | 66 | this.on('end', function () { 67 | this.installDependencies({ skipInstall: this.options['skip-install'] }); 68 | }); 69 | 70 | this.pkg = JSON.parse(this.readFileAsString(path.join(__dirname, '../package.json'))); 71 | }; 72 | 73 | util.inherits(Generator, yeoman.generators.Base); 74 | 75 | Generator.prototype.askForSass = function askForSass() { 76 | var cb = this.async(); 77 | 78 | this.prompt([{ 79 | type: 'confirm', 80 | name: 'usingSass', 81 | message: 'Would you like to use Sass with the Compass CSS Authoring Framework?', 82 | default: true 83 | }, { 84 | type: 'list', 85 | name: 'syntax', 86 | message: 'Which syntax do you prefer?', 87 | choices: ['sass', 'scss'], 88 | when: function (props) { 89 | return props.usingSass; 90 | } 91 | }], function (props) { 92 | var syntax = props.syntax; 93 | 94 | this.usingSass = props.usingSass; 95 | 96 | if (syntax === 'sass') { 97 | this.sass = true; 98 | } else if (syntax === 'scss') { 99 | this.scss = true; 100 | } 101 | 102 | cb(); 103 | }.bind(this)); 104 | }; 105 | 106 | Generator.prototype.askForBootstrap = function askForBootstrap() { 107 | var cb = this.async(); 108 | 109 | this.prompt([{ 110 | type: 'confirm', 111 | name: 'bootstrap', 112 | message: 'Would you like to include Twitter Bootstrap?', 113 | default: true 114 | },{ 115 | type: 'confirm', 116 | name: 'compassBootstrap', 117 | message: 'Would you like to use the SCSS version of Twitter Bootstrap with the Compass CSS Authoring Framework?', 118 | default: true, 119 | when: function (props) { 120 | return props.bootstrap; 121 | } 122 | }], function (props) { 123 | this.bootstrap = props.bootstrap; 124 | this.compassBootstrap = props.compassBootstrap; 125 | 126 | cb(); 127 | }.bind(this)); 128 | }; 129 | 130 | Generator.prototype.askForModules = function askForModules() { 131 | var cb = this.async(); 132 | 133 | var prompts = [{ 134 | type: 'checkbox', 135 | name: 'modules', 136 | message: 'Which modules would you like to include?', 137 | choices: [{ 138 | value: 'resourceModule', 139 | name: 'angular-resource.js', 140 | checked: true 141 | }, { 142 | value: 'cookiesModule', 143 | name: 'angular-cookies.js', 144 | checked: true 145 | }, { 146 | value: 'sanitizeModule', 147 | name: 'angular-sanitize.js', 148 | checked: true 149 | }, { 150 | value: 'uirouterModule', 151 | name: 'angular-ui-router.js', 152 | checked: true 153 | }] 154 | }]; 155 | 156 | this.prompt(prompts, function (props) { 157 | var hasMod = function (mod) { return props.modules.indexOf(mod) !== -1; }; 158 | this.resourceModule = hasMod('resourceModule'); 159 | this.cookiesModule = hasMod('cookiesModule'); 160 | this.sanitizeModule = hasMod('sanitizeModule'); 161 | this.uirouterModule = hasMod('uirouterModule'); 162 | 163 | var angMods = []; 164 | 165 | if (this.cookiesModule) { 166 | angMods.push("'ngCookies'"); 167 | } 168 | 169 | if (this.resourceModule) { 170 | angMods.push("'ngResource'"); 171 | } 172 | if (this.sanitizeModule) { 173 | angMods.push("'ngSanitize'"); 174 | } 175 | if (this.uirouterModule) { 176 | angMods.push("'ui.router'"); 177 | } 178 | 179 | if (angMods.length) { 180 | this.env.options.uirouterModules = this.uirouterModule; 181 | this.env.options.angularDeps = "\n " + angMods.join(",\n ") +"\n"; 182 | } 183 | 184 | cb(); 185 | }.bind(this)); 186 | }; 187 | 188 | Generator.prototype.readIndex = function readIndex() { 189 | this.indexFile = this.engine(this.read('../../templates/common/index.html'), this); 190 | }; 191 | 192 | Generator.prototype.useSass = function useSass() { 193 | var sass = this.sass; 194 | var scss = this.scss; 195 | var prefix; 196 | 197 | if (this.usingSass && !this.compassBootstrap) { 198 | prefix = sass ? 'sa' : 'sc'; 199 | this.copy('styles/sass/main.' + prefix + 'ss', 'app/styles/main.' + prefix + 'ss'); 200 | } 201 | }; 202 | 203 | // Waiting a more flexible solution for #138 204 | // Added an ugly if-else statemnt to exclude copying main.css when user use sass. 205 | Generator.prototype.bootstrapFiles = function bootstrapFiles() { 206 | var sass = this.compassBootstrap; 207 | var files = []; 208 | var source = 'styles/' + ( sass ? 's' : '' ) + 'css/'; 209 | 210 | if (this.bootstrap) { 211 | if (!sass) { 212 | files.push('bootstrap.css'); 213 | this.copy('fonts/glyphicons-halflings-regular.eot', 'app/fonts/glyphicons-halflings-regular.eot'); 214 | this.copy('fonts/glyphicons-halflings-regular.svg', 'app/fonts/glyphicons-halflings-regular.svg'); 215 | this.copy('fonts/glyphicons-halflings-regular.ttf', 'app/fonts/glyphicons-halflings-regular.ttf'); 216 | this.copy('fonts/glyphicons-halflings-regular.woff', 'app/fonts/glyphicons-halflings-regular.woff'); 217 | this.copy('fonts/glyphicons-halflings-regular.woff2', 'app/fonts/glyphicons-halflings-regular.woff2'); 218 | } 219 | } 220 | 221 | files.push('main.' + (sass ? 's' : '') + 'css'); 222 | 223 | files.forEach(function (file) { 224 | if (file !== 'main.css') { 225 | this.copy(source + file, 'app/styles/' + file); 226 | } else if (!this.sass && !this.scss) { 227 | this.copy(source + file, 'app/styles/' + file); 228 | } 229 | }.bind(this)); 230 | 231 | this.indexFile = this.appendFiles({ 232 | html: this.indexFile, 233 | fileType: 'css', 234 | optimizedPath: 'styles/main.css', 235 | sourceFileList: files.map(function (file) { 236 | return 'styles/' + file.replace('.scss', '.css'); 237 | }), 238 | searchPath: '.tmp' 239 | }); 240 | }; 241 | 242 | Generator.prototype.bootstrapJS = function bootstrapJS() { 243 | if (!this.bootstrap) { 244 | return; // Skip if disabled. 245 | } 246 | 247 | // Wire Twitter Bootstrap plugins 248 | this.indexFile = this.appendScripts(this.indexFile, 'scripts/plugins.js', [ 249 | 'bower_components/twitter-bootstrap-sass/assets/javascripts/bootstrap.js', 250 | ]); 251 | }; 252 | 253 | Generator.prototype.extraModules = function extraModules() { 254 | var modules = []; 255 | if (this.resourceModule) { 256 | modules.push('bower_components/angular-resource/angular-resource.js'); 257 | } 258 | 259 | if (this.cookiesModule) { 260 | modules.push('bower_components/angular-cookies/angular-cookies.js'); 261 | } 262 | 263 | if (this.sanitizeModule) { 264 | modules.push('bower_components/angular-sanitize/angular-sanitize.js'); 265 | } 266 | 267 | if (this.uirouterModule) { 268 | modules.push('bower_components/angular-ui-router/release/angular-ui-router.js'); 269 | } 270 | 271 | if (modules.length) { 272 | this.indexFile = this.appendScripts(this.indexFile, 'scripts/modules.js', 273 | modules); 274 | } 275 | }; 276 | 277 | Generator.prototype.appJs = function appJs() { 278 | this.indexFile = this.appendFiles({ 279 | html: this.indexFile, 280 | fileType: 'js', 281 | optimizedPath: 'scripts/scripts.js', 282 | sourceFileList: ['scripts/app.js', 'scripts/controllers/main.js'], 283 | searchPath: ['.tmp', 'app'] 284 | }); 285 | }; 286 | 287 | Generator.prototype.createIndexHtml = function createIndexHtml() { 288 | this.write(path.join(this.appPath, 'index.html'), this.indexFile); 289 | }; 290 | 291 | Generator.prototype.packageFiles = function () { 292 | this.template('../../templates/common/_bower.json', 'bower.json'); 293 | this.template('../../templates/common/_package.json', 'package.json'); 294 | this.template('../../templates/common/Gruntfile.js', 'Gruntfile.js'); 295 | }; 296 | -------------------------------------------------------------------------------- /app/templates/styles/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fafafa; 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | color: #333; 5 | } 6 | 7 | .hero-unit { 8 | margin: 50px auto 0 auto; 9 | width: 300px; 10 | font-size: 18px; 11 | font-weight: 200; 12 | line-height: 30px; 13 | background-color: #eee; 14 | border-radius: 6px; 15 | padding: 60px; 16 | } 17 | 18 | .hero-unit h1 { 19 | font-size: 60px; 20 | line-height: 1; 21 | letter-spacing: -1px; 22 | } 23 | -------------------------------------------------------------------------------- /app/templates/styles/sass/main.sass: -------------------------------------------------------------------------------- 1 | body 2 | background: #fafafa 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif 4 | color: #333 5 | 6 | .hero-unit 7 | margin: 50px auto 0 auto 8 | width: 300px 9 | font-size: 18px 10 | font-weight: 200 11 | line-height: 30px 12 | background-color: #eee 13 | border-radius: 6px 14 | padding: 60px 15 | h1 16 | font-size: 60px 17 | line-height: 1 18 | letter-spacing: -1px -------------------------------------------------------------------------------- /app/templates/styles/sass/main.scss: -------------------------------------------------------------------------------- 1 | body { 2 | background: #fafafa; 3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 4 | color: #333; 5 | } 6 | 7 | .hero-unit { 8 | margin: 50px auto 0 auto; 9 | width: 300px; 10 | font-size: 18px; 11 | font-weight: 200; 12 | line-height: 30px; 13 | background-color: #eee; 14 | border-radius: 6px; 15 | padding: 60px; 16 | h1 { 17 | font-size: 60px; 18 | line-height: 1; 19 | letter-spacing: -1px; 20 | } 21 | } -------------------------------------------------------------------------------- /app/templates/styles/scss/main.scss: -------------------------------------------------------------------------------- 1 | $icon-font-path: "twitter-bootstrap-sass/assets/fonts/bootstrap/"; 2 | 3 | @import "twitter-bootstrap-sass/assets/stylesheets/bootstrap"; 4 | 5 | /* Put your CSS here */ 6 | html, body { 7 | margin: 20px; 8 | } 9 | 10 | body { 11 | background: #fafafa; 12 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 13 | color: #333; 14 | } 15 | 16 | .hero-unit { 17 | margin: 50px auto 0 auto; 18 | width: 300px; 19 | font-size: 18px; 20 | font-weight: 200; 21 | line-height: 30px; 22 | background-color: #eee; 23 | border-radius: 6px; 24 | padding: 60px; 25 | } 26 | 27 | .hero-unit h1 { 28 | font-size: 60px; 29 | line-height: 1; 30 | letter-spacing: -1px; 31 | } 32 | -------------------------------------------------------------------------------- /common/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | 6 | 7 | var Generator = module.exports = function Generator() { 8 | yeoman.generators.Base.apply(this, arguments); 9 | }; 10 | 11 | util.inherits(Generator, yeoman.generators.Base); 12 | 13 | Generator.prototype.setupEnv = function setupEnv() { 14 | // Copies the contents of the generator `templates` 15 | // directory into your users new application path 16 | this.sourceRoot(path.join(__dirname, '../templates/common')); 17 | this.directory('root', '.', true); 18 | this.copy('gitignore', '.gitignore'); 19 | }; 20 | -------------------------------------------------------------------------------- /constant/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS constant. 3 | Docs: http://docs.angularjs.org/guide/dev_guide.services.creating_services 4 | 5 | Example: 6 | yo angular-ui-router:constant thing [--coffee] [--minsafe] 7 | 8 | This will create: 9 | app/scripts/services/thing.js 10 | -------------------------------------------------------------------------------- /constant/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createServiceFiles = function createServiceFiles() { 13 | this.generateSourceAndTest('service/constant', 'spec/service', 'services'); 14 | }; 15 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | See the [contributing docs](https://github.com/yeoman/yeoman/blob/master/contributing.md) 2 | 3 | Additionally for this generator: 4 | 5 | When submitting an issue, please follow the [guidelines](https://github.com/yeoman/yeoman/blob/master/contributing.md#issue-submission). Especially important is to make sure Yeoman is up-to-date, and providing the command or commands that cause the issue. 6 | 7 | When submitting a PR, make sure that the commit messages match the [AngularJS conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/). 8 | 9 | When submitting a bugfix, write a test that exposes the bug and fails before applying your fix. Submit the test alongside the fix. 10 | 11 | When submitting a new feature, add tests that cover the feature. 12 | -------------------------------------------------------------------------------- /controller/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new Angular controller 3 | 4 | Example: 5 | yo angular-ui-router:controller Thing [--coffee] [--minsafe] 6 | 7 | This will create: 8 | app/scripts/controllers/thing-ctrl.js 9 | -------------------------------------------------------------------------------- /controller/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | 9 | // if the controller name is suffixed with ctrl, remove the suffix 10 | // if the controller name is just "ctrl," don't append/remove "ctrl" 11 | if (this.name && this.name.toLowerCase() !== 'ctrl' && this.name.substr(-4).toLowerCase() === 'ctrl') { 12 | this.name = this.name.slice(0, -4); 13 | } 14 | }; 15 | 16 | util.inherits(Generator, ScriptBase); 17 | 18 | Generator.prototype.createControllerFiles = function createControllerFiles() { 19 | this.generateSourceAndTest('controller', 'spec/controller', 'controllers'); 20 | }; 21 | -------------------------------------------------------------------------------- /decorator/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS decorator for a specified service 3 | 4 | Example: 5 | yo angular-ui-router:decorator serviceName [--coffee] 6 | 7 | This will create: 8 | app/scripts/decorators/serviceNameDecorator.js 9 | -------------------------------------------------------------------------------- /decorator/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | var fs = require('fs'); 5 | 6 | var Generator = module.exports = function Generator(args, options) { 7 | ScriptBase.apply(this, arguments); 8 | this.fileName = this.name; 9 | }; 10 | 11 | util.inherits(Generator, ScriptBase); 12 | 13 | Generator.prototype.askForOverwrite = function askForOverwrite() { 14 | var cb = this.async(); 15 | 16 | // TODO: Any yeoman.util function to handle this? 17 | var fileExists = fs.existsSync(this.env.cwd + '/app/scripts/' + buildRelativePath(this.fileName) + ".js"); 18 | if (fileExists) { 19 | var prompts = [{ 20 | type: 'confirm', 21 | name: 'overwriteDecorator', 22 | message: 'Would you like to overwrite existing decorator?', 23 | default: false 24 | }]; 25 | 26 | this.prompt(prompts, function (props) { 27 | this.overwriteDecorator = props.overwriteDecorator; 28 | 29 | cb(); 30 | }.bind(this)); 31 | } 32 | else{ 33 | cb(); 34 | return; 35 | } 36 | }; 37 | 38 | Generator.prototype.askForNewName = function askForNewName() { 39 | var cb = this.async(); 40 | 41 | if (this.overwriteDecorator === undefined || this.overwriteDecorator === true) { 42 | cb(); 43 | return; 44 | } 45 | else { 46 | var prompts = []; 47 | prompts.push({ 48 | name: 'decoratorName', 49 | message: 'Alternative name for the decorator' 50 | }); 51 | 52 | this.prompt(prompts, function (props) { 53 | this.fileName = props.decoratorName; 54 | 55 | cb(); 56 | }.bind(this)); 57 | } 58 | }; 59 | 60 | Generator.prototype.createDecoratorFiles = function createDecoratorFiles() { 61 | this.appTemplate('decorator', 'scripts/' + buildRelativePath(this.fileName)); 62 | this.addScriptToIndex(buildRelativePath(this.fileName)); 63 | }; 64 | 65 | function buildRelativePath(fileName){ 66 | return 'decorators/' + fileName + "Decorator"; 67 | } 68 | -------------------------------------------------------------------------------- /directive/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new Angular directive 3 | 4 | Example: 5 | yo angular-ui-router:directive thing [--coffee] [--minsafe] 6 | 7 | This will create: 8 | app/scripts/directives/thing.js 9 | -------------------------------------------------------------------------------- /directive/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createDirectiveFiles = function createDirectiveFiles() { 13 | this.generateSourceAndTest('directive', 'spec/directive', 'directives'); 14 | }; 15 | -------------------------------------------------------------------------------- /factory/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS service. 3 | Docs: http://docs.angularjs.org/guide/dev_guide.services.creating_services 4 | 5 | Example: 6 | yo angular-ui-router:factory thing [--coffee] [--minsafe] 7 | 8 | This will create: 9 | app/scripts/services/thing.js 10 | -------------------------------------------------------------------------------- /factory/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createServiceFiles = function createServiceFiles() { 13 | this.generateSourceAndTest('service/factory', 'spec/service', 'services'); 14 | }; 15 | -------------------------------------------------------------------------------- /filter/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS filter 3 | 4 | Example: 5 | yo angular-ui-router:filter thing [--coffee] [--minsafe] 6 | 7 | This will create: 8 | app/scripts/filters/thing.js 9 | -------------------------------------------------------------------------------- /filter/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createFilterFiles = function createFilterFiles() { 13 | this.generateSourceAndTest('filter', 'spec/filter', 'filters'); 14 | }; 15 | -------------------------------------------------------------------------------- /main/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var path = require('path'); 4 | var ScriptBase = require('../script-base.js'); 5 | var yeoman = require('yeoman-generator'); 6 | 7 | 8 | var Generator = module.exports = function Generator() { 9 | ScriptBase.apply(this, arguments); 10 | }; 11 | 12 | util.inherits(Generator, ScriptBase); 13 | 14 | Generator.prototype.createAppFile = function createAppFile() { 15 | this.angularModules = this.env.options.angularDeps; 16 | this.uirouterModules = this.env.options.uirouterModules; 17 | this.appTemplate('app', 'scripts/app'); 18 | }; 19 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-angular-ui-router", 3 | "version": "0.5.3", 4 | "description": "Yeoman generator for AngularJS( include UI-router )", 5 | "keywords": [ 6 | "yeoman-generator", 7 | "scaffold", 8 | "framework", 9 | "component", 10 | "front-end", 11 | "app" 12 | ], 13 | "homepage": "https://github.com/yeoman/generator-angular", 14 | "bugs": "https://github.com/iamblue/generator-angular-ui-router/issues", 15 | "author": "Chrome Developer Relations", 16 | "main": "app/index.js", 17 | "repository": { 18 | "type": "git", 19 | "url": "git://github.com/iamblue/generator-angular-ui-router.git" 20 | }, 21 | "scripts": { 22 | "test": "mocha" 23 | }, 24 | "dependencies": { 25 | "yeoman-generator": "~0.18.9" 26 | }, 27 | "peerDependencies": { 28 | "generator-karma": ">=0.8.0", 29 | "yo": ">=1.4.0" 30 | }, 31 | "devDependencies": { 32 | "mocha": "~2.1.0", 33 | "grunt": "~0.4.5", 34 | "grunt-contrib-jshint": "~0.11.0", 35 | "grunt-conventional-changelog": "~1.1.0", 36 | "load-grunt-tasks": "~3.1.0", 37 | "marked": "~0.3.3", 38 | "semver": "~4.3.1", 39 | "underscore.string": "~3.0.3", 40 | "grunt-release": "~0.11.0" 41 | }, 42 | "engines": { 43 | "node": ">=0.8.0", 44 | "npm": ">=1.2.10" 45 | }, 46 | "licenses": [ 47 | { 48 | "type": "BSD" 49 | } 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /provider/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS service. 3 | Docs: http://docs.angularjs.org/guide/dev_guide.services.creating_services 4 | 5 | Example: 6 | yo angular-ui-router:provider thing [--coffee] [--minsafe] 7 | 8 | This will create: 9 | app/scripts/services/thing.js 10 | -------------------------------------------------------------------------------- /provider/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createServiceFiles = function createServiceFiles() { 13 | this.generateSourceAndTest('service/provider', 'spec/service', 'services'); 14 | }; 15 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # AngularJS generator (add ui-router plugin) 2 | 3 | This project fork from :yeoman / generator-angular 4 | I add 'ui-router' plugin in this module. 5 | 6 | Maintainer: [iamblue](https://github.com/iamblue) 7 | 8 | Based on [angular-seed](https://github.com/angular/angular-seed/) 9 | 10 | This project is one of many things that you can use to get started 11 | on a new app. For a comparison of the options and the trade-offs between 12 | them, please visit [this](http://www.dancancro.com/comparison-of-angularjs-application-starters) link. 13 | ## Usage 14 | 15 | Install `generator-angular-ui-router`: 16 | ``` 17 | npm install -g generator-angular-ui-router 18 | ``` 19 | 20 | Make a new directory, and `cd` into it: 21 | ``` 22 | mkdir my-new-project && cd $_ 23 | ``` 24 | 25 | Run `yo angular-ui-router`, optionally passing an app name: 26 | ``` 27 | yo angular-ui-router [app-name] 28 | ``` 29 | 30 | Optionally using Sass: 31 | ``` 32 | [?] Would you like to use Sass with the Compass CSS Authoring Framework? Yes 33 | [?] Which syntax do you prefer? (Use arrow keys) 34 | ❯ sass 35 | scss 36 | ``` 37 | 38 | ## Generators 39 | 40 | Available generators: 41 | 42 | * [angular-ui-router](#app) (aka [angular-ui-router:app](#app)) 43 | * [angular-ui-router:controller](#controller) 44 | * [angular-ui-router:directive](#directive) 45 | * [angular-ui-router:filter](#filter) 46 | * [angular-ui-router:route](#route) 47 | * [angular-ui-router:service](#service) 48 | * [angular-ui-router:provider](#service) 49 | * [angular-ui-router:factory](#service) 50 | * [angular-ui-router:value](#service) 51 | * [angular-ui-router:constant](#service) 52 | * [angular-ui-router:decorator] (#decorator) 53 | * [angular-ui-router:view](#view) 54 | 55 | **Note: Generators are to be run from the root directory of your app.** 56 | 57 | ### App 58 | Sets up a new AngularJS app, generating all the boilerplate you need to get started. The app generator also optionally installs Twitter Bootstrap and additional AngularJS modules, such as angular-resource. 59 | 60 | Example: 61 | ```bash 62 | yo angular-ui-router 63 | ``` 64 | 65 | ### Route 66 | Generates a controller and view, and configures a route in `app/scripts/app.js` connecting them. 67 | 68 | Example: 69 | ```bash 70 | yo angular-ui-router:route myroute 71 | ``` 72 | 73 | Produces `app/scripts/controllers/myroute.js`: 74 | ```javascript 75 | angular.module('myMod').controller('MyrouteCtrl', function ($scope) { 76 | // ... 77 | }); 78 | ``` 79 | 80 | Produces `app/views/myroute.html`: 81 | ```html 82 |

This is the myroute view

83 | ``` 84 | 85 | ### Controller 86 | Generates a controller in `app/scripts/controllers`. 87 | 88 | Example: 89 | ```bash 90 | yo angular-ui-router:controller user 91 | ``` 92 | 93 | Produces `app/scripts/controllers/user.js`: 94 | ```javascript 95 | angular.module('myMod').controller('UserCtrl', function ($scope) { 96 | // ... 97 | }); 98 | ``` 99 | ### Directive 100 | Generates a directive in `app/scripts/directives`. 101 | 102 | Example: 103 | ```bash 104 | yo angular-ui-router:directive myDirective 105 | ``` 106 | 107 | Produces `app/scripts/directives/myDirective.js`: 108 | ```javascript 109 | angular.module('myMod').directive('myDirective', function () { 110 | return { 111 | template: '
', 112 | restrict: 'E', 113 | link: function postLink(scope, element, attrs) { 114 | element.text('this is the myDirective directive'); 115 | } 116 | }; 117 | }); 118 | ``` 119 | 120 | ### Filter 121 | Generates a filter in `app/scripts/filters`. 122 | 123 | Example: 124 | ```bash 125 | yo angular-ui-router:filter myFilter 126 | ``` 127 | 128 | Produces `app/scripts/filters/myFilter.js`: 129 | ```javascript 130 | angular.module('myMod').filter('myFilter', function () { 131 | return function (input) { 132 | return 'myFilter filter:' + input; 133 | }; 134 | }); 135 | ``` 136 | 137 | ### View 138 | Generates an HTML view file in `app/views`. 139 | 140 | Example: 141 | ```bash 142 | yo angular-ui-router:view user 143 | ``` 144 | 145 | Produces `app/views/user.html`: 146 | ```html 147 |

This is the user view

148 | ``` 149 | 150 | ### Service 151 | Generates an AngularJS service. 152 | 153 | Example: 154 | ```bash 155 | yo angular-ui-router:service myService 156 | ``` 157 | 158 | Produces `app/scripts/services/myService.js`: 159 | ```javascript 160 | angular.module('myMod').service('myService', function () { 161 | // ... 162 | }); 163 | ``` 164 | 165 | You can also do `yo angular-ui-router:factory`, `yo angular-ui-router:provider`, `yo angular-ui-router:value`, and `yo angular-ui-router:constant` for other types of services. 166 | 167 | ### Decorator 168 | Generates an AngularJS service decorator. 169 | 170 | Example: 171 | ```bash 172 | yo angular-ui-router:decorator serviceName 173 | ``` 174 | 175 | Produces `app/scripts/decorators/serviceNameDecorator.js`: 176 | ```javascript 177 | angular.module('myMod').config(function ($provide) { 178 | $provide.decorator('serviceName', function ($delegate) { 179 | // ... 180 | return $delegate; 181 | }); 182 | }); 183 | ``` 184 | 185 | ## Options 186 | In general, these options can be applied to any generator, though they only affect generators that produce scripts. 187 | 188 | ### CoffeeScript 189 | For generators that output scripts, the `--coffee` option will output CoffeeScript instead of JavaScript. 190 | 191 | For example: 192 | ```bash 193 | yo angular-ui-router:controller user --coffee 194 | ``` 195 | 196 | Produces `app/scripts/controller/user.coffee`: 197 | ```coffeescript 198 | angular.module('myMod') 199 | .controller 'UserCtrl', ($scope) -> 200 | ``` 201 | 202 | A project can mix CoffeScript and JavaScript files. 203 | 204 | ### Minification Safe 205 | By default, generators produce unannotated code. Without annotations, AngularJS's DI system will break when minified. Typically, these annotations that make minification safe are added automatically at build-time, after application files are concatenated, but before they are minified. By providing the `--minsafe` option, the code generated will out-of-the-box be ready for minification. The trade-off is between amount of boilerplate, and build process complexity. 206 | 207 | #### Example 208 | ```bash 209 | yo angular-ui-router:controller user --minsafe 210 | ``` 211 | 212 | Produces `app/controller/user.js`: 213 | ```javascript 214 | angular.module('myMod').controller('UserCtrl', ['$scope', function ($scope) { 215 | // ... 216 | }]); 217 | ``` 218 | 219 | #### Background 220 | Unannotated: 221 | ```javascript 222 | angular.module('myMod').controller('MyCtrl', function ($scope, $http, myService) { 223 | // ... 224 | }); 225 | ``` 226 | 227 | Annotated: 228 | ```javascript 229 | angular.module('myMod').controller('MyCtrl', 230 | ['$scope', '$http', 'myService', function ($scope, $http, myService) { 231 | 232 | // ... 233 | }]); 234 | ``` 235 | 236 | The annotations are important because minified code will rename variables, making it impossible for AngularJS to infer module names based solely on function parameters. 237 | 238 | The recommended build process uses `ngmin`, a tool that automatically adds these annotations. However, if you'd rather not use `ngmin`, you have to add these annotations manually yourself. 239 | 240 | ## Bower Components 241 | 242 | The following packages are always installed by the [app](#app) generator: 243 | 244 | * angular 245 | * angular-mocks 246 | * angular-scenario 247 | 248 | 249 | The following additional modules are available as components on bower, and installable via `bower install`: 250 | 251 | * angular-cookies 252 | * angular-loader 253 | * angular-resource 254 | * angular-sanitize 255 | * angular-ui-router 256 | 257 | All of these can be updated with `bower update` as new versions of AngularJS are released. 258 | 259 | ## Configuration 260 | Yeoman generated projects can be further tweaked according to your needs by modifying project files appropriately. 261 | 262 | ### Output 263 | You can change the `app` directory by adding a `appPath` property to `bower.json`. For instance, if you wanted to easily integrate with Express.js, you could add the following: 264 | 265 | ```json 266 | { 267 | "name": "yo-testt", 268 | "version": "0.0.0", 269 | ... 270 | "appPath": "public" 271 | } 272 | 273 | ``` 274 | This will cause Yeoman-generated client-side files to be placed in `public`. 275 | 276 | ## Testing 277 | 278 | For tests to work properly, karma needs the `angular-mocks` bower package. 279 | This script is included in the bower.json in the `devDependencies` section, which will 280 | be available very soon, probably with the next minor release of bower. 281 | 282 | While bower `devDependencies` are not yet implemented, you can fix it by running: 283 | ```bash 284 | bower install angular-mocks 285 | ``` 286 | 287 | By running `grunt test` you should now be able to run your unit tests with karma. 288 | 289 | ## Contribute 290 | 291 | See the [contributing docs](https://github.com/yeoman/yeoman/blob/master/contributing.md) 292 | 293 | When submitting an issue, please follow the [guidelines](https://github.com/yeoman/yeoman/blob/master/contributing.md#issue-submission). Especially important is to make sure Yeoman is up-to-date, and providing the command or commands that cause the issue. 294 | 295 | When submitting a PR, make sure that the commit messages match the [AngularJS conventions](https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y/). 296 | 297 | When submitting a bugfix, write a test that exposes the bug and fails before applying your fix. Submit the test alongside the fix. 298 | 299 | When submitting a new feature, add tests that cover the feature. 300 | 301 | ## License 302 | 303 | [BSD license](http://opensource.org/licenses/bsd-license.php) 304 | -------------------------------------------------------------------------------- /route/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS route 3 | 4 | Example: 5 | yo angular-ui-router:route thing [--coffee] [--minsafe] 6 | 7 | This will create: 8 | app/scripts/controllers/thing.js 9 | app/views/thing.html 10 | And add routing to: 11 | app.js 12 | -------------------------------------------------------------------------------- /route/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var util = require('util'); 4 | var ScriptBase = require('../script-base.js'); 5 | var angularUtils = require('../util.js'); 6 | 7 | 8 | var Generator = module.exports = function Generator() { 9 | ScriptBase.apply(this, arguments); 10 | this.hookFor('angular-ui-router:controller'); 11 | this.hookFor('angular-ui-router:view'); 12 | }; 13 | 14 | util.inherits(Generator, ScriptBase); 15 | 16 | Generator.prototype.rewriteAppJs = function () { 17 | var stateName = this.name.split('/').join('.'); 18 | if (this.env.options.coffee) { 19 | angularUtils.rewriteFile({ 20 | file: path.join(this.env.options.appPath, 'scripts/app.coffee'), 21 | needle: '.otherwise', 22 | splicable: [ 23 | '.state \''+stateName + '\',', 24 | ' templateUrl: \'views/' + this.name + '.html\',', 25 | ' controller: \'' + this._.classify(this.name) + 'Ctrl\'' 26 | ] 27 | }); 28 | } 29 | else { 30 | angularUtils.rewriteFile({ 31 | file: path.join(this.env.options.appPath, 'scripts/app.js'), 32 | needle: '.otherwise', 33 | splicable: [ 34 | '.state(\''+stateName + '\', {', 35 | ' templateUrl: \'views/' + this.name + '.html\',', 36 | ' controller: \'' + this._.classify(this.name) + 'Ctrl\'', 37 | '})' 38 | ] 39 | }); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /script-base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var path = require('path'); 4 | var yeoman = require('yeoman-generator'); 5 | var angularUtils = require('./util.js'); 6 | 7 | var Generator = module.exports = function Generator() { 8 | yeoman.generators.NamedBase.apply(this, arguments); 9 | 10 | try { 11 | this.appname = require(path.join(process.cwd(), 'bower.json')).name; 12 | } catch (e) { 13 | this.appname = path.basename(process.cwd()); 14 | } 15 | 16 | if (typeof this.env.options.appPath === 'undefined') { 17 | try { 18 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 19 | } catch (e) {} 20 | this.env.options.appPath = this.env.options.appPath || 'app'; 21 | } 22 | 23 | if (typeof this.env.options.testPath === 'undefined') { 24 | try { 25 | this.env.options.testPath = require(path.join(process.cwd(), 'bower.json')).testPath; 26 | } catch (e) {} 27 | this.env.options.testPath = this.env.options.testPath || 'test/spec'; 28 | } 29 | 30 | this.env.options.coffee = this.options.coffee; 31 | if (typeof this.env.options.coffee === 'undefined') { 32 | this.option('coffee'); 33 | 34 | // attempt to detect if user is using CS or not 35 | // if cml arg provided, use that; else look for the existence of cs 36 | if (!this.options.coffee && 37 | this.expandFiles(path.join(this.env.options.appPath, '/scripts/**/*.coffee'), {}).length > 0) { 38 | this.options.coffee = true; 39 | } 40 | 41 | this.env.options.coffee = this.options.coffee; 42 | } 43 | 44 | if (typeof this.env.options.minsafe === 'undefined') { 45 | this.option('minsafe'); 46 | this.env.options.minsafe = this.options.minsafe; 47 | } 48 | 49 | var sourceRoot = '/templates/javascript'; 50 | this.scriptSuffix = '.js'; 51 | 52 | if (this.env.options.coffee) { 53 | sourceRoot = '/templates/coffeescript'; 54 | this.scriptSuffix = '.coffee'; 55 | } 56 | 57 | if (this.env.options.minsafe) { 58 | sourceRoot += '-min'; 59 | } 60 | 61 | this.sourceRoot(path.join(__dirname, sourceRoot)); 62 | }; 63 | 64 | util.inherits(Generator, yeoman.generators.NamedBase); 65 | 66 | Generator.prototype.appTemplate = function (src, dest) { 67 | // console.log(this.scriptSuffix); 68 | // console.log(src); 69 | 70 | yeoman.generators.Base.prototype.template.apply(this, [ 71 | src + this.scriptSuffix, 72 | path.join(this.env.options.appPath, dest) + this.scriptSuffix 73 | ]); 74 | }; 75 | 76 | Generator.prototype.testTemplate = function (src, dest) { 77 | yeoman.generators.Base.prototype.template.apply(this, [ 78 | src + this.scriptSuffix, 79 | path.join(this.env.options.testPath, dest) + this.scriptSuffix 80 | ]); 81 | }; 82 | 83 | Generator.prototype.htmlTemplate = function (src, dest) { 84 | yeoman.generators.Base.prototype.template.apply(this, [ 85 | src, 86 | path.join(this.env.options.appPath, dest) 87 | ]); 88 | }; 89 | 90 | Generator.prototype.addScriptToIndex = function (script) { 91 | try { 92 | var appPath = this.env.options.appPath; 93 | var fullPath = path.join(appPath, 'index.html'); 94 | angularUtils.rewriteFile({ 95 | file: fullPath, 96 | needle: '', 97 | splicable: [ 98 | '' 99 | ] 100 | }); 101 | } catch (e) { 102 | console.log('\nUnable to find '.yellow + fullPath + '. Reference to '.yellow + script + '.js ' + 'not added.\n'.yellow); 103 | } 104 | }; 105 | 106 | Generator.prototype.generateSourceAndTest = function (appTemplate, testTemplate, targetDirectory) { 107 | this.appTemplate(appTemplate, path.join('scripts', targetDirectory, this.name)); 108 | this.testTemplate(testTemplate, path.join(targetDirectory, this.name)); 109 | this.addScriptToIndex(path.join(targetDirectory, this.name)); 110 | }; 111 | -------------------------------------------------------------------------------- /service/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS service. 3 | Docs: http://docs.angularjs.org/guide/dev_guide.services.creating_services 4 | 5 | Example: 6 | yo angular-ui-router:service thing [--coffee] [--minsafe] 7 | 8 | This will create: 9 | app/scripts/services/thing.js 10 | -------------------------------------------------------------------------------- /service/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createServiceFiles = function createServiceFiles() { 13 | this.generateSourceAndTest('service/service', 'spec/service', 'services'); 14 | }; 15 | -------------------------------------------------------------------------------- /templates/coffeescript-min/app.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 4 | .config ['$routeProvider', ($routeProvider) -> 5 | $routeProvider 6 | .when '/', 7 | templateUrl: 'views/main.html' 8 | controller: 'MainCtrl' 9 | .otherwise 10 | redirectTo: '/' 11 | ] 12 | -------------------------------------------------------------------------------- /templates/coffeescript-min/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .controller '<%= _.classify(name) %>Ctrl', ['$scope', ($scope) -> 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate' 7 | 'AngularJS' 8 | 'Karma' 9 | ] 10 | ] 11 | -------------------------------------------------------------------------------- /templates/coffeescript-min/decorator.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module("<%= _.camelize(appname) %>App").config ["$provide", ($provide) -> 4 | $provide.decorator "<%= _.camelize(name) %>", ($delegate) -> 5 | # decorate the $delegate 6 | $delegate 7 | ] 8 | -------------------------------------------------------------------------------- /templates/coffeescript-min/directive.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .directive '<%= _.camelize(name) %>', [-> 5 | template: '
' 6 | restrict: 'E' 7 | link: (scope, element, attrs) -> 8 | element.text 'this is the <%= _.camelize(name) %> directive' 9 | ] 10 | -------------------------------------------------------------------------------- /templates/coffeescript-min/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .filter '<%= _.camelize(name) %>', [() -> 5 | (input) -> 6 | '<%= _.camelize(name) %> filter: ' + input 7 | ] 8 | -------------------------------------------------------------------------------- /templates/coffeescript-min/service/constant.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .constant '<%= _.camelize(name) %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript-min/service/factory.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .factory '<%= _.camelize(name) %>', [() -> 5 | # Service logic 6 | # ... 7 | 8 | meaningOfLife = 42 9 | 10 | # Public API here 11 | { 12 | someMethod: () -> 13 | meaningOfLife 14 | } 15 | ] 16 | -------------------------------------------------------------------------------- /templates/coffeescript-min/service/provider.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .provider '<%= _.camelize(name) %>', [-> 5 | 6 | # Private variables 7 | salutation = 'Hello' 8 | 9 | # Private constructor 10 | class Greeter 11 | @greet = -> 12 | salutation 13 | 14 | # Public API for configuration 15 | @setSalutation = (s) -> 16 | salutation = s 17 | 18 | # Method for instantiating 19 | @$get = -> 20 | new Greeter() 21 | ] 22 | -------------------------------------------------------------------------------- /templates/coffeescript-min/service/service.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .service '<%= _.classify(name) %>', () -> 5 | # AngularJS will instantiate a singleton by calling "new" on this function 6 | -------------------------------------------------------------------------------- /templates/coffeescript-min/service/value.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .value '<%= _.camelize(name) %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript-min/spec/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Controller: <%= _.classify(name) %>Ctrl', () -> 4 | 5 | # load the controller's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | <%= _.classify(name) %>Ctrl = {} 9 | scope = {} 10 | 11 | # Initialize the controller and a mock scope 12 | beforeEach inject ($controller, $rootScope) -> 13 | scope = $rootScope.$new() 14 | <%= _.classify(name) %>Ctrl = $controller '<%= _.classify(name) %>Ctrl', { 15 | $scope: scope 16 | } 17 | 18 | it 'should attach a list of awesomeThings to the scope', () -> 19 | expect(scope.awesomeThings.length).toBe 3 20 | -------------------------------------------------------------------------------- /templates/coffeescript-min/spec/directive.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Directive: <%= _.camelize(name) %>', () -> 4 | 5 | # load the directive's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | scope = {} 9 | 10 | beforeEach inject ($controller, $rootScope) -> 11 | scope = $rootScope.$new() 12 | 13 | it 'should make hidden element visible', inject ($compile) -> 14 | element = angular.element '<<%= _.dasherize(name) %>>>' 15 | element = $compile(element) scope 16 | expect(element.text()).toBe 'this is the <%= _.camelize(name) %> directive' 17 | -------------------------------------------------------------------------------- /templates/coffeescript-min/spec/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Filter: <%= _.camelize(name) %>', () -> 4 | 5 | # load the filter's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | # initialize a new instance of the filter before each test 9 | <%= _.camelize(name) %> = {} 10 | beforeEach inject ($filter) -> 11 | <%= _.camelize(name) %> = $filter '<%= _.camelize(name) %>' 12 | 13 | it 'should return the input prefixed with "<%= _.camelize(name) %> filter:"', () -> 14 | text = 'angularjs' 15 | expect(<%= _.camelize(name) %> text).toBe ('<%= _.camelize(name) %> filter: ' + text) 16 | -------------------------------------------------------------------------------- /templates/coffeescript-min/spec/service.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Service: <%= _.classify(name) %>', () -> 4 | 5 | # load the service's module 6 | beforeEach module '<%= _.classify(appname) %>App' 7 | 8 | # instantiate service 9 | <%= _.classify(name) %> = {} 10 | beforeEach inject (_<%= _.classify(name) %>_) -> 11 | <%= _.classify(name) %> = _<%= _.classify(name) %>_ 12 | 13 | it 'should do something', () -> 14 | expect(!!<%= _.classify(name) %>).toBe true 15 | -------------------------------------------------------------------------------- /templates/coffeescript/app.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 4 | .config ($routeProvider) -> 5 | $routeProvider 6 | .when '/', 7 | templateUrl: 'views/main.html' 8 | controller: 'MainCtrl' 9 | .otherwise 10 | redirectTo: '/' 11 | -------------------------------------------------------------------------------- /templates/coffeescript/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .controller '<%= _.classify(name) %>Ctrl', ($scope) -> 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate' 7 | 'AngularJS' 8 | 'Karma' 9 | ] 10 | -------------------------------------------------------------------------------- /templates/coffeescript/decorator.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module("<%= _.camelize(appname) %>App").config ($provide) -> 4 | $provide.decorator "<%= _.camelize(name) %>", ($delegate) -> 5 | # decorate the $delegate 6 | $delegate 7 | -------------------------------------------------------------------------------- /templates/coffeescript/directive.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .directive('<%= _.camelize(name) %>', () -> 5 | template: '
' 6 | restrict: 'E' 7 | link: (scope, element, attrs) -> 8 | element.text 'this is the <%= _.camelize(name) %> directive' 9 | ) 10 | -------------------------------------------------------------------------------- /templates/coffeescript/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .filter '<%= _.camelize(name) %>', () -> 5 | (input) -> 6 | '<%= _.camelize(name) %> filter: ' + input 7 | -------------------------------------------------------------------------------- /templates/coffeescript/service/constant.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .constant '<%= _.camelize(name) %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript/service/factory.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .factory '<%= _.camelize(name) %>', () -> 5 | # Service logic 6 | # ... 7 | 8 | meaningOfLife = 42 9 | 10 | # Public API here 11 | { 12 | someMethod: () -> 13 | meaningOfLife 14 | } 15 | -------------------------------------------------------------------------------- /templates/coffeescript/service/provider.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .provider '<%= _.camelize(name) %>', [-> 5 | 6 | # Private variables 7 | salutation = 'Hello' 8 | 9 | # Private constructor 10 | class Greeter 11 | @greet = -> 12 | salutation 13 | 14 | # Public API for configuration 15 | @setSalutation = (s) -> 16 | salutation = s 17 | 18 | # Method for instantiating 19 | @$get = -> 20 | new Greeter() 21 | ] 22 | -------------------------------------------------------------------------------- /templates/coffeescript/service/service.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .service '<%= _.classify(name) %>', () -> 5 | # AngularJS will instantiate a singleton by calling "new" on this function 6 | -------------------------------------------------------------------------------- /templates/coffeescript/service/value.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .value '<%= _.camelize(name) %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Controller: <%= _.classify(name) %>Ctrl', () -> 4 | 5 | # load the controller's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | <%= _.classify(name) %>Ctrl = {} 9 | scope = {} 10 | 11 | # Initialize the controller and a mock scope 12 | beforeEach inject ($controller, $rootScope) -> 13 | scope = $rootScope.$new() 14 | <%= _.classify(name) %>Ctrl = $controller '<%= _.classify(name) %>Ctrl', { 15 | $scope: scope 16 | } 17 | 18 | it 'should attach a list of awesomeThings to the scope', () -> 19 | expect(scope.awesomeThings.length).toBe 3 20 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/directive.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Directive: <%= _.camelize(name) %>', () -> 4 | 5 | # load the directive's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | scope = {} 9 | 10 | beforeEach inject ($controller, $rootScope) -> 11 | scope = $rootScope.$new() 12 | 13 | it 'should make hidden element visible', inject ($compile) -> 14 | element = angular.element '<<%= _.dasherize(name) %>>>' 15 | element = $compile(element) scope 16 | expect(element.text()).toBe 'this is the <%= _.camelize(name) %> directive' 17 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Filter: <%= _.camelize(name) %>', () -> 4 | 5 | # load the filter's module 6 | beforeEach module '<%= _.camelize(appname) %>App' 7 | 8 | # initialize a new instance of the filter before each test 9 | <%= _.camelize(name) %> = {} 10 | beforeEach inject ($filter) -> 11 | <%= _.camelize(name) %> = $filter '<%= _.camelize(name) %>' 12 | 13 | it 'should return the input prefixed with "<%= _.camelize(name) %> filter:"', () -> 14 | text = 'angularjs' 15 | expect(<%= _.camelize(name) %> text).toBe ('<%= _.camelize(name) %> filter: ' + text) 16 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/service.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Service: <%= _.classify(name) %>', () -> 4 | 5 | # load the service's module 6 | beforeEach module '<%= _.classify(appname) %>App' 7 | 8 | # instantiate service 9 | <%= _.classify(name) %> = {} 10 | beforeEach inject (_<%= _.classify(name) %>_) -> 11 | <%= _.classify(name) %> = _<%= _.classify(name) %>_ 12 | 13 | it 'should do something', () -> 14 | expect(!!<%= _.classify(name) %>).toBe true 15 | -------------------------------------------------------------------------------- /templates/common/Gruntfile.js: -------------------------------------------------------------------------------- 1 | // Generated on <%= (new Date).toISOString().split('T')[0] %> using <%= pkg.name %> <%= pkg.version %> 2 | 'use strict'; 3 | 4 | // # Globbing 5 | // for performance reasons we're only matching one level down: 6 | // 'test/spec/**/**/*.js' 7 | // use this if you want to recursively match all subfolders: 8 | // 'test/spec/**/*.js' 9 | 10 | module.exports = function (grunt) { 11 | require('load-grunt-tasks')(grunt); 12 | require('time-grunt')(grunt); 13 | 14 | grunt.initConfig({ 15 | yeoman: { 16 | // configurable paths 17 | app: require('./bower.json').appPath || 'app', 18 | dist: 'dist' 19 | }, 20 | watch: { 21 | coffee: { 22 | files: ['<%%= yeoman.app %>/scripts/**/**/*.coffee'], 23 | tasks: ['coffee:dist'] 24 | }, 25 | coffeeTest: { 26 | files: ['test/spec/**/**/*.coffee'], 27 | tasks: ['coffee:test'] 28 | },<% if (compassBootstrap || usingSass) { %> 29 | compass: { 30 | files: ['<%%= yeoman.app %>/styles/**/**/*.{scss,sass}'], 31 | tasks: ['compass:server', 'autoprefixer'] 32 | },<% } %> 33 | styles: { 34 | files: ['<%%= yeoman.app %>/styles/**/**/*.css'], 35 | tasks: ['copy:styles', 'autoprefixer'] 36 | }, 37 | livereload: { 38 | options: { 39 | livereload: '<%%= connect.options.livereload %>' 40 | }, 41 | files: [ 42 | '<%%= yeoman.app %>/**/**/*.html', 43 | '.tmp/styles/**/**/*.css', 44 | '{.tmp,<%%= yeoman.app %>}/scripts/**/**/*.js', 45 | '<%%= yeoman.app %>/images/**/**/*.{png,jpg,jpeg,gif,webp,svg}' 46 | ] 47 | } 48 | }, 49 | autoprefixer: { 50 | options: ['last 1 version'], 51 | dist: { 52 | files: [{ 53 | expand: true, 54 | cwd: '.tmp/styles/', 55 | src: '**/**/*.css', 56 | dest: '.tmp/styles/' 57 | }] 58 | } 59 | }, 60 | connect: { 61 | options: { 62 | port: 9000, 63 | // Change this to '0.0.0.0' to access the server from outside. 64 | hostname: 'localhost', 65 | livereload: 35729 66 | }, 67 | livereload: { 68 | options: { 69 | open: true, 70 | base: [ 71 | '.tmp', 72 | '<%%= yeoman.app %>' 73 | ] 74 | } 75 | }, 76 | test: { 77 | options: { 78 | port: 9001, 79 | base: [ 80 | '.tmp', 81 | 'test', 82 | '<%%= yeoman.app %>' 83 | ] 84 | } 85 | }, 86 | dist: { 87 | options: { 88 | base: '<%%= yeoman.dist %>' 89 | } 90 | } 91 | }, 92 | clean: { 93 | dist: { 94 | files: [{ 95 | dot: true, 96 | src: [ 97 | '.tmp', 98 | '<%%= yeoman.dist %>/*', 99 | '!<%%= yeoman.dist %>/.git*' 100 | ] 101 | }] 102 | }, 103 | server: '.tmp' 104 | }, 105 | jshint: { 106 | options: { 107 | jshintrc: '.jshintrc' 108 | }, 109 | all: [ 110 | 'Gruntfile.js', 111 | '<%%= yeoman.app %>/scripts/**/**/*.js' 112 | ] 113 | }, 114 | coffee: { 115 | options: { 116 | sourceMap: true, 117 | sourceRoot: '' 118 | }, 119 | dist: { 120 | files: [{ 121 | expand: true, 122 | cwd: '<%%= yeoman.app %>/scripts', 123 | src: '**/**/*.coffee', 124 | dest: '.tmp/scripts', 125 | ext: '.js' 126 | }] 127 | }, 128 | test: { 129 | files: [{ 130 | expand: true, 131 | cwd: 'test/spec', 132 | src: '**/**/*.coffee', 133 | dest: '.tmp/spec', 134 | ext: '.js' 135 | }] 136 | } 137 | },<% if (compassBootstrap || usingSass) { %> 138 | compass: { 139 | options: { 140 | sassDir: '<%%= yeoman.app %>/styles', 141 | cssDir: '.tmp/styles', 142 | generatedImagesDir: '.tmp/images/generated', 143 | imagesDir: '<%%= yeoman.app %>/images', 144 | javascriptsDir: '<%%= yeoman.app %>/scripts', 145 | fontsDir: '<%%= yeoman.app %>/styles/fonts', 146 | importPath: '<%%= yeoman.app %>/bower_components', 147 | httpImagesPath: '/images', 148 | httpGeneratedImagesPath: '/images/generated', 149 | httpFontsPath: '/styles/fonts', 150 | relativeAssets: false 151 | }, 152 | dist: {}, 153 | server: { 154 | options: { 155 | debugInfo: true 156 | } 157 | } 158 | },<% } %> 159 | // not used since Uglify task does concat, 160 | // but still available if needed 161 | /*concat: { 162 | dist: {} 163 | },*/ 164 | rev: { 165 | dist: { 166 | files: { 167 | src: [ 168 | '<%%= yeoman.dist %>/scripts/**/**/*.js', 169 | '<%%= yeoman.dist %>/styles/**/**/*.css', 170 | '<%%= yeoman.dist %>/images/**/**/*.{png,jpg,jpeg,gif,webp,svg}', 171 | '<%%= yeoman.dist %>/styles/fonts/*' 172 | ] 173 | } 174 | } 175 | }, 176 | useminPrepare: { 177 | html: '<%%= yeoman.app %>/index.html', 178 | options: { 179 | dest: '<%%= yeoman.dist %>' 180 | } 181 | }, 182 | usemin: { 183 | html: ['<%%= yeoman.dist %>/**/**/*.html'], 184 | css: ['<%%= yeoman.dist %>/styles/**/**/*.css'], 185 | options: { 186 | dirs: ['<%%= yeoman.dist %>'] 187 | } 188 | }, 189 | imagemin: { 190 | dist: { 191 | files: [{ 192 | expand: true, 193 | cwd: '<%%= yeoman.app %>/images', 194 | src: '**/**/*.{png,jpg,jpeg}', 195 | dest: '<%%= yeoman.dist %>/images' 196 | }] 197 | } 198 | }, 199 | svgmin: { 200 | dist: { 201 | files: [{ 202 | expand: true, 203 | cwd: '<%%= yeoman.app %>/images', 204 | src: '**/**/*.svg', 205 | dest: '<%%= yeoman.dist %>/images' 206 | }] 207 | } 208 | }, 209 | cssmin: { 210 | // By default, your `index.html` will take care of 211 | // minification. This option is pre-configured if you do not wish to use 212 | // Usemin blocks. 213 | // dist: { 214 | // files: { 215 | // '<%%= yeoman.dist %>/styles/main.css': [ 216 | // '.tmp/styles/**/**/*.css', 217 | // '<%%= yeoman.app %>/styles/**/**/*.css' 218 | // ] 219 | // } 220 | // } 221 | }, 222 | htmlmin: { 223 | dist: { 224 | options: { 225 | /*removeCommentsFromCDATA: true, 226 | // https://github.com/yeoman/grunt-usemin/issues/44 227 | //collapseWhitespace: true, 228 | collapseBooleanAttributes: true, 229 | removeAttributeQuotes: true, 230 | removeRedundantAttributes: true, 231 | useShortDoctype: true, 232 | removeEmptyAttributes: true, 233 | removeOptionalTags: true*/ 234 | }, 235 | files: [{ 236 | expand: true, 237 | cwd: '<%%= yeoman.app %>', 238 | src: ['*.html', 'views/*.html'], 239 | dest: '<%%= yeoman.dist %>' 240 | }] 241 | } 242 | }, 243 | // Put files not handled in other tasks here 244 | copy: { 245 | dist: { 246 | files: [{ 247 | expand: true, 248 | dot: true, 249 | cwd: '<%%= yeoman.app %>', 250 | dest: '<%%= yeoman.dist %>', 251 | src: [ 252 | '*.{ico,png,txt}', 253 | '.htaccess', 254 | 'bower_components/**/*', 255 | 'images/**/**/*.{gif,webp}', 256 | 'styles/fonts/*' 257 | ] 258 | }, { 259 | expand: true, 260 | cwd: '.tmp/images', 261 | dest: '<%%= yeoman.dist %>/images', 262 | src: [ 263 | 'generated/*' 264 | ] 265 | }] 266 | }, 267 | styles: { 268 | expand: true, 269 | cwd: '<%%= yeoman.app %>/styles', 270 | dest: '.tmp/styles/', 271 | src: '**/**/*.css' 272 | } 273 | }, 274 | concurrent: { 275 | server: [ 276 | 'coffee:dist',<% if (compassBootstrap || usingSass) { %> 277 | 'compass:server',<% } %> 278 | 'copy:styles' 279 | ], 280 | test: [ 281 | 'coffee',<% if (compassBootstrap || usingSass) { %> 282 | 'compass',<% } %> 283 | 'copy:styles' 284 | ], 285 | dist: [ 286 | 'coffee',<% if (compassBootstrap || usingSass) { %> 287 | 'compass:dist',<% } %> 288 | 'copy:styles', 289 | 'imagemin', 290 | 'svgmin', 291 | 'htmlmin' 292 | ] 293 | }, 294 | karma: { 295 | unit: { 296 | configFile: 'karma.conf.js', 297 | singleRun: true 298 | } 299 | }, 300 | cdnify: { 301 | dist: { 302 | html: ['<%%= yeoman.dist %>/*.html'] 303 | } 304 | }, 305 | ngmin: { 306 | dist: { 307 | files: [{ 308 | expand: true, 309 | cwd: '<%%= yeoman.dist %>/scripts', 310 | src: '*.js', 311 | dest: '<%%= yeoman.dist %>/scripts' 312 | }] 313 | } 314 | }, 315 | uglify: { 316 | dist: { 317 | files: { 318 | '<%%= yeoman.dist %>/scripts/scripts.js': [ 319 | '<%%= yeoman.dist %>/scripts/scripts.js' 320 | ] 321 | } 322 | } 323 | } 324 | }); 325 | 326 | grunt.registerTask('server', function (target) { 327 | if (target === 'dist') { 328 | return grunt.task.run(['build', 'connect:dist:keepalive']); 329 | } 330 | 331 | grunt.task.run([ 332 | 'clean:server', 333 | 'concurrent:server', 334 | 'autoprefixer', 335 | 'connect:livereload', 336 | 'watch' 337 | ]); 338 | }); 339 | 340 | grunt.registerTask('test', [ 341 | 'clean:server', 342 | 'concurrent:test', 343 | 'autoprefixer', 344 | 'connect:test', 345 | 'karma' 346 | ]); 347 | 348 | grunt.registerTask('build', [ 349 | 'clean:dist', 350 | 'useminPrepare', 351 | 'concurrent:dist', 352 | 'autoprefixer', 353 | 'concat', 354 | 'copy:dist', 355 | 'cdnify', 356 | 'ngmin', 357 | 'cssmin', 358 | 'uglify', 359 | 'rev', 360 | 'usemin' 361 | ]); 362 | 363 | grunt.registerTask('default', [ 364 | 'jshint', 365 | 'test', 366 | 'build' 367 | ]); 368 | }; 369 | -------------------------------------------------------------------------------- /templates/common/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.camelize(appname) %>", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": ">=1.3.14", 6 | "json3": ">=3.2.4",<% if (bootstrap) { %> 7 | "jquery": ">=2.1.3", 8 | "twitter-bootstrap-sass": ">=3.3.3", 9 | <% } %>"es5-shim": "~2.0.8"<% if (resourceModule) { %>, 10 | "angular-resource": ">=1.3.14" <% } %><% if (cookiesModule) { %>, 11 | "angular-cookies": ">=1.3.14" <% } %><% if (sanitizeModule) { %>, 12 | "angular-sanitize": ">=1.3.14" <% } %><% if (uirouterModule) { %>, 13 | "angular-ui-router": "*"<% } %> 14 | }, 15 | "devDependencies": { 16 | "angular-mocks": ">=1.3.14", 17 | "angular-scenario": ">=1.3.14" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /templates/common/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.0.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "grunt": "~0.4.5", 7 | "grunt-contrib-copy": "~0.8.0", 8 | "grunt-contrib-concat": "~0.5.1", 9 | "grunt-contrib-coffee": "~0.13.0", 10 | "grunt-contrib-uglify": "~0.8.0", 11 | "grunt-contrib-compass": "~1.0.1", 12 | "grunt-contrib-jshint": "~0.11.0", 13 | "grunt-contrib-cssmin": "~0.12.2", 14 | "grunt-contrib-connect": "~0.9.0", 15 | "grunt-contrib-clean": "~0.6.0", 16 | "grunt-contrib-htmlmin": "~0.4.0", 17 | "grunt-contrib-imagemin": "~1.0.1", 18 | "grunt-contrib-watch": "~0.6.1", 19 | "grunt-autoprefixer": "~2.2.0", 20 | "grunt-usemin": "~3.0.0", 21 | "grunt-svgmin": "~2.0.1", 22 | "grunt-rev": "~0.1.0", 23 | "grunt-concurrent": "~1.0.0", 24 | "load-grunt-tasks": "~3.1.0", 25 | "grunt-google-cdn": "~0.4.3", 26 | "grunt-ngmin": "~0.0.3", 27 | "time-grunt": "~1.1.0" 28 | }, 29 | "engines": { 30 | "node": ">=0.10.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /templates/common/gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .tmp 4 | .sass-cache 5 | app/bower_components 6 | -------------------------------------------------------------------------------- /templates/common/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 23 | 24 | 25 | <% if (uirouterModule){ %> 26 |
27 | <% }else{ %> 28 |
29 | <% } %> 30 | 31 | 32 | 41 | 42 | <% if (bootstrap) { %><% } %> 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /templates/common/root/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "app/bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /templates/common/root/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /templates/common/root/.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /templates/common/root/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "angular": false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /templates/common/root/app/.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee -------------------------------------------------------------------------------- /templates/common/root/app/.htaccess: -------------------------------------------------------------------------------- 1 | # Apache Configuration File 2 | 3 | # (!) Using `.htaccess` files slows down Apache, therefore, if you have access 4 | # to the main server config file (usually called `httpd.conf`), you should add 5 | # this logic there: http://httpd.apache.org/docs/current/howto/htaccess.html. 6 | 7 | # ############################################################################## 8 | # # CROSS-ORIGIN RESOURCE SHARING (CORS) # 9 | # ############################################################################## 10 | 11 | # ------------------------------------------------------------------------------ 12 | # | Cross-domain AJAX requests | 13 | # ------------------------------------------------------------------------------ 14 | 15 | # Enable cross-origin AJAX requests. 16 | # http://code.google.com/p/html5security/wiki/CrossOriginRequestSecurity 17 | # http://enable-cors.org/ 18 | 19 | # 20 | # Header set Access-Control-Allow-Origin "*" 21 | # 22 | 23 | # ------------------------------------------------------------------------------ 24 | # | CORS-enabled images | 25 | # ------------------------------------------------------------------------------ 26 | 27 | # Send the CORS header for images when browsers request it. 28 | # https://developer.mozilla.org/en/CORS_Enabled_Image 29 | # http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html 30 | # http://hacks.mozilla.org/2011/11/using-cors-to-load-webgl-textures-from-cross-domain-images/ 31 | 32 | 33 | 34 | 35 | SetEnvIf Origin ":" IS_CORS 36 | Header set Access-Control-Allow-Origin "*" env=IS_CORS 37 | 38 | 39 | 40 | 41 | # ------------------------------------------------------------------------------ 42 | # | Web fonts access | 43 | # ------------------------------------------------------------------------------ 44 | 45 | # Allow access from all domains for web fonts 46 | 47 | 48 | 49 | Header set Access-Control-Allow-Origin "*" 50 | 51 | 52 | 53 | 54 | # ############################################################################## 55 | # # ERRORS # 56 | # ############################################################################## 57 | 58 | # ------------------------------------------------------------------------------ 59 | # | 404 error prevention for non-existing redirected folders | 60 | # ------------------------------------------------------------------------------ 61 | 62 | # Prevent Apache from returning a 404 error for a rewrite if a directory 63 | # with the same name does not exist. 64 | # http://httpd.apache.org/docs/current/content-negotiation.html#multiviews 65 | # http://www.webmasterworld.com/apache/3808792.htm 66 | 67 | Options -MultiViews 68 | 69 | # ------------------------------------------------------------------------------ 70 | # | Custom error messages / pages | 71 | # ------------------------------------------------------------------------------ 72 | 73 | # You can customize what Apache returns to the client in case of an error (see 74 | # http://httpd.apache.org/docs/current/mod/core.html#errordocument), e.g.: 75 | 76 | ErrorDocument 404 /404.html 77 | 78 | 79 | # ############################################################################## 80 | # # INTERNET EXPLORER # 81 | # ############################################################################## 82 | 83 | # ------------------------------------------------------------------------------ 84 | # | Better website experience | 85 | # ------------------------------------------------------------------------------ 86 | 87 | # Force IE to render pages in the highest available mode in the various 88 | # cases when it may not: http://hsivonen.iki.fi/doctype/ie-mode.pdf. 89 | 90 | 91 | Header set X-UA-Compatible "IE=edge" 92 | # `mod_headers` can't match based on the content-type, however, we only 93 | # want to send this header for HTML pages and not for the other resources 94 | 95 | Header unset X-UA-Compatible 96 | 97 | 98 | 99 | # ------------------------------------------------------------------------------ 100 | # | Cookie setting from iframes | 101 | # ------------------------------------------------------------------------------ 102 | 103 | # Allow cookies to be set from iframes in IE. 104 | 105 | # 106 | # Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" 107 | # 108 | 109 | # ------------------------------------------------------------------------------ 110 | # | Screen flicker | 111 | # ------------------------------------------------------------------------------ 112 | 113 | # Stop screen flicker in IE on CSS rollovers (this only works in 114 | # combination with the `ExpiresByType` directives for images from below). 115 | 116 | # BrowserMatch "MSIE" brokenvary=1 117 | # BrowserMatch "Mozilla/4.[0-9]{2}" brokenvary=1 118 | # BrowserMatch "Opera" !brokenvary 119 | # SetEnvIf brokenvary 1 force-no-vary 120 | 121 | 122 | # ############################################################################## 123 | # # MIME TYPES AND ENCODING # 124 | # ############################################################################## 125 | 126 | # ------------------------------------------------------------------------------ 127 | # | Proper MIME types for all files | 128 | # ------------------------------------------------------------------------------ 129 | 130 | 131 | 132 | # Audio 133 | AddType audio/mp4 m4a f4a f4b 134 | AddType audio/ogg oga ogg 135 | 136 | # JavaScript 137 | # Normalize to standard type (it's sniffed in IE anyways): 138 | # http://tools.ietf.org/html/rfc4329#section-7.2 139 | AddType application/javascript js jsonp 140 | AddType application/json json 141 | 142 | # Video 143 | AddType video/mp4 mp4 m4v f4v f4p 144 | AddType video/ogg ogv 145 | AddType video/webm webm 146 | AddType video/x-flv flv 147 | 148 | # Web fonts 149 | AddType application/font-woff woff 150 | AddType application/vnd.ms-fontobject eot 151 | 152 | # Browsers usually ignore the font MIME types and sniff the content, 153 | # however, Chrome shows a warning if other MIME types are used for the 154 | # following fonts. 155 | AddType application/x-font-ttf ttc ttf 156 | AddType font/opentype otf 157 | 158 | # Make SVGZ fonts work on iPad: 159 | # https://twitter.com/FontSquirrel/status/14855840545 160 | AddType image/svg+xml svg svgz 161 | AddEncoding gzip svgz 162 | 163 | # Other 164 | AddType application/octet-stream safariextz 165 | AddType application/x-chrome-extension crx 166 | AddType application/x-opera-extension oex 167 | AddType application/x-shockwave-flash swf 168 | AddType application/x-web-app-manifest+json webapp 169 | AddType application/x-xpinstall xpi 170 | AddType application/xml atom rdf rss xml 171 | AddType image/webp webp 172 | AddType image/x-icon ico 173 | AddType text/cache-manifest appcache manifest 174 | AddType text/vtt vtt 175 | AddType text/x-component htc 176 | AddType text/x-vcard vcf 177 | 178 | 179 | 180 | # ------------------------------------------------------------------------------ 181 | # | UTF-8 encoding | 182 | # ------------------------------------------------------------------------------ 183 | 184 | # Use UTF-8 encoding for anything served as `text/html` or `text/plain`. 185 | AddDefaultCharset utf-8 186 | 187 | # Force UTF-8 for certain file formats. 188 | 189 | AddCharset utf-8 .atom .css .js .json .rss .vtt .webapp .xml 190 | 191 | 192 | 193 | # ############################################################################## 194 | # # URL REWRITES # 195 | # ############################################################################## 196 | 197 | # ------------------------------------------------------------------------------ 198 | # | Rewrite engine | 199 | # ------------------------------------------------------------------------------ 200 | 201 | # Turning on the rewrite engine and enabling the `FollowSymLinks` option is 202 | # necessary for the following directives to work. 203 | 204 | # If your web host doesn't allow the `FollowSymlinks` option, you may need to 205 | # comment it out and use `Options +SymLinksIfOwnerMatch` but, be aware of the 206 | # performance impact: http://httpd.apache.org/docs/current/misc/perf-tuning.html#symlinks 207 | 208 | # Also, some cloud hosting services require `RewriteBase` to be set: 209 | # http://www.rackspace.com/knowledge_center/frequently-asked-question/why-is-mod-rewrite-not-working-on-my-site 210 | 211 | 212 | Options +FollowSymlinks 213 | # Options +SymLinksIfOwnerMatch 214 | RewriteEngine On 215 | # RewriteBase / 216 | 217 | 218 | # ------------------------------------------------------------------------------ 219 | # | Suppressing / Forcing the "www." at the beginning of URLs | 220 | # ------------------------------------------------------------------------------ 221 | 222 | # The same content should never be available under two different URLs especially 223 | # not with and without "www." at the beginning. This can cause SEO problems 224 | # (duplicate content), therefore, you should choose one of the alternatives and 225 | # redirect the other one. 226 | 227 | # By default option 1 (no "www.") is activated: 228 | # http://no-www.org/faq.php?q=class_b 229 | 230 | # If you'd prefer to use option 2, just comment out all the lines from option 1 231 | # and uncomment the ones from option 2. 232 | 233 | # IMPORTANT: NEVER USE BOTH RULES AT THE SAME TIME! 234 | 235 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 236 | 237 | # Option 1: rewrite www.example.com → example.com 238 | 239 | 240 | RewriteCond %{HTTPS} !=on 241 | RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] 242 | RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] 243 | 244 | 245 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 246 | 247 | # Option 2: rewrite example.com → www.example.com 248 | 249 | # Be aware that the following might not be a good idea if you use "real" 250 | # subdomains for certain parts of your website. 251 | 252 | # 253 | # RewriteCond %{HTTPS} !=on 254 | # RewriteCond %{HTTP_HOST} !^www\..+$ [NC] 255 | # RewriteRule ^ http://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 256 | # 257 | 258 | 259 | # ############################################################################## 260 | # # SECURITY # 261 | # ############################################################################## 262 | 263 | # ------------------------------------------------------------------------------ 264 | # | Content Security Policy (CSP) | 265 | # ------------------------------------------------------------------------------ 266 | 267 | # You can mitigate the risk of cross-site scripting and other content-injection 268 | # attacks by setting a Content Security Policy which whitelists trusted sources 269 | # of content for your site. 270 | 271 | # The example header below allows ONLY scripts that are loaded from the current 272 | # site's origin (no inline scripts, no CDN, etc). This almost certainly won't 273 | # work as-is for your site! 274 | 275 | # To get all the details you'll need to craft a reasonable policy for your site, 276 | # read: http://html5rocks.com/en/tutorials/security/content-security-policy (or 277 | # see the specification: http://w3.org/TR/CSP). 278 | 279 | # 280 | # Header set Content-Security-Policy "script-src 'self'; object-src 'self'" 281 | # 282 | # Header unset Content-Security-Policy 283 | # 284 | # 285 | 286 | # ------------------------------------------------------------------------------ 287 | # | File access | 288 | # ------------------------------------------------------------------------------ 289 | 290 | # Block access to directories without a default document. 291 | # Usually you should leave this uncommented because you shouldn't allow anyone 292 | # to surf through every directory on your server (which may includes rather 293 | # private places like the CMS's directories). 294 | 295 | 296 | Options -Indexes 297 | 298 | 299 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 300 | 301 | # Block access to hidden files and directories. 302 | # This includes directories used by version control systems such as Git and SVN. 303 | 304 | 305 | RewriteCond %{SCRIPT_FILENAME} -d [OR] 306 | RewriteCond %{SCRIPT_FILENAME} -f 307 | RewriteRule "(^|/)\." - [F] 308 | 309 | 310 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 311 | 312 | # Block access to backup and source files. 313 | # These files may be left by some text editors and can pose a great security 314 | # danger when anyone has access to them. 315 | 316 | 317 | Order allow,deny 318 | Deny from all 319 | Satisfy All 320 | 321 | 322 | # ------------------------------------------------------------------------------ 323 | # | Secure Sockets Layer (SSL) | 324 | # ------------------------------------------------------------------------------ 325 | 326 | # Rewrite secure requests properly to prevent SSL certificate warnings, e.g.: 327 | # prevent `https://www.example.com` when your certificate only allows 328 | # `https://secure.example.com`. 329 | 330 | # 331 | # RewriteCond %{SERVER_PORT} !^443 332 | # RewriteRule ^ https://example-domain-please-change-me.com%{REQUEST_URI} [R=301,L] 333 | # 334 | 335 | # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 336 | 337 | # Force client-side SSL redirection. 338 | 339 | # If a user types "example.com" in his browser, the above rule will redirect him 340 | # to the secure version of the site. That still leaves a window of opportunity 341 | # (the initial HTTP connection) for an attacker to downgrade or redirect the 342 | # request. The following header ensures that browser will ONLY connect to your 343 | # server via HTTPS, regardless of what the users type in the address bar. 344 | # http://www.html5rocks.com/en/tutorials/security/transport-layer-security/ 345 | 346 | # 347 | # Header set Strict-Transport-Security max-age=16070400; 348 | # 349 | 350 | # ------------------------------------------------------------------------------ 351 | # | Server software information | 352 | # ------------------------------------------------------------------------------ 353 | 354 | # Avoid displaying the exact Apache version number, the description of the 355 | # generic OS-type and the information about Apache's compiled-in modules. 356 | 357 | # ADD THIS DIRECTIVE IN THE `httpd.conf` AS IT WILL NOT WORK IN THE `.htaccess`! 358 | 359 | # ServerTokens Prod 360 | 361 | 362 | # ############################################################################## 363 | # # WEB PERFORMANCE # 364 | # ############################################################################## 365 | 366 | # ------------------------------------------------------------------------------ 367 | # | Compression | 368 | # ------------------------------------------------------------------------------ 369 | 370 | 371 | 372 | # Force compression for mangled headers. 373 | # http://developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping 374 | 375 | 376 | SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding 377 | RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding 378 | 379 | 380 | 381 | # Compress all output labeled with one of the following MIME-types 382 | # (for Apache versions below 2.3.7, you don't need to enable `mod_filter` 383 | # and can remove the `` and `` lines 384 | # as `AddOutputFilterByType` is still in the core directives). 385 | 386 | AddOutputFilterByType DEFLATE application/atom+xml \ 387 | application/javascript \ 388 | application/json \ 389 | application/rss+xml \ 390 | application/vnd.ms-fontobject \ 391 | application/x-font-ttf \ 392 | application/x-web-app-manifest+json \ 393 | application/xhtml+xml \ 394 | application/xml \ 395 | font/opentype \ 396 | image/svg+xml \ 397 | image/x-icon \ 398 | text/css \ 399 | text/html \ 400 | text/plain \ 401 | text/x-component \ 402 | text/xml 403 | 404 | 405 | 406 | 407 | # ------------------------------------------------------------------------------ 408 | # | Content transformations | 409 | # ------------------------------------------------------------------------------ 410 | 411 | # Prevent some of the mobile network providers from modifying the content of 412 | # your site: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.5. 413 | 414 | # 415 | # Header set Cache-Control "no-transform" 416 | # 417 | 418 | # ------------------------------------------------------------------------------ 419 | # | ETag removal | 420 | # ------------------------------------------------------------------------------ 421 | 422 | # Since we're sending far-future expires headers (see below), ETags can 423 | # be removed: http://developer.yahoo.com/performance/rules.html#etags. 424 | 425 | # `FileETag None` is not enough for every server. 426 | 427 | Header unset ETag 428 | 429 | 430 | FileETag None 431 | 432 | # ------------------------------------------------------------------------------ 433 | # | Expires headers (for better cache control) | 434 | # ------------------------------------------------------------------------------ 435 | 436 | # The following expires headers are set pretty far in the future. If you don't 437 | # control versioning with filename-based cache busting, consider lowering the 438 | # cache time for resources like CSS and JS to something like 1 week. 439 | 440 | 441 | 442 | ExpiresActive on 443 | ExpiresDefault "access plus 1 month" 444 | 445 | # CSS 446 | ExpiresByType text/css "access plus 1 year" 447 | 448 | # Data interchange 449 | ExpiresByType application/json "access plus 0 seconds" 450 | ExpiresByType application/xml "access plus 0 seconds" 451 | ExpiresByType text/xml "access plus 0 seconds" 452 | 453 | # Favicon (cannot be renamed!) 454 | ExpiresByType image/x-icon "access plus 1 week" 455 | 456 | # HTML components (HTCs) 457 | ExpiresByType text/x-component "access plus 1 month" 458 | 459 | # HTML 460 | ExpiresByType text/html "access plus 0 seconds" 461 | 462 | # JavaScript 463 | ExpiresByType application/javascript "access plus 1 year" 464 | 465 | # Manifest files 466 | ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds" 467 | ExpiresByType text/cache-manifest "access plus 0 seconds" 468 | 469 | # Media 470 | ExpiresByType audio/ogg "access plus 1 month" 471 | ExpiresByType image/gif "access plus 1 month" 472 | ExpiresByType image/jpeg "access plus 1 month" 473 | ExpiresByType image/png "access plus 1 month" 474 | ExpiresByType video/mp4 "access plus 1 month" 475 | ExpiresByType video/ogg "access plus 1 month" 476 | ExpiresByType video/webm "access plus 1 month" 477 | 478 | # Web feeds 479 | ExpiresByType application/atom+xml "access plus 1 hour" 480 | ExpiresByType application/rss+xml "access plus 1 hour" 481 | 482 | # Web fonts 483 | ExpiresByType application/font-woff "access plus 1 month" 484 | ExpiresByType application/vnd.ms-fontobject "access plus 1 month" 485 | ExpiresByType application/x-font-ttf "access plus 1 month" 486 | ExpiresByType font/opentype "access plus 1 month" 487 | ExpiresByType image/svg+xml "access plus 1 month" 488 | 489 | 490 | 491 | # ------------------------------------------------------------------------------ 492 | # | Filename-based cache busting | 493 | # ------------------------------------------------------------------------------ 494 | 495 | # If you're not using a build process to manage your filename version revving, 496 | # you might want to consider enabling the following directives to route all 497 | # requests such as `/css/style.12345.css` to `/css/style.css`. 498 | 499 | # To understand why this is important and a better idea than `*.css?v231`, read: 500 | # http://stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring 501 | 502 | # 503 | # RewriteCond %{REQUEST_FILENAME} !-f 504 | # RewriteCond %{REQUEST_FILENAME} !-d 505 | # RewriteRule ^(.+)\.(\d+)\.(js|css|png|jpg|gif)$ $1.$3 [L] 506 | # 507 | 508 | # ------------------------------------------------------------------------------ 509 | # | File concatenation | 510 | # ------------------------------------------------------------------------------ 511 | 512 | # Allow concatenation from within specific CSS and JS files, e.g.: 513 | # Inside of `script.combined.js` you could have 514 | # 515 | # 516 | # and they would be included into this single file. 517 | 518 | # 519 | # 520 | # Options +Includes 521 | # AddOutputFilterByType INCLUDES application/javascript application/json 522 | # SetOutputFilter INCLUDES 523 | # 524 | # 525 | # Options +Includes 526 | # AddOutputFilterByType INCLUDES text/css 527 | # SetOutputFilter INCLUDES 528 | # 529 | # 530 | 531 | # ------------------------------------------------------------------------------ 532 | # | Persistent connections | 533 | # ------------------------------------------------------------------------------ 534 | 535 | # Allow multiple requests to be sent over the same TCP connection: 536 | # http://httpd.apache.org/docs/current/en/mod/core.html#keepalive. 537 | 538 | # Enable if you serve a lot of static content but, be aware of the 539 | # possible disadvantages! 540 | 541 | # 542 | # Header set Connection Keep-Alive 543 | # 544 | -------------------------------------------------------------------------------- /templates/common/root/app/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found :( 6 | 141 | 142 | 143 |
144 |

Not found :(

145 |

Sorry, but the page you were trying to view does not exist.

146 |

It looks like this was the result of either:

147 | 151 | 154 | 155 |
156 | 157 | 158 | -------------------------------------------------------------------------------- /templates/common/root/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iamblue/generator-angular-ui-router/36c01509f087be5bc441111969e19f8b95879654/templates/common/root/app/favicon.ico -------------------------------------------------------------------------------- /templates/common/root/app/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /templates/common/root/app/views/main.html: -------------------------------------------------------------------------------- 1 |
2 |

'Allo, 'Allo!

3 |

You now have

4 | 7 |

installed.

8 |

Enjoy coding! - Yeoman

9 |
10 | -------------------------------------------------------------------------------- /templates/common/root/test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "after": false, 23 | "afterEach": false, 24 | "angular": false, 25 | "before": false, 26 | "beforeEach": false, 27 | "browser": false, 28 | "describe": false, 29 | "expect": false, 30 | "inject": false, 31 | "it": false, 32 | "spyOn": false 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /templates/common/root/test/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | End2end Test Runner 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /templates/common/view.html: -------------------------------------------------------------------------------- 1 |

This is the <%= name %> view.

2 | -------------------------------------------------------------------------------- /templates/javascript-min/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | <% if(uirouterModules){ %> 4 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 5 | .config(function ($stateProvider, $urlRouterProvider) { 6 | //delete $httpProvider.defaults.headers.common['X-Requested-With']; 7 | $stateProvider 8 | .state('index', { 9 | url: '/', 10 | templateUrl: 'views/main.html', 11 | controller:'MainCtrl' 12 | }) 13 | $urlRouterProvider.otherwise('/'); 14 | }) 15 | <% }else{ %> 16 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 17 | .config(function ($routeProvider) { 18 | $routeProvider 19 | .when('/', { 20 | templateUrl: 'views/main.html', 21 | controller: 'MainCtrl' 22 | }) 23 | .otherwise({ 24 | redirectTo: '/' 25 | }); 26 | }); 27 | <% } %> 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /templates/javascript-min/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .controller('<%= _.classify(name) %>Ctrl', ['$scope', function ($scope) { 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate', 7 | 'AngularJS', 8 | 'Karma' 9 | ]; 10 | }]); 11 | -------------------------------------------------------------------------------- /templates/javascript-min/decorator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .config(['$provide', function ($provide) { 5 | $provide.decorator('<%= _.camelize(name) %>', function ($delegate) { 6 | // decorate the $delegate 7 | return $delegate; 8 | }); 9 | }]); 10 | -------------------------------------------------------------------------------- /templates/javascript-min/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .directive('<%= _.camelize(name) %>', [function () { 5 | return { 6 | template: '
', 7 | restrict: 'E', 8 | link: function postLink(scope, element, attrs) { 9 | element.text('this is the <%= _.camelize(name) %> directive'); 10 | } 11 | }; 12 | }]); 13 | -------------------------------------------------------------------------------- /templates/javascript-min/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .filter('<%= _.camelize(name) %>', [function () { 5 | return function (input) { 6 | return '<%= _.camelize(name) %> filter: ' + input; 7 | }; 8 | }]); 9 | -------------------------------------------------------------------------------- /templates/javascript-min/service/constant.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .constant('<%= _.camelize(name) %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript-min/service/factory.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .factory('<%= _.camelize(name) %>', [function() { 5 | // Service logic 6 | // ... 7 | 8 | var meaningOfLife = 42; 9 | 10 | // Public API here 11 | return { 12 | someMethod: function() { 13 | return meaningOfLife; 14 | } 15 | }; 16 | }]); 17 | -------------------------------------------------------------------------------- /templates/javascript-min/service/provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .provider('<%= _.camelize(name) %>', [function() { 5 | 6 | // Private variables 7 | var salutation = 'Hello'; 8 | 9 | // Private constructor 10 | function Greeter() { 11 | this.greet = function() { 12 | return salutation; 13 | }; 14 | } 15 | 16 | // Public API for configuration 17 | this.setSalutation = function(s) { 18 | salutation = s; 19 | }; 20 | 21 | // Method for instantiating 22 | this.$get = function() { 23 | return new Greeter(); 24 | }; 25 | }]); 26 | -------------------------------------------------------------------------------- /templates/javascript-min/service/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .service('<%= _.classify(name) %>', function <%= _.classify(name) %>() { 5 | // AngularJS will instantiate a singleton by calling "new" on this function 6 | }); 7 | -------------------------------------------------------------------------------- /templates/javascript-min/service/value.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .value('<%= _.camelize(name) %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript-min/spec/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: <%= _.classify(name) %>Ctrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | var <%= _.classify(name) %>Ctrl, 9 | scope; 10 | 11 | // Initialize the controller and a mock scope 12 | beforeEach(inject(function ($controller, $rootScope) { 13 | scope = $rootScope.$new(); 14 | <%= _.classify(name) %>Ctrl = $controller('<%= _.classify(name) %>Ctrl', { 15 | $scope: scope 16 | }); 17 | })); 18 | 19 | it('should attach a list of awesomeThings to the scope', function () { 20 | expect(scope.awesomeThings.length).toBe(3); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /templates/javascript-min/spec/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Directive: <%= _.camelize(name) %>', function () { 4 | 5 | // load the directive's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | var element, 9 | scope; 10 | 11 | beforeEach(inject(function ($rootScope) { 12 | scope = $rootScope.$new(); 13 | })); 14 | 15 | it('should make hidden element visible', inject(function ($compile) { 16 | element = angular.element('<<%= _.dasherize(name) %>>>'); 17 | element = $compile(element)(scope); 18 | expect(element.text()).toBe('this is the <%= _.camelize(name) %> directive'); 19 | })); 20 | }); 21 | -------------------------------------------------------------------------------- /templates/javascript-min/spec/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Filter: <%= _.camelize(name) %>', function () { 4 | 5 | // load the filter's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | // initialize a new instance of the filter before each test 9 | var <%= _.camelize(name) %>; 10 | beforeEach(inject(function($filter) { 11 | <%= _.camelize(name) %> = $filter('<%= _.camelize(name) %>'); 12 | })); 13 | 14 | it('should return the input prefixed with "<%= _.camelize(name) %> filter:"', function () { 15 | var text = 'angularjs'; 16 | expect(<%= _.camelize(name) %>(text)).toBe('<%= _.camelize(name) %> filter: ' + text); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /templates/javascript-min/spec/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: <%= _.classify(name) %>', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('<%= _.classify(appname) %>App')); 7 | 8 | // instantiate service 9 | var <%= _.classify(name) %>; 10 | beforeEach(inject(function(_<%= _.classify(name) %>_) { 11 | <%= _.classify(name) %> = _<%= _.classify(name) %>_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!<%= _.classify(name) %>).toBe(true); 16 | }); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /templates/javascript/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | <% if(uirouterModules){ %> 4 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 5 | .config(function ($stateProvider, $urlRouterProvider) { 6 | //delete $httpProvider.defaults.headers.common['X-Requested-With']; 7 | $urlRouterProvider.otherwise('/'); 8 | $stateProvider 9 | .state('index', { 10 | url: '/', 11 | templateUrl: 'views/main.html', 12 | controller:'MainCtrl' 13 | }) 14 | }) 15 | <% }else{ %> 16 | angular.module('<%= _.camelize(appname) %>App', [<%= angularModules %>]) 17 | .config(function ($routeProvider) { 18 | $routeProvider 19 | .when('/', { 20 | templateUrl: 'views/main.html', 21 | controller: 'MainCtrl' 22 | }) 23 | .otherwise({ 24 | redirectTo: '/' 25 | }); 26 | }); 27 | <% } %> 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /templates/javascript/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .controller('<%= _.classify(name) %>Ctrl', function ($scope) { 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate', 7 | 'AngularJS', 8 | 'Karma' 9 | ]; 10 | }); 11 | -------------------------------------------------------------------------------- /templates/javascript/decorator.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .config(function ($provide) { 5 | $provide.decorator('<%= _.camelize(name) %>', function ($delegate) { 6 | // decorate the $delegate 7 | return $delegate; 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /templates/javascript/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .directive('<%= _.camelize(name) %>', function () { 5 | return { 6 | template: '
', 7 | restrict: 'E', 8 | link: function postLink(scope, element, attrs) { 9 | element.text('this is the <%= _.camelize(name) %> directive'); 10 | } 11 | }; 12 | }); 13 | -------------------------------------------------------------------------------- /templates/javascript/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .filter('<%= _.camelize(name) %>', function () { 5 | return function (input) { 6 | return '<%= _.camelize(name) %> filter: ' + input; 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /templates/javascript/service/constant.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .constant('<%= _.camelize(name) %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript/service/factory.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .factory('<%= _.camelize(name) %>', function () { 5 | // Service logic 6 | // ... 7 | 8 | var meaningOfLife = 42; 9 | 10 | // Public API here 11 | return { 12 | someMethod: function () { 13 | return meaningOfLife; 14 | } 15 | }; 16 | }); 17 | -------------------------------------------------------------------------------- /templates/javascript/service/provider.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .provider('<%= _.camelize(name) %>', function () { 5 | 6 | // Private variables 7 | var salutation = 'Hello'; 8 | 9 | // Private constructor 10 | function Greeter() { 11 | this.greet = function () { 12 | return salutation; 13 | }; 14 | } 15 | 16 | // Public API for configuration 17 | this.setSalutation = function (s) { 18 | salutation = s; 19 | }; 20 | 21 | // Method for instantiating 22 | this.$get = function () { 23 | return new Greeter(); 24 | }; 25 | }); 26 | -------------------------------------------------------------------------------- /templates/javascript/service/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .service('<%= _.classify(name) %>', function <%= _.classify(name) %>() { 5 | // AngularJS will instantiate a singleton by calling "new" on this function 6 | }); 7 | -------------------------------------------------------------------------------- /templates/javascript/service/value.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= _.camelize(appname) %>App') 4 | .value('<%= _.camelize(name) %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript/spec/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Controller: <%= _.classify(name) %>Ctrl', function () { 4 | 5 | // load the controller's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | var <%= _.classify(name) %>Ctrl, 9 | scope; 10 | 11 | // Initialize the controller and a mock scope 12 | beforeEach(inject(function ($controller, $rootScope) { 13 | scope = $rootScope.$new(); 14 | <%= _.classify(name) %>Ctrl = $controller('<%= _.classify(name) %>Ctrl', { 15 | $scope: scope 16 | }); 17 | })); 18 | 19 | it('should attach a list of awesomeThings to the scope', function () { 20 | expect(scope.awesomeThings.length).toBe(3); 21 | }); 22 | }); 23 | -------------------------------------------------------------------------------- /templates/javascript/spec/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Directive: <%= _.camelize(name) %>', function () { 4 | 5 | // load the directive's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | var element, 9 | scope; 10 | 11 | beforeEach(inject(function ($rootScope) { 12 | scope = $rootScope.$new(); 13 | })); 14 | 15 | it('should make hidden element visible', inject(function ($compile) { 16 | element = angular.element('<<%= _.dasherize(name) %>>>'); 17 | element = $compile(element)(scope); 18 | expect(element.text()).toBe('this is the <%= _.camelize(name) %> directive'); 19 | })); 20 | }); 21 | -------------------------------------------------------------------------------- /templates/javascript/spec/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Filter: <%= _.camelize(name) %>', function () { 4 | 5 | // load the filter's module 6 | beforeEach(module('<%= _.camelize(appname) %>App')); 7 | 8 | // initialize a new instance of the filter before each test 9 | var <%= _.camelize(name) %>; 10 | beforeEach(inject(function ($filter) { 11 | <%= _.camelize(name) %> = $filter('<%= _.camelize(name) %>'); 12 | })); 13 | 14 | it('should return the input prefixed with "<%= _.camelize(name) %> filter:"', function () { 15 | var text = 'angularjs'; 16 | expect(<%= _.camelize(name) %>(text)).toBe('<%= _.camelize(name) %> filter: ' + text); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /templates/javascript/spec/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('Service: <%= _.classify(name) %>', function () { 4 | 5 | // load the service's module 6 | beforeEach(module('<%= _.classify(appname) %>App')); 7 | 8 | // instantiate service 9 | var <%= _.classify(name) %>; 10 | beforeEach(inject(function (_<%= _.classify(name) %>_) { 11 | <%= _.classify(name) %> = _<%= _.classify(name) %>_; 12 | })); 13 | 14 | it('should do something', function () { 15 | expect(!!<%= _.classify(name) %>).toBe(true); 16 | }); 17 | 18 | }); 19 | -------------------------------------------------------------------------------- /test/test-appname-substitution.js: -------------------------------------------------------------------------------- 1 | /*global describe, before, it, beforeEach */ 2 | 'use strict'; 3 | var fs = require('fs'); 4 | var assert = require('assert'); 5 | var path = require('path'); 6 | var util = require('util'); 7 | var generators = require('yeoman-generator'); 8 | var helpers = require('yeoman-generator').test; 9 | 10 | 11 | describe('Angular generator template mechanism', function () { 12 | //TODO: Add underscore dependency and test with _.camelize(folderName); 13 | var folderName = 'UpperCaseBug'; 14 | var angular; 15 | 16 | beforeEach(function (done) { 17 | var deps = [ 18 | '../../app', 19 | '../../common', 20 | '../../controller', 21 | '../../main', [ 22 | helpers.createDummyGenerator(), 23 | 'karma:app' 24 | ] 25 | ]; 26 | helpers.testDirectory(path.join(__dirname, folderName), function (err) { 27 | if (err) { 28 | done(err); 29 | } 30 | angular = helpers.createGenerator('angular-ui-router:app', deps); 31 | angular.options['skip-install'] = true; 32 | done(); 33 | }); 34 | }); 35 | 36 | it('should generate the same appName in every file', function (done) { 37 | var expectedAppName = folderName + 'App'; 38 | var expected = [ 39 | 'app/scripts/app.js', 40 | 'app/scripts/controllers/main.js', 41 | 'app/index.html', 42 | 'test/spec/controllers/main.js' 43 | ]; 44 | helpers.mockPrompt(angular, { 45 | bootstrap: true, 46 | compassBoostrap: true, 47 | modules: [] 48 | }); 49 | 50 | angular.run({}, function () { 51 | // Check if all files are created for the test 52 | helpers.assertFiles(expected); 53 | 54 | // read JS Files 55 | var app_js = fs.readFileSync('app/scripts/app.js', 'utf8'); 56 | var main_js = fs.readFileSync('app/scripts/controllers/main.js', 'utf8'); 57 | var main_test_js = fs.readFileSync('test/spec/controllers/main.js', 'utf8'); 58 | 59 | // Test JS Files 60 | var regex_js = new RegExp('module\\(\'' + expectedAppName + '\''); 61 | assert.ok(regex_js.test(app_js), 'app.js template using a wrong appName'); 62 | assert.ok(regex_js.test(main_js), 'main.js template using a wrong appName'); 63 | assert.ok(regex_js.test(main_test_js), 'controller spec template using a wrong appName'); 64 | 65 | // read HTML file 66 | var index_html = fs.readFileSync('app/index.html', 'utf8'); 67 | 68 | // Test HTML File 69 | var regex_html = new RegExp('ng-app=\"' + expectedAppName + '\"'); 70 | assert.ok(regex_html.test(index_html), 'index.html template using a wrong appName'); 71 | done(); 72 | }); 73 | }); 74 | }); 75 | -------------------------------------------------------------------------------- /test/test-file-creation.js: -------------------------------------------------------------------------------- 1 | /*global describe, before, it, beforeEach */ 2 | 'use strict'; 3 | var fs = require('fs'); 4 | var assert = require('assert'); 5 | var path = require('path'); 6 | var util = require('util'); 7 | var generators = require('yeoman-generator'); 8 | var helpers = require('yeoman-generator').test; 9 | var _ = require('underscore.string'); 10 | 11 | describe('angular-ui-router generator', function () { 12 | var angular; 13 | 14 | beforeEach(function (done) { 15 | var deps = [ 16 | '../../app', 17 | '../../common', 18 | '../../controller', 19 | '../../main', [ 20 | helpers.createDummyGenerator(), 21 | 'karma:app' 22 | ] 23 | ]; 24 | helpers.testDirectory(path.join(__dirname, 'temp'), function (err) { 25 | if (err) { 26 | done(err); 27 | } 28 | angular = helpers.createGenerator('angular-ui-router:app', deps); 29 | angular.options['skip-install'] = true; 30 | done(); 31 | }); 32 | }); 33 | 34 | it('should generate dotfiles', function (done) { 35 | helpers.mockPrompt(angular, { 36 | bootstrap: true, 37 | compassBoostrap: true, 38 | modules: [] 39 | }); 40 | 41 | angular.run({}, function () { 42 | helpers.assertFiles(['.bowerrc', '.gitignore', '.editorconfig', '.jshintrc']); 43 | done(); 44 | }); 45 | }); 46 | 47 | it('creates expected files', function (done) { 48 | var expected = ['app/.htaccess', 49 | 'app/404.html', 50 | 'app/favicon.ico', 51 | 'app/robots.txt', 52 | 'app/styles/main.css', 53 | 'app/views/main.html', 54 | ['.bowerrc', /"directory": "app\/bower_components"/], 55 | 'Gruntfile.js', 56 | 'package.json', 57 | ['bower.json', /"name":\s+"temp"/], 58 | 'app/scripts/app.js', 59 | 'app/index.html', 60 | 'app/scripts/controllers/main.js', 61 | 'test/spec/controllers/main.js' 62 | ]; 63 | helpers.mockPrompt(angular, { 64 | bootstrap: true, 65 | compassBoostrap: true, 66 | modules: [] 67 | }); 68 | 69 | angular.run({}, function() { 70 | helpers.assertFiles(expected); 71 | done(); 72 | }); 73 | }); 74 | 75 | it('creates coffeescript files', function (done) { 76 | var expected = ['app/.htaccess', 77 | 'app/404.html', 78 | 'app/favicon.ico', 79 | 'app/robots.txt', 80 | 'app/styles/main.css', 81 | 'app/views/main.html', 82 | ['.bowerrc', /"directory": "app\/bower_components"/], 83 | 'Gruntfile.js', 84 | 'package.json', 85 | ['bower.json', /"name":\s+"temp"/], 86 | 'app/scripts/app.coffee', 87 | 'app/index.html', 88 | 'app/scripts/controllers/main.coffee', 89 | 'test/spec/controllers/main.coffee' 90 | ]; 91 | helpers.mockPrompt(angular, { 92 | bootstrap: true, 93 | compassBoostrap: true, 94 | modules: [] 95 | }); 96 | 97 | angular.env.options.coffee = true; 98 | angular.run([], function () { 99 | helpers.assertFiles(expected); 100 | done(); 101 | }); 102 | }); 103 | 104 | /** 105 | * Generic test function that can be used to cover the scenarios where a generator is creating both a source file 106 | * and a test file. The function will run the respective generator, and then check for the existence of the two 107 | * generated files. A RegExp check is done on each file, checking for the generated content with a pattern. 108 | * 109 | * The number of parameters is quite huge due to the many options in which the generated files differ, 110 | * e.g. Services start with an upper case letter, whereas filters, directives or constants start with a lower case 111 | * letter. 112 | * 113 | * The generated items all use the dummy name 'foo'. 114 | * 115 | * @param generatorType The type of generator to run, e.g. 'filter'. 116 | * @param specType The type of the generated spec file, e.g. 'service' - all service types (constant, value, ...) 117 | * use the same Service spec template. 118 | * @param targetDirectory The directory into which the files are generated, e.g. 'directives' - this will be 119 | * located under 'app/scripts' for the sources and 'test/spec' for the tests. 120 | * @param scriptNameFn The function used to create the name of the created item, e.g. _.classify to generate 'Foo', 121 | * or _.camelize to generate 'foo'. 122 | * @param specNameFn Same as scriptNameFn, but for the describe text used in the Spec file. Some generators use 123 | * _.classify, others use _.camelize. 124 | * @param suffix An optional suffix to be appended to the generated item name, e.g. 'Ctrl' for controllers, which 125 | * will generate 'FooCtrl'. 126 | * @param done The done function. 127 | */ 128 | function generatorTest(generatorType, specType, targetDirectory, scriptNameFn, specNameFn, suffix, done) { 129 | var angularGenerator; 130 | var name = 'foo'; 131 | var deps = [path.join('../..', generatorType)]; 132 | angularGenerator = helpers.createGenerator('angular-ui-router:' + generatorType, deps, [name]); 133 | 134 | helpers.mockPrompt(angular, { 135 | bootstrap: true, 136 | compassBoostrap: true, 137 | modules: [] 138 | }); 139 | angular.run([], function (){ 140 | angularGenerator.run([], function () { 141 | helpers.assertFiles([ 142 | [path.join('app/scripts', targetDirectory, name + '.js'), new RegExp(generatorType + '\\(\'' + scriptNameFn(name) + suffix + '\'', 'g')], 143 | [path.join('test/spec', targetDirectory, name + '.js'), new RegExp('describe\\(\'' + _.classify(specType) + ': ' + specNameFn(name) + suffix + '\'', 'g')] 144 | ]); 145 | done(); 146 | }); 147 | }); 148 | } 149 | 150 | describe('Controller', function () { 151 | it('should generate a new controller', function (done) { 152 | generatorTest('controller', 'controller', 'controllers', _.classify, _.classify, 'Ctrl', done); 153 | }); 154 | }); 155 | 156 | describe('Directive', function () { 157 | it('should generate a new directive', function (done) { 158 | generatorTest('directive', 'directive', 'directives', _.camelize, _.camelize, '', done); 159 | }); 160 | }); 161 | 162 | describe('Filter', function () { 163 | it('should generate a new filter', function (done) { 164 | generatorTest('filter', 'filter', 'filters', _.camelize, _.camelize, '', done); 165 | }); 166 | }); 167 | 168 | describe('Service', function () { 169 | function serviceTest (generatorType, nameFn, done) { 170 | generatorTest(generatorType, 'service', 'services', nameFn, _.classify, '', done); 171 | }; 172 | 173 | it('should generate a new constant', function (done) { 174 | serviceTest('constant', _.camelize, done); 175 | }); 176 | 177 | it('should generate a new service', function (done) { 178 | serviceTest('service', _.classify, done); 179 | }); 180 | 181 | it('should generate a new factory', function (done) { 182 | serviceTest('factory', _.camelize, done); 183 | }); 184 | 185 | it('should generate a new provider', function (done) { 186 | serviceTest('provider', _.camelize, done); 187 | }); 188 | 189 | it('should generate a new value', function (done) { 190 | serviceTest('value', _.camelize, done); 191 | }); 192 | }); 193 | 194 | describe('View', function () { 195 | it('should generate a new view', function (done) { 196 | var angularView; 197 | var deps = ['../../view']; 198 | angularView = helpers.createGenerator('angular-ui-router:view', deps, ['foo']); 199 | 200 | helpers.mockPrompt(angular, { 201 | bootstrap: true, 202 | compassBoostrap: true, 203 | modules: [] 204 | }); 205 | angular.run([], function (){ 206 | angularView.run([], function () { 207 | helpers.assertFiles([ 208 | ['app/views/foo.html'] 209 | ]); 210 | done(); 211 | }); 212 | }); 213 | }); 214 | 215 | it('should generate a new view in subdirectories', function (done) { 216 | var angularView; 217 | var deps = ['../../view']; 218 | angularView = helpers.createGenerator('angular-ui-router:view', deps, ['foo/bar']); 219 | 220 | helpers.mockPrompt(angular, { 221 | bootstrap: true, 222 | compassBoostrap: true, 223 | modules: [] 224 | }); 225 | angular.run([], function (){ 226 | angularView.run([], function () { 227 | helpers.assertFiles([ 228 | ['app/views/foo/bar.html'] 229 | ]); 230 | done(); 231 | }); 232 | }); 233 | }); 234 | }); 235 | }); 236 | -------------------------------------------------------------------------------- /util.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var fs = require('fs'); 4 | 5 | 6 | module.exports = { 7 | rewrite: rewrite, 8 | rewriteFile: rewriteFile 9 | }; 10 | 11 | function rewriteFile (args) { 12 | args.path = args.path || process.cwd(); 13 | var fullPath = path.join(args.path, args.file); 14 | 15 | args.haystack = fs.readFileSync(fullPath, 'utf8'); 16 | var body = rewrite(args); 17 | 18 | fs.writeFileSync(fullPath, body); 19 | } 20 | 21 | function escapeRegExp (str) { 22 | return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'); 23 | } 24 | 25 | function rewrite (args) { 26 | // check if splicable is already in the body text 27 | var re = new RegExp(args.splicable.map(function (line) { 28 | return '\s*' + escapeRegExp(line); 29 | }).join('\n')); 30 | 31 | if (re.test(args.haystack)) { 32 | return args.haystack; 33 | } 34 | 35 | var lines = args.haystack.split('\n'); 36 | 37 | var otherwiseLineIndex = 0; 38 | lines.forEach(function (line, i) { 39 | if (line.indexOf(args.needle) !== -1) { 40 | otherwiseLineIndex = i; 41 | } 42 | }); 43 | 44 | var spaces = 0; 45 | while (lines[otherwiseLineIndex].charAt(spaces) === ' ') { 46 | spaces += 1; 47 | } 48 | 49 | var spaceStr = ''; 50 | while ((spaces -= 1) >= 0) { 51 | spaceStr += ' '; 52 | } 53 | 54 | lines.splice(otherwiseLineIndex, 0, args.splicable.map(function (line) { 55 | return spaceStr + line; 56 | }).join('\n')); 57 | 58 | return lines.join('\n'); 59 | } 60 | -------------------------------------------------------------------------------- /value/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS service. 3 | Docs: http://docs.angularjs.org/guide/dev_guide.services.creating_services 4 | 5 | Example: 6 | yo angular-ui-router:value thing [--coffee] [--minsafe] 7 | 8 | This will create: 9 | app/scripts/services/thing.js 10 | -------------------------------------------------------------------------------- /value/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var util = require('util'); 3 | var ScriptBase = require('../script-base.js'); 4 | 5 | 6 | var Generator = module.exports = function Generator() { 7 | ScriptBase.apply(this, arguments); 8 | }; 9 | 10 | util.inherits(Generator, ScriptBase); 11 | 12 | Generator.prototype.createServiceFiles = function createServiceFiles() { 13 | this.generateSourceAndTest('service/value', 'spec/service', 'services'); 14 | }; 15 | -------------------------------------------------------------------------------- /view/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS view 3 | 4 | Example: 5 | yo angular-ui-router:view thing 6 | 7 | This will create: 8 | app/views/thing.html 9 | -------------------------------------------------------------------------------- /view/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'); 3 | var util = require('util'); 4 | var yeoman = require('yeoman-generator'); 5 | 6 | 7 | var Generator = module.exports = function Generator() { 8 | yeoman.generators.NamedBase.apply(this, arguments); 9 | this.sourceRoot(path.join(__dirname, '../templates')); 10 | 11 | if (typeof this.env.options.appPath === 'undefined') { 12 | try { 13 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 14 | } catch (e) {} 15 | this.env.options.appPath = this.env.options.appPath || 'app'; 16 | } 17 | }; 18 | 19 | util.inherits(Generator, yeoman.generators.NamedBase); 20 | 21 | Generator.prototype.createViewFiles = function createViewFiles() { 22 | this.template('common/view.html', path.join(this.env.options.appPath, 'views', this.name + '.html')); 23 | }; 24 | --------------------------------------------------------------------------------