├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── README.md ├── app ├── USAGE ├── index.js └── templates │ ├── css │ ├── main.css │ └── main.scss │ ├── img │ ├── ionic.png │ └── yeoman.png │ └── res │ ├── icon │ ├── android │ │ ├── icon-36-ldpi.png │ │ ├── icon-48-mdpi.png │ │ ├── icon-72-hdpi.png │ │ └── icon-96-xhdpi.png │ ├── bada-wac │ │ ├── icon-48-type5.png │ │ ├── icon-50-type3.png │ │ └── icon-80-type4.png │ ├── bada │ │ └── icon-128.png │ ├── blackberry │ │ └── icon-80.png │ ├── ios │ │ ├── icon-57-2x.png │ │ ├── icon-57.png │ │ ├── icon-72-2x.png │ │ └── icon-72.png │ ├── tizen │ │ └── icon-128.png │ ├── webos │ │ └── icon-64.png │ └── windows-phone │ │ ├── icon-173-tile.png │ │ ├── icon-48.png │ │ └── icon-62-tile.png │ └── screen │ ├── android │ ├── screen-hdpi-landscape.png │ ├── screen-hdpi-portrait.png │ ├── screen-ldpi-landscape.png │ ├── screen-ldpi-portrait.png │ ├── screen-mdpi-landscape.png │ ├── screen-mdpi-portrait.png │ ├── screen-xhdpi-landscape.png │ └── screen-xhdpi-portrait.png │ ├── bada-wac │ ├── screen-type3.png │ ├── screen-type4.png │ └── screen-type5.png │ ├── bada │ └── screen-portrait.png │ ├── blackberry │ └── screen-225.png │ ├── ios │ ├── screen-ipad-landscape-2x.png │ ├── screen-ipad-landscape.png │ ├── screen-ipad-portrait-2x.png │ ├── screen-ipad-portrait.png │ ├── screen-iphone-landscape-2x.png │ ├── screen-iphone-landscape.png │ ├── screen-iphone-portrait-2x.png │ ├── screen-iphone-portrait-568h-2x.png │ └── screen-iphone-portrait.png │ ├── tizen │ └── README.md │ ├── webos │ └── screen-64.png │ └── windows-phone │ └── screen-portrait.jpg ├── common └── index.js ├── constant ├── USAGE └── index.js ├── 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 ├── route ├── USAGE └── index.js ├── script-base.js ├── service ├── USAGE └── index.js ├── templates ├── 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 │ ├── bowerrc │ ├── editorconfig │ ├── gitignore │ ├── index.html │ ├── jshintrc │ ├── root │ │ ├── test │ │ │ ├── .jshintrc │ │ │ └── runner.html │ │ └── www │ │ │ ├── .buildignore │ │ │ ├── 404.html │ │ │ ├── favicon.ico │ │ │ └── tpl │ │ │ ├── about.html │ │ │ ├── detail.html │ │ │ ├── form.html │ │ │ ├── index.html │ │ │ └── tabs.html │ └── view.html └── 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-creation.js ├── test-file-creation.js └── test-load.js ├── util.js ├── value ├── USAGE └── index.js └── view ├── USAGE └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 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 | temp/ 3 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "regexp": true, 15 | "undef": true, 16 | "unused": true, 17 | "strict": true, 18 | "trailing": true, 19 | "smarttabs": true, 20 | "white": true 21 | } 22 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_install: 5 | - currentfolder=${PWD##*/} 6 | - if [ "$currentfolder" != 'generator-angular-cordova' ]; then cd .. && eval "mv $currentfolder generator-angular-cordova" && cd generator-angular-cordova; fi 7 | 8 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generator-angular-cordova [![Build Status](https://secure.travis-ci.org/wangshijun2010/generator-angular-cordova.png?branch=master)](https://travis-ci.org/wangshijun2010/generator-angular-cordova) 2 | 3 | > [Yeoman](http://yeoman.io) generator for Angular + Ionic + Cordova, let you quickly setup a project with sensible default and best practices 4 | 5 | ## Getting started 6 | - Make sure you have the following installed: 7 | - [yo](https://github.com/yeoman/yo): `npm install -g yo` 8 | - [grunt-cli](https://github.com/gruntjs/grunt): `npm install -g grunt-cli` 9 | - [cordova-cli](https://github.com/apache/cordova-cli): `npm install -g cordova` 10 | 11 | - Install any SDKs you need for developing platform applications: 12 | - [iOS](https://developer.apple.com/xcode/) 13 | - [Android](http://developer.android.com/sdk/index.html#ExistingIDE) 14 | - etc... 15 | 16 | - Install the generator: `npm install -g generator-angular-cordova` 17 | - Run: `yo angular-cordova` 18 | 19 | 20 | ## Usage 21 | Once you have ran `yo angular-cordova` and answered some questions, yeoman should now have scaffolded a cordova, ionic, angular skeleton for you. 22 | 23 | ### Serve to web browser 24 | To deploy as local web server and watch for changes requires the installation of [LiveReload](http://livereload.com/) browser extension. 25 | 26 | `grunt serve --platform=ios`: prepares and serves the application as a local web server at [http://localhost:9000/](http://localhost:9000/), watching for changes then preparing/redeploying the web server. 27 | 28 | ### Serve to emulator 29 | `grunt emulate`: builds and emulates all installed platforms 30 | 31 | `grunt live-emulate`: builds and emulates all installed platforms, watching for changes then building/redeploying the emulator. 32 | 33 | ### Serve to device 34 | `grunt device`: builds and runs all installed platforms 35 | 36 | `grunt live-device`: builds and runs all installed platforms, watching for changes then building/redeploying. 37 | 38 | 39 | ## Usage 40 | 41 | Install `generator-angular-cordova`: 42 | ``` 43 | npm install -g generator-angular-cordova 44 | ``` 45 | 46 | Make a new directory, and `cd` into it: 47 | ``` 48 | mkdir my-new-project && cd $_ 49 | ``` 50 | 51 | Run `yo angular-cordova`, optionally passing an app name: 52 | ``` 53 | yo angular-cordova [app-name] 54 | ``` 55 | 56 | Run `grunt` for building and `grunt serve` for preview 57 | 58 | 59 | ## Generators 60 | 61 | Available generators: 62 | 63 | * [angular-cordova](#app) (aka [angular-cordova:app](#app)) 64 | * [angular-cordova:controller](#controller) 65 | * [angular-cordova:directive](#directive) 66 | * [angular-cordova:filter](#filter) 67 | * [angular-cordova:route](#route) 68 | * [angular-cordova:service](#service) 69 | * [angular-cordova:provider](#service) 70 | * [angular-cordova:factory](#service) 71 | * [angular-cordova:value](#service) 72 | * [angular-cordova:constant](#service) 73 | * [angular-cordova:decorator] (#decorator) 74 | * [angular-cordova:view](#view) 75 | 76 | **Note: Generators are to be run from the root directory of your app.** 77 | 78 | ### App 79 | 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 (installed by default). 80 | 81 | Example: 82 | ```bash 83 | yo angular-cordova 84 | ``` 85 | 86 | ### Route 87 | Generates a controller and view, and configures a route in `app/js/app.js` connecting them. 88 | 89 | Example: 90 | ```bash 91 | yo angular-cordova:route myroute 92 | ``` 93 | 94 | Produces `www/js/controller/myroute.js`: 95 | ```javascript 96 | angular.module('myMod').controller('MyrouteCtrl', function ($scope) { 97 | // ... 98 | }); 99 | ``` 100 | 101 | Produces `www/views/myroute.html`: 102 | ```html 103 |

This is the myroute view

104 | ``` 105 | 106 | ### Controller 107 | Generates a controller in `www/js/controller`. 108 | 109 | Example: 110 | ```bash 111 | yo angular-cordova:controller user 112 | ``` 113 | 114 | Produces `www/js/controller/user.js`: 115 | ```javascript 116 | angular.module('myMod').controller('UserController', function ($scope) { 117 | // ... 118 | }); 119 | ``` 120 | ### Directive 121 | Generates a directive in `www/js/directive`. 122 | 123 | Example: 124 | ```bash 125 | yo angular-cordova:directive myDirective 126 | ``` 127 | 128 | Produces `www/js/directive/myDirective.js`: 129 | ```javascript 130 | angular.module('myMod').directive('myDirective', function () { 131 | return { 132 | template: '
', 133 | restrict: 'E', 134 | link: function postLink(scope, element, attrs) { 135 | element.text('this is the myDirective directive'); 136 | } 137 | }; 138 | }); 139 | ``` 140 | 141 | ### Filter 142 | Generates a filter in `www/js/filter`. 143 | 144 | Example: 145 | ```bash 146 | yo angular-cordova:filter myFilter 147 | ``` 148 | 149 | Produces `www/js/filter/myFilter.js`: 150 | ```javascript 151 | angular.module('myMod').filter('myFilter', function () { 152 | return function (input) { 153 | return 'myFilter filter:' + input; 154 | }; 155 | }); 156 | ``` 157 | 158 | ### View 159 | Generates an HTML view file in `www/views`. 160 | 161 | Example: 162 | ```bash 163 | yo angular-cordova:view user 164 | ``` 165 | 166 | Produces `www/views/user.html`: 167 | ```html 168 |

This is the user view

169 | ``` 170 | 171 | ### Service 172 | Generates an AngularJS service. 173 | 174 | Example: 175 | ```bash 176 | yo angular-cordova:service myService 177 | ``` 178 | 179 | Produces `www/js/service/myService.js`: 180 | ```javascript 181 | angular.module('myMod').service('myService', function () { 182 | // ... 183 | }); 184 | ``` 185 | 186 | You can also do `yo angular-cordova:factory`, `yo angular-cordova:provider`, `yo angular-cordova:value`, and `yo angular-cordova:constant` for other types of service. 187 | 188 | ### Decorator 189 | Generates an AngularJS service decorator. 190 | 191 | Example: 192 | ```bash 193 | yo angular-cordova:decorator serviceName 194 | ``` 195 | 196 | Produces `www/js/decorators/serviceNameDecorator.js`: 197 | ```javascript 198 | angular.module('myMod').config(function ($provide) { 199 | $provide.decorator('serviceName', function ($delegate) { 200 | // ... 201 | return $delegate; 202 | }); 203 | }); 204 | ``` 205 | 206 | ### Getting To Know Yeoman 207 | 208 | Yeoman has a heart of gold. He's a person with feelings and opinions, but he's very easy to work with. If you think he's too opinionated, he can be easily convinced. 209 | 210 | If you'd like to get to know Yeoman better and meet some of his friends, [Grunt](http://gruntjs.com) and [Bower](http://bower.io), check out the complete [Getting Started Guide](https://github.com/yeoman/yeoman/wiki/Getting-Started). 211 | 212 | 213 | ## License 214 | 215 | MIT 216 | -------------------------------------------------------------------------------- /app/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a default AngularJS app 3 | 4 | Example: 5 | yo angular [--coffee] 6 | 7 | This will create: 8 | Gruntfile.js 9 | bower.json 10 | 11 | www/index.html 12 | www/js/your-app-name-here.js 13 | www/js/controllers/main.js 14 | www/vendor/angular/angular.js 15 | www/css/main.css 16 | www/tpl/main.html 17 | 18 | test/lib/angular-mocks.js 19 | test/spec/controllers/main.js 20 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var fs = require('fs'), 3 | path = require('path'), 4 | util = require('util'), 5 | _ = require('lodash'), 6 | yeoman = require('yeoman-generator'), 7 | chalk = require('chalk'), 8 | wiredep = require('wiredep'), 9 | cordova = require('cordova'), 10 | plugman = require('plugman'); 11 | 12 | var Generator = module.exports = function Generator(args, options) { 13 | yeoman.generators.Base.apply(this, arguments); 14 | 15 | args = ['index']; 16 | 17 | this.hookFor('angular-cordova:common', { 18 | args: args 19 | }); 20 | 21 | this.hookFor('angular-cordova:main', { 22 | args: args 23 | }); 24 | 25 | this.hookFor('angular-cordova:controller', { 26 | args: args 27 | }); 28 | 29 | this.on('end', function () { 30 | this.installDependencies({ 31 | skipInstall: this.options['skip-install'], 32 | callback: this._injectDependencies.bind(this) 33 | }); 34 | 35 | var enabledComponents = []; 36 | 37 | if (this.resourceModule) { 38 | enabledComponents.push('angular-resource/angular-resource.js'); 39 | } 40 | 41 | if (this.cookiesModule) { 42 | enabledComponents.push('angular-cookies/angular-cookies.js'); 43 | } 44 | 45 | if (this.sanitizeModule) { 46 | enabledComponents.push('angular-sanitize/angular-sanitize.js'); 47 | } 48 | 49 | this.invoke('karma:app', { 50 | options: { 51 | coffee: this.options.coffee, 52 | travis: true, 53 | 'skip-install': this.options['skip-install'], 54 | components: [ 55 | 'angular/angular.js', 56 | 'angular-mocks/angular-mocks.js' 57 | ].concat(enabledComponents) 58 | } 59 | }); 60 | 61 | }); 62 | 63 | this.pkg = require('../package.json'); 64 | }; 65 | 66 | util.inherits(Generator, yeoman.generators.Base); 67 | 68 | Generator.prototype.welcome = function welcome() { 69 | // welcome message 70 | if (!this.options['skip-welcome-message']) { 71 | console.log(this.yeoman); 72 | console.log( 73 | 'Out of the box I include Ionic and some AngularJS recommended modules.\n' 74 | ); 75 | 76 | // Removed notice for minsafe 77 | if (this.options.minsafe) { 78 | console.warn( 79 | '\n** The --minsafe flag has been removed. For more information, see ' + 80 | 'https://github.com/yeoman/generator-angular#minification-safe. **\n' 81 | ); 82 | } 83 | } 84 | }; 85 | 86 | Generator.prototype.askForCordova = function askForCordova() { 87 | var next = this.async(); 88 | 89 | // We do some working directory hoping, so keep a track where we start 90 | this.cwd = process.cwd(); 91 | 92 | var prompts = [ 93 | { 94 | name: 'appname', 95 | message: 'What is the name of your app? (Spaces aren\'t allowed)', 96 | default: 'HelloCordova' 97 | }, 98 | { 99 | name: 'packagename', 100 | message: 'What would you like the package to be?', 101 | default: 'io.cordova.hellocordova' 102 | }, 103 | { 104 | type: 'checkbox', 105 | name: 'platforms', 106 | message: 'What platforms would you like to add support for?', 107 | choices: [ 108 | { 109 | name: 'Android', 110 | value: 'android', 111 | checked: true 112 | }, 113 | { 114 | name: 'iOS', 115 | value: 'ios', 116 | checked: true 117 | }, 118 | { 119 | name: 'Blackberry 10', 120 | value: 'blackberry10', 121 | checked: false 122 | }, 123 | { 124 | name: 'Windows Phone 7', 125 | value: 'wp7', 126 | checked: false 127 | }, 128 | { 129 | name: 'Windows Phone 8', 130 | value: 'wp7', 131 | checked: false 132 | } 133 | ] 134 | }, 135 | { 136 | type: 'checkbox', 137 | name: 'plugins', 138 | message: 'What plugins would you like to include by default?', 139 | // Find these values using command 'plugman search ' 140 | // Find these values here: https://git-wip-us.apache.org/repos/asf 141 | choices: [ 142 | { 143 | name: 'Device Info', 144 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-device.git', 145 | checked: false 146 | }, 147 | { 148 | name: 'Camera', 149 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-camera.git', 150 | checked: false 151 | }, 152 | { 153 | name: 'Contacts', 154 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-contacts.git', 155 | checked: false 156 | }, 157 | { 158 | name: 'Dialogs', 159 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-dialogs.git', 160 | checked: false 161 | }, 162 | { 163 | name: 'Geolocation', 164 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-geolocation.git', 165 | checked: false 166 | }, 167 | { 168 | name: 'In App Browser', 169 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-inappbrowser.git', 170 | checked: false 171 | }, 172 | { 173 | name: 'Audio Handler (a.k.a Media on Cordova Docs)', 174 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-media.git', 175 | checked: false 176 | }, 177 | { 178 | name: 'Media Capture', 179 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-media-capture.git', 180 | checked: false 181 | }, 182 | { 183 | name: 'Network Information', 184 | value: 'https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git', 185 | checked: false 186 | } 187 | ] 188 | }, 189 | { 190 | type: 'confirm', 191 | name: 'copyIcons', 192 | message: 'Would you like to copy some sample icons for cordova?', 193 | default: true 194 | } 195 | ]; 196 | 197 | this.prompt(prompts, function (props) { 198 | for (var key in props) { 199 | this[key] = props[key]; 200 | } 201 | 202 | this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname))); 203 | this.scriptAppName = this.appname; 204 | 205 | if (typeof this.env.options.appPath === 'undefined') { 206 | try { 207 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 208 | } catch (e) {} 209 | this.env.options.appPath = this.env.options.appPath || 'www'; 210 | } 211 | 212 | this.appPath = this.env.options.appPath; 213 | 214 | if (typeof this.env.options.coffee === 'undefined') { 215 | this.option('coffee', { 216 | desc: 'Generate CoffeeScript instead of JavaScript' 217 | }); 218 | 219 | // attempt to detect if user is using CS or not 220 | // if cml arg provided, use that; else look for the existence of cs 221 | if (!this.options.coffee && this.expandFiles(path.join(this.appPath, '/js/**/*.coffee'), {}).length > 0) { 222 | this.options.coffee = true; 223 | } 224 | 225 | this.env.options.coffee = this.options.coffee; 226 | } 227 | 228 | // TODO improve this 229 | // console.log('appname: ' + this.appname); 230 | // console.log('scriptAppName: ' + this.scriptAppName); 231 | // console.log('appPath: ' + this.appPath); 232 | 233 | next(); 234 | }.bind(this)); 235 | }; 236 | 237 | Generator.prototype.cordovaCreate = function cordovaCreate() { 238 | var next = this.async(), 239 | appPath = this.appPath; 240 | 241 | console.log("Creating cordova app: " + this.appname); 242 | try { 243 | cordova.create(process.cwd(), this.packagename, this.appname, function () { 244 | // remove cordova created files, we will write later 245 | var cwd = process.cwd(); 246 | fs.unlinkSync(cwd + '/' + appPath + '/js/index.js'); 247 | fs.unlinkSync(cwd + '/' + appPath + '/css/index.css'); 248 | fs.unlinkSync(cwd + '/' + appPath + '/index.html'); 249 | fs.renameSync(cwd + '/' + appPath + '/img/logo.png', cwd + '/' + appPath + '/img/cordova.png'); 250 | next(); 251 | }); 252 | } catch (err) { 253 | console.error('Failed to create cordova proect: ' + err); 254 | process.exit(1); 255 | } 256 | }; 257 | 258 | Generator.prototype.addPlatforms = function addPlatforms() { 259 | if (typeof this.platforms === 'undefined') { 260 | return; 261 | } 262 | 263 | console.log('Adding requested platforms to the Cordova project...'); 264 | 265 | var next = this.async(); 266 | addPlatformsToCordova(0, this.platforms, next); 267 | }; 268 | 269 | Generator.prototype.addPlugins = function addPlugins() { 270 | console.log('Installing the Cordova plugins...'); 271 | 272 | var next = this.async(); 273 | if (this.plugins.length) { 274 | addPluginsToCordova(0, this.plugins, next); 275 | } else { 276 | console.log(chalk.gray('no plugin selected')); 277 | next(); 278 | } 279 | } 280 | 281 | Generator.prototype.askForCompass = function askForCompass() { 282 | var next = this.async(); 283 | 284 | this.prompt([{ 285 | type: 'confirm', 286 | name: 'compass', 287 | message: 'Would you like to use Sass (with Compass)?', 288 | default: false 289 | }], function (props) { 290 | this.compass = props.compass; 291 | 292 | next(); 293 | }.bind(this)); 294 | }; 295 | 296 | Generator.prototype.askForIonic = function askForIonic() { 297 | var compass = this.compass; 298 | var next = this.async(); 299 | 300 | this.prompt([{ 301 | type: 'confirm', 302 | name: 'ionic', 303 | message: 'Would you like to include Ionic', 304 | default: true 305 | }, { 306 | type: 'confirm', 307 | name: 'compassIonic', 308 | message: 'Would you like to use the Sass version of Ionic', 309 | default: false, 310 | when: function (props) { 311 | return props.ionic && compass; 312 | } 313 | }], function (props) { 314 | this.ionic = props.ionic; 315 | this.compassIonic = props.compassIonic; 316 | 317 | next(); 318 | }.bind(this)); 319 | }; 320 | 321 | Generator.prototype.askForAngularModules = function askForAngularModules() { 322 | var next = this.async(); 323 | 324 | var prompts = [{ 325 | type: 'checkbox', 326 | name: 'modules', 327 | message: 'Which modules would you like to include?', 328 | choices: [{ 329 | value: 'resourceModule', 330 | name: 'angular-resource.js', 331 | checked: true 332 | }, { 333 | value: 'cookiesModule', 334 | name: 'angular-cookies.js', 335 | checked: true 336 | }, { 337 | value: 'sanitizeModule', 338 | name: 'angular-sanitize.js', 339 | checked: true 340 | }] 341 | }]; 342 | 343 | this.prompt(prompts, function (props) { 344 | var hasMod = function (mod) { return props.modules.indexOf(mod) !== -1; }; 345 | this.resourceModule = hasMod('resourceModule'); 346 | this.cookiesModule = hasMod('cookiesModule'); 347 | this.sanitizeModule = hasMod('sanitizeModule'); 348 | 349 | var angMods = []; 350 | 351 | if (this.ionic) { 352 | angMods.push("'ionic'"); 353 | } 354 | 355 | if (this.cookiesModule) { 356 | angMods.push("'ngCookies'"); 357 | } 358 | 359 | if (this.resourceModule) { 360 | angMods.push("'ngResource'"); 361 | } 362 | 363 | if (this.sanitizeModule) { 364 | angMods.push("'ngSanitize'"); 365 | } 366 | 367 | if (angMods.length) { 368 | this.env.options.angularDeps = angMods.join(", "); 369 | } 370 | 371 | next(); 372 | }.bind(this)); 373 | }; 374 | 375 | Generator.prototype.readIndex = function readIndex() { 376 | this.indexFile = this.engine(this.read('../../templates/common/index.html'), this); 377 | }; 378 | 379 | Generator.prototype.bootstrapFiles = function bootstrapFiles() { 380 | var sass = this.compass; 381 | var mainFile = 'main.' + (sass ? 's' : '') + 'css'; 382 | 383 | this.copy('css/' + mainFile, 'www/css/' + mainFile); 384 | }; 385 | 386 | Generator.prototype.appJs = function appJs() { 387 | this.indexFile = this.appendFiles({ 388 | html: this.indexFile, 389 | fileType: 'js', 390 | optimizedPath: 'js/js.js', 391 | sourceFileList: [ 392 | 'js/app.js', 393 | 'js/controller/index.js' 394 | ], 395 | searchPath: ['.tmp', 'www'] 396 | }); 397 | }; 398 | 399 | Generator.prototype.createIndexHtml = function createIndexHtml() { 400 | this.indexFile = this.indexFile.replace(/'/g, "'"); 401 | this.write(path.join(this.appPath, 'index.html'), this.indexFile); 402 | }; 403 | 404 | Generator.prototype.packageFiles = function () { 405 | this.coffee = this.env.options.coffee; 406 | this.template('../../templates/common/_bower.json', 'bower.json'); 407 | this.template('../../templates/common/_package.json', 'package.json'); 408 | this.template('../../templates/common/bowerrc', '.bowerrc'); 409 | this.template('../../templates/common/jshintrc', '.jshintrc'); 410 | this.template('../../templates/common/editorconfig', '.editorconfig'); 411 | this.template('../../templates/common/Gruntfile.js', 'Gruntfile.js'); 412 | }; 413 | 414 | Generator.prototype.imageFiles = function () { 415 | this.sourceRoot(path.join(__dirname, 'templates')); 416 | this.directory('img', 'www/img', true); 417 | 418 | if (this.copyIcons && this.platforms.indexOf('android') > -1) { 419 | this.directory('res/icon/android', 'www/res/icons/android', true); 420 | this.directory('res/screen/android', 'www/res/screens/android', true); 421 | } 422 | 423 | if (this.copyIcons && this.platforms.indexOf('ios') > -1) { 424 | this.directory('res/icon/ios', 'www/res/icons/ios', true); 425 | this.directory('res/screen/ios', 'www/res/screens/ios', true); 426 | } 427 | }; 428 | 429 | Generator.prototype._injectDependencies = function _injectDependencies() { 430 | var howToInstall = 431 | '\nAfter running `npm install & bower install`, inject your front end dependencies into' + 432 | '\nyour HTML by running:' + 433 | '\n' + 434 | chalk.yellow.bold('\n grunt bower-install'); 435 | 436 | if (this.options['skip-install']) { 437 | console.log(howToInstall); 438 | } else { 439 | wiredep({ 440 | directory: 'www/vendor', 441 | bowerJson: JSON.parse(fs.readFileSync('./bower.json')), 442 | ignorePath: 'www/', 443 | htmlFile: 'www/index.html', 444 | cssPattern: '' 445 | }); 446 | } 447 | }; 448 | 449 | function addPlatformsToCordova(index, platforms, next) { 450 | if (!(index < platforms.length)) { 451 | next(); 452 | return; 453 | } 454 | 455 | try { 456 | cordova.platform('add', platforms[index], function () { 457 | console.log(chalk.green('✔ ') + ' added ' + chalk.gray(platforms[index])); 458 | addPlatformsToCordova(index + 1, platforms, next); 459 | }); 460 | } catch (err) { 461 | console.error('Failed to add platform ' + platforms['index'] + ': ' + err); 462 | process.exit(1); 463 | } 464 | } 465 | 466 | function addPluginsToCordova(index, plugins, next) { 467 | if (!(index < plugins.length)) { 468 | next(); 469 | return; 470 | } 471 | 472 | cordova.plugin('add', plugins[index], function () { 473 | console.log(chalk.green('✔ ') + ' added ' + chalk.gray(plugins[index])); 474 | addPluginsToCordova(index + 1, plugins, next); 475 | }); 476 | } 477 | 478 | -------------------------------------------------------------------------------- /app/templates/css/main.css: -------------------------------------------------------------------------------- 1 | * { 2 | -webkit-tap-highlight-color: rgba(0,0,0,0); /* make transparent link selection, adjust last value opacity 0 to 1.0 */ 3 | } 4 | 5 | body { 6 | -webkit-touch-callout: none; /* prevent callout to copy image, etc when tap to hold */ 7 | -webkit-text-size-adjust: none; /* prevent webkit from resizing text to fit */ 8 | -webkit-user-select: none; /* prevent copy paste, to allow, change 'none' to 'text' */ 9 | background-color:#E4E4E4; 10 | background-image:linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 11 | background-image:-webkit-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 12 | background-image:-ms-linear-gradient(top, #A7A7A7 0%, #E4E4E4 51%); 13 | background-image:-webkit-gradient( 14 | linear, 15 | left top, 16 | left bottom, 17 | color-stop(0, #A7A7A7), 18 | color-stop(0.51, #E4E4E4) 19 | ); 20 | background-attachment:fixed; 21 | font-family:'HelveticaNeue-Light', 'HelveticaNeue', Helvetica, Arial, sans-serif; 22 | font-size:12px; 23 | height:100%; 24 | margin:0px; 25 | padding:0px; 26 | text-transform:uppercase; 27 | width:100%; 28 | } 29 | 30 | /* Portrait layout (default) */ 31 | .app { 32 | background:url(../img/logo.png) no-repeat center top; /* 170px x 200px */ 33 | position:absolute; /* position in the center of the screen */ 34 | left:50%; 35 | top:50%; 36 | height:50px; /* text area height */ 37 | width:225px; /* text area width */ 38 | text-align:center; 39 | padding:180px 0px 0px 0px; /* image height is 200px (bottom 20px are overlapped with text) */ 40 | margin:-115px 0px 0px -112px; /* offset vertical: half of image height and text area height */ 41 | /* offset horizontal: half of text area width */ 42 | } 43 | 44 | /* Landscape layout (with min-width) */ 45 | @media screen and (min-aspect-ratio: 1/1) and (min-width:400px) { 46 | .app { 47 | background-position:left center; 48 | padding:75px 0px 75px 170px; /* padding-top + padding-bottom + text area = image height */ 49 | margin:-90px 0px 0px -198px; /* offset vertical: half of image height */ 50 | /* offset horizontal: half of image width and text area width */ 51 | } 52 | } 53 | 54 | h1 { 55 | font-size:24px; 56 | font-weight:normal; 57 | margin:0px; 58 | overflow:visible; 59 | padding:0px; 60 | text-align:center; 61 | } 62 | 63 | .event { 64 | border-radius:4px; 65 | -webkit-border-radius:4px; 66 | color:#FFFFFF; 67 | font-size:12px; 68 | margin:0px 30px; 69 | padding:2px 0px; 70 | } 71 | 72 | .event.listening { 73 | background-color:#333333; 74 | display:block; 75 | } 76 | 77 | .event.received { 78 | background-color:#4B946A; 79 | display:none; 80 | } 81 | 82 | @keyframes fade { 83 | from { opacity: 1.0; } 84 | 50% { opacity: 0.4; } 85 | to { opacity: 1.0; } 86 | } 87 | 88 | @-webkit-keyframes fade { 89 | from { opacity: 1.0; } 90 | 50% { opacity: 0.4; } 91 | to { opacity: 1.0; } 92 | } 93 | 94 | .blink { 95 | animation:fade 3000ms infinite; 96 | -webkit-animation:fade 3000ms infinite; 97 | } 98 | 99 | -------------------------------------------------------------------------------- /app/templates/css/main.scss: -------------------------------------------------------------------------------- 1 | <% if (compassBootstrap) { %>$icon-font-path: "/bower_components/sass-bootstrap/fonts/"; 2 | 3 | @import 'sass-bootstrap/lib/bootstrap'; 4 | 5 | <% } %>.browsehappy { 6 | margin: 0.2em 0; 7 | background: #ccc; 8 | color: #000; 9 | padding: 0.2em 0; 10 | } 11 | 12 | /* Space out content a bit */ 13 | body { 14 | padding-top: 20px; 15 | padding-bottom: 20px; 16 | } 17 | 18 | /* Everything but the jumbotron gets side spacing for mobile first views */ 19 | .header, 20 | .marketing, 21 | .footer { 22 | padding-left: 15px; 23 | padding-right: 15px; 24 | } 25 | 26 | /* Custom page header */ 27 | .header { 28 | border-bottom: 1px solid #e5e5e5; 29 | } 30 | 31 | /* Make the masthead heading the same height as the navigation */ 32 | .header h3 { 33 | margin-top: 0; 34 | margin-bottom: 0; 35 | line-height: 40px; 36 | padding-bottom: 19px; 37 | } 38 | 39 | /* Custom page footer */ 40 | .footer { 41 | padding-top: 19px; 42 | color: #777; 43 | border-top: 1px solid #e5e5e5; 44 | } 45 | 46 | .container-narrow > hr { 47 | margin: 30px 0; 48 | } 49 | 50 | /* Main marketing message and sign up button */ 51 | .jumbotron { 52 | text-align: center; 53 | border-bottom: 1px solid #e5e5e5; 54 | } 55 | 56 | .jumbotron .btn { 57 | font-size: 21px; 58 | padding: 14px 24px; 59 | } 60 | 61 | /* Supporting marketing content */ 62 | .marketing { 63 | margin: 40px 0; 64 | } 65 | 66 | .marketing p + h4 { 67 | margin-top: 28px; 68 | } 69 | 70 | /* Responsive: Portrait tablets and up */ 71 | @media screen and (min-width: 768px) { 72 | .container { 73 | max-width: 730px; 74 | } 75 | 76 | /* Remove the padding we set earlier */ 77 | .header, 78 | .marketing, 79 | .footer { 80 | padding-left: 0; 81 | padding-right: 0; 82 | } 83 | /* Space out the masthead */ 84 | .header { 85 | margin-bottom: 30px; 86 | } 87 | /* Remove the bottom border on the jumbotron for visual effect */ 88 | .jumbotron { 89 | border-bottom: 0; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/templates/img/ionic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/img/ionic.png -------------------------------------------------------------------------------- /app/templates/img/yeoman.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/img/yeoman.png -------------------------------------------------------------------------------- /app/templates/res/icon/android/icon-36-ldpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/android/icon-36-ldpi.png -------------------------------------------------------------------------------- /app/templates/res/icon/android/icon-48-mdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/android/icon-48-mdpi.png -------------------------------------------------------------------------------- /app/templates/res/icon/android/icon-72-hdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/android/icon-72-hdpi.png -------------------------------------------------------------------------------- /app/templates/res/icon/android/icon-96-xhdpi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/android/icon-96-xhdpi.png -------------------------------------------------------------------------------- /app/templates/res/icon/bada-wac/icon-48-type5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/bada-wac/icon-48-type5.png -------------------------------------------------------------------------------- /app/templates/res/icon/bada-wac/icon-50-type3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/bada-wac/icon-50-type3.png -------------------------------------------------------------------------------- /app/templates/res/icon/bada-wac/icon-80-type4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/bada-wac/icon-80-type4.png -------------------------------------------------------------------------------- /app/templates/res/icon/bada/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/bada/icon-128.png -------------------------------------------------------------------------------- /app/templates/res/icon/blackberry/icon-80.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/blackberry/icon-80.png -------------------------------------------------------------------------------- /app/templates/res/icon/ios/icon-57-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/ios/icon-57-2x.png -------------------------------------------------------------------------------- /app/templates/res/icon/ios/icon-57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/ios/icon-57.png -------------------------------------------------------------------------------- /app/templates/res/icon/ios/icon-72-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/ios/icon-72-2x.png -------------------------------------------------------------------------------- /app/templates/res/icon/ios/icon-72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/ios/icon-72.png -------------------------------------------------------------------------------- /app/templates/res/icon/tizen/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/tizen/icon-128.png -------------------------------------------------------------------------------- /app/templates/res/icon/webos/icon-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/webos/icon-64.png -------------------------------------------------------------------------------- /app/templates/res/icon/windows-phone/icon-173-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/windows-phone/icon-173-tile.png -------------------------------------------------------------------------------- /app/templates/res/icon/windows-phone/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/windows-phone/icon-48.png -------------------------------------------------------------------------------- /app/templates/res/icon/windows-phone/icon-62-tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/icon/windows-phone/icon-62-tile.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-hdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-hdpi-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-hdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-hdpi-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-ldpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-ldpi-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-ldpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-ldpi-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-mdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-mdpi-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-mdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-mdpi-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-xhdpi-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-xhdpi-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/android/screen-xhdpi-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/android/screen-xhdpi-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/bada-wac/screen-type3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/bada-wac/screen-type3.png -------------------------------------------------------------------------------- /app/templates/res/screen/bada-wac/screen-type4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/bada-wac/screen-type4.png -------------------------------------------------------------------------------- /app/templates/res/screen/bada-wac/screen-type5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/bada-wac/screen-type5.png -------------------------------------------------------------------------------- /app/templates/res/screen/bada/screen-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/bada/screen-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/blackberry/screen-225.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/blackberry/screen-225.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-ipad-landscape-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-ipad-landscape-2x.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-ipad-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-ipad-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-ipad-portrait-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-ipad-portrait-2x.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-ipad-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-ipad-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-iphone-landscape-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-iphone-landscape-2x.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-iphone-landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-iphone-landscape.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-iphone-portrait-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-iphone-portrait-2x.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-iphone-portrait-568h-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-iphone-portrait-568h-2x.png -------------------------------------------------------------------------------- /app/templates/res/screen/ios/screen-iphone-portrait.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/ios/screen-iphone-portrait.png -------------------------------------------------------------------------------- /app/templates/res/screen/tizen/README.md: -------------------------------------------------------------------------------- 1 | # Tizen Splash Screen 2 | 3 | Splash screens are unsupported on the Tizen platform. 4 | -------------------------------------------------------------------------------- /app/templates/res/screen/webos/screen-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/webos/screen-64.png -------------------------------------------------------------------------------- /app/templates/res/screen/windows-phone/screen-portrait.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/app/templates/res/screen/windows-phone/screen-portrait.jpg -------------------------------------------------------------------------------- /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-cordova:constant thing [--coffee] 7 | 8 | This will create: 9 | www/js/service/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( 14 | 'service/constant', 15 | 'spec/service', 16 | 'service', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /controller/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new Angular controller 3 | 4 | Example: 5 | yo angular-cordova:controller Thing [--coffee] 6 | 7 | This will create: 8 | www/js/controller/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() !== 'controller' && this.name.substr(-4).toLowerCase() === 'controller') { 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( 20 | 'controller', 21 | 'spec/controller', 22 | 'controller', 23 | this.options['skip-add'] || false 24 | ); 25 | }; 26 | -------------------------------------------------------------------------------- /decorator/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS decorator for a specified service 3 | 4 | Example: 5 | yo angular-cordova: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 | } else{ 32 | cb(); 33 | return; 34 | } 35 | }; 36 | 37 | Generator.prototype.askForNewName = function askForNewName() { 38 | var cb = this.async(); 39 | 40 | if (this.overwriteDecorator === undefined || this.overwriteDecorator === true) { 41 | cb(); 42 | return; 43 | } else { 44 | var prompts = []; 45 | prompts.push({ 46 | name: 'decoratorName', 47 | message: 'Alternative name for the decorator' 48 | }); 49 | 50 | this.prompt(prompts, function (props) { 51 | this.fileName = props.decoratorName; 52 | 53 | cb(); 54 | }.bind(this)); 55 | } 56 | }; 57 | 58 | Generator.prototype.createDecoratorFiles = function createDecoratorFiles() { 59 | this.appTemplate('decorator', 'scripts/' + buildRelativePath(this.fileName)); 60 | this.addScriptToIndex(buildRelativePath(this.fileName)); 61 | }; 62 | 63 | function buildRelativePath(fileName){ 64 | return 'decorators/' + fileName + "Decorator"; 65 | } 66 | -------------------------------------------------------------------------------- /directive/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new Angular directive 3 | 4 | Example: 5 | yo angular-cordova:directive thing [--coffee] 6 | 7 | This will create: 8 | www/js/directive/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( 14 | 'directive', 15 | 'spec/directive', 16 | 'directive', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /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-cordova:factory thing [--coffee] 7 | 8 | This will create: 9 | www/js/service/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( 14 | 'service/factory', 15 | 'spec/service', 16 | 'service', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /filter/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS filter 3 | 4 | Example: 5 | yo angular-cordova:filter thing [--coffee] 6 | 7 | This will create: 8 | www/js/filter/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( 14 | 'filter', 15 | 'spec/filter', 16 | 'filter', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /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.appTemplate('app', 'js/app'); 17 | }; 18 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "generator-angular-cordova", 3 | "version": "0.0.1", 4 | "description": "Yeoman generator", 5 | "license": "MIT", 6 | "main": "app/index.js", 7 | "repository": "wangshijun2010/generator-angular-cordova", 8 | "author": { 9 | "name": "wangshijun", 10 | "email": "wangshijun2010@gmail.com", 11 | "url": "https://github.com/wangshijun2010" 12 | }, 13 | "engines": { 14 | "node": ">=0.10.0" 15 | }, 16 | "scripts": { 17 | "test": "mocha" 18 | }, 19 | "files": [ 20 | "app" 21 | ], 22 | "keywords": [ 23 | "yeoman-generator", 24 | "scaffold", 25 | "framework", 26 | "component", 27 | "app", 28 | "cordova", 29 | "ionic", 30 | "angular" 31 | ], 32 | "dependencies": { 33 | "chalk": "~0.4.0", 34 | "wiredep": "~0.4.2", 35 | "cordova": "latest", 36 | "plugman": "~0.10.0", 37 | "lodash": "~1.3.1", 38 | "yeoman-generator": "~0.16.0" 39 | }, 40 | "peerDependencies": { 41 | "generator-karma": ">=0.6.0", 42 | "yo": ">=1.0.0" 43 | }, 44 | "devDependencies": { 45 | "grunt": "~0.4.1", 46 | "grunt-contrib-jshint": "~0.8.0", 47 | "grunt-conventional-changelog": "~1.0.0", 48 | "grunt-release": "~0.6.0", 49 | "load-grunt-tasks": "~0.3.0", 50 | "marked": "~0.2.8", 51 | "mocha": "*", 52 | "semver": "~2.2.1", 53 | "underscore.string": "~2.3.1" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /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-cordova:provider thing [--coffee] 7 | 8 | This will create: 9 | www/js/service/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( 14 | 'service/provider', 15 | 'spec/service', 16 | 'service', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /route/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS route 3 | 4 | Example: 5 | yo angular-cordova:route thing [--coffee] 6 | 7 | This will create: 8 | www/js/controller/thing.js 9 | www/tpl/thing.html 10 | And add routing to: 11 | app.js 12 | -------------------------------------------------------------------------------- /route/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var path = require('path'), 3 | util = require('util'), 4 | ScriptBase = require('../script-base.js'), 5 | angularUtils = require('../util.js'); 6 | 7 | var Generator = module.exports = function Generator() { 8 | ScriptBase.apply(this, arguments); 9 | this.hookFor('angular-cordova:controller'); 10 | this.hookFor('angular-cordova:view'); 11 | }; 12 | 13 | util.inherits(Generator, ScriptBase); 14 | 15 | Generator.prototype.rewriteAppJs = function () { 16 | var coffee = this.env.options.coffee; 17 | var config = { 18 | file: path.join(this.env.options.appPath, 'js/app.' + (coffee ? 'coffee' : 'js')), 19 | needle: '.otherwise', 20 | splicable: [ 21 | " templateUrl: 'tpl/" + this.name.toLowerCase() + ".html'" + (coffee ? "" : "," ), 22 | " controller: '" + this.classedName + "Controller'" 23 | ] 24 | }; 25 | 26 | if (coffee) { 27 | config.splicable.unshift(".when '/" + this.name + "',"); 28 | } else { 29 | config.splicable.unshift(".when('/" + this.name + "', {"); 30 | config.splicable.push("})"); 31 | } 32 | 33 | angularUtils.rewriteFile(config); 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /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 | this.appname = this._.slugify(this._.humanize(this.appname)); 16 | this.scriptAppName = this._.camelize(this.appname); 17 | 18 | this.cameledName = this._.camelize(this.name); 19 | this.classedName = this._.classify(this.name); 20 | 21 | if (typeof this.env.options.appPath === 'undefined') { 22 | try { 23 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 24 | } catch (e) {} 25 | this.env.options.appPath = this.env.options.appPath || 'app'; 26 | } 27 | 28 | if (typeof this.env.options.testPath === 'undefined') { 29 | try { 30 | this.env.options.testPath = require(path.join(process.cwd(), 'bower.json')).testPath; 31 | } catch (e) {} 32 | this.env.options.testPath = this.env.options.testPath || 'test/spec'; 33 | } 34 | 35 | this.env.options.coffee = this.options.coffee; 36 | if (typeof this.env.options.coffee === 'undefined') { 37 | this.option('coffee'); 38 | 39 | // attempt to detect if user is using CS or not 40 | // if cml arg provided, use that; else look for the existence of cs 41 | if (!this.options.coffee && this.expandFiles(path.join(this.env.options.appPath, '/js/**/*.coffee'), {}).length > 0) { 42 | this.options.coffee = true; 43 | } 44 | 45 | this.env.options.coffee = this.options.coffee; 46 | } 47 | 48 | var sourceRoot = '/templates/javascript'; 49 | this.scriptSuffix = '.js'; 50 | 51 | if (this.env.options.coffee) { 52 | sourceRoot = '/templates/coffeescript'; 53 | this.scriptSuffix = '.coffee'; 54 | } 55 | 56 | this.sourceRoot(path.join(__dirname, sourceRoot)); 57 | }; 58 | 59 | util.inherits(Generator, yeoman.generators.NamedBase); 60 | 61 | Generator.prototype.appTemplate = function (src, dest) { 62 | yeoman.generators.Base.prototype.template.apply(this, [ src + this.scriptSuffix, path.join(this.env.options.appPath, dest.toLowerCase()) + this.scriptSuffix ]); 63 | }; 64 | 65 | Generator.prototype.testTemplate = function (src, dest) { 66 | yeoman.generators.Base.prototype.template.apply(this, [ src + this.scriptSuffix, path.join(this.env.options.testPath, dest.toLowerCase()) + this.scriptSuffix ]); 67 | }; 68 | 69 | Generator.prototype.htmlTemplate = function (src, dest) { 70 | yeoman.generators.Base.prototype.template.apply(this, [ src, path.join(this.env.options.appPath, dest.toLowerCase()) ]); 71 | }; 72 | 73 | Generator.prototype.addScriptToIndex = function (script) { 74 | try { 75 | var appPath = this.env.options.appPath; 76 | var fullPath = path.join(appPath, 'index.html'); 77 | angularUtils.rewriteFile({ 78 | file: fullPath, 79 | needle: '', 80 | splicable: [ 81 | '' 82 | ] 83 | }); 84 | } catch (e) { 85 | console.log('\nUnable to find '.yellow + fullPath + '. Reference to '.yellow + script + '.js ' + 'not added.\n'.yellow); 86 | } 87 | }; 88 | 89 | Generator.prototype.generateSourceAndTest = function (appTemplate, testTemplate, targetDirectory, skipAdd) { 90 | // Services use classified names 91 | if (this.generatorName.toLowerCase() === 'service') { 92 | this.cameledName = this.classedName; 93 | } 94 | 95 | this.appTemplate(appTemplate, path.join('js', targetDirectory, this.name)); 96 | this.testTemplate(testTemplate, path.join(targetDirectory, this.name)); 97 | if (!skipAdd) { 98 | this.addScriptToIndex(path.join(targetDirectory, this.name)); 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /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-cordova:service thing [--coffee] 7 | 8 | This will create: 9 | www/js/service/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( 14 | 'service/service', 15 | 'spec/service', 16 | 'service', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /templates/coffeescript/app.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>', [<%= angularModules %>]) 4 | .config ($routeProvider) -> 5 | $routeProvider 6 | .when '/', 7 | templateUrl: 'tpl/main.html' 8 | controller: 'MainController' 9 | .otherwise 10 | redirectTo: '/' 11 | -------------------------------------------------------------------------------- /templates/coffeescript/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .controller '<%= classedName %>Controller', ($scope) -> 5 | $scope.awesomeThings = [ 6 | 'HTML5 Boilerplate' 7 | 'AngularJS' 8 | 'Karma' 9 | ] 10 | -------------------------------------------------------------------------------- /templates/coffeescript/decorator.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module("<%= scriptAppName %>").config ($provide) -> 4 | $provide.decorator "<%= cameledName %>", ($delegate) -> 5 | # decorate the $delegate 6 | $delegate 7 | -------------------------------------------------------------------------------- /templates/coffeescript/directive.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .directive('<%= cameledName %>', -> 5 | template: '
' 6 | restrict: 'E' 7 | link: (scope, element, attrs) -> 8 | element.text 'this is the <%= cameledName %> directive' 9 | ) 10 | -------------------------------------------------------------------------------- /templates/coffeescript/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .filter '<%= cameledName %>', -> 5 | (input) -> 6 | '<%= cameledName %> filter: ' + input 7 | -------------------------------------------------------------------------------- /templates/coffeescript/service/constant.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .constant '<%= cameledName %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript/service/factory.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .factory '<%= cameledName %>', -> 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('<%= scriptAppName %>') 4 | .provider '<%= cameledName %>', [-> 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('<%= scriptAppName %>') 4 | .service '<%= classedName %>', -> 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('<%= scriptAppName %>') 4 | .value '<%= cameledName %>', 42 5 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/controller.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Controller: <%= classedName %>Controller', -> 4 | 5 | # load the controller's module 6 | beforeEach module '<%= scriptAppName %>' 7 | 8 | <%= classedName %>Controller = {} 9 | scope = {} 10 | 11 | # Initialize the controller and a mock scope 12 | beforeEach inject ($controller, $rootScope) -> 13 | scope = $rootScope.$new() 14 | <%= classedName %>Controller = $controller '<%= classedName %>Controller', { 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: <%= cameledName %>', -> 4 | 5 | # load the directive's module 6 | beforeEach module '<%= scriptAppName %>' 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 <%= cameledName %> directive' 17 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/filter.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Filter: <%= cameledName %>', -> 4 | 5 | # load the filter's module 6 | beforeEach module '<%= scriptAppName %>' 7 | 8 | # initialize a new instance of the filter before each test 9 | <%= cameledName %> = {} 10 | beforeEach inject ($filter) -> 11 | <%= cameledName %> = $filter '<%= cameledName %>' 12 | 13 | it 'should return the input prefixed with "<%= cameledName %> filter:"', -> 14 | text = 'angularjs' 15 | expect(<%= cameledName %> text).toBe ('<%= cameledName %> filter: ' + text) 16 | -------------------------------------------------------------------------------- /templates/coffeescript/spec/service.coffee: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | describe 'Service: <%= cameledName %>', -> 4 | 5 | # load the service's module 6 | beforeEach module '<%= scriptAppName %>' 7 | 8 | # instantiate service 9 | <%= cameledName %> = {} 10 | beforeEach inject (_<%= cameledName %>_) -> 11 | <%= cameledName %> = _<%= cameledName %>_ 12 | 13 | it 'should do something', -> 14 | expect(!!<%= cameledName %>).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 | 12 | var cordova = require('cordova'); 13 | var device = { 14 | platform: grunt.option('platform') || 'all', 15 | family: grunt.option('family') || 'default', 16 | target: grunt.option('target') || 'emulator' 17 | }; 18 | 19 | // Load grunt tasks automatically 20 | require('load-grunt-tasks')(grunt); 21 | 22 | // Time how long tasks take. Can help when optimizing build times 23 | require('time-grunt')(grunt); 24 | 25 | // Define the configuration for all the tasks 26 | grunt.initConfig({ 27 | 28 | // Project settings 29 | yeoman: { 30 | // configurable paths 31 | app: require('./bower.json').appPath || 'app', 32 | dist: 'dist' 33 | }, 34 | 35 | watchfiles: { 36 | all: [ 37 | 'www/{,*/}*.html', 38 | 'www/js/{,*/,*/}*.js', 39 | 'www/css/{,*/}*.css', 40 | 'www/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 41 | ] 42 | }, 43 | 44 | // Watches files for changes and runs tasks based on the changed files 45 | watch: {<% if (coffee) { %> 46 | coffee: { 47 | files: ['<%%= yeoman.app %>/js/{,*/}*.{coffee,litcoffee,coffee.md}'], 48 | tasks: ['newer:coffee:dist'] 49 | }, 50 | coffeeTest: { 51 | files: ['test/spec/{,*/}*.{coffee,litcoffee,coffee.md}'], 52 | tasks: ['newer:coffee:test', 'karma'] 53 | },<% } else { %> 54 | js: { 55 | files: ['<%%= yeoman.app %>/js/{,*/}*.js'], 56 | tasks: ['newer:jshint:all'], 57 | options: { 58 | livereload: true 59 | } 60 | }, 61 | jsTest: { 62 | files: ['test/spec/{,*/}*.js'], 63 | tasks: ['newer:jshint:test', 'karma'] 64 | },<% } %><% if (compass) { %> 65 | compass: { 66 | files: ['<%%= yeoman.app %>/css/{,*/}*.{scss,sass}'], 67 | tasks: ['compass:server', 'autoprefixer'] 68 | },<% } else { %> 69 | css: { 70 | files: ['<%%= yeoman.app %>/css/{,*/}*.css'], 71 | tasks: ['newer:copy:css', 'autoprefixer'] 72 | },<% } %> 73 | gruntfile: { 74 | files: ['Gruntfile.js'] 75 | }, 76 | livereload: { 77 | options: { 78 | livereload: '<%%= connect.options.livereload %>' 79 | }, 80 | files: [ 81 | '<%%= yeoman.app %>/{,*/}*.html', 82 | '.tmp/css/{,*/}*.css',<% if (coffee) { %> 83 | '.tmp/js/{,*/}*.js',<% } %> 84 | '<%%= yeoman.app %>/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 85 | ], 86 | tasks: ['cordova-prepare', 'cordova-build', 'cordova-emulate'] 87 | } 88 | }, 89 | 90 | // The actual grunt server settings 91 | connect: { 92 | options: { 93 | port: 9000, 94 | // Change this to '0.0.0.0' to access the server from outside. 95 | hostname: 'localhost', 96 | livereload: 35729 97 | }, 98 | livereload: { 99 | options: { 100 | open: true, 101 | base: [ 102 | '.tmp', 103 | '<%%= yeoman.app %>' 104 | ] 105 | } 106 | }, 107 | test: { 108 | options: { 109 | port: 9001, 110 | base: [ 111 | '.tmp', 112 | 'test', 113 | '<%%= yeoman.app %>' 114 | ] 115 | } 116 | }, 117 | dist: { 118 | options: { 119 | base: '<%%= yeoman.dist %>' 120 | } 121 | } 122 | }, 123 | 124 | // Make sure code styles are up to par and there are no obvious mistakes 125 | jshint: { 126 | options: { 127 | jshintrc: '.jshintrc', 128 | reporter: require('jshint-stylish') 129 | }, 130 | all: [ 131 | 'Gruntfile.js'<% if (!coffee) { %>, 132 | '<%%= yeoman.app %>/js/{,*/}*.js'<% } %> 133 | ]<% if (!coffee) { %>, 134 | test: { 135 | options: { 136 | jshintrc: 'test/.jshintrc' 137 | }, 138 | src: ['test/spec/{,*/}*.js'] 139 | }<% } %> 140 | }, 141 | 142 | // Empties folders to start fresh 143 | clean: { 144 | dist: { 145 | files: [{ 146 | dot: true, 147 | src: [ 148 | '.tmp', 149 | '<%%= yeoman.dist %>/*', 150 | '!<%%= yeoman.dist %>/.git*' 151 | ] 152 | }] 153 | }, 154 | server: '.tmp' 155 | }, 156 | 157 | // Add vendor prefixed styles 158 | autoprefixer: { 159 | options: { 160 | browsers: ['last 1 version'] 161 | }, 162 | dist: { 163 | files: [{ 164 | expand: true, 165 | cwd: '.tmp/css/', 166 | src: '{,*/}*.css', 167 | dest: '.tmp/css/' 168 | }] 169 | } 170 | }, 171 | 172 | // Automatically inject Bower components into the app 173 | 'bower-install': { 174 | app: { 175 | html: '<%%= yeoman.app %>/index.html', 176 | ignorePath: '<%%= yeoman.app %>/' 177 | } 178 | }, 179 | 180 | <% if (coffee) { %> 181 | // Compiles CoffeeScript to JavaScript 182 | coffee: { 183 | options: { 184 | sourceMap: true, 185 | sourceRoot: '' 186 | }, 187 | dist: { 188 | files: [{ 189 | expand: true, 190 | cwd: '<%%= yeoman.app %>/js', 191 | src: '{,*/}*.coffee', 192 | dest: '.tmp/js', 193 | ext: '.js' 194 | }] 195 | }, 196 | test: { 197 | files: [{ 198 | expand: true, 199 | cwd: 'test/spec', 200 | src: '{,*/}*.coffee', 201 | dest: '.tmp/spec', 202 | ext: '.js' 203 | }] 204 | } 205 | },<% } %><% if (compass) { %> 206 | 207 | // Compiles Sass to CSS and generates necessary files if requested 208 | compass: { 209 | options: { 210 | sassDir: '<%%= yeoman.app %>/css', 211 | cssDir: '.tmp/css', 212 | generatedImagesDir: '.tmp/img/generated', 213 | imagesDir: '<%%= yeoman.app %>/img', 214 | javascriptsDir: '<%%= yeoman.app %>/js', 215 | fontsDir: '<%%= yeoman.app %>/css/fonts', 216 | importPath: '<%%= yeoman.app %>/bower_components', 217 | httpImagesPath: '/img', 218 | httpGeneratedImagesPath: '/img/generated', 219 | httpFontsPath: '/css/fonts', 220 | relativeAssets: false, 221 | assetCacheBuster: false, 222 | raw: 'Sass::Script::Number.precision = 10\n' 223 | }, 224 | dist: { 225 | options: { 226 | generatedImagesDir: '<%%= yeoman.dist %>/img/generated' 227 | } 228 | }, 229 | server: { 230 | options: { 231 | debugInfo: true 232 | } 233 | } 234 | },<% } %> 235 | 236 | // Renames files for browser caching purposes 237 | rev: { 238 | dist: { 239 | files: { 240 | src: [ 241 | '<%%= yeoman.dist %>/js/{,*/}*.js', 242 | '<%%= yeoman.dist %>/css/{,*/}*.css', 243 | '<%%= yeoman.dist %>/img/{,*/}*.{png,jpg,jpeg,gif,webp,svg}', 244 | '<%%= yeoman.dist %>/css/fonts/*' 245 | ] 246 | } 247 | } 248 | }, 249 | 250 | // Reads HTML for usemin blocks to enable smart builds that automatically 251 | // concat, minify and revision files. Creates configurations in memory so 252 | // additional tasks can operate on them 253 | useminPrepare: { 254 | html: '<%%= yeoman.app %>/index.html', 255 | options: { 256 | dest: '<%%= yeoman.dist %>', 257 | flow: { 258 | html: { 259 | steps: { 260 | js: ['concat', 'uglifyjs'], 261 | css: ['cssmin'] 262 | }, 263 | post: {} 264 | } 265 | } 266 | } 267 | }, 268 | 269 | // Copies remaining files to places other tasks can use 270 | copy: { 271 | dist: { 272 | files: [{ 273 | expand: true, 274 | dot: true, 275 | cwd: '<%%= yeoman.app %>', 276 | dest: '<%%= yeoman.dist %>', 277 | src: [ 278 | '*.{ico,png,txt}', 279 | '.htaccess', 280 | '*.html', 281 | 'tpl/{,*/}*.html', 282 | 'vendor/**/*', 283 | 'img/{,*/}*.{webp}', 284 | 'fonts/*' 285 | ] 286 | }, { 287 | expand: true, 288 | cwd: '.tmp/images', 289 | dest: '<%%= yeoman.dist %>/img', 290 | src: ['generated/*'] 291 | }] 292 | }, 293 | css: { 294 | expand: true, 295 | cwd: '<%%= yeoman.app %>/css', 296 | dest: '.tmp/css/', 297 | src: '{,*/}*.css' 298 | } 299 | }, 300 | 301 | // Performs rewrites based on rev and the useminPrepare configuration 302 | usemin: { 303 | html: ['<%%= yeoman.dist %>/{,*/}*.html'], 304 | css: ['<%%= yeoman.dist %>/css/{,*/}*.css'], 305 | options: { 306 | assetsDirs: ['<%%= yeoman.dist %>'] 307 | } 308 | }, 309 | 310 | // The following *-min tasks produce minified files in the dist folder 311 | cssmin: { 312 | options: { 313 | root: '<%%= yeoman.app %>' 314 | } 315 | }, 316 | 317 | imagemin: { 318 | dist: { 319 | files: [{ 320 | expand: true, 321 | cwd: '<%%= yeoman.app %>/img', 322 | src: '{,*/}*.{png,jpg,jpeg,gif}', 323 | dest: '<%%= yeoman.dist %>/img' 324 | }] 325 | } 326 | }, 327 | 328 | // ngmin tries to make the code safe for minification automatically by 329 | // using the Angular long form for dependency injection. It doesn't work on 330 | // things like resolve or inject so those have to be done manually. 331 | ngmin: { 332 | dist: { 333 | files: [{ 334 | expand: true, 335 | cwd: '.tmp/concat/js', 336 | src: '*.js', 337 | dest: '.tmp/concat/js' 338 | }] 339 | } 340 | }, 341 | 342 | // Run some tasks in parallel to speed up the build process 343 | concurrent: { 344 | server: [<% if (coffee) { %> 345 | 'coffee:dist',<% } %><% if (compass) { %> 346 | 'compass:server'<% } else { %> 347 | 'copy:css'<% } %> 348 | ], 349 | test: [<% if (coffee) { %> 350 | 'coffee',<% } %><% if (compass) { %> 351 | 'compass'<% } else { %> 352 | 'copy:css'<% } %> 353 | ], 354 | dist: [<% if (coffee) { %> 355 | 'coffee',<% } %><% if (compass) { %> 356 | 'compass:dist',<% } else { %> 357 | 'copy:css',<% } %> 358 | 'imagemin' 359 | ] 360 | }, 361 | 362 | // Test settings 363 | karma: { 364 | unit: { 365 | configFile: 'karma.conf.js', 366 | singleRun: true 367 | } 368 | }, 369 | 370 | shell: { 371 | iossimstart: { 372 | command: 'ios-sim launch platforms/ios/build/<%= appname %>.app --exit' + (device.family !== 'default' ? ' --family ' + device.family : ''), 373 | options: { 374 | stdout: true 375 | } 376 | }, 377 | iossimend: { 378 | command: 'killall -9 "iPhone Simulator"' 379 | } 380 | } 381 | 382 | }); 383 | 384 | // Cordova Tasks 385 | grunt.registerTask('cordova-prepare', 'Cordova prepare tasks', function () { 386 | var done = this.async(); 387 | 388 | if (device.platform === 'all') { 389 | // Prepare all platforms 390 | cordova.prepare(done); 391 | } else { 392 | cordova.prepare(device.platform, done); 393 | } 394 | }); 395 | 396 | grunt.registerTask('cordova-build', 'Cordova building tasks', function () { 397 | var done = this.async(); 398 | 399 | if (device.platform === 'all') { 400 | // Build all platforms 401 | cordova.build(done); 402 | } else { 403 | cordova.build(device.platform, done); 404 | } 405 | }); 406 | 407 | grunt.registerTask('cordova-run', 'Cordova running tasks', function () { 408 | var done = this.async(); 409 | 410 | if (device.platform === 'all') { 411 | // Build all platforms 412 | cordova.run(); 413 | } else { 414 | cordova.run(device.platform); 415 | } 416 | 417 | done(); 418 | }); 419 | 420 | grunt.registerTask('cordova-emulate', 'Cordova emulation tasks', function () { 421 | var done = this.async(); 422 | 423 | if (device.platform === 'all') { 424 | // Emulate all platforms 425 | cordova.emulate(); 426 | } else { 427 | if (device.platform === 'ios') { 428 | grunt.task.run('shell:iossimstart'); 429 | } else { 430 | cordova.emulate(device.platform, function() { 431 | grunt.task.run('cordova-emulate-end'); 432 | }); 433 | } 434 | } 435 | 436 | done(); 437 | }); 438 | 439 | grunt.registerTask('cordova-emulate-end', 'Cordova emulation tasks', function () { 440 | if (device.platform === 'all' || device.platform === 'ios') { 441 | grunt.task.run('shell:iossimend'); 442 | } 443 | }); 444 | 445 | grunt.registerTask('cordova-buildemulate', [ 446 | 'cordova-build', 447 | 'cordova-emulate' 448 | ]); 449 | 450 | grunt.registerTask('cordova-buildrun', [ 451 | 'cordova-build', 452 | 'cordova-run' 453 | ]); 454 | 455 | grunt.registerTask('emulate', ['cordova-buildemulate']); 456 | 457 | grunt.registerTask('device', ['cordova-buildrun']); 458 | 459 | grunt.registerTask('serve', function (target) { 460 | if (target === 'dist') { 461 | return grunt.task.run(['build', 'connect:dist:keepalive']); 462 | } 463 | 464 | grunt.task.run([ 465 | 'clean:server', 466 | 'bower-install', 467 | 'concurrent:server', 468 | 'autoprefixer', 469 | 'connect:livereload', 470 | 'cordova-prepare', 471 | 'watch' 472 | ]); 473 | }); 474 | 475 | grunt.registerTask('test', [ 476 | 'clean:server', 477 | 'concurrent:test', 478 | 'autoprefixer', 479 | 'connect:test', 480 | 'karma' 481 | ]); 482 | 483 | grunt.registerTask('build', [ 484 | 'clean:dist', 485 | 'bower-install', 486 | 'useminPrepare', 487 | 'concurrent:dist', 488 | 'autoprefixer', 489 | 'concat', 490 | 'ngmin', 491 | 'copy:dist', 492 | 'cdnify', 493 | 'cssmin', 494 | 'uglify', 495 | 'rev', 496 | 'usemin' 497 | ]); 498 | 499 | grunt.registerTask('default', [ 500 | 'newer:jshint', 501 | 'test', 502 | 'build' 503 | ]); 504 | }; 505 | -------------------------------------------------------------------------------- /templates/common/_bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(_.humanize(appname)) %>", 3 | "appPath": "www", 4 | "version": "0.0.0", 5 | "dependencies": { 6 | "angular": "1.2.10"<% if (ionic) { %>, 7 | "ionic": "latest"<% } %><% if (resourceModule) { %>, 8 | "angular-resource": "1.2.10"<% } %><% if (cookiesModule) { %>, 9 | "angular-cookies": "1.2.10"<% } %><% if (sanitizeModule) { %>, 10 | "angular-sanitize": "1.2.10"<% } %>, 11 | "angular-ui-router": "0.2.7" 12 | }, 13 | "devDependencies": { 14 | "angular-mocks": "1.2.10", 15 | "angular-scenario": "1.2.10" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /templates/common/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "version": "0.0.0", 4 | "dependencies": {}, 5 | "devDependencies": { 6 | "grunt": "~0.4.1", 7 | "cordova": "latest", 8 | "grunt-autoprefixer": "~0.4.0", 9 | "grunt-bower-install": "~0.7.0", 10 | "grunt-concurrent": "~0.4.1", 11 | "grunt-contrib-clean": "~0.5.0",<% if (coffee) { %> 12 | "grunt-contrib-coffee": "~0.7.0",<% } %><% if (compass) { %> 13 | "grunt-contrib-compass": "~0.6.0",<% } %> 14 | "grunt-contrib-concat": "~0.3.0", 15 | "grunt-contrib-connect": "~0.5.0", 16 | "grunt-contrib-copy": "~0.4.1", 17 | "grunt-contrib-cssmin": "~0.7.0", 18 | "grunt-contrib-imagemin": "~0.3.0", 19 | "grunt-contrib-jshint": "~0.7.1", 20 | "grunt-contrib-uglify": "~0.2.0", 21 | "grunt-contrib-watch": "~0.5.2", 22 | "grunt-newer": "~0.5.4", 23 | "grunt-ngmin": "~0.0.2", 24 | "grunt-rev": "~0.1.0", 25 | "grunt-usemin": "~2.0.0", 26 | "grunt-shell": "~0.6.4", 27 | "jshint-stylish": "~0.1.3", 28 | "load-grunt-tasks": "~0.2.0", 29 | "time-grunt": "~0.2.1" 30 | }, 31 | "engines": { 32 | "node": ">=0.10.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /templates/common/bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "www/vendor" 3 | } 4 | 5 | -------------------------------------------------------------------------------- /templates/common/editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 4 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 | -------------------------------------------------------------------------------- /templates/common/gitignore: -------------------------------------------------------------------------------- 1 | .tmp 2 | .sass-cache 3 | *.keystore 4 | *.sw* 5 | platforms/^.* 6 | www/dist 7 | www/vendor 8 | node_modules 9 | -------------------------------------------------------------------------------- /templates/common/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | <%= scriptAppName %> 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 28 | 29 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /templates/common/jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "bitwise" : true, 3 | "camelcase" : true, 4 | "curly" : false, 5 | "eqeqeq" : true, 6 | "forin" : true, 7 | "immed" : false, 8 | "indent" : 4, 9 | "latedef" : false, 10 | "newcap" : true, 11 | "noarg" : true, 12 | "noempty" : true, 13 | "nonew" : false, 14 | "plusplus" : false, 15 | "quotmark" : false, 16 | "regexp" : false, 17 | "undef" : true, 18 | "unused" : true, 19 | "strict" : false, 20 | "trailing" : true, 21 | "maxparams" : 7, 22 | "maxdepth" : 7, 23 | "maxstatements" : 200, 24 | "maxcomplexity" : 24, 25 | "maxlen" : 512, 26 | 27 | "asi" : false, 28 | "boss" : false, 29 | "debug" : false, 30 | "eqnull" : true, 31 | "es5" : false, 32 | "esnext" : false, 33 | "evil" : false, 34 | "expr" : false, 35 | "funcscope" : false, 36 | "globalstrict" : false, 37 | "iterator" : false, 38 | "lastsemic" : false, 39 | "laxbreak" : false, 40 | "laxcomma" : false, 41 | 42 | "loopfunc" : true, 43 | "multistr" : false, 44 | "onecase" : false, 45 | "proto" : false, 46 | "regexdash" : false, 47 | "scripturl" : true, 48 | "smarttabs" : true, 49 | "shadow" : false, 50 | "sub" : true, 51 | "supernew" : false, 52 | "validthis" : false, 53 | 54 | "browser" : true, 55 | "couch" : false, 56 | "devel" : false, 57 | "dojo" : false, 58 | "jquery" : true, 59 | "mootools" : false, 60 | "node" : false, 61 | "nonstandard" : false, 62 | "prototypejs" : false, 63 | "rhino" : false, 64 | "worker" : false, 65 | "wsh" : false, 66 | "yui" : false, 67 | 68 | "nomen" : false, 69 | "onevar" : false, 70 | "passfail" : false, 71 | "white" : true, 72 | 73 | "globals" : { 74 | "app" : false, 75 | "jquery" : false, 76 | "$" : false, 77 | "bootstrap" : false, 78 | "require" : false, 79 | "define" : false, 80 | "module" : false, 81 | "angular" : false, 82 | "prettyPrint": false, 83 | "alert" : false, 84 | "confirm" : false, 85 | "console" : false, 86 | "setInterval" : false, 87 | "clearInterval" : false, 88 | "setTimeout" : false, 89 | "clearTimeout" : false 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /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 | "jasmine": false, 33 | "spyOn": false 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /templates/common/root/test/runner.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | End2end Test Runner 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /templates/common/root/www/.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee -------------------------------------------------------------------------------- /templates/common/root/www/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/www/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wangshijun/generator-angular-cordova/84c826a59a03678b5967b7bd7dc6943405750099/templates/common/root/www/favicon.ico -------------------------------------------------------------------------------- /templates/common/root/www/tpl/about.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 |

8 | This is a sample seed project for the Ionic Framework. Please cut it up and make it your own. 9 | Check out the docs 10 | for more info. 11 |

12 |

13 | Questions? Hit up the 14 | forum. 15 |

16 |

17 | Find a bug? Create an 18 | issue. 19 |

20 |

21 | What to help improve Ionic? 22 | Contribute. 23 |

24 |

25 | Stay up-to-date with the Ionic 26 | newsletter and 27 | twitter account. 28 |

29 |

30 | MIT Licensed. Happy coding. 31 |

32 |
33 |
34 | -------------------------------------------------------------------------------- /templates/common/root/www/tpl/detail.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 |

{{ item.description }}

10 |

All Items

11 |
12 |
13 | -------------------------------------------------------------------------------- /templates/common/root/www/tpl/form.html: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 |
7 | 11 | 15 | Subscribe To Newsletter 16 | 17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /templates/common/root/www/tpl/index.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 |

{{item.title}}

11 |

{{item.description}}

12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /templates/common/root/www/tpl/tabs.html: -------------------------------------------------------------------------------- 1 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /templates/common/view.html: -------------------------------------------------------------------------------- 1 |

This is the <%= name %> view.

2 | -------------------------------------------------------------------------------- /templates/javascript/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>', [<%= angularModules %>]) 4 | .config(function ($stateProvider, $urlRouterProvider) { 5 | // Ionic uses AngularUI Router which uses the concept of states 6 | // Learn more here: https://github.com/angular-ui/ui-router 7 | // Set up the various states which the app can be in. 8 | // Each state's controller can be found in controllers.js 9 | $stateProvider 10 | 11 | // setup an abstract state for the tabs directive 12 | .state('tab', { 13 | url: "/tab", 14 | abstract: true, 15 | templateUrl: "tpl/tabs.html" 16 | }) 17 | 18 | // the pet tab has its own child nav-view and history 19 | .state('tab.index', { 20 | url: '/items', 21 | views: { 22 | 'index-tab': { 23 | templateUrl: 'tpl/index.html', 24 | controller: 'IndexController' 25 | } 26 | } 27 | }) 28 | 29 | .state('tab.detail', { 30 | url: '/item/:itemId', 31 | views: { 32 | 'index-tab': { 33 | templateUrl: 'tpl/detail.html', 34 | controller: 'IndexController' 35 | } 36 | } 37 | }) 38 | 39 | .state('tab.form', { 40 | url: '/form', 41 | views: { 42 | 'form-tab': { 43 | templateUrl: 'tpl/form.html' 44 | } 45 | } 46 | }) 47 | 48 | .state('tab.about', { 49 | url: '/about', 50 | views: { 51 | 'about-tab': { 52 | templateUrl: 'tpl/about.html' 53 | } 54 | } 55 | }); 56 | 57 | // if none of the above states are matched, use this as the fallback 58 | $urlRouterProvider.otherwise('/tab/items'); 59 | 60 | }); 61 | -------------------------------------------------------------------------------- /templates/javascript/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .controller('<%= classedName %>Controller', function <%= classedName %>Controller($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('<%= scriptAppName %>') 4 | .config(function ($provide) { 5 | $provide.decorator('<%= cameledName %>', function <%= cameledName %>($delegate) { 6 | // decorate the $delegate 7 | return $delegate; 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /templates/javascript/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .directive('<%= cameledName %>', function <%= cameledName %>() { 5 | return { 6 | template: '
', 7 | restrict: 'E', 8 | link: function postLink(scope, element, attrs) { 9 | element.text('this is the <%= cameledName %> directive'); 10 | } 11 | }; 12 | }); 13 | -------------------------------------------------------------------------------- /templates/javascript/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .filter('<%= cameledName %>', function <%= cameledName %>() { 5 | return function (input) { 6 | return '<%= cameledName %> filter: ' + input; 7 | }; 8 | }); 9 | -------------------------------------------------------------------------------- /templates/javascript/service/constant.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .constant('<%= cameledName %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript/service/factory.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('<%= scriptAppName %>') 4 | .factory('<%= cameledName %>', function <%= cameledName %>() { 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('<%= scriptAppName %>') 4 | .provider('<%= cameledName %>', function <%= cameledName %>() { 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('<%= scriptAppName %>') 4 | .service('<%= classedName %>', function <%= classedName %>() { 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('<%= scriptAppName %>') 4 | .value('<%= cameledName %>', 42); 5 | -------------------------------------------------------------------------------- /templates/javascript/spec/controller.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint indent: false */ 4 | describe('Controller: <%= classedName %>Controller', function () { 5 | 6 | // load the controller's module 7 | beforeEach(module('<%= scriptAppName %>')); 8 | 9 | var <%= classedName %>Controller, 10 | scope; 11 | 12 | // Initialize the controller and a mock scope 13 | beforeEach(inject(function ($controller, $rootScope) { 14 | scope = $rootScope.$new(); 15 | <%= classedName %>Controller = $controller('<%= classedName %>Controller', { 16 | $scope: scope 17 | }); 18 | })); 19 | 20 | it('should attach a list of awesomeThings to the scope', function () { 21 | expect(scope.awesomeThings.length).toBe(3); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /templates/javascript/spec/directive.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint indent: false */ 4 | describe('Directive: <%= cameledName %>', function () { 5 | 6 | // load the directive's module 7 | beforeEach(module('<%= scriptAppName %>')); 8 | 9 | var element, 10 | scope; 11 | 12 | beforeEach(inject(function ($rootScope) { 13 | scope = $rootScope.$new(); 14 | })); 15 | 16 | it('should make hidden element visible', inject(function ($compile) { 17 | element = angular.element('<<%= _.dasherize(name) %>>>'); 18 | element = $compile(element)(scope); 19 | expect(element.text()).toBe('this is the <%= cameledName %> directive'); 20 | })); 21 | }); 22 | -------------------------------------------------------------------------------- /templates/javascript/spec/filter.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint indent: false */ 4 | describe('Filter: <%= cameledName %>', function () { 5 | 6 | // load the filter's module 7 | beforeEach(module('<%= scriptAppName %>')); 8 | 9 | // initialize a new instance of the filter before each test 10 | var <%= cameledName %>; 11 | beforeEach(inject(function ($filter) { 12 | <%= cameledName %> = $filter('<%= cameledName %>'); 13 | })); 14 | 15 | it('should return the input prefixed with "<%= cameledName %> filter:"', function () { 16 | var text = 'angularjs'; 17 | expect(<%= cameledName %>(text)).toBe('<%= cameledName %> filter: ' + text); 18 | }); 19 | 20 | }); 21 | -------------------------------------------------------------------------------- /templates/javascript/spec/service.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* jshint indent: false */ 4 | describe('Service: <%= cameledName %>', function () { 5 | 6 | // load the service's module 7 | beforeEach(module('<%= scriptAppName %>')); 8 | 9 | // instantiate service 10 | var <%= cameledName %>; 11 | beforeEach(inject(function (_<%= cameledName %>_) { 12 | <%= cameledName %> = _<%= cameledName %>_; 13 | })); 14 | 15 | it('should do something', function () { 16 | expect(!!<%= cameledName %>).toBe(true); 17 | }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /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: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 = 'upperCaseBugApp'; 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 | compass: true, 46 | bootstrap: true, 47 | compassBootstrap: true, 48 | modules: [] 49 | }); 50 | 51 | angular.run({}, function () { 52 | // Check if all files are created for the test 53 | helpers.assertFiles(expected); 54 | 55 | // read JS Files 56 | var app_js = fs.readFileSync('app/scripts/app.js', 'utf8'); 57 | var main_js = fs.readFileSync('app/scripts/controllers/main.js', 'utf8'); 58 | var main_test_js = fs.readFileSync('test/spec/controllers/main.js', 'utf8'); 59 | 60 | // Test JS Files 61 | var regex_js = new RegExp('module\\(\'' + expectedAppName + '\''); 62 | assert.ok(regex_js.test(app_js), 'app.js template using a wrong appName'); 63 | assert.ok(regex_js.test(main_js), 'main.js template using a wrong appName'); 64 | assert.ok(regex_js.test(main_test_js), 'controller spec template using a wrong appName'); 65 | 66 | // read HTML file 67 | var index_html = fs.readFileSync('app/index.html', 'utf8'); 68 | 69 | // Test HTML File 70 | var regex_html = new RegExp('ng-app=\"' + expectedAppName + '\"'); 71 | assert.ok(regex_html.test(index_html), 'index.html template using a wrong appName'); 72 | done(); 73 | }); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /test/test-creation.js: -------------------------------------------------------------------------------- 1 | /*global describe, beforeEach, it */ 2 | 'use strict'; 3 | var path = require('path'); 4 | var helpers = require('yeoman-generator').test; 5 | 6 | describe('angular-cordova generator', function () { 7 | beforeEach(function (done) { 8 | helpers.testDirectory(path.join(__dirname, 'temp'), function (err) { 9 | if (err) { 10 | return done(err); 11 | } 12 | 13 | this.app = helpers.createGenerator('angular-cordova:app', [ 14 | '../../app' 15 | ]); 16 | done(); 17 | }.bind(this)); 18 | }); 19 | 20 | it('creates expected files', function (done) { 21 | var expected = [ 22 | // add files you expect to exist here. 23 | '.jshintrc', 24 | '.editorconfig' 25 | ]; 26 | 27 | helpers.mockPrompt(this.app, { 28 | 'someOption': true 29 | }); 30 | this.app.options['skip-install'] = true; 31 | this.app.run({}, function () { 32 | helpers.assertFile(expected); 33 | done(); 34 | }); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /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 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-cordova: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 | compass: true, 37 | bootstrap: true, 38 | compassBootstrap: true, 39 | modules: [] 40 | }); 41 | 42 | angular.run({}, function () { 43 | helpers.assertFiles(['.bowerrc', '.gitignore', '.editorconfig', '.jshintrc']); 44 | done(); 45 | }); 46 | }); 47 | 48 | it('creates expected files', function (done) { 49 | var expected = ['www/404.html', 50 | 'www/favicon.ico', 51 | 'www/css/main.scss', 52 | 'www/tpl/main.html', 53 | ['.bowerrc', /"directory": "www\/vendor"/], 54 | 'Gruntfile.js', 55 | 'package.json', 56 | ['bower.json', /"name":\s+"temp"/], 57 | 'www/js/app.js', 58 | 'www/index.html', 59 | 'www/js/controller/main.js', 60 | 'test/spec/controller/main.js' 61 | ]; 62 | helpers.mockPrompt(angular, { 63 | compass: true, 64 | bootstrap: true, 65 | compassBootstrap: 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 = ['www/404.html', 77 | 'www/favicon.ico', 78 | 'www/css/main.scss', 79 | 'www/tpl/main.html', 80 | ['.bowerrc', /"directory": "www\/vendor"/], 81 | 'Gruntfile.js', 82 | 'package.json', 83 | ['bower.json', /"name":\s+"temp"/], 84 | 'www/js/app.coffee', 85 | 'www/index.html', 86 | 'www/js/controller/main.coffee', 87 | 'test/spec/controller/main.coffee' 88 | ]; 89 | helpers.mockPrompt(angular, { 90 | compass: true, 91 | bootstrap: true, 92 | compassBootstrap: true, 93 | modules: [] 94 | }); 95 | 96 | angular.env.options.coffee = true; 97 | angular.run([], function () { 98 | helpers.assertFiles(expected); 99 | done(); 100 | }); 101 | }); 102 | 103 | /** 104 | * Generic test function that can be used to cover the scenarios where a generator is creating both a source file 105 | * and a test file. The function will run the respective generator, and then check for the existence of the two 106 | * generated files. A RegExp check is done on each file, checking for the generated content with a pattern. 107 | * 108 | * The number of parameters is quite huge due to the many options in which the generated files differ, 109 | * e.g. Services start with an upper case letter, whereas filters, directives or constants start with a lower case 110 | * letter. 111 | * 112 | * The generated items all use the dummy name 'foo'. 113 | * 114 | * @param generatorType The type of generator to run, e.g. 'filter'. 115 | * @param specType The type of the generated spec file, e.g. 'service' - all service types (constant, value, ...) 116 | * use the same Service spec template. 117 | * @param targetDirectory The directory into which the files are generated, e.g. 'directives' - this will be 118 | * located under 'www/js' for the sources and 'test/spec' for the tests. 119 | * @param scriptNameFn The function used to create the name of the created item, e.g. _.classify to generate 'Foo', 120 | * or _.camelize to generate 'foo'. 121 | * @param specNameFn Same as scriptNameFn, but for the describe text used in the Spec file. Some generators use 122 | * _.classify, others use _.camelize. 123 | * @param suffix An optional suffix to be appended to the generated item name, e.g. 'Controller' for controller, which 124 | * will generate 'FooController'. 125 | * @param done The done function. 126 | */ 127 | function generatorTest(generatorType, specType, targetDirectory, scriptNameFn, specNameFn, suffix, done) { 128 | var angularGenerator; 129 | var name = 'foo'; 130 | var deps = [path.join('../..', generatorType)]; 131 | angularGenerator = helpers.createGenerator('angular-cordova:' + generatorType, deps, [name]); 132 | 133 | helpers.mockPrompt(angular, { 134 | compass: true, 135 | bootstrap: true, 136 | compassBootstrap: true, 137 | modules: [] 138 | }); 139 | angular.run([], function (){ 140 | angularGenerator.run([], function () { 141 | helpers.assertFiles([ 142 | [path.join('www/js', 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', 'controller', _.classify, _.classify, 'Controller', done); 153 | }); 154 | }); 155 | 156 | describe('Directive', function () { 157 | it('should generate a new directive', function (done) { 158 | generatorTest('directive', 'directive', 'directive', _.camelize, _.camelize, '', done); 159 | }); 160 | }); 161 | 162 | describe('Filter', function () { 163 | it('should generate a new filter', function (done) { 164 | generatorTest('filter', 'filter', 'filter', _.camelize, _.camelize, '', done); 165 | }); 166 | }); 167 | 168 | describe('Service', function () { 169 | function serviceTest (generatorType, nameFn, done) { 170 | generatorTest(generatorType, 'service', 'service', nameFn, nameFn, '', 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-cordova:view', deps, ['foo']); 199 | 200 | helpers.mockPrompt(angular, { 201 | compass: true, 202 | bootstrap: true, 203 | compassBootstrap: true, 204 | modules: [] 205 | }); 206 | angular.run([], function (){ 207 | angularView.run([], function () { 208 | helpers.assertFile( 209 | ['www/tpl/foo.html'] 210 | ); 211 | done(); 212 | }); 213 | }); 214 | }); 215 | 216 | it('should generate a new view in subdirectories', function (done) { 217 | var angularView; 218 | var deps = ['../../view']; 219 | angularView = helpers.createGenerator('angular-cordova:view', deps, ['foo/bar']); 220 | 221 | helpers.mockPrompt(angular, { 222 | compass: true, 223 | ionic: true, 224 | compassIonic: true, 225 | modules: [] 226 | }); 227 | angular.run([], function (){ 228 | angularView.run([], function () { 229 | helpers.assertFile( 230 | ['www/tpl/foo/bar.html'] 231 | ); 232 | done(); 233 | }); 234 | }); 235 | }); 236 | }); 237 | }); 238 | -------------------------------------------------------------------------------- /test/test-load.js: -------------------------------------------------------------------------------- 1 | /*global describe, beforeEach, it*/ 2 | 'use strict'; 3 | var assert = require('assert'); 4 | 5 | describe('angular-cordova generator', function () { 6 | it('can be imported without blowing up', function () { 7 | var app = require('../app'); 8 | assert(app !== undefined); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /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-cordova:value thing [--coffee] 7 | 8 | This will create: 9 | www/js/service/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( 14 | 'service/value', 15 | 'spec/service', 16 | 'services', 17 | this.options['skip-add'] || false 18 | ); 19 | }; 20 | -------------------------------------------------------------------------------- /view/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a new AngularJS view 3 | 4 | Example: 5 | yo angular-cordova:view thing 6 | 7 | This will create: 8 | www/tpl/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 || 'www'; 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, 'tpl', this.name.toLowerCase() + '.html')); 23 | }; 24 | --------------------------------------------------------------------------------