├── .bowerrc ├── .gitignore ├── .jshintrc ├── README.md ├── bower.json ├── config.xml ├── gulpfile.js ├── hooks ├── README.md └── after_prepare │ └── 010_add_platform_class.js ├── ionic.config.json ├── package.json ├── scss └── ionic.app.scss ├── tests ├── .jshintrc ├── fixture │ └── .gitkeep ├── karma.conf.js └── spec │ ├── controllers │ └── .gitkeep │ ├── directives │ └── .gitkeep │ ├── example.js.dist │ ├── factories │ └── .gitkeep │ └── services │ └── .gitkeep └── www ├── index.html └── js └── app.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "www/vendor" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Specifies intentionally untracked files to ignore when using Git 2 | # http://git-scm.com/docs/gitignore 3 | 4 | node_modules/ 5 | platforms/ 6 | plugins/ 7 | www/vendor/ 8 | www/css/ionic.app.css 9 | www/css/ionic.app.min.css -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": false, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 4, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "undef": true, 16 | "unused": true, 17 | "strict": true, 18 | "trailing": true, 19 | "smarttabs": true, 20 | "globals": { 21 | "angular": false, 22 | "ionic": false 23 | } 24 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ionic App Base 2 | ===================== 3 | 4 | A starting project for Ionic that supports using custom SCSS with bulk file importing (globbing), Compass, wired dependencies using `wiredeps` so you don't have to include everything and Jasmine for scaffolding and running tests. 5 | 6 | ## Using this project 7 | 8 | We recommend reading the [Getting Started](http://ionicframework.com/getting-started) page in order to get familar with ionic and installing it's dependencies. 9 | 10 | You'll need to run 3 commands to get started: 11 | 12 | `npm install` - installs development dependencies 13 | 14 | `bower install` - installs all application dependencies 15 | 16 | `ionic state restore` - installs Cordova Plugins setup by default 17 | 18 | ### Adding Platforms 19 | You will still need to add platforms in the normal way. Using `ionic platform add ` 20 | 21 | ##Changes from the original ionic-app-base 22 | #### Renamed lib to vendor 23 | Renaming `lib` to `vendor` was an idealogical change, in most robust applications there will be an internal library that shares common code, particularly if you are building applications that include common feature sets. `Vendor` provides a more coherent relationship with external dependencies. 24 | 25 | #### Added Sass bulk imports 26 | If you use any form of structured CSS methodology such as [BEM](https://en.bem.info/) or [SMACSS](https://smacss.com) you'll no doubt use several `.scss` files and folders. Including these files can become cumbersome and if you forget to update your imports you can run into a number of errors. 27 | 28 | #### Remove splash screen spinner 29 | Cordova applications show a loading spinner on the splash screen, we've added `` to remove it by default. 30 | 31 | #### Included Compass into the `sass` block for gulp 32 | We like using [Compass](http://compass-style.org) it includes a wide range of helpful mixins and functions. 33 | 34 | #### Included [`Wiredep`](https://github.com/taptapship/wiredep) as part of the build process 35 | Manually adding dependencies to your `index.html` file can become tedious, so automatically wiring them up based on your `bower.json` just makes sense and saves a lot of time. 36 | 37 | #### We love tests 38 | Testing is good, we love tests. So including scaffolding and a test runner is essential, which is why we've added [Jasmine](http://jasmine.github.io/) to the build process. 39 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "HelloIonic", 3 | "private": "true", 4 | "devDependencies": { 5 | "ionic": "driftyco/ionic-bower", 6 | "angular-mocks": "~1.3.15" 7 | }, 8 | "dependencies": { 9 | "ngCordova": "~0.1.15-alpha" 10 | }, 11 | "resolutions": { 12 | "angular": "1.5.3" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | HelloCordova 4 | 5 | An Ionic Framework and Cordova project. 6 | 7 | 8 | Ionic Framework Team 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'); 2 | var karma = require('gulp-karma'); 3 | var gutil = require('gulp-util'); 4 | var bower = require('bower'); 5 | var concat = require('gulp-concat'); 6 | var sass = require('gulp-sass'); 7 | var minifyCss = require('gulp-minify-css'); 8 | var rename = require('gulp-rename'); 9 | var sh = require('shelljs'); 10 | var bulkSass = require('gulp-sass-bulk-import'); 11 | var wiredep = require('wiredep').stream; 12 | var templateCache = require('gulp-angular-templatecache'); 13 | 14 | var paths = { 15 | sass: ['./scss/**/*.scss'] 16 | }; 17 | 18 | gulp.task('default', ['sass', 'templates', 'bower']); 19 | 20 | gulp.task('sass', function (done) { 21 | gulp.src('./scss/ionic.app.scss') 22 | .pipe(bulkSass()) 23 | .pipe(sass({ 24 | compass: true, 25 | errLogToConsole: true 26 | })) 27 | .pipe(gulp.dest('./www/css/')) 28 | .pipe(minifyCss({ 29 | keepSpecialComments: 0 30 | })) 31 | .pipe(rename({extname: '.min.css'})) 32 | .pipe(gulp.dest('./www/css/')) 33 | .on('end', done); 34 | }); 35 | 36 | gulp.task('templates', function(){ 37 | return gulp.src('./www/views/**/*.html') 38 | // Create entries within $templateCache 39 | // Module uses ionic namespace as we can always guarantee it's existence within our application 40 | .pipe(templateCache('templates.js',{module: 'ionic', root:'views/'})) 41 | .pipe(gulp.dest('www/js')); 42 | }); 43 | 44 | gulp.task('test', function () { 45 | // Be sure to return the stream 46 | // NOTE: Using the fake './foobar' so as to run the files 47 | // listed in karma.conf.js INSTEAD of what was passed to 48 | // gulp.src ! 49 | return gulp.src('./foobar') 50 | .pipe(karma({ 51 | configFile: './tests/karma.conf.js', 52 | action: 'run' 53 | })) 54 | .on('error', function (err) { 55 | // Make sure failed tests cause gulp to exit non-zero 56 | console.log(err); 57 | this.emit('end'); //instead of erroring the stream, end it 58 | }); 59 | }); 60 | 61 | gulp.task('autotest', function () { 62 | return gulp.watch(['./www/js/**/*.js', './tests/spec/*.js'], ['test']); 63 | }); 64 | 65 | gulp.task('bump', require('gulp-cordova-bump')); 66 | 67 | gulp.task('watch', function () { 68 | gulp.watch(paths.sass, ['sass']); 69 | }); 70 | 71 | gulp.task('bower', function () { 72 | gulp.src('./www/index.html') 73 | .pipe(wiredep({ 74 | exclude: "www/vendor/angular/angular.js" 75 | })) 76 | .pipe(gulp.dest('./www')); 77 | 78 | gulp.src('./tests/karma.conf.js') 79 | .pipe(wiredep({ 80 | devDependencies: true 81 | })) 82 | .pipe(gulp.dest('./tests')); 83 | }); 84 | 85 | gulp.task('install', ['git-check'], function () { 86 | return bower.commands.install() 87 | .on('log', function (data) { 88 | gutil.log('bower', gutil.colors.cyan(data.id), data.message); 89 | }); 90 | }); 91 | 92 | gulp.task('git-check', function (done) { 93 | if (!sh.which('git')) { 94 | console.log( 95 | ' ' + gutil.colors.red('Git is not installed.'), 96 | '\n Git, the version control system, is required to download Ionic.', 97 | '\n Download git here:', gutil.colors.cyan('http://git-scm.com/downloads') + '.', 98 | '\n Once git is installed, run \'' + gutil.colors.cyan('gulp install') + '\' again.' 99 | ); 100 | process.exit(1); 101 | } 102 | done(); 103 | }); 104 | -------------------------------------------------------------------------------- /hooks/README.md: -------------------------------------------------------------------------------- 1 | 21 | # Cordova Hooks 22 | 23 | This directory may contain scripts used to customize cordova commands. This 24 | directory used to exist at `.cordova/hooks`, but has now been moved to the 25 | project root. Any scripts you add to these directories will be executed before 26 | and after the commands corresponding to the directory name. Useful for 27 | integrating your own build systems or integrating with version control systems. 28 | 29 | __Remember__: Make your scripts executable. 30 | 31 | ## Hook Directories 32 | The following subdirectories will be used for hooks: 33 | 34 | after_build/ 35 | after_compile/ 36 | after_docs/ 37 | after_emulate/ 38 | after_platform_add/ 39 | after_platform_rm/ 40 | after_platform_ls/ 41 | after_plugin_add/ 42 | after_plugin_ls/ 43 | after_plugin_rm/ 44 | after_plugin_search/ 45 | after_prepare/ 46 | after_run/ 47 | after_serve/ 48 | before_build/ 49 | before_compile/ 50 | before_docs/ 51 | before_emulate/ 52 | before_platform_add/ 53 | before_platform_rm/ 54 | before_platform_ls/ 55 | before_plugin_add/ 56 | before_plugin_ls/ 57 | before_plugin_rm/ 58 | before_plugin_search/ 59 | before_prepare/ 60 | before_run/ 61 | before_serve/ 62 | pre_package/ <-- Windows 8 and Windows Phone only. 63 | 64 | ## Script Interface 65 | 66 | All scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables: 67 | 68 | * CORDOVA_VERSION - The version of the Cordova-CLI. 69 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios). 70 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer) 71 | * CORDOVA_HOOK - Path to the hook that is being executed. 72 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate) 73 | 74 | If a script returns a non-zero exit code, then the parent cordova command will be aborted. 75 | 76 | 77 | ## Writing hooks 78 | 79 | We highly recommend writting your hooks using Node.js so that they are 80 | cross-platform. Some good examples are shown here: 81 | 82 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/) 83 | 84 | -------------------------------------------------------------------------------- /hooks/after_prepare/010_add_platform_class.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Add Platform Class 4 | // v1.0 5 | // Automatically adds the platform class to the body tag 6 | // after the `prepare` command. By placing the platform CSS classes 7 | // directly in the HTML built for the platform, it speeds up 8 | // rendering the correct layout/style for the specific platform 9 | // instead of waiting for the JS to figure out the correct classes. 10 | 11 | var fs = require('fs'); 12 | var path = require('path'); 13 | 14 | var rootdir = process.argv[2]; 15 | 16 | function addPlatformBodyTag(indexPath, platform) { 17 | // add the platform class to the body tag 18 | try { 19 | var platformClass = 'platform-' + platform; 20 | var cordovaClass = 'platform-cordova platform-webview'; 21 | 22 | var html = fs.readFileSync(indexPath, 'utf8'); 23 | 24 | var bodyTag = findBodyTag(html); 25 | if(!bodyTag) return; // no opening body tag, something's wrong 26 | 27 | if(bodyTag.indexOf(platformClass) > -1) return; // already added 28 | 29 | var newBodyTag = bodyTag; 30 | 31 | var classAttr = findClassAttr(bodyTag); 32 | if(classAttr) { 33 | // body tag has existing class attribute, add the classname 34 | var endingQuote = classAttr.substring(classAttr.length-1); 35 | var newClassAttr = classAttr.substring(0, classAttr.length-1); 36 | newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote; 37 | newBodyTag = bodyTag.replace(classAttr, newClassAttr); 38 | 39 | } else { 40 | // add class attribute to the body tag 41 | newBodyTag = bodyTag.replace('>', ' class="' + platformClass + ' ' + cordovaClass + '">'); 42 | } 43 | 44 | html = html.replace(bodyTag, newBodyTag); 45 | 46 | fs.writeFileSync(indexPath, html, 'utf8'); 47 | 48 | process.stdout.write('add to body class: ' + platformClass + '\n'); 49 | } catch(e) { 50 | process.stdout.write(e); 51 | } 52 | } 53 | 54 | function findBodyTag(html) { 55 | // get the body tag 56 | try{ 57 | return html.match(/])(.*?)>/gi)[0]; 58 | }catch(e){} 59 | } 60 | 61 | function findClassAttr(bodyTag) { 62 | // get the body tag's class attribute 63 | try{ 64 | return bodyTag.match(/ class=["|'](.*?)["|']/gi)[0]; 65 | }catch(e){} 66 | } 67 | 68 | if (rootdir) { 69 | 70 | // go through each of the platform directories that have been prepared 71 | var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []); 72 | 73 | for(var x=0; x 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |

Ionic Blank Starter

28 |
29 | 30 | 31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /www/js/app.js: -------------------------------------------------------------------------------- 1 | // Ionic Starter App 2 | 3 | // angular.module is a global place for creating, registering and retrieving Angular modules 4 | // 'starter' is the name of this angular module example (also set in a attribute in index.html) 5 | // the 2nd parameter is an array of 'requires' 6 | angular.module('starter', ['ionic', 'ngCordova']) 7 | 8 | .run(function ($ionicPlatform) { 9 | $ionicPlatform.ready(function () { 10 | // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard 11 | // for form inputs). 12 | // The reason we default this to hidden is that native apps don't usually show an accessory bar, at 13 | // least on iOS. It's a dead giveaway that an app is using a Web View. However, it's sometimes 14 | // useful especially with forms, though we would prefer giving the user a little more room 15 | // to interact with the app. 16 | if (window.cordova && window.cordova.plugins.Keyboard) { 17 | cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true); 18 | cordova.plugins.Keyboard.disableScroll(true); // Fixes issues with keyboard creating space whilst animating 19 | } 20 | if (window.StatusBar) { 21 | // Set the statusbar to use the default style, tweak this to 22 | // remove the status bar on iOS or change it to use white instead of dark colors. 23 | StatusBar.styleDefault(); 24 | } 25 | }); 26 | }); 27 | --------------------------------------------------------------------------------