├── .bowerrc
├── .gitignore
├── .jshintrc
├── Gruntfile.js
├── LICENSE
├── README.md
├── app
├── README.md
├── fonts
│ ├── FontAwesome.otf
│ ├── fontawesome-webfont.eot
│ ├── fontawesome-webfont.svg
│ ├── fontawesome-webfont.ttf
│ ├── fontawesome-webfont.woff
│ ├── fontawesome-webfont.woff2
│ ├── ionicons.eot
│ ├── ionicons.svg
│ ├── ionicons.ttf
│ └── ionicons.woff
├── images
│ ├── cards
│ │ ├── ben.png
│ │ ├── face-1.jpg
│ │ ├── face-2.jpg
│ │ ├── face-3.jpg
│ │ ├── face-4.jpg
│ │ ├── face-5.jpg
│ │ ├── face-6.jpg
│ │ ├── face-7.jpg
│ │ ├── max.jpg
│ │ └── perry.jpg
│ └── ionic.png
├── index.html
├── scripts
│ ├── app.js
│ ├── common
│ │ ├── common.module.js
│ │ ├── directives
│ │ │ └── gmaps
│ │ │ │ └── gmaps.directive.js
│ │ └── services
│ │ │ ├── extenal-apps.service.js
│ │ │ └── html-to-plain-text.service.js
│ ├── config
│ │ ├── internet-connectivity.js
│ │ └── spinner.js
│ ├── elements
│ │ ├── checkbox.html
│ │ ├── elements.controller.js
│ │ ├── elements.html
│ │ ├── elements.module.js
│ │ ├── form-floating-labels.html
│ │ ├── form-inline-labels.html
│ │ ├── form-input-icons.html
│ │ ├── form-inset-form.html
│ │ ├── form-inset-inputs.html
│ │ ├── form-placeholder-labels.html
│ │ ├── form-stacked-labels.html
│ │ ├── radiobuttons.html
│ │ ├── range.html
│ │ ├── select.html
│ │ ├── tabs-icononly.html
│ │ ├── tabs-lefticon.html
│ │ ├── tabs-striped.html
│ │ ├── tabs-topicon.html
│ │ └── toggle.html
│ ├── home
│ │ ├── home-data.service.js
│ │ ├── home.controller.js
│ │ ├── home.html
│ │ ├── home.module.js
│ │ └── menu-items.service.js
│ ├── map
│ │ ├── map.controller.js
│ │ ├── map.html
│ │ ├── map.module.js
│ │ └── map.service.js
│ ├── menu
│ │ ├── menu.controller.js
│ │ ├── menu.html
│ │ └── menu.module.js
│ ├── native-scrolling
│ │ ├── native-scrolling.controller.js
│ │ ├── native-scrolling.html
│ │ ├── native-scrolling.module.js
│ │ └── native-scrolling.service.js
│ ├── new-slide-box
│ │ ├── new-slide-box.controller.js
│ │ ├── new-slide-box.html
│ │ └── new-slide-box.module.js
│ ├── popover-menu
│ │ ├── popover-menu.controller.js
│ │ ├── popover-menu.html
│ │ ├── popover-menu.module.js
│ │ ├── popover-view.html
│ │ └── popover-view.service.js
│ └── wordpress
│ │ ├── wordpress-article.controller.js
│ │ ├── wordpress-article.html
│ │ ├── wordpress-articles.controller.js
│ │ ├── wordpress-articles.html
│ │ ├── wordpress.module.js
│ │ └── wordpress.service.js
└── styles
│ ├── common.scss
│ ├── home.scss
│ ├── main.scss
│ └── map.scss
├── bower.json
├── changelog.md
├── config.xml
├── hooks
├── README.md
├── after_platform_add
│ └── install_plugins.js
├── after_plugin_add
│ └── register_plugins.js
├── after_plugin_rm
│ └── deregister_plugins.js
├── after_prepare
│ ├── icons_and_splashscreens.js
│ └── update_platform_config.js
└── before_platform_add
│ └── init_directories.js
├── install.bat
├── install.sh
├── ionic.project
├── misc
├── faces.psd
└── menu-items
│ ├── item-01-1.jpg
│ ├── item-01-thumb.jpg
│ ├── item-02-1.jpg
│ ├── item-02-thumb.jpg
│ ├── item-03-1.jpg
│ ├── item-03-thumb.jpg
│ ├── item-04-1.jpg
│ ├── item-04-thumb.jpg
│ ├── item-05-1.jpg
│ ├── item-05-thumb.jpg
│ ├── item-06-1.jpg
│ ├── item-06-thumb.jpg
│ ├── item-07-1.jpg
│ ├── item-07-thumb.jpg
│ ├── item-08-1.jpg
│ ├── item-08-thumb.jpg
│ ├── item-09-1.jpg
│ ├── item-09-thumb.jpg
│ ├── item-10-1.jpg
│ ├── item-10-thumb.jpg
│ ├── item-11-1.jpg
│ ├── item-11-thumb.jpg
│ ├── item-12-1.jpg
│ ├── item-12-thumb.jpg
│ └── items.json
├── package.json
├── package.json.local
├── resources
├── android
│ ├── drawable-hdpi
│ │ ├── ic_action_next_item.png
│ │ ├── ic_action_previous_item.png
│ │ ├── ic_action_remove.png
│ │ └── icon.png
│ ├── drawable-land-hdpi
│ │ └── screen.png
│ ├── drawable-land-ldpi
│ │ └── screen.png
│ ├── drawable-land-mdpi
│ │ └── screen.png
│ ├── drawable-land-xhdpi
│ │ └── screen.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ ├── ic_action_next_item.png
│ │ ├── ic_action_previous_item.png
│ │ ├── ic_action_remove.png
│ │ └── icon.png
│ ├── drawable-port-hdpi
│ │ └── screen.png
│ ├── drawable-port-ldpi
│ │ └── screen.png
│ ├── drawable-port-mdpi
│ │ └── screen.png
│ ├── drawable-port-xhdpi
│ │ └── screen.png
│ ├── drawable-xhdpi
│ │ ├── ic_action_next_item.png
│ │ ├── ic_action_previous_item.png
│ │ ├── ic_action_remove.png
│ │ └── icon.png
│ ├── drawable-xxhdpi
│ │ ├── ic_action_next_item.png
│ │ ├── ic_action_previous_item.png
│ │ └── ic_action_remove.png
│ └── drawable
│ │ └── icon.png
└── ios
│ ├── icons
│ ├── icon-40.png
│ ├── icon-40@2x.png
│ ├── icon-50.png
│ ├── icon-50@2x.png
│ ├── icon-60.png
│ ├── icon-60@2x.png
│ ├── icon-60@3x.png
│ ├── icon-72.png
│ ├── icon-72@2x.png
│ ├── icon-76.png
│ ├── icon-76@2x.png
│ ├── icon-small.png
│ ├── icon-small@2x.png
│ ├── icon.png
│ └── icon@2x.png
│ └── splash
│ ├── Default-568h@2x~iphone.png
│ ├── Default-667h.png
│ ├── Default-736h.png
│ ├── Default-Landscape-736h.png
│ ├── Default-Landscape@2x~ipad.png
│ ├── Default-Landscape~ipad.png
│ ├── Default-Portrait@2x~ipad.png
│ ├── Default-Portrait~ipad.png
│ ├── Default@2x~iphone.png
│ └── Default~iphone.png
├── test
└── .jshintrc
└── typings
└── angularjs
└── angular.d.ts
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | www
3 | .idea
4 | .temp
5 | .sass-cache
6 | app/bower_components
7 | coverage
8 | platforms
9 | plugins
10 | *.swp
11 | *.swo
12 | *.log
13 | *.DS_Store
14 |
15 | app/scripts/configuration.js
16 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "bitwise": true,
3 | "camelcase": true,
4 | "curly": true,
5 | "eqeqeq": true,
6 | "es3": false,
7 | "forin": true,
8 | "freeze": true,
9 | "immed": true,
10 | "indent": 4,
11 | "latedef": "nofunc",
12 | "newcap": true,
13 | "noarg": true,
14 | "noempty": true,
15 | "nonbsp": true,
16 | "nonew": true,
17 | "plusplus": false,
18 | "quotmark": "single",
19 | "undef": true,
20 | "unused": false,
21 | "strict": false,
22 | "maxparams": 10,
23 | "maxdepth": 5,
24 | "maxstatements": 40,
25 | "maxcomplexity": 8,
26 | "maxlen": 120,
27 |
28 | "asi": false,
29 | "boss": false,
30 | "debug": false,
31 | "eqnull": true,
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 | "loopfunc": true,
42 | "maxerr": false,
43 | "moz": false,
44 | "multistr": false,
45 | "notypeof": false,
46 | "proto": false,
47 | "scripturl": false,
48 | "shadow": false,
49 | "sub": true,
50 | "supernew": false,
51 | "validthis": false,
52 | "noyield": false,
53 |
54 | "browser": true,
55 | "node": true,
56 |
57 | "globals": {
58 | "alert": false,
59 | "angular": false,
60 | "cordova": false,
61 | "StatusBar": false,
62 | "ionic": false
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | // Generated on 2015-05-01 using generator-ionic 0.7.3
2 | 'use strict';
3 |
4 | var _ = require('lodash');
5 | var path = require('path');
6 | var cordovaCli = require('cordova');
7 | var spawn = process.platform === 'win32' ? require('win-spawn') : require('child_process').spawn;
8 |
9 | module.exports = function(grunt) {
10 |
11 | // Load grunt tasks automatically
12 | require('load-grunt-tasks')(grunt);
13 |
14 | // Time how long tasks take. Can help when optimizing build times
15 | require('time-grunt')(grunt);
16 |
17 | // Define the configuration for all the tasks
18 | grunt.initConfig({
19 |
20 | // Project settings
21 | yeoman: {
22 | // configurable paths
23 | app: 'app',
24 | scripts: 'scripts',
25 | styles: 'styles',
26 | images: 'images',
27 | test: 'test',
28 | dist: 'www'
29 | },
30 |
31 | // Includes all js files into index.html
32 | includeSource: {
33 | options: {
34 | basePath: 'app',
35 | baseUrl: '',
36 | },
37 | server: {
38 | files: {
39 | '.temp/index.html': '<%= yeoman.app %>/index.html'
40 | }
41 | },
42 | dist: {
43 | files: {
44 | '<%= yeoman.dist %>/index.html': '<%= yeoman.app %>/index.html'
45 | }
46 | }
47 | },
48 |
49 | // Environment Variables for Angular App
50 | // This creates an Angular Module that can be injected via ENV
51 | // Add any desired constants to the ENV objects below.
52 | // https://github.com/diegonetto/generator-ionic/blob/master/docs/FAQ.md#how-do-i-add-constants
53 | ngconstant: {
54 | options: {
55 | space: ' ',
56 | wrap: '"use strict";\n\n {%= __ngModule %}',
57 | name: 'config',
58 | dest: '<%= yeoman.app %>/<%= yeoman.scripts %>/configuration.js'
59 | },
60 | development: {
61 | constants: {
62 | ENV: {
63 | name: 'development',
64 | apiEndpoint: 'http://dev.yoursite.com:10000/',
65 | youtubeKey: 'AIzaSyDael5MmCQa1GKQNKQYypmBeB08GATgSEo',
66 | ionicPrivateKey: 'a9265eaf15a20cc8516c770e8748aeed4891b28f453ce755', //'c63b22cd7330a4a9d5e526bfcd74891a59fd5c23d1d81239',
67 | ionicPublicKey: 'e30d4d540b8c75d1f167bbf242423c3fb23fe10275d1c016', //'04dee953a91ef3857f1c8a7cf4748ecee375848681f7e833',
68 | ionicAppId: '241b6d37', //'2113c758',
69 | gcmId: '228071472080',
70 | // https://developer.vimeo.com/api/authentication#single-user
71 | vimeoAccessToken: 'd995ffff0228beba7c9716c3ee0d4add',
72 | // https://developers.facebook.com/apps/
73 | facebookAppId: '785803021527033', //'927897987270774',
74 | // http://logicum.co/getting-a-facebook-page-permanent-access-token/
75 | facebookPermanentAccessToken: 'CAANL6xXrSHYBANNHhMUDugVZBHXfVQBMeWG6FmpYROWcOEmC2xze1BNiraZB87NCAZC3w08L7KhCBnhJItZCUzWCgBNzBjt0BkoV6qMoXjIZBjkWRTUGgZBR39OZAiP3DF76jufQ4hJ7xsdQc0l68vFAZAePdZCZAjkjTwaOeEZC22xi8ZAQYBqvNvYRgIfOZBzf4zRURHgrLtNazxzln8ZBkd9FZC7',
76 | facebookPage: 'apple.inc',
77 | // https://instagram.com/developer/
78 | instagramAppId: '2998ca20ed924ca3be22907c6ae77363', //'ab4ccebff87a46e789e231bed83685e4'
79 | firebaseUrl: 'barebone-ionic.firebaseio.com', //'https://barebone-chat.firebaseio.com/',
80 | iosUrl: 'com.titaniumtemplates.barebone-ionic',
81 | androidUrl: 'market://details?id=com.titaniumtemplates.barebone-ionic',
82 | usesUntilRatePrompt: 4,
83 | androidPublisherKey: 'ca-app-pub-3965039466794589/2790557649',
84 | //'ca-app-pub-5273644196186544/3459900111',
85 | iosPublisherKey: 'ca-app-pub-3965039466794589/2930158449',
86 | //'ca-app-pub-5273644196186544/3850179718'
87 | // http://excellencenodejsblog.com/cordova-ionic-google-oauth-login-for-your-mobile-app/
88 | googleAppId: '400671186930-m07eu77bm43tgr30p90k6b9e1qgsva4p.apps.googleusercontent.com',
89 | // http://devdactic.com/twitter-rest-api-angularjs/
90 | // Requesting a user’s email address requires your application to be whitelisted by Twitter
91 | // https://dev.twitter.com/rest/reference/get/account/verify_credentials
92 | twitterApiKey: 'wXRPbDKzyLXOy4etLq4fNqu8M',
93 | twitterApiSecret: '1Bi6DGM98yc9MToSLstGLFaB2tvHOLkBrBBYm8WWI2fTKl0gWX'
94 | }
95 | }
96 | },
97 | production: {
98 | constants: {
99 | ENV: {
100 | name: 'production',
101 | apiEndpoint: 'http://api.yoursite.com/',
102 | youtubeKey: ''
103 | }
104 | }
105 | }
106 | },
107 |
108 | // Watches files for changes and runs tasks based on the changed files
109 | watch: {
110 | bower: {
111 | files: ['bower.json'],
112 | tasks: ['wiredep', 'newer:copy:app']
113 | },
114 | html: {
115 | files: ['<%= yeoman.app %>/**/*.html'],
116 | tasks: ['newer:copy:app']
117 | },
118 | js: {
119 | files: ['<%= yeoman.app %>/<%= yeoman.scripts %>/**/*.js'],
120 | tasks: ['newer:copy:app', 'newer:jshint:all']
121 | },
122 | styles: {
123 | files: ['<%= yeoman.app %>/<%= yeoman.styles %>/**/*.css'],
124 | tasks: ['newer:copy:styles', 'autoprefixer', 'newer:copy:tmp']
125 | },
126 | gruntfile: {
127 | files: ['Gruntfile.js'],
128 | tasks: ['ngconstant:development', 'newer:copy:app']
129 | },
130 | includeSource: {
131 | files: ['<%= yeoman.app %>/index.html'],
132 | tasks: ['includeSource:server']
133 | },
134 | sass: {
135 | files: ['<%= yeoman.app %>/<%= yeoman.styles %>/**/*.scss'],
136 | tasks: ['sass:dist', 'newer:copy:styles', 'newer:copy:tmp']
137 | }
138 | },
139 |
140 | // The actual grunt server settings
141 | connect: {
142 | options: {
143 | port: 9000,
144 | // Change this to '0.0.0.0' to access the server from outside.
145 | hostname: 'localhost'
146 | },
147 | dist: {
148 | options: {
149 | base: '<%= yeoman.dist %>'
150 | }
151 | },
152 | coverage: {
153 | options: {
154 | port: 9002,
155 | open: true,
156 | base: ['coverage']
157 | }
158 | }
159 | },
160 |
161 | // Make sure code styles are up to par and there are no obvious mistakes
162 | jshint: {
163 | options: {
164 | jshintrc: '.jshintrc',
165 | reporter: require('jshint-stylish')
166 | },
167 | all: [
168 | 'Gruntfile.js',
169 | '<%= yeoman.app %>/<%= yeoman.scripts %>/**/*.js'
170 | ],
171 | test: {
172 | options: {
173 | jshintrc: 'test/.jshintrc'
174 | },
175 | src: ['test/unit/**/*.js']
176 | }
177 | },
178 |
179 | // Empties folders to start fresh
180 | clean: {
181 | dist: {
182 | files: [{
183 | dot: true,
184 | src: [
185 | '.temp',
186 | '<%= yeoman.dist %>/*',
187 | '!<%= yeoman.dist %>/.git*'
188 | ]
189 | }]
190 | },
191 | server: '.temp'
192 | },
193 |
194 | autoprefixer: {
195 | options: {
196 | browsers: ['last 1 version']
197 | },
198 | dist: {
199 | files: [{
200 | expand: true,
201 | cwd: '.temp/<%= yeoman.styles %>/',
202 | src: '{,*/}*.css',
203 | dest: '.temp/<%= yeoman.styles %>/'
204 | }]
205 | }
206 | },
207 |
208 | // Automatically inject Bower components into the app
209 | wiredep: {
210 | app: {
211 | src: ['<%= yeoman.app %>/index.html'],
212 | ignorePath: /\.\.\//,
213 | exclude: ['app/bower_components/ionic/release/css/ionic.css', /jquery/, /bower_components\/bootstrap/]
214 | }
215 | },
216 | sass: { // Task
217 | dist: { // Target
218 | options: { // Target options
219 | style: 'expanded'
220 | },
221 | files: { // Dictionary of files
222 | '.temp/<%= yeoman.styles %>/main.css': '<%= yeoman.app %>/<%= yeoman.styles %>/main.scss', // 'destination': 'source'
223 | }
224 | }
225 | },
226 |
227 | // Reads HTML for usemin blocks to enable smart builds that automatically
228 | // concat, minify and revision files. Creates configurations in memory so
229 | // additional tasks can operate on them
230 | useminPrepare: {
231 | html: '<%= yeoman.app %>/index.html',
232 | options: {
233 | dest: '<%= yeoman.dist %>',
234 | staging: '.temp',
235 | flow: {
236 | html: {
237 | steps: {
238 | js: ['concat', 'uglifyjs'],
239 | css: ['cssmin']
240 | },
241 | post: {}
242 | }
243 | }
244 | }
245 | },
246 |
247 | // Performs rewrites based on the useminPrepare configuration
248 | usemin: {
249 | html: ['<%= yeoman.dist %>/**/*.html'],
250 | css: ['<%= yeoman.dist %>/<%= yeoman.styles %>/**/*.css'],
251 | options: {
252 | assetsDirs: ['<%= yeoman.dist %>']
253 | }
254 | },
255 |
256 | // The following *-min tasks produce minified files in the dist folder
257 | cssmin: {
258 | options: {
259 | //root: '<%= yeoman.app %>',
260 | noRebase: true
261 | }
262 | },
263 | htmlmin: {
264 | dist: {
265 | options: {
266 | collapseWhitespace: true,
267 | collapseBooleanAttributes: true,
268 | removeCommentsFromCDATA: true,
269 | removeOptionalTags: true
270 | },
271 | files: [{
272 | expand: true,
273 | cwd: '<%= yeoman.dist %>',
274 | src: ['*.html', 'templates/**/*.html'],
275 | dest: '<%= yeoman.dist %>'
276 | }]
277 | }
278 | },
279 |
280 | // Copies remaining files to places other tasks can use
281 | copy: {
282 | dist: {
283 | files: [{
284 | expand: true,
285 | dot: true,
286 | cwd: '<%= yeoman.app %>',
287 | dest: '<%= yeoman.dist %>',
288 | src: [
289 | '<%= yeoman.images %>/**/*.{png,jpg,jpeg,gif,webp,svg}',
290 | '*.html',
291 | 'templates/**/*.html',
292 | 'fonts/*'
293 | ]
294 | }, {
295 | expand: true,
296 | cwd: '.temp/<%= yeoman.images %>',
297 | dest: '<%= yeoman.dist %>/<%= yeoman.images %>',
298 | src: ['generated/*']
299 | }]
300 | },
301 | styles: {
302 | expand: true,
303 | cwd: '<%= yeoman.app %>/<%= yeoman.styles %>',
304 | dest: '.temp/<%= yeoman.styles %>/',
305 | src: '{,*/}*.css'
306 | },
307 | fonts: {
308 | expand: true,
309 | cwd: 'app/bower_components/ionic/release/fonts/',
310 | dest: '<%= yeoman.app %>/fonts/',
311 | src: '*'
312 | },
313 | vendor: {
314 | expand: true,
315 | cwd: '<%= yeoman.app %>/vendor',
316 | dest: '.temp/<%= yeoman.styles %>/',
317 | src: '{,*/}*.css'
318 | },
319 | app: {
320 | expand: true,
321 | cwd: '<%= yeoman.app %>',
322 | dest: '<%= yeoman.dist %>/',
323 | src: [
324 | '**/*',
325 | '!**/*.scss',
326 | ]
327 | },
328 | tmp: {
329 | expand: true,
330 | cwd: '.temp',
331 | dest: '<%= yeoman.dist %>/',
332 | src: '**/*'
333 | },
334 | misc: {
335 | expand: true,
336 | cwd: 'misc',
337 | dest: '<%= yeoman.dist %>/misc',
338 | src: ['**/*', '!assets/**', '!**/*.jpg', '!**/*.psd']
339 | }
340 | },
341 |
342 | concurrent: {
343 | ionic: {
344 | tasks: [],
345 | options: {
346 | logConcurrentOutput: true
347 | }
348 | },
349 | server: [
350 | 'sass:dist',
351 | 'copy:styles',
352 | 'copy:vendor',
353 | 'copy:fonts',
354 | ],
355 | test: [
356 | 'sass:dist',
357 | 'copy:styles',
358 | 'copy:vendor',
359 | 'copy:fonts',
360 | ],
361 | dist: [
362 | 'sass:dist',
363 | 'copy:styles',
364 | 'copy:vendor',
365 | 'copy:fonts',
366 | ]
367 | },
368 |
369 | // By default, your `index.html`'s will take care of
370 | // minification. These next options are pre-configured if you do not wish
371 | // to use the Usemin blocks.
372 | // cssmin: {
373 | // dist: {
374 | // files: {
375 | // '<%= yeoman.dist %>/<%= yeoman.styles %>/main.css': [
376 | // '.temp/<%= yeoman.styles %>/**/*.css',
377 | // '<%= yeoman.app %>/<%= yeoman.styles %>/**/*.css'
378 | // ]
379 | // }
380 | // }
381 | // },
382 | // uglify: {
383 | // dist: {
384 | // files: {
385 | // '<%= yeoman.dist %>/<%= yeoman.scripts %>/scripts.js': [
386 | // '<%= yeoman.dist %>/<%= yeoman.scripts %>/scripts.js'
387 | // ]
388 | // }
389 | // }
390 | // },
391 | // concat: {
392 | // dist: {}
393 | // },
394 |
395 | // Test settings
396 | // These will override any config options in karma.conf.js if you create it.
397 | karma: {
398 | options: {
399 | basePath: '',
400 | frameworks: ['mocha', 'chai'],
401 | files: [
402 | '<%= yeoman.app %>/bower_components/angular/angular.js',
403 | '<%= yeoman.app %>/bower_components/angular-mocks/angular-mocks.js',
404 | '<%= yeoman.app %>/bower_components/angular-animate/angular-animate.js',
405 | '<%= yeoman.app %>/bower_components/angular-sanitize/angular-sanitize.js',
406 | '<%= yeoman.app %>/bower_components/angular-ui-router/release/angular-ui-router.js',
407 | '<%= yeoman.app %>/bower_components/ionic/release/js/ionic.js',
408 | '<%= yeoman.app %>/bower_components/ionic/release/js/ionic-angular.js',
409 | '<%= yeoman.app %>/<%= yeoman.scripts %>/**/*.js',
410 | '<%= yeoman.test %>/mock/**/*.js',
411 | '<%= yeoman.test %>/spec/**/*.js'
412 | ],
413 | autoWatch: false,
414 | reporters: ['dots', 'coverage'],
415 | port: 8080,
416 | singleRun: false,
417 | preprocessors: {
418 | // Update this if you change the yeoman config path
419 | '<%= yeoman.app %>/<%= yeoman.scripts %>/**/*.js': ['coverage']
420 | },
421 | coverageReporter: {
422 | reporters: [{
423 | type: 'html',
424 | dir: 'coverage/'
425 | }, {
426 | type: 'text-summary'
427 | }]
428 | }
429 | },
430 | unit: {
431 | // Change this to 'Chrome', 'Firefox', etc. Note that you will need
432 | // to install a karma launcher plugin for browsers other than Chrome.
433 | browsers: ['PhantomJS'],
434 | background: true
435 | },
436 | continuous: {
437 | browsers: ['PhantomJS'],
438 | singleRun: true,
439 | }
440 | },
441 |
442 | // ngAnnotate tries to make the code safe for minification automatically by
443 | // using the Angular long form for dependency injection.
444 | ngAnnotate: {
445 | dist: {
446 | files: [{
447 | expand: true,
448 | cwd: '.temp/concat/<%= yeoman.scripts %>',
449 | src: '*.js',
450 | dest: '.temp/concat/<%= yeoman.scripts %>'
451 | }]
452 | }
453 | }
454 |
455 | });
456 |
457 | // Register tasks for all Cordova commands
458 | _.functions(cordovaCli).forEach(function(name) {
459 | grunt.registerTask(name, function() {
460 | this.args.unshift(name.replace('cordova:', ''));
461 | // Handle URL's being split up by Grunt because of `:` characters
462 | if (_.contains(this.args, 'http') || _.contains(this.args, 'https')) {
463 | this.args = this.args.slice(0, -2).concat(_.last(this.args, 2).join(':'));
464 | }
465 | var done = this.async();
466 | var exec = process.platform === 'win32' ? 'cordova.cmd' : 'cordova';
467 | var cmd = path.resolve('./node_modules/cordova/bin', exec);
468 | var flags = process.argv.splice(3);
469 | var child = spawn(cmd, this.args.concat(flags));
470 | child.stdout.on('data', function(data) {
471 | grunt.log.writeln(data);
472 | });
473 | child.stderr.on('data', function(data) {
474 | grunt.log.error(data);
475 | });
476 | child.on('close', function(code) {
477 | code = code ? false : true;
478 | done(code);
479 | });
480 | });
481 | });
482 |
483 | // Since Apache Ripple serves assets directly out of their respective platform
484 | // directories, we watch all registered files and then copy all un-built assets
485 | // over to <%= yeoman.dist %>/. Last step is running cordova prepare so we can refresh the ripple
486 | // browser tab to see the changes. Technically ripple runs `cordova prepare` on browser
487 | // refreshes, but at this time you would need to re-run the emulator to see changes.
488 | grunt.registerTask('ripple', ['wiredep', 'newer:copy:app', 'ripple-emulator']);
489 | grunt.registerTask('ripple-emulator', function() {
490 | grunt.config.set('watch', {
491 | all: {
492 | files: _.flatten(_.pluck(grunt.config.get('watch'), 'files')),
493 | tasks: ['newer:copy:app', 'prepare']
494 | }
495 | });
496 |
497 | var cmd = path.resolve('./node_modules/ripple-emulator/bin', 'ripple');
498 | var child = spawn(cmd, ['emulate']);
499 | child.stdout.on('data', function(data) {
500 | grunt.log.writeln(data);
501 | });
502 | child.stderr.on('data', function(data) {
503 | grunt.log.error(data);
504 | });
505 | process.on('exit', function(code) {
506 | child.kill('SIGINT');
507 | process.exit(code);
508 | });
509 |
510 | return grunt.task.run(['watch']);
511 | });
512 |
513 | // Dynamically configure `karma` target of `watch` task so that
514 | // we don't have to run the karma test server as part of `grunt serve`
515 | grunt.registerTask('watch:karma', function() {
516 | var karma = {
517 | files: ['<%= yeoman.app %>/<%= yeoman.scripts %>/**/*.js', '<%= yeoman.test %>/spec/**/*.js'],
518 | tasks: ['newer:jshint:test', 'karma:unit:run']
519 | };
520 | grunt.config.set('watch', karma);
521 | return grunt.task.run(['watch']);
522 | });
523 |
524 | // Wrap ionic-cli commands
525 | grunt.registerTask('ionic', function() {
526 | var done = this.async();
527 | var script = path.resolve('./node_modules/ionic/bin/', 'ionic');
528 | var flags = process.argv.splice(3);
529 | var child = spawn(script, this.args.concat(flags), {
530 | stdio: 'inherit'
531 | });
532 | child.on('close', function(code) {
533 | code = code ? false : true;
534 | done(code);
535 | });
536 | });
537 |
538 | grunt.registerTask('test', [
539 | 'wiredep',
540 | 'clean',
541 | 'concurrent:test',
542 | 'autoprefixer',
543 | 'karma:unit:start',
544 | 'watch:karma'
545 | ]);
546 |
547 | grunt.registerTask('serve', function(target) {
548 | if (target === 'compress') {
549 | return grunt.task.run(['compress', 'ionic:serve']);
550 | }
551 |
552 | grunt.config('concurrent.ionic.tasks', ['ionic:serve', 'watch']);
553 | grunt.task.run(['wiredep', 'init', 'concurrent:ionic']);
554 | });
555 | grunt.registerTask('emulate', function() {
556 | grunt.config('concurrent.ionic.tasks', ['ionic:emulate:' + this.args.join(), 'watch']);
557 | return grunt.task.run(['init', 'concurrent:ionic']);
558 | });
559 | grunt.registerTask('run', function() {
560 | grunt.config('concurrent.ionic.tasks', ['ionic:run:' + this.args.join(), 'watch']);
561 | return grunt.task.run(['init', 'concurrent:ionic']);
562 | });
563 | grunt.registerTask('build', function() {
564 | return grunt.task.run(['init', 'ionic:build:' + this.args.join()]);
565 | });
566 |
567 | grunt.registerTask('init', [
568 | 'clean',
569 | 'includeSource:dist',
570 | 'ngconstant:development',
571 | 'wiredep',
572 | 'concurrent:server',
573 | 'autoprefixer',
574 | 'newer:copy:app',
575 | 'newer:copy:tmp',
576 | 'newer:copy:misc'
577 | ]);
578 |
579 |
580 | grunt.registerTask('compress', [
581 | 'clean',
582 | 'ngconstant:production',
583 | 'wiredep',
584 | 'useminPrepare',
585 | 'concurrent:dist',
586 | 'autoprefixer',
587 | 'concat',
588 | 'ngAnnotate',
589 | 'copy:dist',
590 | 'cssmin',
591 | 'uglify',
592 | 'usemin',
593 | 'htmlmin'
594 | ]);
595 |
596 | grunt.registerTask('coverage', ['karma:continuous',
597 | 'connect:coverage:keepalive'
598 | ]);
599 |
600 | grunt.registerTask('default', [
601 | 'wiredep',
602 | 'newer:jshint',
603 | 'karma:continuous',
604 | 'compress'
605 | ]);
606 | };
607 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Stavros Kounis
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Supermodular Ionic
3 | A super modular Ionic starter application.
4 |
5 | * Project's Home: https://github.com/skounis/supermodular
6 |
7 | > Are you interesting in **Ionic 2**?
8 | > * Check our [Supermodular 2](https://github.com/skounis/supermodular2) starter kit
9 |
10 | ## Dependecies, Run and Build
11 |
12 | ### Install NodeJS dependencies
13 |
14 | Run `npm install` to install all needed dependencies.
15 |
16 | ### Install Plugins and Javascript dependencies
17 | #### Linux/MacOX
18 | Run `./install.sh` to install all needed plugins and dependencies
19 |
20 | #### Windows Users
21 | Similarly, Windows users should run `install.bat`.
22 |
23 | ### Run the app
24 | Use `grunt serve -l` to run the app in browser and watch for changes in code
25 |
26 | or
27 |
28 | use `grunt serve` to just run the app for a browser preview
29 |
30 | or
31 |
32 | use `grunt serve --lab` to run the app in a browser on two platforms at the same time.
33 |
34 | ### Add a platform
35 |
36 | ```bash
37 | $ grunt platform:add:
38 | ```
39 |
40 | Supported Cordova platforms:
41 |
42 | ```bash
43 | $ grunt platform:add:ios
44 | $ grunt platform:add:android
45 | ```
46 |
47 | ### Build the app
48 |
49 | ```bash
50 | $ grunt build
51 | ```
52 |
53 | ### Εmulate the app on simulator
54 | iOS:
55 |
56 | ```bash
57 | $ grunt emulate:ios
58 | ```
59 |
60 | Android:
61 |
62 | ```bash
63 | $ grunt emulate:android
64 | ```
65 |
66 | For more information, see [Ionic Framework Generator's instructions](https://github.com/diegonetto/generator-ionic).
67 |
68 | ### Plugins installation
69 |
70 | Use the following commands and install all the plugins required by the app:
71 | ```bash
72 | $ cordova plugin add {plugin id or url}
73 | ```
74 |
75 | eg:
76 |
77 | ```bash
78 | cordova plugin add cordova-plugin-inappbrowser
79 | ```
80 |
81 | #### Used Cordova plugins
82 | In case that the required Cordova plugins are not installed while installing NodeJS dependencies, Cordova's command mentioned previously can be used to install the following plugins:
83 |
84 | * **cordova-plugin-device** - This plugin defines a global device object, which describes the device's hardware and software.
85 | * **cordova-plugin-console** - This plugin is meant to ensure that console.log() is as useful as it can be. It adds additional function for iOS, Ubuntu, Windows Phone 8, and Windows.
86 | * **com.ionic.keyboard** - It provides functions to make interacting with the keyboard easier, and fires events to indicate that the keyboard will hide/show.
87 | * **cordova-plugin-inappbrowser** - Provides a web browser view. It could be used to open images, access web pages, and open PDF files.
88 | * **cordova-plugin-geolocation** - Grab the current location of the user, or grab continuous location changes
89 | * **nl.x-services.plugins.socialsharing** - Share images, text, messages via Facebook, Twitter, Email, SMS, WhatsApp, etc using this plugin (https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git).
90 | * **de.appplant.cordova.plugin.email-composer** - The plugin provides access to the standard interface that manages the editing and sending an email message.
91 | * **cordova-plugin-network-information** - This plugin provides an implementation of an old version of the Network Information API. It provides information about the device's cellular and wifi connection, and whether the device has an internet connection.
92 | * **cordova-plugin-whitelist** - This plugin implements a whitelist policy for navigating the application webview on Cordova 4.0
93 | * **cordova-plugin-transport-security** - Cordova / PhoneGap Plugin to allow 'Arbitrary Loads' by adding a declaration to the Info.plist file to bypass the iOS 9 App Transport Security
94 |
95 | ## Branches naming convention
96 | Each branch is related to the Ionic framework version the source code is based on. Currently, there are the following branches:
97 | 1. `master`: Main development source code
98 | 2. `1.1-1.x`: Source code maintenance based on Ionic 1.1.x
99 |
100 | ## Credits
101 |
102 | * [Yeoman](http://yeoman.io/)
103 | * [Yeoman's Ionic Framework generator](https://github.com/diegonetto/generator-ionic)
104 |
105 | ## Third Party Licences
106 | * [Apache License](http://www.apache.org/licenses/)
107 | * [MIT License](https://opensource.org/licenses/MIT)
108 |
--------------------------------------------------------------------------------
/app/README.md:
--------------------------------------------------------------------------------
1 | This is an addon starter template for the [Ionic Framework](http://ionicframework.com/).
2 |
3 | ## How to use this template
4 |
5 | *This template does not work on its own*. It is missing the Ionic library, and AngularJS.
6 |
7 | To use this, either create a new ionic project using the ionic node.js utility, or copy and paste this into an existing Cordova project and download a release of Ionic separately.
8 |
9 | ### With the Ionic tool:
10 |
11 | Take the name after `ionic-starter-`, and that is the name of the template to be used when using the `ionic start` command below:
12 |
13 | ```bash
14 | $ sudo npm install -g ionic cordova
15 | $ ionic start myApp sidemenu
16 | ```
17 |
18 | Then, to run it, cd into `myApp` and run:
19 |
20 | ```bash
21 | $ ionic platform add ios
22 | $ ionic build ios
23 | $ ionic emulate ios
24 | ```
25 |
26 | Substitute ios for android if not on a Mac, but if you can, the ios development toolchain is a lot easier to work with until you need to do anything custom to Android.
27 |
28 | ## Demo
29 | http://plnkr.co/edit/0RXSDB?p=preview
30 |
31 | ## Issues
32 | Issues have been disabled on this repo, if you do find an issue or have a question consider posting it on the [Ionic Forum](http://forum.ionicframework.com/). Or else if there is truly an error, follow our guidelines for [submitting an issue](http://ionicframework.com/contribute/#issues) to the main Ionic repository. On the other hand, pull requests are welcome here!
33 |
--------------------------------------------------------------------------------
/app/fonts/FontAwesome.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/FontAwesome.otf
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/fontawesome-webfont.eot
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/fontawesome-webfont.ttf
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/fontawesome-webfont.woff
--------------------------------------------------------------------------------
/app/fonts/fontawesome-webfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/fontawesome-webfont.woff2
--------------------------------------------------------------------------------
/app/fonts/ionicons.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/ionicons.eot
--------------------------------------------------------------------------------
/app/fonts/ionicons.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/ionicons.ttf
--------------------------------------------------------------------------------
/app/fonts/ionicons.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/fonts/ionicons.woff
--------------------------------------------------------------------------------
/app/images/cards/ben.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/ben.png
--------------------------------------------------------------------------------
/app/images/cards/face-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-1.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-2.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-3.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-4.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-5.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-6.jpg
--------------------------------------------------------------------------------
/app/images/cards/face-7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/face-7.jpg
--------------------------------------------------------------------------------
/app/images/cards/max.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/max.jpg
--------------------------------------------------------------------------------
/app/images/cards/perry.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/cards/perry.jpg
--------------------------------------------------------------------------------
/app/images/ionic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/app/images/ionic.png
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/scripts/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 | // 'starter.controllers' is found in controllers.js
7 | angular.module('starter', [
8 | 'ionic',
9 | 'ionic.service.core',
10 | 'config',
11 | 'ionic.service.core',
12 | 'ionic.service.push',
13 | 'supermodular.common',
14 | 'supermodular.home',
15 | 'supermodular.map',
16 | 'supermodular.wordpress',
17 | 'supermodular.menu',
18 | 'supermodular.elements',
19 | 'supermodular.popover-menu',
20 | 'supermodular.native-scrolling',
21 | 'supermodular.new-slide-box',
22 | 'gMaps',
23 | 'ngCordova'
24 | ])
25 |
26 | .value('_', window._)
27 |
28 | .run(function($ionicPlatform) {
29 | $ionicPlatform.ready(function() {
30 | // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
31 | // for form inputs)
32 |
33 | if (window.cordova && window.cordova.plugins.Keyboard) {
34 | window.cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
35 | }
36 | if (window.StatusBar) {
37 | // org.apache.cordova.statusbar required
38 | StatusBar.styleDefault();
39 | }
40 | });
41 | })
42 |
43 | .config(function($urlRouterProvider, $compileProvider) {
44 | $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|blob|cdvfile|content):|data:image\//);
45 | // if none of the above states are matched, use this as the fallback
46 | $urlRouterProvider.otherwise('/app/home');
47 | });
48 |
--------------------------------------------------------------------------------
/app/scripts/common/common.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.common', ['ionic']);
6 | })();
7 |
--------------------------------------------------------------------------------
/app/scripts/common/directives/gmaps/gmaps.directive.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | angular.module('gMaps', [])
3 |
4 | /**
5 | * Handle Google Maps API V3+
6 | */
7 | // - Documentation: https://developers.google.com/maps/documentation/
8 | .directive('gmaps', function($window) {
9 |
10 | return {
11 | restrict: 'E',
12 | replace: true,
13 | template: '
',
14 | scope: {
15 | center: '=', // Center point on the map (e.g. { latitude: 10, longitude: 10 }
).
16 | markers: '=', // Array of map markers (e.g. [{ lat: 10, lon: 10, name: 'hello' }]
).
17 | width: '@', // Map width in pixels.
18 | height: '@', // Map height in pixels.
19 | zoom: '=', // Zoom level (one is totally zoomed out, 25 is very much zoomed in).
20 | mapTypeId: '@', // Type of tile to show on the map (roadmap, satellite, hybrid, terrain).
21 | panControl: '@', // Whether to show a pan control on the map.
22 | zoomControl: '@', // Whether to show a zoom control on the map.
23 | scaleControl: '@' // Whether to show scale control on the map.
24 | },
25 | link: function(scope, element, attrs) {
26 | var toResize, toCenter;
27 | var map;
28 | var infowindow;
29 | var currentMarkers;
30 | var callbackName = 'InitMapCb';
31 | var google;
32 |
33 | // callback when google maps is loaded
34 | $window[callbackName] = function() {
35 | google = window.google;
36 | console.log('map: init callback');
37 | createMap();
38 | updateMarkers();
39 | };
40 |
41 | if (!$window.google || !$window.google.maps) {
42 | console.log('map: not available - load now gmap js');
43 | loadGMaps();
44 | } else {
45 | console.log('map: IS available - create only map now');
46 | google = window.google;
47 | createMap();
48 | }
49 |
50 | function loadGMaps() {
51 | console.log('map: start loading js gmaps');
52 | var script = $window.document.createElement('script');
53 | script.type = 'text/javascript';
54 | script.src = 'http://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true&callback=InitMapCb';
55 | $window.document.body.appendChild(script);
56 | }
57 |
58 | function createMap() {
59 | console.log('map: create map start');
60 | var c = scope.center;
61 | var mapOptions = {
62 | zoom: scope.zoom || 10,
63 | center: new google.maps.LatLng(c.lat, c.lon),
64 | mapTypeId: google.maps.MapTypeId.ROADMAP,
65 | panControl: true,
66 | zoomControl: true,
67 | mapTypeControl: true,
68 | scaleControl: false,
69 | streetViewControl: false,
70 | navigationControl: true,
71 | disableDefaultUI: true,
72 | overviewMapControl: true
73 | };
74 | if (!(map instanceof google.maps.Map)) {
75 | console.log('map: create map now as not already available ');
76 | map = new google.maps.Map(element[0], mapOptions);
77 | // EDIT Added this and it works on android now
78 | // Stop the side bar from dragging when mousedown/tapdown on the map
79 | google.maps.event.addDomListener(element[0], 'mousedown', function(e) {
80 | e.preventDefault();
81 | return false;
82 | });
83 | infowindow = new google.maps.InfoWindow({
84 | disableAutoPan: true
85 | });
86 | }
87 | }
88 |
89 | scope.$watch('markers', function() {
90 | updateMarkers();
91 | });
92 |
93 | // Info window trigger function
94 | function onItemClick(pin, label) {
95 | // Create content
96 | var contentString = label;
97 | // Replace our Info Window's content and position
98 | infowindow.setContent(contentString);
99 | infowindow.setPosition(pin.position);
100 | infowindow.open(map);
101 | google.maps.event.addListener(infowindow, 'closeclick', function() {
102 | //console.log('map: info windows close listener triggered ');
103 | infowindow.close();
104 | });
105 | }
106 |
107 | function markerCb(marker, member, location) {
108 | return function() {
109 | //console.log('map: marker listener for ' + member.name);
110 | // var href = 'http://maps.apple.com/?q=' + member.lat + ',' + member.lon;
111 | // map.setCenter(location);
112 | onItemClick(marker, member.name);
113 | };
114 | }
115 |
116 | // update map markers to match scope marker collection
117 | function updateMarkers() {
118 | if (map && scope.markers) {
119 | // create new markers
120 | //console.log('map: make markers ');
121 | currentMarkers = [];
122 | var markers = scope.markers;
123 | if (angular.isString(markers)) {
124 | markers = scope.$eval(scope.markers);
125 | }
126 | for (var i = 0; i < markers.length; i++) {
127 | var m = markers[i];
128 | var loc = new google.maps.LatLng(m.lat, m.lon);
129 | var mm = new google.maps.Marker({
130 | position: loc,
131 | map: map,
132 | title: m.name
133 | });
134 | //console.log('map: make marker for ' + m.name);
135 | google.maps.event.addListener(mm, 'click', markerCb(mm, m, loc));
136 | currentMarkers.push(mm);
137 | }
138 | }
139 | }
140 |
141 | // convert current location to Google maps location
142 | function getLocation(loc) {
143 | if (loc == null) {
144 | return new google.maps.LatLng(40, -73);
145 | }
146 | if (angular.isString(loc)) {
147 | loc = scope.$eval(loc);
148 | }
149 | return new google.maps.LatLng(loc.lat, loc.lon);
150 | }
151 |
152 | } // end of link:
153 | }; // end of return
154 | });
155 |
--------------------------------------------------------------------------------
/app/scripts/common/services/extenal-apps.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.common')
6 | .factory('externalAppsService', externalAppsService);
7 |
8 | externalAppsService.$inject = ['$window'];
9 |
10 | /* @ngInject */
11 | function externalAppsService($window) {
12 | var service = {
13 | openMapsApp: openMapsApp,
14 | openExternalUrl: openExternalUrl
15 | };
16 | return service;
17 |
18 | // ******************************************************
19 |
20 | function openMapsApp(coords) {
21 | var q;
22 | if (ionic.Platform.isAndroid()) {
23 | q = 'geo:' + coords;
24 | } else {
25 | q = 'maps://maps.apple.com/?q=' + coords;
26 | }
27 | $window.location.href = q;
28 | }
29 |
30 | function openExternalUrl(url) {
31 | $window.open(url, '_system', 'location=yes');
32 | return false;
33 | }
34 | }
35 | })();
36 |
--------------------------------------------------------------------------------
/app/scripts/common/services/html-to-plain-text.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.common')
6 | .factory('htmlToPlainText', htmlToPlainText);
7 |
8 | htmlToPlainText.$inject = [];
9 |
10 | /* @ngInject */
11 | function htmlToPlainText() {
12 | return function(text) {
13 | return String(text).replace(/<[^>]+>/gm, '');
14 | };
15 | }
16 | })();
17 |
--------------------------------------------------------------------------------
/app/scripts/config/internet-connectivity.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('starter')
6 | .config(function($httpProvider) {
7 | $httpProvider.interceptors.push(function($cordovaNetwork, $q, $rootScope, $injector) {
8 | return {
9 | request: function(config) {
10 | if (!ionic.Platform.isReady) {
11 | return config;
12 | }
13 |
14 | if (config.url.indexOf('http') !== 0) {
15 | return config;
16 | }
17 |
18 | var isOnline = getNetworkStatus();
19 |
20 | if (isOnline) {
21 | return config;
22 | }
23 |
24 | var $ionicPopup = $injector.get('$ionicPopup');
25 | var alertPopup = $ionicPopup.alert({
26 | title: 'Alert',
27 | template: 'There is no internet connection'
28 | });
29 |
30 | return $q.reject('No internet connection');
31 | },
32 | response: function(response) {
33 | return response;
34 | }
35 | };
36 |
37 | function getNetworkStatus() {
38 |
39 | // On Android and when only the 3G interface is on
40 | // the return connection type is `unknown` even the device is online.
41 | // To work around this we will assume that only Connection.NONE
42 | // is declaring an offline device. Which is returned when data are
43 | // disabled.
44 |
45 | var isPluginAvailable = !!navigator.connection;
46 |
47 | if (isPluginAvailable) {
48 | var networkState = JSON.stringify(navigator.connection); //.type
49 | console.log('Internet connectivity chech. NetworkState: ' + networkState);
50 |
51 | // HACK: this is a temporary hack due to Android 3G related issue
52 | // described above.
53 | if (navigator.connection.type.toLowerCase() == 'unknown'){
54 | return true;
55 | }else {
56 | return $cordovaNetwork.isOnline();
57 | }
58 | }
59 |
60 | return navigator.onLine;
61 | }
62 | });
63 | });
64 | })();
65 |
--------------------------------------------------------------------------------
/app/scripts/config/spinner.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('starter')
6 | .config(function($httpProvider) {
7 | $httpProvider.interceptors.push(function($rootScope, $q) {
8 | return {
9 | request: function(config) {
10 | $rootScope.$broadcast('loading:show');
11 | return config;
12 | },
13 | response: function(response) {
14 | $rootScope.$broadcast('loading:hide');
15 | return response;
16 | },
17 | requestError: function(rejectReason) {
18 | $rootScope.$broadcast('loading:hide');
19 | return $q.reject(rejectReason);
20 | },
21 | responseError: function(rejectReason) {
22 | $rootScope.$broadcast('loading:hide');
23 | return $q.reject(rejectReason);
24 | }
25 | };
26 | });
27 | })
28 | .run(function($rootScope, $ionicLoading) {
29 | $rootScope.$on('loading:show', function() {
30 | $ionicLoading.show({});
31 | });
32 |
33 | $rootScope.$on('loading:hide', function() {
34 | $ionicLoading.hide();
35 | });
36 | });
37 | })();
--------------------------------------------------------------------------------
/app/scripts/elements/checkbox.html:
--------------------------------------------------------------------------------
1 |
2 |
38 |
39 |
--------------------------------------------------------------------------------
/app/scripts/elements/elements.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.elements')
6 | .controller('ElementsController', ElementsController);
7 |
8 | ElementsController.$inject = ['menuItems'];
9 |
10 | /* @ngInject */
11 | function ElementsController(menuItems) {
12 | var vm = angular.extend(this, {
13 | //TODO: add methods and properties to this controller
14 | });
15 |
16 | }
17 | })();
18 |
--------------------------------------------------------------------------------
/app/scripts/elements/elements.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/app/scripts/elements/elements.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.elements', [
6 | 'ionic',
7 | 'ngCordova'
8 | ])
9 | .config(function($stateProvider) {
10 | $stateProvider
11 | .state('app.elements', {
12 | url: '/elements',
13 | views: {
14 | 'menuContent': {
15 | templateUrl: 'scripts/elements/elements.html',
16 | controller: 'ElementsController as vm'
17 | }
18 | }
19 | })
20 | .state('app.elements-form-placeholder-labels', {
21 | url: '/elements-form-placeholder-labels',
22 | views: {
23 | 'menuContent': {
24 | templateUrl: 'scripts/elements/form-placeholder-labels.html'
25 | }
26 | }
27 | })
28 | .state('app.elements-form-inline-labels', {
29 | url: '/elements-form-inline-labels',
30 | views: {
31 | 'menuContent': {
32 | templateUrl: 'scripts/elements/form-inline-labels.html'
33 | }
34 | }
35 | })
36 | .state('app.elements-form-stacked-labels', {
37 | url: '/elements-form-stacked-labels',
38 | views: {
39 | 'menuContent': {
40 | templateUrl: 'scripts/elements/form-stacked-labels.html'
41 | }
42 | }
43 | })
44 | .state('app.elements-form-floating-labels', {
45 | url: '/elements-form-floating-labels',
46 | views: {
47 | 'menuContent': {
48 | templateUrl: 'scripts/elements/form-floating-labels.html'
49 | }
50 | }
51 | })
52 | .state('app.elements-form-inset-form', {
53 | url: '/elements-form-inset-form',
54 | views: {
55 | 'menuContent': {
56 | templateUrl: 'scripts/elements/form-inset-form.html'
57 | }
58 | }
59 | })
60 | .state('app.elements-form-inset-inputs', {
61 | url: '/elements-form-inset-inputs',
62 | views: {
63 | 'menuContent': {
64 | templateUrl: 'scripts/elements/form-inset-inputs.html'
65 | }
66 | }
67 | })
68 | .state('app.elements-form-input-icons', {
69 | url: '/elements-form-input-icons',
70 | views: {
71 | 'menuContent': {
72 | templateUrl: 'scripts/elements/form-input-icons.html'
73 | }
74 | }
75 | })
76 | .state('app.elements-toggle', {
77 | url: '/elements-toggle',
78 | views: {
79 | 'menuContent': {
80 | templateUrl: 'scripts/elements/toggle.html'
81 | }
82 | }
83 | })
84 | .state('app.elements-checkbox', {
85 | url: '/elements-checkbox',
86 | views: {
87 | 'menuContent': {
88 | templateUrl: 'scripts/elements/checkbox.html'
89 | }
90 | }
91 | })
92 | .state('app.elements-radiobuttons', {
93 | url: '/elements-radiobuttons',
94 | views: {
95 | 'menuContent': {
96 | templateUrl: 'scripts/elements/radiobuttons.html'
97 | }
98 | }
99 | })
100 | .state('app.elements-range', {
101 | url: '/elements-range',
102 | views: {
103 | 'menuContent': {
104 | templateUrl: 'scripts/elements/range.html'
105 | }
106 | }
107 | })
108 | .state('app.elements-select', {
109 | url: '/elements-select',
110 | views: {
111 | 'menuContent': {
112 | templateUrl: 'scripts/elements/select.html'
113 | }
114 | }
115 | })
116 | .state('app.elements-tabs-icononly', {
117 | url: '/elements-tabs-icononly',
118 | views: {
119 | 'menuContent': {
120 | templateUrl: 'scripts/elements/tabs-icononly.html'
121 | }
122 | }
123 | })
124 | .state('app.elements-tabs-topicon', {
125 | url: '/elements-tabs-topicon',
126 | views: {
127 | 'menuContent': {
128 | templateUrl: 'scripts/elements/tabs-topicon.html'
129 | }
130 | }
131 | })
132 | .state('app.elements-tabs-lefticon', {
133 | url: '/elements-tabs-lefticon',
134 | views: {
135 | 'menuContent': {
136 | templateUrl: 'scripts/elements/tabs-lefticon.html'
137 | }
138 | }
139 | })
140 | .state('app.elements-tabs-striped', {
141 | url: '/elements-tabs-striped',
142 | views: {
143 | 'menuContent': {
144 | templateUrl: 'scripts/elements/tabs-striped.html'
145 | }
146 | }
147 | });
148 | });
149 | })();
150 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-floating-labels.html:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-inline-labels.html:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-input-icons.html:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-inset-form.html:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-inset-inputs.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-placeholder-labels.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
--------------------------------------------------------------------------------
/app/scripts/elements/form-stacked-labels.html:
--------------------------------------------------------------------------------
1 |
2 |
21 |
22 |
--------------------------------------------------------------------------------
/app/scripts/elements/radiobuttons.html:
--------------------------------------------------------------------------------
1 |
2 |
57 |
58 |
--------------------------------------------------------------------------------
/app/scripts/elements/range.html:
--------------------------------------------------------------------------------
1 |
2 |
52 |
53 |
--------------------------------------------------------------------------------
/app/scripts/elements/select.html:
--------------------------------------------------------------------------------
1 |
2 |
68 |
69 |
--------------------------------------------------------------------------------
/app/scripts/elements/tabs-icononly.html:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
--------------------------------------------------------------------------------
/app/scripts/elements/tabs-lefticon.html:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
--------------------------------------------------------------------------------
/app/scripts/elements/tabs-striped.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
19 |
35 |
36 |
--------------------------------------------------------------------------------
/app/scripts/elements/tabs-topicon.html:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
--------------------------------------------------------------------------------
/app/scripts/elements/toggle.html:
--------------------------------------------------------------------------------
1 |
2 |
71 |
72 |
--------------------------------------------------------------------------------
/app/scripts/home/home-data.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.home')
6 | .factory('homeDataService', homeDataService);
7 |
8 | homeDataService.$inject = [];
9 |
10 | /* @ngInject */
11 | function homeDataService() {
12 | return {
13 | phoneNumber: '+306973216110',
14 | email: 'skounis@gmail.com',
15 | officeLocation: '37.7736854,-122.421034',
16 | facebookPage: 'https://www.facebook.com/ionicframework'
17 | };
18 | }
19 | })();
20 |
--------------------------------------------------------------------------------
/app/scripts/home/home.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.home')
6 | .controller('HomeController', HomeController);
7 |
8 | HomeController.$inject = ['menuItems', 'homeDataService', 'externalAppsService', '$cordovaEmailComposer'];
9 |
10 | /* @ngInject */
11 | function HomeController(menuItems, homeDataService, externalAppsService, $cordovaEmailComposer) {
12 | var vm = angular.extend(this, {
13 | entries: menuItems,
14 | phoneNumber: homeDataService.phoneNumber,
15 | getDirections: getDirections,
16 | sendEmail: sendEmail,
17 | openFacebookPage: openFacebookPage
18 | });
19 |
20 | function getDirections() {
21 | externalAppsService.openMapsApp(homeDataService.officeLocation);
22 | }
23 |
24 | function sendEmail() {
25 | $cordovaEmailComposer.isAvailable().then(function() {
26 | var email = {
27 | to: homeDataService.email,
28 | subject: 'Cordova Icons',
29 | body: 'How are you? Nice greetings from Leipzig'
30 | };
31 |
32 | $cordovaEmailComposer.open(email);
33 | });
34 | }
35 |
36 | function openFacebookPage() {
37 | externalAppsService.openExternalUrl(homeDataService.facebookPage);
38 | }
39 |
40 | }
41 | })();
42 |
--------------------------------------------------------------------------------
/app/scripts/home/home.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
ABC Corp Inc.
7 | 50 Market Street, San Francisco, California 94103, United States
8 |
9 |
10 |
11 |
15 |
16 |
17 |
23 |
24 |
30 |
31 |
32 |
33 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/app/scripts/home/home.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.home', [
6 | 'ionic',
7 | 'ngCordova',
8 | 'supermodular.common'
9 | ])
10 | .config(function($stateProvider) {
11 | $stateProvider
12 | .state('app.home', {
13 | url: '/home',
14 | views: {
15 | 'menuContent': {
16 | templateUrl: 'scripts/home/home.html',
17 | controller: 'HomeController as vm'
18 | }
19 | }
20 | });
21 | });
22 | })();
23 |
--------------------------------------------------------------------------------
/app/scripts/home/menu-items.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.home')
6 | .factory('menuItems', menuItems);
7 |
8 | menuItems.$inject = [];
9 |
10 | /* @ngInject */
11 | function menuItems() {
12 | var data = [{
13 | title: 'PopOver menu',
14 | path: 'popover-menu',
15 | icon: 'ion-ios-arrow-down'
16 | }, {
17 | title: 'Wordpress',
18 | path: 'wordpress-articles',
19 | icon: 'ion-social-wordpress'
20 | }, {
21 | title: 'Elements',
22 | path: 'elements',
23 | icon: 'ion-android-checkbox-outline'
24 | }, {
25 | title: 'Map',
26 | path: 'map',
27 | icon: 'ion-map'
28 | }];
29 |
30 | return data;
31 | }
32 | })();
33 |
--------------------------------------------------------------------------------
/app/scripts/map/map.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.map')
6 | .controller('MapController', MapController);
7 |
8 | MapController.$inject = ['$scope', 'mapService'];
9 |
10 | /* @ngInject */
11 | function MapController($scope, mapService) {
12 | var vm = angular.extend(this, {
13 | origin: {
14 | lat: mapService.origin.latitude,
15 | lon: mapService.origin.longitude
16 | },
17 | zoom: mapService.zoomLevel,
18 | markers: []
19 | });
20 |
21 | var markers = [];
22 | for (var i = 0; i < mapService.annotations.length; i++) {
23 | var annotation = mapService.annotations[i];
24 | markers.push({
25 | name: annotation.title,
26 | lat: annotation.latitude,
27 | lon: annotation.longitude
28 | });
29 | }
30 | vm.markers = markers;
31 | }
32 | })();
33 |
--------------------------------------------------------------------------------
/app/scripts/map/map.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/scripts/map/map.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.map', [
6 | 'ionic'
7 | ])
8 | .config(function($stateProvider) {
9 | $stateProvider
10 |
11 | .state('app.map', {
12 | url: '/map',
13 | views: {
14 | 'menuContent': {
15 | templateUrl: 'scripts/map/map.html',
16 | controller: 'MapController as vm'
17 | }
18 | }
19 | });
20 | });
21 | })();
22 |
--------------------------------------------------------------------------------
/app/scripts/map/map.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.map')
6 | .factory('mapService', mapService);
7 |
8 | mapService.$inject = [];
9 |
10 | /* @ngInject */
11 | function mapService() {
12 | var data = {
13 | origin: {
14 | latitude : 37.407,
15 | longitude : -122.1
16 | },
17 | zoomLevel: 15,
18 | annotations : [{
19 | title : 'Molestie et wisi.',
20 | latitude : 37.407,
21 | longitude : -122.1
22 | }, {
23 | title : 'Ullamcorper eros.',
24 | latitude : 37.41,
25 | longitude : -122.1
26 | }]
27 | };
28 | return data;
29 | }
30 | })();
31 |
--------------------------------------------------------------------------------
/app/scripts/menu/menu.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.menu')
6 | .controller('MenuController', MenuController);
7 |
8 | MenuController.$inject = [];
9 |
10 | /* @ngInject */
11 | function MenuController() {
12 |
13 | }
14 | })();
15 |
--------------------------------------------------------------------------------
/app/scripts/menu/menu.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Left
19 |
20 |
21 |
22 |
23 |
24 | Home
25 |
26 |
27 |
28 | PopOver menu
29 |
30 |
31 |
32 | Wordpress
33 |
34 |
35 |
36 | Elements
37 |
38 |
39 |
40 | Native scrolling
41 |
42 |
43 |
44 | New slide box
45 |
46 |
47 |
48 | Map
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/app/scripts/menu/menu.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.menu', [
6 | 'ionic'
7 | ])
8 | .config(function($stateProvider) {
9 | $stateProvider
10 | .state('app', {
11 | url: '/app',
12 | abstract: true,
13 | templateUrl: 'scripts/menu/menu.html',
14 | controller: 'MenuController as vm'
15 | });
16 | });
17 | })();
18 |
--------------------------------------------------------------------------------
/app/scripts/native-scrolling/native-scrolling.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.native-scrolling')
6 | .controller('NativeScrollingController', NativeScrollingController);
7 |
8 | NativeScrollingController.$inject = ['nativeScrollingService'];
9 |
10 | /* @ngInject */
11 | function NativeScrollingController(nativeScrollingService) {
12 | var vm = angular.extend(this, {
13 | items: []
14 | });
15 |
16 | (function activate() {
17 | getItems();
18 | })();
19 |
20 | // ********************************************************************
21 |
22 | function getItems() {
23 | nativeScrollingService.getItems(200)
24 | .then(function(items) {
25 | vm.items = items;
26 | });
27 | }
28 | }
29 | })();
30 |
--------------------------------------------------------------------------------
/app/scripts/native-scrolling/native-scrolling.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{item}}
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/scripts/native-scrolling/native-scrolling.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.native-scrolling', [
6 | 'ionic',
7 | 'supermodular.common'
8 | ])
9 | .config(function($stateProvider) {
10 | $stateProvider
11 | .state('app.native-scrolling', {
12 | url: '/native-scrolling',
13 | views: {
14 | 'menuContent': {
15 | templateUrl: 'scripts/native-scrolling/native-scrolling.html',
16 | controller: 'NativeScrollingController as vm'
17 | }
18 | }
19 | });
20 | });
21 | })();
22 |
--------------------------------------------------------------------------------
/app/scripts/native-scrolling/native-scrolling.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.native-scrolling')
6 | .factory('nativeScrollingService', nativeScrollingService);
7 |
8 | nativeScrollingService.$inject = ['$q'];
9 |
10 | /* @ngInject */
11 | function nativeScrollingService($q) {
12 | var service = {
13 | getItems: getItems
14 | };
15 | return service;
16 |
17 | // *************************************************************************
18 |
19 | function getItems(numberOfItems) {
20 | var items = [];
21 | for (var i = 0;i < numberOfItems;i++) {
22 | items.push('Item #' + (i + 1));
23 | }
24 | return $q.when(items);
25 | }
26 | }
27 | })();
28 |
--------------------------------------------------------------------------------
/app/scripts/new-slide-box/new-slide-box.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.new-slide-box')
6 | .controller('NewSlideBoxController', NewSlideBoxController);
7 |
8 | NewSlideBoxController.$inject = [];
9 |
10 | /* @ngInject */
11 | function NewSlideBoxController() {
12 | var vm = angular.extend(this, {
13 | items: getItems(),
14 | options: {
15 | loop: true
16 | }
17 | });
18 |
19 | // ********************************************************************
20 |
21 | function getItems() {
22 | var items = [];
23 | for (var i = 1;i <= 7;i++) {
24 | //
25 | // Local stored images
26 | //
27 | // items.push({
28 | // image: 'images/cards/face-' + i + '.jpg'
29 | // });
30 | //
31 | // Online images
32 | //
33 | items.push({
34 | image: 'http://lorempixel.com/786/1024/nightlife/' + i + '/'
35 | });
36 | }
37 | return items;
38 | }
39 | }
40 | })();
41 |
--------------------------------------------------------------------------------
/app/scripts/new-slide-box/new-slide-box.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/scripts/new-slide-box/new-slide-box.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.new-slide-box', [
6 | 'ionic',
7 | 'supermodular.common'
8 | ])
9 | .config(function($stateProvider) {
10 | $stateProvider
11 | .state('app.new-slide-box', {
12 | url: '/new-slide-box',
13 | views: {
14 | 'menuContent': {
15 | templateUrl: 'scripts/new-slide-box/new-slide-box.html',
16 | controller: 'NewSlideBoxController as vm'
17 | }
18 | }
19 | });
20 | });
21 | })();
22 |
--------------------------------------------------------------------------------
/app/scripts/popover-menu/popover-menu.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.popover-menu')
6 | .controller('PopoverMenuController', PopoverMenuController);
7 |
8 | PopoverMenuController.$inject = ['popoverViewService'];
9 |
10 | /* @ngInject */
11 | function PopoverMenuController(popoverViewService) {
12 | var vm = angular.extend(this, {
13 | showPopover: showPopover
14 | });
15 |
16 | (function activate() {
17 | })();
18 |
19 | // ********************************************************************
20 |
21 | function showPopover(event) {
22 | popoverViewService.show(event).then(function(option) {
23 | alert('You have selected option \'' + option + '\'');
24 | });
25 | }
26 | }
27 | })();
28 |
--------------------------------------------------------------------------------
/app/scripts/popover-menu/popover-menu.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iusto molestias libero beatae aliquam hic illo minus, vel quo fugiat rem, fugit eaque officia pariatur deleniti temporibus accusantium a dolorum quidem.
9 |
10 |
11 |
--------------------------------------------------------------------------------
/app/scripts/popover-menu/popover-menu.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.popover-menu', [
6 | 'ionic'
7 | ])
8 | .config(function($stateProvider) {
9 | $stateProvider
10 | .state('app.popover-menu', {
11 | url: '/popover-menu',
12 | views: {
13 | 'menuContent': {
14 | templateUrl: 'scripts/popover-menu/popover-menu.html',
15 | controller: 'PopoverMenuController as vm'
16 | }
17 | }
18 | });
19 | });
20 | })();
21 |
--------------------------------------------------------------------------------
/app/scripts/popover-menu/popover-view.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | Select an option
4 |
5 |
6 |
7 |
8 | {{option}}
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/scripts/popover-menu/popover-view.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.popover-menu')
6 | .factory('popoverViewService', popoverViewService);
7 |
8 | popoverViewService.$inject = ['$rootScope', '$ionicPopover', '$q'];
9 |
10 | /* @ngInject */
11 | function popoverViewService($rootScope, $ionicPopover, $q) {
12 | var scope = createPopover();
13 | var service = {
14 | show: show
15 | };
16 | return service;
17 |
18 | // ***************************************************
19 |
20 | function show(event) {
21 | var defer = $q.defer();
22 |
23 | scope.select = function(option) {
24 | defer.resolve(option);
25 | scope.popover.hide();
26 | }
27 |
28 | scope.popover.show(event);
29 | return defer.promise;
30 | }
31 |
32 | function createPopover() {
33 | var scope = $rootScope.$new();
34 | scope.options = ['Red', 'Green', 'Blue', 'White'];
35 |
36 | $ionicPopover.fromTemplateUrl('scripts/popover-menu/popover-view.html', {
37 | scope: scope
38 | }).then(function(popover) {
39 | scope.popover = popover;
40 | });
41 |
42 | return scope;
43 | }
44 | }
45 | })();
46 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress-article.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.wordpress')
6 | .controller('WordpressArticleController', WordpressArticleController);
7 |
8 | WordpressArticleController.$inject = [
9 | '$stateParams', '$ionicActionSheet', '$cordovaSocialSharing', 'wordpressService'];
10 |
11 | /* @ngInject */
12 | function WordpressArticleController($stateParams, $ionicActionSheet, $cordovaSocialSharing, wordpressService) {
13 | var articleId = parseInt($stateParams.articleId, 10);
14 |
15 | var vm = angular.extend(this, {
16 | article: null,
17 | share: share
18 | });
19 |
20 | function activate() {
21 | loadArticle();
22 | }
23 | activate();
24 |
25 | // ********************************************************************
26 |
27 | function share() {
28 | $ionicActionSheet.show({
29 | buttons: [
30 | { text: 'Facebook' },
31 | { text: 'Twitter' },
32 | { text: 'Email' },
33 | { text: 'Share' }
34 | ],
35 | titleText: 'Share',
36 | cancelText: 'Cancel',
37 | buttonClicked: function(index) {
38 | switch(index) {
39 | case 0:
40 | shareToFacebook();
41 | break;
42 | case 1:
43 | shareToTwitter();
44 | break;
45 | case 2:
46 | shareViaEmail();
47 | break;
48 | case 3:
49 | shareNative();
50 | break;
51 | }
52 | return true;
53 | }
54 | });
55 | }
56 |
57 | function shareNative() {
58 | var message = vm.article.title;
59 | var subject = vm.article.title;
60 |
61 | $cordovaSocialSharing
62 | .share(message, subject, null, vm.article.url);
63 | }
64 |
65 | function shareToFacebook() {
66 | var message = vm.article.title;
67 | var image = vm.article.image;
68 | var link = vm.article.url;
69 |
70 | $cordovaSocialSharing
71 | .shareViaFacebook(message, image, link);
72 | }
73 |
74 | function shareToTwitter() {
75 | var message = vm.article.title + ' ' + vm.article.url;
76 | var image = vm.article.image;
77 | var link = vm.article.url;
78 |
79 | $cordovaSocialSharing
80 | .shareViaTwitter(message, image, link);
81 | }
82 |
83 | function shareViaEmail() {
84 | var message = 'Read more about "' + vm.article.title + '" ' + vm.article.url;
85 | var subject = vm.article.title;
86 |
87 | $cordovaSocialSharing
88 | .shareViaEmail(message, subject, [], [], [], null);
89 | }
90 |
91 | function loadArticle() {
92 | wordpressService.getArticle(articleId)
93 | .then(function(article) {
94 | vm.article = article;
95 | });
96 | }
97 | }
98 | })();
99 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress-article.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
{{vm.article.title}}
10 |
11 |
{{vm.article.author}} - {{vm.article.date}}
12 |
[{{vm.article.tags.join(", ")}}]
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress-articles.controller.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.wordpress')
6 | .controller('WordpressArticlesController', WordpressArticlesController);
7 |
8 | WordpressArticlesController.$inject = ['$state', 'wordpressService'];
9 |
10 | /* @ngInject */
11 | function WordpressArticlesController($state, wordpressService) {
12 | var vm = angular.extend(this, {
13 | articles: [],
14 | navigate: navigate
15 | });
16 |
17 | function activate() {
18 | getArticles();
19 | }
20 | activate();
21 |
22 | // ********************************************************************
23 |
24 | function getArticles() {
25 | wordpressService.getArticles()
26 | .then(function(articles) {
27 | vm.articles = articles;
28 | });
29 | }
30 |
31 | function navigate(articleId) {
32 | $state.go('app.wordpress-article', { articleId: articleId });
33 | }
34 | }
35 | })();
36 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress-articles.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{article.title}}
8 |
{{article.brief | limitTo: 120 }}{{article.brief.length > 120 ? '...' : ''}}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress.module.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.wordpress', [
6 | 'ionic',
7 | 'supermodular.common'
8 | ])
9 | .config(function($stateProvider) {
10 | $stateProvider
11 | .state('app.wordpress-articles', {
12 | url: '/wordpress-articles',
13 | views: {
14 | 'menuContent': {
15 | templateUrl: 'scripts/wordpress/wordpress-articles.html',
16 | controller: 'WordpressArticlesController as vm'
17 | }
18 | }
19 | })
20 | .state('app.wordpress-article', {
21 | url: '/wordpress-articles/:articleId',
22 | views: {
23 | 'menuContent': {
24 | templateUrl: 'scripts/wordpress/wordpress-article.html',
25 | controller: 'WordpressArticleController as vm'
26 | }
27 | }
28 | });
29 | });
30 | })();
31 |
--------------------------------------------------------------------------------
/app/scripts/wordpress/wordpress.service.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | 'use strict';
3 |
4 | angular
5 | .module('supermodular.wordpress')
6 | .factory('wordpressService', wordpressService);
7 |
8 | wordpressService.$inject = ['$http', '$q', '_', 'htmlToPlainText'];
9 |
10 | /* @ngInject */
11 | function wordpressService($http, $q, _, htmlToPlainText) {
12 | var url = 'http://demo.titaniumtemplates.com/wordpress/?json=1';
13 | var articles = [];
14 |
15 | var service = {
16 | getArticles: getArticles,
17 | getArticle: getArticle
18 | };
19 | return service;
20 |
21 | ////////////////
22 |
23 | function getArticles() {
24 | return $http.get(url)
25 | .then(function(response) {
26 | articles = [];
27 | _.each(response.data.posts, function(item) {
28 | var imageUrl = item.attachments.length > 0 ? item.attachments[0].images.full.url : null;
29 | var tags = [];
30 | _.each(item.tags, function(tag) {
31 | tags.push(tag.title);
32 | });
33 |
34 | var contentIndex = item.content.indexOf('
') + 4;
35 | var content = contentIndex === -1 ? item.content : item.content.substring(contentIndex);
36 |
37 | articles.push({
38 | id: item.id,
39 | title: item.title,
40 | brief: htmlToPlainText(item.excerpt),
41 | image: imageUrl,
42 | date: item.date,
43 | content: content,
44 | author: item.author.name,
45 | tags: tags,
46 | url: url
47 | });
48 | });
49 | return articles;
50 | });
51 | }
52 |
53 | function getArticle(articleId) {
54 | if (articles.length) {
55 | return $q.when(_.find(articles, 'id', articleId));
56 | } else {
57 | var deferred = $q.defer();
58 |
59 | getArticles()
60 | .then(function() {
61 | deferred.resolve(_.find(articles, 'id', articleId));
62 | });
63 |
64 | return deferred.promise;
65 | }
66 | }
67 | }
68 | })();
69 |
--------------------------------------------------------------------------------
/app/styles/common.scss:
--------------------------------------------------------------------------------
1 | /* Empty. Add your own CSS if you like */
2 | img {max-width: 100%;}
3 |
4 | .content-inner{padding: 16px;}
5 |
6 | .card.col{padding: 0;}
7 |
8 | /*
9 | * Android. Action sheet
10 | */
11 | .platform-android .action-sheet .button {
12 | padding-left: 16px;
13 | }
14 |
15 | .has-extended-footer {
16 | bottom: $extended-footer-height;
17 | }
18 |
19 | .extended-footer {
20 | height: $extended-footer-height;
21 | .subtitle {
22 | text-align: center;
23 | width: 100%;
24 | position: absolute;
25 | bottom: 10px;
26 | left: -5px;
27 | }
28 | }
29 |
30 | .item-icon-left-extended {
31 | padding-left: 80px;
32 | .icon {
33 | left: 20px;
34 | font-size: 50px;
35 | }
36 | }
37 |
38 | .error-message {
39 | color: orangered !important;
40 | }
--------------------------------------------------------------------------------
/app/styles/home.scss:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Home
4 | */
5 | .home-hello{
6 | position:relative;
7 | }
8 |
9 | .home img{
10 | display: inherit;
11 | }
12 |
13 | .home-hello .item{
14 | position: absolute;
15 | left: 0;
16 | right: 0;
17 | bottom: 0;
18 | margin: 0;
19 | border: 0;
20 | background: rgba(255,255,255, 0.6);
21 | }
22 |
23 | .card.col.home h1{text-align: center;}
24 | .card.col.home h2{text-align: center;}
25 |
--------------------------------------------------------------------------------
/app/styles/main.scss:
--------------------------------------------------------------------------------
1 | /*
2 | To customize the look and feel of Ionic, you can override the variables
3 | in ionic's _variables.scss file.
4 |
5 | For example, you might change some of the default colors:
6 |
7 | $light: #fff !default;
8 | $stable: #f8f8f8 !default;
9 | $positive: #387ef5 !default;
10 | $calm: #11c1f3 !default;
11 | $balanced: #33cd5f !default;
12 | $energized: #ffc900 !default;
13 | $assertive: #ef473a !default;
14 | $royal: #886aea !default;
15 | $dark: #444 !default;
16 | */
17 |
18 | // The path for our ionicons font files, relative to the built CSS in www/css
19 | $ionicons-font-path: "../fonts" !default;
20 |
21 | $extended-footer-height: 70px;
22 |
23 | // Include all of Ionic
24 | @import "../bower_components/ionic/scss/ionic";
25 |
26 | @import "common";
27 | @import "home";
28 | @import "map";
29 |
--------------------------------------------------------------------------------
/app/styles/map.scss:
--------------------------------------------------------------------------------
1 | /*
2 | * Map
3 | */
4 |
5 | #map-view .scroll {
6 | height: 100%;
7 | }
8 |
9 | .gmaps {
10 | height: 100%;
11 | }
12 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Supermodular",
3 | "version": "1.1.0",
4 | "dependencies": {
5 | "ionic": "~1.2.1",
6 | "angular-websocket": "~1.0.9",
7 | "ngCordova": "~0.1.18-alpha",
8 | "lodash": "~3.8.0",
9 | "angular-base64": "~2.0.4",
10 | "ionic-service-core": "~0.1.3",
11 | "ionic-service-push": "~0.1.3",
12 | "angular-moment": "~0.10.1",
13 | "angularfire": "~1.1.1",
14 | "angular-bootstrap-calendar": "~0.11.3",
15 | "components-font-awesome": "~4.3.0",
16 | "ng-cordova-oauth": "~0.1.4"
17 | },
18 | "devDependencies": {
19 | "angular-mocks": "~1.3.6",
20 | "angular-scenario": "~1.3.6"
21 | },
22 | "resolutions": {
23 | "angular": ">= 1.4.3"
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/changelog.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | ```
3 | 2.0 - December 31, 2015
4 | - Ionic update to v1.2.1
5 | - Demonstration examples of Native Scrolling as it is now Ionic's default and Ionic's Slide Box based on Swiper widget (http://blog.ionic.io/announcing-ionic-1-2/)
6 |
7 | 1.2 - December 22, 2015
8 | - Downgrade Cordova iOS to 3.9.2 so there is no conflict with the plugins used
9 | - Improved installation process
10 | - Copy of package.json for the replacement of the original one when needed
11 |
12 | 1.1 - December 17, 2015
13 | - Fix on ConnectionType always returning Connection.UNKNOWN (Android)
14 | - Ionic update to v1.1.1
15 | - Cordova CLI update to v5.4.1
16 | - Ionic CLI update to v1.7.12
17 | - ngCordova update to v0.1.23-alpha
18 | - Support of android versions back to 4.0
19 | - Cordova iOS engine update to 4.0.0
20 | - Plugins update
21 | - Improved installation process for Win/Linux/MacOS
22 | - README.md update with improved instructions on how to install, run, build the app.
23 |
24 | 1.0 - Nov 23, 2015
25 | - Initial release
26 | ```
27 |
--------------------------------------------------------------------------------
/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Supermodular
4 |
5 | Supermodular Ionic. The boostrap you need in order to build your next Ionic application.
6 |
7 |
8 | Stavros Kounis
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/hooks/README.md:
--------------------------------------------------------------------------------
1 |
21 | # Cordova Hooks
22 |
23 | Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. Hook scripts could be defined by adding them to the special predefined folder (`/hooks`) or via configuration files (`config.xml` and `plugin.xml`) and run serially in the following order:
24 | * Application hooks from `/hooks`;
25 | * Application hooks from `config.xml`;
26 | * Plugin hooks from `plugins/.../plugin.xml`.
27 |
28 | __Remember__: Make your scripts executable.
29 |
30 | __Note__: `.cordova/hooks` directory is also supported for backward compatibility, but we don't recommend using it as it is deprecated.
31 |
32 | ## Supported hook types
33 | The following hook types are supported:
34 |
35 | after_build/
36 | after_compile/
37 | after_docs/
38 | after_emulate/
39 | after_platform_add/
40 | after_platform_rm/
41 | after_platform_ls/
42 | after_plugin_add/
43 | after_plugin_ls/
44 | after_plugin_rm/
45 | after_plugin_search/
46 | after_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed
47 | after_prepare/
48 | after_run/
49 | after_serve/
50 | before_build/
51 | before_compile/
52 | before_docs/
53 | before_emulate/
54 | before_platform_add/
55 | before_platform_rm/
56 | before_platform_ls/
57 | before_plugin_add/
58 | before_plugin_ls/
59 | before_plugin_rm/
60 | before_plugin_search/
61 | before_plugin_install/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being installed
62 | before_plugin_uninstall/ <-- Plugin hooks defined in plugin.xml are executed exclusively for a plugin being uninstalled
63 | before_prepare/
64 | before_run/
65 | before_serve/
66 | pre_package/ <-- Windows 8 and Windows Phone only.
67 |
68 | ## Ways to define hooks
69 | ### Via '/hooks' directory
70 | To execute custom action when corresponding hook type is fired, use hook type as a name for a subfolder inside 'hooks' directory and place you script file here, for example:
71 |
72 | # script file will be automatically executed after each build
73 | hooks/after_build/after_build_custom_action.js
74 |
75 |
76 | ### Config.xml
77 |
78 | Hooks can be defined in project's `config.xml` using `` elements, for example:
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | ...
89 |
90 |
91 |
92 |
93 |
94 |
95 | ...
96 |
97 |
98 | ### Plugin hooks (plugin.xml)
99 |
100 | As a plugin developer you can define hook scripts using `` elements in a `plugin.xml` like that:
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | ...
109 |
110 |
111 | `before_plugin_install`, `after_plugin_install`, `before_plugin_uninstall` plugin hooks will be fired exclusively for the plugin being installed/uninstalled.
112 |
113 | ## Script Interface
114 |
115 | ### Javascript
116 |
117 | If you are writing hooks in Javascript you should use the following module definition:
118 | ```javascript
119 | module.exports = function(context) {
120 | ...
121 | }
122 | ```
123 |
124 | You can make your scipts async using Q:
125 | ```javascript
126 | module.exports = function(context) {
127 | var Q = context.requireCordovaModule('q');
128 | var deferral = new Q.defer();
129 |
130 | setTimeout(function(){
131 | console.log('hook.js>> end');
132 | deferral.resolve();
133 | }, 1000);
134 |
135 | return deferral.promise;
136 | }
137 | ```
138 |
139 | `context` object contains hook type, executed script full path, hook options, command-line arguments passed to Cordova and top-level "cordova" object:
140 | ```json
141 | {
142 | "hook": "before_plugin_install",
143 | "scriptLocation": "c:\\script\\full\\path\\appBeforePluginInstall.js",
144 | "cmdLine": "The\\exact\\command\\cordova\\run\\with arguments",
145 | "opts": {
146 | "projectRoot":"C:\\path\\to\\the\\project",
147 | "cordova": {
148 | "platforms": ["wp8"],
149 | "plugins": ["com.plugin.withhooks"],
150 | "version": "0.21.7-dev"
151 | },
152 | "plugin": {
153 | "id": "com.plugin.withhooks",
154 | "pluginInfo": {
155 | ...
156 | },
157 | "platform": "wp8",
158 | "dir": "C:\\path\\to\\the\\project\\plugins\\com.plugin.withhooks"
159 | }
160 | },
161 | "cordova": {...}
162 | }
163 |
164 | ```
165 | `context.opts.plugin` object will only be passed to plugin hooks scripts.
166 |
167 | You can also require additional Cordova modules in your script using `context.requireCordovaModule` in the following way:
168 | ```javascript
169 | var Q = context.requireCordovaModule('q');
170 | ```
171 |
172 | __Note__: new module loader script interface is used for the `.js` files defined via `config.xml` or `plugin.xml` only.
173 | For compatibility reasons hook files specified via `/hooks` folders are run via Node child_process spawn, see 'Non-javascript' section below.
174 |
175 | ### Non-javascript
176 |
177 | Non-javascript scripts are run via Node child_process spawn 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:
178 |
179 | * CORDOVA_VERSION - The version of the Cordova-CLI.
180 | * CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios).
181 | * CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer)
182 | * CORDOVA_HOOK - Path to the hook that is being executed.
183 | * CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate)
184 |
185 | If a script returns a non-zero exit code, then the parent cordova command will be aborted.
186 |
187 | ## Writing hooks
188 |
189 | We highly recommend writing your hooks using Node.js so that they are
190 | cross-platform. Some good examples are shown here:
191 |
192 | [http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/)
193 |
194 | Also, note that even if you are working on Windows, and in case your hook scripts aren't bat files (which is recommended, if you want your scripts to work in non-Windows operating systems) Cordova CLI will expect a shebang line as the first line for it to know the interpreter it needs to use to launch the script. The shebang line should match the following example:
195 |
196 | #!/usr/bin/env [name_of_interpreter_executable]
197 |
--------------------------------------------------------------------------------
/hooks/after_platform_add/install_plugins.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Install all plugins listed in package.json
5 | */
6 | var exec = require('child_process').exec;
7 | var path = require('path');
8 | var sys = require('sys');
9 |
10 | var packageJSON = require('../../package.json');
11 | var cmd = process.platform === 'win32' ? 'cordova.cmd' : 'cordova';
12 | var script = path.resolve(__dirname, '../../node_modules/cordova/bin', cmd);
13 |
14 | packageJSON.cordovaPlugins = packageJSON.cordovaPlugins || [];
15 | packageJSON.cordovaPlugins.forEach(function (plugin) {
16 | exec(script + ' plugin add ' + plugin, function (error, stdout, stderr) {
17 | sys.puts(stdout);
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/hooks/after_plugin_add/register_plugins.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Push plugins to cordovaPlugins array after_plugin_add
5 | */
6 | var fs = require('fs');
7 | var packageJSON = require('../../package.json');
8 |
9 | packageJSON.cordovaPlugins = packageJSON.cordovaPlugins || [];
10 |
11 | var fromEnv = process.env.CORDOVA_PLUGINS.split(',');
12 | for (var i = 0; i < fromEnv.length; i++) {
13 | var plugin = fromEnv[i];
14 |
15 | if (packageJSON.cordovaPlugins.indexOf(plugin) !== -1) {
16 | packageJSON.cordovaPlugins.push(plugin);
17 | }
18 | }
19 |
20 | fs.writeFileSync('package.json', JSON.stringify(packageJSON, null, 2));
21 |
--------------------------------------------------------------------------------
/hooks/after_plugin_rm/deregister_plugins.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Remove plugins from cordovaPlugins array after_plugin_rm
5 | */
6 | var fs = require('fs');
7 | var _ = require('lodash');
8 | var packageJSON = require('../../package.json');
9 |
10 | packageJSON.cordovaPlugins = packageJSON.cordovaPlugins || [];
11 | _.each(process.env.CORDOVA_PLUGINS.split(','), function (plugin) {
12 | _.remove(packageJSON.cordovaPlugins, function (p) { return p === plugin; });
13 | });
14 |
15 | fs.writeFile('package.json', JSON.stringify(packageJSON, null, 2));
16 |
--------------------------------------------------------------------------------
/hooks/after_prepare/icons_and_splashscreens.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 | /**
3 | * Algorithm
4 | * [1] Look at all installed platforms
5 | * [2] Copy (non-destructive) icons and splash screens from platform to local RESOURCE_DIR
6 | * [3] Copy (destructive) matching icons and splash screens from RESOURCE_DIR to platform
7 | *
8 | * This ensures that local RESOURCE_DIR will be pre-scaffolded with icons and splash
9 | * screens generated by Cordova as placeholder ONLY for installed platforms and that
10 | * any modifications to local assets are reflected in the CORRECT Cordova platform
11 | * locations, without having to hardcode file paths.
12 | */
13 | var fs = require('fs');
14 | var path = require('path');
15 | var _ = require('lodash');
16 | var ncp = require('ncp');
17 | var mkdirp = require('mkdirp');
18 | var glob = require('glob');
19 | var Orchestrator = require('orchestrator');
20 |
21 | var BASES = {
22 | android: 'res',
23 | ios: 'Supermodular/Resources'
24 | };
25 | var RESOURCE_DIR = 'resources';
26 |
27 | // Helper function for file copying that ensures directory existence.
28 | function copyFile (src, dest, ncpOpts, callback) {
29 | var orchestrator = new Orchestrator();
30 | var parts = dest.split(path.sep);
31 | var fileName = parts.pop();
32 | var destDir = parts.join(path.sep);
33 | var destFile = path.resolve(destDir, fileName);
34 | orchestrator.add('ensureDir', function (done) {
35 | mkdirp(destDir, function (err) {
36 | done(err);
37 | });
38 | });
39 | orchestrator.add('copyFile', ['ensureDir'], function (done) {
40 | ncp(src, destFile, ncpOpts, function (err) {
41 | done(err);
42 | });
43 | });
44 | orchestrator.start('copyFile', function (err) {
45 | callback(err);
46 | });
47 | }
48 |
49 | // Main
50 | var platforms = _.filter(fs.readdirSync('platforms'), function (file) {
51 | return fs.statSync(path.resolve('platforms', file)).isDirectory();
52 | });
53 | _.each(platforms, function (platform) {
54 | var base = path.resolve('platforms', platform, BASES[platform]);
55 | glob(base + '/**/*.png', function (err, files) {
56 | _.each(files, function (cordovaFile) {
57 | var orchestrator = new Orchestrator();
58 | var parts = cordovaFile.split('/');
59 | var fileName = parts.pop();
60 | var localDir = path.resolve(RESOURCE_DIR, platform, _.last(parts));
61 | var localFile = path.resolve(localDir, fileName);
62 |
63 | orchestrator.add('copyFromCordova', function (done) {
64 | copyFile(cordovaFile, localFile, { clobber: false }, function (err) {
65 | done(err);
66 | });
67 | });
68 | orchestrator.add('copyToCordova', ['copyFromCordova'], function (done) {
69 | copyFile(localFile, cordovaFile, { clobber: true }, function (err) {
70 | done(err);
71 | });
72 | });
73 | orchestrator.start('copyToCordova', function (err) {
74 | if (err) { console.error(err); }
75 | });
76 | });
77 | });
78 | });
79 |
--------------------------------------------------------------------------------
/hooks/after_prepare/update_platform_config.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /** This hook updates platform configuration files based on preferences and config-file data defined in config.xml.
4 | Currently only the AndroidManifest.xml and IOS *-Info.plist file are supported.
5 |
6 | Preferences:
7 | 1. Preferences defined outside of the platform element will apply to all platforms
8 | 2. Preferences defined inside a platform element will apply only to the specified platform
9 | 3. Platform preferences take precedence over common preferences
10 | 4. The preferenceMappingData object contains all of the possible custom preferences to date including the
11 | target file they belong to, parent element, and destination element or attribute
12 |
13 | Config Files
14 | 1. config-file elements MUST be defined inside a platform element, otherwise they will be ignored.
15 | 2. config-file target attributes specify the target file to update. (AndroidManifest.xml or *-Info.plist)
16 | 3. config-file parent attributes specify the parent element (AndroidManifest.xml) or parent key (*-Info.plist)
17 | that the child data will replace or be appended to.
18 | 4. config-file elements are uniquely indexed by target AND parent for each platform.
19 | 5. If there are multiple config-file's defined with the same target AND parent, the last config-file will be used
20 | 6. Elements defined WITHIN a config-file will replace or be appended to the same elements relative to the parent element
21 | 7. If a unique config-file contains multiples of the same elements (other than uses-permssion elements which are
22 | selected by by the uses-permission name attribute), the last defined element will be retrieved.
23 |
24 | Examples:
25 |
26 | AndroidManifest.xml
27 | NOTE: For possible manifest values see http://developer.android.com/guide/topics/manifest/manifest-intro.html
28 |
29 |
30 | //These preferences are actually available in Cordova by default although not currently documented
31 |
32 |
33 |
34 |
35 | //custom preferences examples
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
49 |
50 |
51 |
52 |
53 |
54 |
55 | *-Info.plist
56 |
57 |
58 |
59 |
60 | UIInterfaceOrientationLandscapeOmg
61 |
62 |
63 |
64 |
65 | someValue
66 |
67 |
68 |
69 | NOTE: Currently, items aren't removed from the platform config files if you remove them from config.xml.
70 | For example, if you add a custom permission, build the remove it, it will still be in the manifest.
71 | If you make a mistake, for example adding an element to the wrong parent, you may need to remove and add your platform,
72 | or revert to your previous manifest/plist file.
73 |
74 | TODO: We may need to capture all default manifest/plist elements/keys created by Cordova along with any plugin elements/keys to compare against custom elements to remove.
75 | */
76 |
77 | // global vars
78 | var fs = require('fs');
79 | var path = require('path');
80 | var _ = require('lodash');
81 | var et = require('elementtree');
82 | var plist = require('plist');
83 |
84 | var rootdir = path.resolve(__dirname, '../../');
85 |
86 | var platformConfig = (function(){
87 | /* Global object that defines the available custom preferences for each platform.
88 | Maps a config.xml preference to a specific target file, parent element, and destination attribute or element
89 | */
90 | var preferenceMappingData = {
91 | 'android': {
92 | 'android-manifest-hardwareAccelerated': {target: 'AndroidManifest.xml', parent: './', destination: 'android:hardwareAccelerated'},
93 | 'android-installLocation': {target: 'AndroidManifest.xml', parent: './', destination: 'android:installLocation'},
94 | 'android-activity-hardwareAccelerated': {target: 'AndroidManifest.xml', parent: 'application', destination: 'android:hardwareAccelerated'},
95 | 'android-configChanges': {target: 'AndroidManifest.xml', parent: 'application/activity[@android:name=\'CordovaApp\']', destination: 'android:configChanges'},
96 | 'android-launchMode': {target: 'AndroidManifest.xml', parent: 'application/activity[@android:name=\'CordovaApp\']', destination: 'android:launchMode'},
97 | 'android-theme': {target: 'AndroidManifest.xml', parent: 'application/activity[@android:name=\'CordovaApp\']', destination: 'android:theme'},
98 | 'android-windowSoftInputMode': {target: 'AndroidManifest.xml', parent: 'application/activity[@android:name=\'CordovaApp\']', destination: 'android:windowSoftInputMode'}
99 | },
100 | 'ios': {}
101 | };
102 | var configXmlData, preferencesData;
103 |
104 | return {
105 | // Parses a given file into an elementtree object
106 | parseElementtreeSync: function (filename) {
107 | var contents = fs.readFileSync(filename, 'utf-8');
108 | if(contents) {
109 | //Windows is the BOM. Skip the Byte Order Mark.
110 | contents = contents.substring(contents.indexOf('<'));
111 | }
112 | return new et.ElementTree(et.XML(contents));
113 | },
114 |
115 | // Converts an elementtree object to an xml string. Since this is used for plist values, we don't care about attributes
116 | eltreeToXmlString: function (data) {
117 | var tag = data.tag;
118 | var el = '<' + tag + '>';
119 |
120 | if(data.text && data.text.trim()) {
121 | el += data.text.trim();
122 | } else {
123 | _.each(data.getchildren(), function (child) {
124 | el += platformConfig.eltreeToXmlString(child);
125 | });
126 | }
127 |
128 | el += '' + tag + '>';
129 | return el;
130 | },
131 |
132 | // Parses the config.xml into an elementtree object and stores in the config object
133 | getConfigXml: function () {
134 | if(!configXmlData) {
135 | configXmlData = this.parseElementtreeSync(path.join(rootdir, 'config.xml'));
136 | }
137 |
138 | return configXmlData;
139 | },
140 |
141 | /* Retrieves all from config.xml and returns a map of preferences with platform as the key.
142 | If a platform is supplied, common prefs + platform prefs will be returned, otherwise just common prefs are returned.
143 | */
144 | getPreferences: function (platform) {
145 | var configXml = this.getConfigXml();
146 |
147 | //init common config.xml prefs if we haven't already
148 | if(!preferencesData) {
149 | preferencesData = {
150 | common: configXml.findall('preference')
151 | };
152 | }
153 |
154 | var prefs = preferencesData.common || [];
155 | if(platform) {
156 | if(!preferencesData[platform]) {
157 | preferencesData[platform] = configXml.findall('platform[@name=\'' + platform + '\']/preference');
158 | }
159 | prefs = prefs.concat(preferencesData[platform]);
160 | }
161 |
162 | return prefs;
163 | },
164 |
165 | /* Retrieves all configured xml for a specific platform/target/parent element nested inside a platforms config-file
166 | element within the config.xml. The config-file elements are then indexed by target|parent so if there are
167 | any config-file elements per platform that have the same target and parent, the last config-file element is used.
168 | */
169 | getConfigFilesByTargetAndParent: function (platform) {
170 | var configFileData = this.getConfigXml().findall('platform[@name=\'' + platform + '\']/config-file');
171 |
172 | return _.indexBy(configFileData, function(item) {
173 | var parent = item.attrib.parent;
174 | //if parent attribute is undefined /* or */, set parent to top level elementree selector
175 | if(!parent || parent === '/*' || parent === '*/') {
176 | parent = './';
177 | }
178 | return item.attrib.target + '|' + parent;
179 | });
180 | },
181 |
182 | // Parses the config.xml's preferences and config-file elements for a given platform
183 | parseConfigXml: function (platform) {
184 | var configData = {};
185 | this.parsePreferences(configData, platform);
186 | this.parseConfigFiles(configData, platform);
187 |
188 | return configData;
189 | },
190 |
191 | // Retrieves the config.xml's pereferences for a given platform and parses them into JSON data
192 | parsePreferences: function (configData, platform) {
193 | var preferences = this.getPreferences(platform),
194 | type = 'preference';
195 |
196 | _.each(preferences, function (preference) {
197 | var prefMappingData = preferenceMappingData[platform][preference.attrib.name],
198 | target,
199 | prefData;
200 |
201 | if (prefMappingData) {
202 | prefData = {
203 | parent: prefMappingData.parent,
204 | type: type,
205 | destination: prefMappingData.destination,
206 | data: preference
207 | };
208 |
209 | target = prefMappingData.target;
210 | if(!configData[target]) {
211 | configData[target] = [];
212 | }
213 | configData[target].push(prefData);
214 | }
215 | });
216 | },
217 |
218 | // Retrieves the config.xml's config-file elements for a given platform and parses them into JSON data
219 | parseConfigFiles: function (configData, platform) {
220 | var configFiles = this.getConfigFilesByTargetAndParent(platform),
221 | type = 'configFile';
222 |
223 | _.each(configFiles, function (configFile, key) {
224 | var keyParts = key.split('|');
225 | var target = keyParts[0];
226 | var parent = keyParts[1];
227 | var items = configData[target] || [];
228 |
229 | _.each(configFile.getchildren(), function (element) {
230 | items.push({
231 | parent: parent,
232 | type: type,
233 | destination: element.tag,
234 | data: element
235 | });
236 | });
237 |
238 | configData[target] = items;
239 | });
240 | },
241 |
242 | // Parses config.xml data, and update each target file for a specified platform
243 | updatePlatformConfig: function (platform) {
244 | var configData = this.parseConfigXml(platform),
245 | platformPath = path.join(rootdir, 'platforms', platform);
246 |
247 | _.each(configData, function (configItems, targetFileName) {
248 | var projectName, targetFile;
249 |
250 | if (platform === 'ios' && targetFileName.indexOf("Info.plist") > -1) {
251 | projectName = platformConfig.getConfigXml().findtext('name');
252 | targetFile = path.join(platformPath, projectName, projectName + '-Info.plist');
253 | platformConfig.updateIosPlist(targetFile, configItems);
254 | } else if (platform === 'android' && targetFileName === 'AndroidManifest.xml') {
255 | targetFile = path.join(platformPath, targetFileName);
256 | platformConfig.updateAndroidManifest(targetFile, configItems);
257 | }
258 | });
259 | },
260 |
261 | // Updates the AndroidManifest.xml target file with data from config.xml
262 | updateAndroidManifest: function (targetFile, configItems) {
263 | var tempManifest = platformConfig.parseElementtreeSync(targetFile),
264 | root = tempManifest.getroot();
265 |
266 | _.each(configItems, function (item) {
267 | // if parent is not found on the root, child/grandchild nodes are searched
268 | var parentEl = root.find(item.parent) || root.find('*/' + item.parent),
269 | data = item.data,
270 | childSelector = item.destination,
271 | childEl;
272 |
273 | if(!parentEl) {
274 | return;
275 | }
276 |
277 | if(item.type === 'preference') {
278 | parentEl.attrib[childSelector] = data.attrib['value'];
279 | } else {
280 | // since there can be multiple uses-permission elements, we need to select them by unique name
281 | if(childSelector === 'uses-permission') {
282 | childSelector += '[@android:name=\'' + data.attrib['android:name'] + '\']';
283 | }
284 |
285 | childEl = parentEl.find(childSelector);
286 | // if child element doesnt exist, create new element
287 | if(!childEl) {
288 | childEl = new et.Element(item.destination);
289 | parentEl.append(childEl);
290 | }
291 |
292 | // copy all config.xml data except for the generated _id property
293 | _.each(data, function (prop, propName) {
294 | if(propName !== '_id') {
295 | childEl[propName] = prop;
296 | }
297 | });
298 | }
299 | });
300 |
301 | fs.writeFileSync(targetFile, tempManifest.write({indent: 4}), 'utf-8');
302 | },
303 |
304 | /* Updates the *-Info.plist file with data from config.xml by parsing to an xml string, then using the plist
305 | module to convert the data to a map. The config.xml data is then replaced or appended to the original plist file
306 | */
307 | updateIosPlist: function (targetFile, configItems) {
308 | var infoPlist = plist.parse(fs.readFileSync(targetFile, 'utf-8')),
309 | tempInfoPlist;
310 |
311 | _.each(configItems, function (item) {
312 | var key = item.parent;
313 | var plistXml = '' + key + ' ';
314 | plistXml += platformConfig.eltreeToXmlString(item.data) + ' ';
315 |
316 | var configPlistObj = plist.parse(plistXml);
317 | infoPlist[key] = configPlistObj[key];
318 | });
319 |
320 | tempInfoPlist = plist.build(infoPlist);
321 | tempInfoPlist = tempInfoPlist.replace(/[\s\r\n]*<\/string>/g,' ');
322 | fs.writeFileSync(targetFile, tempInfoPlist, 'utf-8');
323 | }
324 | };
325 | })();
326 |
327 | // Main
328 | (function () {
329 | if (rootdir) {
330 | // go through each of the platform directories that have been prepared
331 | var platforms = _.filter(fs.readdirSync('platforms'), function (file) {
332 | return fs.statSync(path.resolve('platforms', file)).isDirectory();
333 | });
334 |
335 | _.each(platforms, function (platform) {
336 | try {
337 | platform = platform.trim().toLowerCase();
338 | platformConfig.updatePlatformConfig(platform);
339 | } catch (e) {
340 | process.stdout.write(e);
341 | }
342 | });
343 | }
344 | })();
--------------------------------------------------------------------------------
/hooks/before_platform_add/init_directories.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * On a fresh clone, the local platforms/ and plugins/ directories will be
5 | * missing, so ensure they get created before the first platform is added.
6 | */
7 | var mkdirp = require('mkdirp');
8 | var path = require('path');
9 |
10 | var platformsDir = path.resolve(__dirname, '../../platforms');
11 | var pluginsDir = path.resolve(__dirname, '../../plugins');
12 |
13 | mkdirp(platformsDir, function (err) {
14 | if (err) { console.error(err); }
15 | });
16 |
17 | mkdirp(pluginsDir, function (err) {
18 | if (err) { console.error(err); }
19 | });
20 |
--------------------------------------------------------------------------------
/install.bat:
--------------------------------------------------------------------------------
1 | ::
2 | :: Create output (Cordova) directory
3 | ::
4 | mkdir www
5 |
6 | ::
7 | :: Install client libraries
8 | ::
9 | bower install
10 |
11 | ::
12 | :: Install cordova plugins
13 | :: The quickest option is to ask from Ionic
14 | :: to restore the state of the app.
15 | :: https://github.com/driftyco/ionic-cli::ionic-state-restore
16 | :: If this process fails comment this line and uncomment the
17 | :: "cordova plugin add ..." lines that follow.
18 | ::
19 | ionic state restore
20 | ::
21 | :: cordova plugin add cordova-plugin-device
22 | :: cordova plugin add cordova-plugin-console
23 | :: cordova plugin add com.ionic.keyboard
24 | :: cordova plugin add cordova-plugin-inappbrowser
25 | :: cordova plugin add cordova-plugin-geolocation
26 | :: cordova plugin add https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git
27 | :: cordova plugin add de.appplant.cordova.plugin.email-composer
28 | :: cordova plugin add cordova-plugin-network-information
29 | :: cordova plugin add cordova-plugin-whitelist
30 | :: cordova plugin add cordova-plugin-transport-security
31 |
32 | ::
33 | :: Add target platform
34 | ::
35 | :: Comment out the platform(s) your system supports
36 | ::
37 | grunt platform:add:ios
38 | :: grunt platform:add:android
39 |
40 | ::
41 | :: Build the project and generate the cordova directory (www)
42 | ::
43 | grunt build
44 |
--------------------------------------------------------------------------------
/install.sh:
--------------------------------------------------------------------------------
1 | #
2 | # Create output (Cordova) directory
3 | #
4 | mkdir www
5 |
6 | #
7 | # Install client libraries
8 | #
9 | bower install
10 |
11 | #
12 | # Install cordova plugins
13 | # The quickest option is to ask from Ionic
14 | # to restore the state of the app.
15 | # https://github.com/driftyco/ionic-cli#ionic-state-restore
16 | # If this process fails comment this line and uncomment the
17 | # "cordova plugin add ..." lines that follow.
18 | #
19 | ionic state restore
20 | #
21 | # cordova plugin add cordova-plugin-device
22 | # cordova plugin add cordova-plugin-console
23 | # cordova plugin add com.ionic.keyboard
24 | # cordova plugin add cordova-plugin-inappbrowser
25 | # cordova plugin add cordova-plugin-geolocation
26 | # cordova plugin add https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git
27 | # cordova plugin add de.appplant.cordova.plugin.email-composer
28 | # cordova plugin add cordova-plugin-network-information
29 | # cordova plugin add cordova-plugin-whitelist
30 | # cordova plugin add cordova-plugin-transport-security
31 |
32 | #
33 | # Add target platform
34 | #
35 | # Comment out the platform(s) your system supports
36 | #
37 | grunt platform:add:ios
38 | # grunt platform:add:android
39 |
40 | #
41 | # Build the project and generate the cordova directory (www)
42 | #
43 | grunt build
44 |
--------------------------------------------------------------------------------
/ionic.project:
--------------------------------------------------------------------------------
1 | {
2 | "name": "supermodular-ionic",
3 | "app_id": "d25614ca"
4 | }
5 |
--------------------------------------------------------------------------------
/misc/faces.psd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/faces.psd
--------------------------------------------------------------------------------
/misc/menu-items/item-01-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-01-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-01-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-01-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-02-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-02-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-02-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-02-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-03-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-03-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-03-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-03-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-04-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-04-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-04-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-04-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-05-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-05-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-05-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-05-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-06-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-06-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-06-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-06-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-07-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-07-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-07-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-07-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-08-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-08-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-08-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-08-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-09-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-09-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-09-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-09-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-10-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-10-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-10-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-10-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-11-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-11-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-11-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-11-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-12-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-12-1.jpg
--------------------------------------------------------------------------------
/misc/menu-items/item-12-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/misc/menu-items/item-12-thumb.jpg
--------------------------------------------------------------------------------
/misc/menu-items/items.json:
--------------------------------------------------------------------------------
1 | {
2 | "id": 1,
3 | "jsonrpc": "2.0",
4 | "total": 6,
5 | "result": [
6 | {
7 | "id": 1,
8 | "guid": "1d4aa3b2-c059-4fa7-a751-9bca735e4ebb",
9 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-01-thumb.jpg",
10 | "title": "Mozzarella sticks",
11 | "body": "Extra delicious Mozzarella cheese sticks, mixed with zucchini and potatoes coated with flavorful herbs. Served with a side of marinara sauce for dipping.",
12 | "tags": ["mozzarella", "sticks"],
13 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/9",
14 | "currency": "£",
15 | "price" : "11.00",
16 | "pictures": [
17 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-01-1.jpg"
18 | ]
19 | }, {
20 | "id": 2,
21 | "guid": "6630fb89-94d6-4fec-a1c3-c48d80b88895",
22 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-02-thumb.jpg",
23 | "title": "Cheesy Rosemary Monkey Bread Rolls",
24 | "body": "Rosemary, garlic and cheese make these monkey bread rolls perfect with any meal.",
25 | "tags": ["bread", "rosemary"],
26 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/10",
27 | "currency": "£",
28 | "price" : "11.00",
29 | "pictures": [
30 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-02-1.jpg"
31 | ]
32 | }, {
33 | "id": 3,
34 | "guid": "861d3f45-28ce-4b10-80e5-e98fafee4d4f",
35 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-03-thumb.jpg",
36 | "title": "Sticks variety",
37 | "body": "A variety of vegetable and beef sticks will keep the balance for a healthy yet tasteful starter.",
38 | "tags": ["sticks", "beef", "vegetables"],
39 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/11",
40 | "currency": "£",
41 | "price" : "18.00",
42 | "pictures": [
43 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-03-1.jpg"
44 | ]
45 | }, {
46 | "id": 4,
47 | "guid": "205f2dd0-35e8-450c-9577-bb71be487fe7",
48 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-04-thumb.jpg",
49 | "title": "Espresso coffee",
50 | "body": "Classic italian espresso made with blends of 80% arabica and 20% robusta. Served with cinnamon cookies.",
51 | "tags": ["coffee", "espresso"],
52 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/12",
53 | "currency": "£",
54 | "price" : "7.00",
55 | "pictures": [
56 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-04-1.jpg"
57 | ]
58 | }, {
59 | "id": 5,
60 | "guid": "4e0d6228-1ffc-46d4-ba68-22454728dd37",
61 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-05-thumb.jpg",
62 | "title": "Plum layered dessert",
63 | "body": "A delicious dessert which is low in both fat and sugar.",
64 | "tags": ["plum"],
65 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/13",
66 | "currency": "£",
67 | "price" : "9.00",
68 | "pictures": [
69 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-05-1.jpg"
70 | ]
71 | }, {
72 | "id": 6,
73 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
74 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-06-thumb.jpg",
75 | "title": "Chocolate, raspberry and vanilla cake",
76 | "body": "Cake with almond sponge, raspberry coulis and raspberry sorbet.",
77 | "tags": ["cake", "raspberry", "Chocolate"],
78 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
79 | "currency": "£",
80 | "price" : "7.00",
81 | "pictures": [
82 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-06-1.jpg"
83 | ]
84 | }, {
85 | "id": 7,
86 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
87 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-07-thumb.jpg",
88 | "title": "Strawberry heaven",
89 | "body": "Crispy base smothered with a layer of light mousse is then perfectly complemented by a layer of dreamy strawberry puree.",
90 | "tags": ["strawberry", "layered"],
91 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
92 | "currency": "£",
93 | "price" : "9.00",
94 | "pictures": [
95 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-07-1.jpg"
96 | ]
97 | }, {
98 | "id": 8,
99 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
100 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-08-thumb.jpg",
101 | "title": "Mix of meat",
102 | "body": "Filets and sausages served with herb roasted potatoes and roasted vegetables seasoned with rosemary and thyme.",
103 | "tags": ["filet", "sausage", "red meat"],
104 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
105 | "currency": "£",
106 | "price" : "21.00",
107 | "pictures": [
108 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-08-1.jpg"
109 | ]
110 | }, {
111 | "id": 9,
112 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
113 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-09-thumb.jpg",
114 | "title": "Handmade burgers",
115 | "body": "The beef we source for our burgers is sourced from Aberdeenshire a we just love the distinctive flavour and quality.",
116 | "tags": ["burger", "beef", "handmade"],
117 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
118 | "currency": "£",
119 | "price" : "16.00",
120 | "pictures": [
121 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-09-1.jpg"
122 | ]
123 | }, {
124 | "id": 10,
125 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
126 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-10-thumb.jpg",
127 | "title": "Supreme Pizza",
128 | "body": "Beef, ham, pepperoni, Italian sausage, onion, mushroom, pineapple, capsicum & peppers.",
129 | "tags": ["pizza"],
130 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
131 | "currency": "£",
132 | "price" : "17.00",
133 | "pictures": [
134 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-10-1.jpg"
135 | ]
136 | }, {
137 | "id": 11,
138 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
139 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-11-thumb.jpg",
140 | "title": "Mixed Vegetable Salad with Lime Dressing",
141 | "body": "This raw mixed vegetable salad takes the green leaves out of the mix and focuses more on the topping vegetables.",
142 | "tags": ["raw", "vegetables"],
143 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
144 | "currency": "£",
145 | "price" : "11.00",
146 | "pictures": [
147 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-11-1.jpg"
148 | ]
149 | }, {
150 | "id": 12,
151 | "guid": "b3119483-5125-4f6c-89a3-849ebc732447",
152 | "thumb": "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-12-thumb.jpg",
153 | "title": "Lettuce Salad with Garlic Croutons",
154 | "body": "This salad has a fresh crunch due to different kinds of lettuce, garlic croutons and nuts.",
155 | "tags": ["lettuce", "croutons", "nuts"],
156 | "url" : "http://demo.morethanthemes.com/retailplus/commerce-default/node/14",
157 | "currency": "£",
158 | "price" : "11.00",
159 | "pictures": [
160 | "http://skounis.s3.amazonaws.com/mobile-apps/barebone-ionic/item-12-1.jpg"
161 | ]
162 | }
163 | ]
164 | }
165 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Supermodular",
3 | "version": "1.1.0",
4 | "private": true,
5 | "dependencies": {},
6 | "devDependencies": {
7 | "cordova": "^5.4.1",
8 | "elementtree": "0.1.6",
9 | "glob": "~4.3.5",
10 | "grunt": "~0.4.5",
11 | "grunt-autoprefixer": "~2.2.0",
12 | "grunt-concurrent": "1.0.0",
13 | "grunt-contrib-clean": "~0.6.0",
14 | "grunt-contrib-concat": "~0.5.0",
15 | "grunt-contrib-connect": "~0.9.0",
16 | "grunt-contrib-copy": "~0.7.0",
17 | "grunt-contrib-cssmin": "~0.11.0",
18 | "grunt-contrib-htmlmin": "~0.3.0",
19 | "grunt-contrib-jshint": "~0.11.0",
20 | "grunt-contrib-sass": "^0.9.2",
21 | "grunt-contrib-uglify": "~0.7.0",
22 | "grunt-contrib-watch": "~0.6.1",
23 | "grunt-include-source": "^0.5.1",
24 | "grunt-karma": "~0.12.1",
25 | "grunt-newer": "~1.1.0",
26 | "grunt-ng-annotate": "~0.9.2",
27 | "grunt-ng-constant": "^1.0.0",
28 | "grunt-usemin": "~3.0.0",
29 | "grunt-wiredep": "^2.0.0",
30 | "ionic": "^1.7.12",
31 | "jshint-stylish": "~1.0.0",
32 | "karma": "~0.13.15",
33 | "karma-chai": "~0.1.0",
34 | "karma-chrome-launcher": "~0.2.2",
35 | "karma-coverage": "~0.5.3",
36 | "karma-mocha": "~0.2.1",
37 | "karma-phantomjs-launcher": "~0.2.1",
38 | "load-grunt-tasks": "~3.1.0",
39 | "lodash": "~3.10.1",
40 | "mkdirp": "~0.5.0",
41 | "ncp": "~1.0.1",
42 | "orchestrator": "~0.3.7",
43 | "plist": "^1.2.0",
44 | "ripple-emulator": "~0.9.24",
45 | "time-grunt": "~1.0.0",
46 | "win-spawn": "^2.0.0"
47 | },
48 | "engines": {
49 | "node": ">=0.10.0"
50 | },
51 | "scripts": {
52 | "test": "grunt test",
53 | "//": "Post installation.",
54 | "//": "Uncomment the next line to enable post install script.",
55 | "//": "There is always the option to run it manually.",
56 | "//": { "postinstall": "./install.sh" },
57 | "//": { "postinstall": "./install.bat" }
58 | },
59 | "cordovaPlatforms": [],
60 | "cordovaPlugins": [
61 | "cordova-plugin-device",
62 | "cordova-plugin-console",
63 | "com.ionic.keyboard",
64 | "cordova-plugin-inappbrowser",
65 | "cordova-plugin-geolocation",
66 | {
67 | "locator": "https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git",
68 | "id": "nl.x-services.plugins.socialsharing"
69 | },
70 | {
71 | "locator": "https://github.com/katzer/cordova-plugin-email-composer.git",
72 | "id": "de.appplant.cordova.plugin.email-composer"
73 | },
74 | "cordova-plugin-network-information",
75 | "cordova-plugin-whitelist",
76 | "cordova-plugin-transport-security"
77 | ]
78 | }
79 |
--------------------------------------------------------------------------------
/package.json.local:
--------------------------------------------------------------------------------
1 | {
2 | "name": "Supermodular",
3 | "version": "1.1.0",
4 | "private": true,
5 | "dependencies": {},
6 | "devDependencies": {
7 | "cordova": "^5.4.1",
8 | "elementtree": "0.1.6",
9 | "glob": "~4.3.5",
10 | "grunt": "~0.4.5",
11 | "grunt-autoprefixer": "~2.2.0",
12 | "grunt-concurrent": "1.0.0",
13 | "grunt-contrib-clean": "~0.6.0",
14 | "grunt-contrib-concat": "~0.5.0",
15 | "grunt-contrib-connect": "~0.9.0",
16 | "grunt-contrib-copy": "~0.7.0",
17 | "grunt-contrib-cssmin": "~0.11.0",
18 | "grunt-contrib-htmlmin": "~0.3.0",
19 | "grunt-contrib-jshint": "~0.11.0",
20 | "grunt-contrib-sass": "^0.9.2",
21 | "grunt-contrib-uglify": "~0.7.0",
22 | "grunt-contrib-watch": "~0.6.1",
23 | "grunt-include-source": "^0.5.1",
24 | "grunt-karma": "~0.12.1",
25 | "grunt-newer": "~1.1.0",
26 | "grunt-ng-annotate": "~0.9.2",
27 | "grunt-ng-constant": "^1.0.0",
28 | "grunt-usemin": "~3.0.0",
29 | "grunt-wiredep": "^2.0.0",
30 | "ionic": "^1.7.12",
31 | "jshint-stylish": "~1.0.0",
32 | "karma": "~0.13.15",
33 | "karma-chai": "~0.1.0",
34 | "karma-chrome-launcher": "~0.2.2",
35 | "karma-coverage": "~0.5.3",
36 | "karma-mocha": "~0.2.1",
37 | "karma-phantomjs-launcher": "~0.2.1",
38 | "load-grunt-tasks": "~3.1.0",
39 | "lodash": "~3.10.1",
40 | "mkdirp": "~0.5.0",
41 | "ncp": "~1.0.1",
42 | "orchestrator": "~0.3.7",
43 | "plist": "^1.2.0",
44 | "ripple-emulator": "~0.9.24",
45 | "time-grunt": "~1.0.0",
46 | "win-spawn": "^2.0.0"
47 | },
48 | "engines": {
49 | "node": ">=0.10.0"
50 | },
51 | "scripts": {
52 | "test": "grunt test",
53 | "//": "Post installation.",
54 | "//": "Uncomment the next line to enable post install script.",
55 | "//": "There is always the option to run it manually.",
56 | "//": { "postinstall": "./install.sh" },
57 | "//": { "postinstall": "./install.bat" }
58 | },
59 | "cordovaPlatforms": [],
60 | "cordovaPlugins": [
61 | "cordova-plugin-device",
62 | "cordova-plugin-console",
63 | "com.ionic.keyboard",
64 | "cordova-plugin-inappbrowser",
65 | "cordova-plugin-geolocation",
66 | {
67 | "locator": "https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin.git",
68 | "id": "nl.x-services.plugins.socialsharing"
69 | },
70 | {
71 | "locator": "https://github.com/katzer/cordova-plugin-email-composer.git",
72 | "id": "de.appplant.cordova.plugin.email-composer"
73 | },
74 | "cordova-plugin-network-information",
75 | "cordova-plugin-whitelist",
76 | "cordova-plugin-transport-security"
77 | ]
78 | }
79 |
--------------------------------------------------------------------------------
/resources/android/drawable-hdpi/ic_action_next_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-hdpi/ic_action_next_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-hdpi/ic_action_previous_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-hdpi/ic_action_previous_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-hdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-hdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/resources/android/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/resources/android/drawable-land-hdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-land-hdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-land-ldpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-land-ldpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-land-mdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-land-mdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-land-xhdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-land-xhdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/resources/android/drawable-mdpi/ic_action_next_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-mdpi/ic_action_next_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-mdpi/ic_action_previous_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-mdpi/ic_action_previous_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-mdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-mdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/resources/android/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/resources/android/drawable-port-hdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-port-hdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-port-ldpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-port-ldpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-port-mdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-port-mdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-port-xhdpi/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-port-xhdpi/screen.png
--------------------------------------------------------------------------------
/resources/android/drawable-xhdpi/ic_action_next_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xhdpi/ic_action_next_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-xhdpi/ic_action_previous_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xhdpi/ic_action_previous_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-xhdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xhdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/resources/android/drawable-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xhdpi/icon.png
--------------------------------------------------------------------------------
/resources/android/drawable-xxhdpi/ic_action_next_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xxhdpi/ic_action_next_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-xxhdpi/ic_action_previous_item.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xxhdpi/ic_action_previous_item.png
--------------------------------------------------------------------------------
/resources/android/drawable-xxhdpi/ic_action_remove.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable-xxhdpi/ic_action_remove.png
--------------------------------------------------------------------------------
/resources/android/drawable/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/android/drawable/icon.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-40.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-40@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-50.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-50.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-50@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-50@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-60.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-60@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-60@3x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-72.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-72.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-72@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-72@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-76.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-76@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-small.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon-small@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon-small@2x.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon.png
--------------------------------------------------------------------------------
/resources/ios/icons/icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/icons/icon@2x.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-568h@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-568h@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-667h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-667h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape-736h.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-Landscape-736h.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-Landscape@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Landscape~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-Landscape~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait@2x~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-Portrait@2x~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default-Portrait~ipad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default-Portrait~ipad.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default@2x~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default@2x~iphone.png
--------------------------------------------------------------------------------
/resources/ios/splash/Default~iphone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/appseed-io/supermodular/1c165275bf7efc7be0c91ea7e08f8c56a69197f0/resources/ios/splash/Default~iphone.png
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------