├── .gitattributes
├── .yo-rc.json
├── app
├── styles
│ └── main.css
├── images
│ ├── icon-128.png
│ ├── icon-16.png
│ ├── icon-19.png
│ ├── icon-38.png
│ └── screenshot.png
├── scripts
│ ├── lookup_class.js
│ ├── student_tab.js
│ ├── oscar.js
│ ├── select_term.js
│ ├── advance_search.js
│ ├── chromereload.js
│ └── background.js
├── _locales
│ └── en
│ │ └── messages.json
└── manifest.json
├── .bowerrc
├── test
├── .bowerrc
├── bower.json
├── spec
│ └── test.js
└── index.html
├── .gitignore
├── bower.json
├── .jshintrc
├── .editorconfig
├── package.json
├── README.md
└── Gruntfile.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.yo-rc.json:
--------------------------------------------------------------------------------
1 | {
2 | "generator-mocha": {}
3 | }
--------------------------------------------------------------------------------
/app/styles/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding: 20px;
3 | }
4 |
--------------------------------------------------------------------------------
/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "app/bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/test/.bowerrc:
--------------------------------------------------------------------------------
1 | {
2 | "directory": "bower_components"
3 | }
4 |
--------------------------------------------------------------------------------
/app/images/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jotielim/gatechomscsclass/HEAD/app/images/icon-128.png
--------------------------------------------------------------------------------
/app/images/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jotielim/gatechomscsclass/HEAD/app/images/icon-16.png
--------------------------------------------------------------------------------
/app/images/icon-19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jotielim/gatechomscsclass/HEAD/app/images/icon-19.png
--------------------------------------------------------------------------------
/app/images/icon-38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jotielim/gatechomscsclass/HEAD/app/images/icon-38.png
--------------------------------------------------------------------------------
/app/images/screenshot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jotielim/gatechomscsclass/HEAD/app/images/screenshot.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | temp
3 | .tmp
4 | dist
5 | .sass-cache
6 | app/bower_components
7 | test/bower_components
8 | package
9 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatechomscsclass",
3 | "version": "0.0.0",
4 | "dependencies": {},
5 | "devDependencies": {}
6 | }
7 |
--------------------------------------------------------------------------------
/test/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatechomscsclass",
3 | "private": true,
4 | "dependencies": {
5 | "chai": "~1.8.0",
6 | "mocha": "~1.14.0"
7 | },
8 | "devDependencies": {}
9 | }
10 |
--------------------------------------------------------------------------------
/app/scripts/lookup_class.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Change url to OSCAR class look up
3 | */
4 |
5 | 'use strict';
6 |
7 | var url = 'https://oscar.gatech.edu/pls/bprod/bwskfcls.p_sel_crse_search';
8 | var el = document.querySelector('iframe');
9 |
10 | el.src = url;
--------------------------------------------------------------------------------
/app/_locales/en/messages.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": {
3 | "message": "gatechomscsclass",
4 | "description": "GA Tech OMSCS Class"
5 | },
6 | "appDescription": {
7 | "message": "GA Tech OMSCS Class",
8 | "description": "GA Tech OMSCS Class"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/test/spec/test.js:
--------------------------------------------------------------------------------
1 | /* global describe, it */
2 |
3 | (function () {
4 | 'use strict';
5 |
6 | describe('Give it some context', function () {
7 | describe('maybe a bit more context here', function () {
8 | it('should run here few assertions', function () {
9 |
10 | });
11 | });
12 | });
13 | })();
14 |
--------------------------------------------------------------------------------
/app/scripts/student_tab.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Navigate to student page
3 | */
4 |
5 | 'use strict';
6 |
7 | var elements = document.getElementById('utilityNav').getElementsByClassName('dragTab');
8 | var el;
9 |
10 | for (var i = 0; i < elements.length; i++) {
11 | el = elements[i];
12 | if (el.childNodes[0].innerHTML.toLowerCase().indexOf('student') !== -1) {
13 | break;
14 | }
15 | el = null;
16 | }
17 |
18 | if (el) {
19 | el.childNodes[0].click();
20 | }
--------------------------------------------------------------------------------
/.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 | "newcap": true,
12 | "noarg": true,
13 | "quotmark": "single",
14 | "regexp": true,
15 | "undef": true,
16 | "unused": true,
17 | "strict": true,
18 | "trailing": true,
19 | "smarttabs": true,
20 | "globals" : {
21 | "chrome": true
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 |
8 | [*]
9 |
10 | # Change these settings to your own preference
11 | indent_style = space
12 | indent_size = 2
13 |
14 | [*.json]
15 | indent_size = 2
16 |
17 | # We recommend you to keep these unchanged
18 | end_of_line = lf
19 | charset = utf-8
20 | trim_trailing_whitespace = true
21 | insert_final_newline = true
22 |
23 | [*.md]
24 | trim_trailing_whitespace = false
25 |
--------------------------------------------------------------------------------
/app/scripts/oscar.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Navigate to OSCAR
3 | */
4 |
5 | 'use strict';
6 |
7 | var elements = document.querySelectorAll('tr.uportal-background-content [id^="col_"]')[1].getElementsByTagName('a');
8 | var url = 'http://buzzport.gatech.edu/render.UserLayoutRootNode.uP?uP_tparam=utf&utf=%2Fcp%2Fip%2Flogin%3Fsys%3Dsct%26url%3Dhttps%3A%2F%2Foscar.gatech.edu/pls/bprod%2Fztgkauth.zp_authorize_from_login';
9 | var el;
10 |
11 | for (var i = 0; i < elements.length; i++) {
12 | el = elements[i];
13 | if (el.href === url) {
14 | break;
15 | }
16 | el = null;
17 | }
18 |
19 | if (el) {
20 | el.click();
21 | }
--------------------------------------------------------------------------------
/app/scripts/select_term.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Select the most recent term
3 | */
4 |
5 | 'use strict';
6 |
7 | var select = document.querySelector('#term_input_id');
8 | var options = select.getElementsByTagName('option');
9 | var form = document.querySelector('form[action="/pls/bprod/bwckgens.p_proc_term_date"]');
10 | var currentTerm;
11 |
12 | for (var i = 0; i < options.length; i++) {
13 | currentTerm = options[i];
14 | if (currentTerm.value == '201505' /*'201508' for Fall 2015*/ && currentTerm.value.length > 0) {
15 | break;
16 | }
17 | currentTerm = null;
18 | }
19 |
20 | if (select && currentTerm) {
21 | select.value = currentTerm.value;
22 | form.submit();
23 | }
24 |
--------------------------------------------------------------------------------
/app/scripts/advance_search.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Select CS subject and Online campus
3 | */
4 |
5 | 'use strict';
6 |
7 | var subject = document.querySelector('#subj_id');
8 | var campus = document.querySelector('#camp_id');
9 | var advanceSearchBtn = document.querySelector('form[action="/pls/bprod/bwskfcls.P_GetCrse_Advanced"] input[type="submit"]');
10 |
11 | var subjectsToSelect = ['CS','CSE'];
12 |
13 | for(var i = 0; i < subject.length; i++) {
14 | for (var k = 0; k < subjectsToSelect.length; k++){
15 | if(subject.options[i].value == subjectsToSelect[k]) {
16 | subject.options[i].selected = true;
17 | }
18 | }
19 | }
20 | campus.value = 'O';
21 |
22 | advanceSearchBtn.click();
23 |
--------------------------------------------------------------------------------
/app/scripts/chromereload.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | // Reload client for Chrome Apps & Extensions.
4 | // The reload client has a compatibility with livereload.
5 | // WARNING: only supports reload command.
6 |
7 | var LIVERELOAD_HOST = 'localhost:';
8 | var LIVERELOAD_PORT = 35729;
9 | var connection = new WebSocket('ws://' + LIVERELOAD_HOST + LIVERELOAD_PORT + '/livereload');
10 |
11 | connection.onerror = function (error) {
12 | console.log('reload connection got error' + JSON.stringify(error));
13 | };
14 |
15 | connection.onmessage = function (e) {
16 | if (e.data) {
17 | var data = JSON.parse(e.data);
18 | if (data && data.command === 'reload') {
19 | chrome.runtime.reload();
20 | }
21 | }
22 | };
23 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Mocha Spec Runner
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/app/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "GA Tech OMSCS Class",
3 | "version": "0.0.3",
4 | "manifest_version": 2,
5 | "description": "Chrome extension to automatically navigate to GA Tech OMSCS Classes",
6 | "icons": {
7 | "16": "images/icon-16.png",
8 | "128": "images/icon-128.png"
9 | },
10 | "default_locale": "en",
11 | "background": {
12 | "scripts": [
13 | "scripts/chromereload.js",
14 | "scripts/background.js"
15 | ]
16 | },
17 | "browser_action": {
18 | "default_icon": {
19 | "19": "images/icon-19.png",
20 | "38": "images/icon-38.png"
21 | },
22 | "default_title": "GA Tech OMSCS Class"
23 | },
24 | "permissions": [
25 | "http://*.gatech.edu/",
26 | "https://*.gatech.edu/"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gatechomscsclass",
3 | "version": "0.0.0",
4 | "dependencies": {},
5 | "devDependencies": {
6 | "grunt": "~0.4.1",
7 | "grunt-bower-install": "~1.0.0",
8 | "grunt-chrome-manifest": "~0.2.0",
9 | "grunt-concurrent": "~0.5.0",
10 | "grunt-contrib-clean": "~0.5.0",
11 | "grunt-contrib-compress": "~0.9.1",
12 | "grunt-contrib-concat": "~0.3.0",
13 | "grunt-contrib-connect": "~0.7.1",
14 | "grunt-contrib-copy": "~0.5.0",
15 | "grunt-contrib-cssmin": "~0.9.0",
16 | "grunt-contrib-htmlmin": "~0.2.0",
17 | "grunt-contrib-imagemin": "~0.7.1",
18 | "grunt-contrib-jshint": "~0.9.2",
19 | "grunt-contrib-uglify": "~0.4.0",
20 | "grunt-contrib-watch": "~0.6.1",
21 | "grunt-mocha": "~0.4.10",
22 | "grunt-svgmin": "~0.4.0",
23 | "grunt-usemin": "~2.1.0",
24 | "jshint-stylish": "~0.1.5",
25 | "load-grunt-tasks": "~0.4.0",
26 | "time-grunt": "~0.3.1"
27 | },
28 | "engines": {
29 | "node": ">=0.8.0"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GA Tech OMSCS Class
2 |
3 | Chrome extension to automatically navigate to GA Tech OMSCS Classes
4 |
5 | 
6 |
7 | ### To use:
8 | 1. Go to chrome://extensions/ and enable 'Developer mode'
9 | 2. Click 'Load unpacked extension' button and point to /path/to/gatechomscsclass/app
10 | 3. Login to http://buzzport.gatech.edu
11 | 4. Click on the gatechomscsclass extension button
12 | 5. Wait for it to finish navigating
13 |
14 | ### Dev:
15 | Prerequisites: node.js, npm
16 | $ npm install
17 | $ grunt debug
18 |
19 | ### Known issues:
20 | 1. [Priyank Patel](https://github.com/TempleOwl) mentioned that when he run the script from buzzport, it logged him out of OSCAR. If this happen, Priyank suggested to manually click on 'OSCAR' button to login to OSCAR and click the extension button again.
21 | 2. The extension requires buzzport/oscar to be the active tab while running. If you change to another tab, the script will fail.
--------------------------------------------------------------------------------
/app/scripts/background.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | chrome.browserAction.setBadgeText({text: 'OMS'});
4 |
5 | /**
6 | * Navigate to student page
7 | */
8 | var studentTab = function (tab) {
9 | chrome.tabs.executeScript(null, { file: 'scripts/student_tab.js', runAt: 'document_end' }, function () {
10 | chrome.tabs.onUpdated.addListener(function studentTabListener (_tabId, info) {
11 | if (tab.id === _tabId && info.status === 'complete') {
12 | chrome.tabs.onUpdated.removeListener(studentTabListener);
13 | oscar(tab);
14 | }
15 | });
16 | });
17 | };
18 |
19 | /**
20 | * Navigate to OSCAR
21 | */
22 | var oscar = function (tab) {
23 | chrome.tabs.executeScript(null, { file: 'scripts/oscar.js', runAt: 'document_end' }, function () {
24 | chrome.tabs.onUpdated.addListener(function oscarListener (_tabId, info) {
25 | if (tab.id === _tabId && info.status === 'complete') {
26 | chrome.tabs.onUpdated.removeListener(oscarListener);
27 | lookupClass(tab);
28 | }
29 | });
30 | });
31 | };
32 |
33 | /**
34 | * Change url to OSCAR class look up
35 | */
36 | var lookupClass = function (tab) {
37 | chrome.tabs.update(tab.id, {
38 | url: 'https://oscar.gatech.edu/pls/bprod/bwskfcls.p_sel_crse_search'
39 | }, function () {
40 | chrome.tabs.onUpdated.addListener(function lookupClassListener (_tabId, info) {
41 | if (tab.id === _tabId && info.status === 'complete') {
42 | chrome.tabs.onUpdated.removeListener(lookupClassListener);
43 | selectTerm(tab);
44 | }
45 | });
46 | });
47 | };
48 |
49 | /**
50 | * Select the most recent term
51 | */
52 | var selectTerm = function (tab) {
53 | chrome.tabs.executeScript(null, { file: 'scripts/select_term.js', runAt: 'document_end' }, function () {
54 | chrome.tabs.onUpdated.addListener(function selectTermListener (_tabId, info) {
55 | if (tab.id === _tabId && info.status === 'complete') {
56 | chrome.tabs.onUpdated.removeListener(selectTermListener);
57 | courseSearch(tab);
58 | }
59 | });
60 | });
61 | };
62 |
63 | /**
64 | * Navigate to advance search
65 | */
66 | var courseSearch = function (tab) {
67 | chrome.tabs.executeScript({
68 | code: 'document.querySelectorAll(\'form[action="/pls/bprod/bwskfcls.P_GetCrse"] input[type="submit"]\')[1].click()'
69 | }, function () {
70 | chrome.tabs.onUpdated.addListener(function courseSearchListener (_tabId, info) {
71 | if (tab.id === _tabId && info.status === 'complete') {
72 | chrome.tabs.onUpdated.removeListener(courseSearchListener);
73 | advanceSearch(tab);
74 | }
75 | });
76 | });
77 | };
78 |
79 | /**
80 | * Select CS subject and Online campus
81 | */
82 | var advanceSearch = function (tab) {
83 | chrome.tabs.executeScript(null, { file: 'scripts/advance_search.js', runAt: 'document_end' }, function () {
84 | chrome.tabs.onUpdated.addListener(function advanceSearchListener (_tabId, info) {
85 | if (tab.id === _tabId && info.status === 'complete') {
86 | chrome.tabs.onUpdated.removeListener(advanceSearchListener);
87 | }
88 | });
89 | });
90 | };
91 |
92 | /**
93 | * On browser icon clicked
94 | */
95 | chrome.browserAction.onClicked.addListener(function (tab) {
96 | if (tab.url.indexOf('http://buzzport.gatech.edu') !== -1) {
97 | studentTab(tab);
98 | } else if (tab.url.indexOf('https://oscar.gatech.edu') !== -1) {
99 | lookupClass(tab);
100 | }
101 | });
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | // Generated on 2015-01-06 using generator-chrome-extension 0.2.11
2 | 'use strict';
3 |
4 | // # Globbing
5 | // for performance reasons we're only matching one level down:
6 | // 'test/spec/{,*/}*.js'
7 | // use this if you want to recursively match all subfolders:
8 | // 'test/spec/**/*.js'
9 |
10 | module.exports = function (grunt) {
11 |
12 | // Load grunt tasks automatically
13 | require('load-grunt-tasks')(grunt);
14 |
15 | // Time how long tasks take. Can help when optimizing build times
16 | require('time-grunt')(grunt);
17 |
18 | // Configurable paths
19 | var config = {
20 | app: 'app',
21 | dist: 'dist'
22 | };
23 |
24 | grunt.initConfig({
25 |
26 | // Project settings
27 | config: config,
28 |
29 | // Watches files for changes and runs tasks based on the changed files
30 | watch: {
31 | bower: {
32 | files: ['bower.json'],
33 | tasks: ['bowerInstall']
34 | },
35 | js: {
36 | files: ['<%= config.app %>/scripts/{,*/}*.js'],
37 | tasks: ['jshint'],
38 | options: {
39 | livereload: true
40 | }
41 | },
42 | gruntfile: {
43 | files: ['Gruntfile.js']
44 | },
45 | styles: {
46 | files: ['<%= config.app %>/styles/{,*/}*.css'],
47 | tasks: [],
48 | options: {
49 | livereload: true
50 | }
51 | },
52 | livereload: {
53 | options: {
54 | livereload: '<%= connect.options.livereload %>'
55 | },
56 | files: [
57 | '<%= config.app %>/*.html',
58 | '<%= config.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
59 | '<%= config.app %>/manifest.json',
60 | '<%= config.app %>/_locales/{,*/}*.json'
61 | ]
62 | }
63 | },
64 |
65 | // Grunt server and debug server setting
66 | connect: {
67 | options: {
68 | port: 9000,
69 | livereload: 35729,
70 | // change this to '0.0.0.0' to access the server from outside
71 | hostname: 'localhost'
72 | },
73 | chrome: {
74 | options: {
75 | open: false,
76 | base: [
77 | '<%= config.app %>'
78 | ]
79 | }
80 | },
81 | test: {
82 | options: {
83 | open: false,
84 | base: [
85 | 'test',
86 | '<%= config.app %>'
87 | ]
88 | }
89 | }
90 | },
91 |
92 | // Empties folders to start fresh
93 | clean: {
94 | chrome: {
95 | },
96 | dist: {
97 | files: [{
98 | dot: true,
99 | src: [
100 | '<%= config.dist %>/*',
101 | '!<%= config.dist %>/.git*'
102 | ]
103 | }]
104 | }
105 | },
106 |
107 | // Make sure code styles are up to par and there are no obvious mistakes
108 | jshint: {
109 | options: {
110 | jshintrc: '.jshintrc',
111 | reporter: require('jshint-stylish')
112 | },
113 | all: [
114 | 'Gruntfile.js',
115 | '<%= config.app %>/scripts/{,*/}*.js',
116 | '!<%= config.app %>/scripts/vendor/*',
117 | 'test/spec/{,*/}*.js'
118 | ]
119 | },
120 | mocha: {
121 | all: {
122 | options: {
123 | run: true,
124 | urls: ['http://localhost:<%= connect.options.port %>/index.html'],
125 | log: true
126 | }
127 | }
128 | },
129 |
130 | // Automatically inject Bower components into the HTML file
131 | bowerInstall: {
132 | app: {
133 | src: [
134 | '<%= config.app %>/*.html'
135 | ]
136 | }
137 | },
138 |
139 | // Reads HTML for usemin blocks to enable smart builds that automatically
140 | // concat, minify and revision files. Creates configurations in memory so
141 | // additional tasks can operate on them
142 | useminPrepare: {
143 | options: {
144 | dest: '<%= config.dist %>'
145 | },
146 | html: [
147 | '<%= config.app %>/popup.html',
148 | '<%= config.app %>/options.html'
149 | ]
150 | },
151 |
152 | // Performs rewrites based on rev and the useminPrepare configuration
153 | usemin: {
154 | options: {
155 | assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images']
156 | },
157 | html: ['<%= config.dist %>/{,*/}*.html'],
158 | css: ['<%= config.dist %>/styles/{,*/}*.css']
159 | },
160 |
161 | // The following *-min tasks produce minifies files in the dist folder
162 | imagemin: {
163 | dist: {
164 | files: [{
165 | expand: true,
166 | cwd: '<%= config.app %>/images',
167 | src: '{,*/}*.{gif,jpeg,jpg,png}',
168 | dest: '<%= config.dist %>/images'
169 | }]
170 | }
171 | },
172 |
173 | svgmin: {
174 | dist: {
175 | files: [{
176 | expand: true,
177 | cwd: '<%= config.app %>/images',
178 | src: '{,*/}*.svg',
179 | dest: '<%= config.dist %>/images'
180 | }]
181 | }
182 | },
183 |
184 | htmlmin: {
185 | dist: {
186 | options: {
187 | // removeCommentsFromCDATA: true,
188 | // collapseWhitespace: true,
189 | // collapseBooleanAttributes: true,
190 | // removeAttributeQuotes: true,
191 | // removeRedundantAttributes: true,
192 | // useShortDoctype: true,
193 | // removeEmptyAttributes: true,
194 | // removeOptionalTags: true
195 | },
196 | files: [{
197 | expand: true,
198 | cwd: '<%= config.app %>',
199 | src: '*.html',
200 | dest: '<%= config.dist %>'
201 | }]
202 | }
203 | },
204 |
205 | // By default, your `index.html`'s will take care of
206 | // minification. These next options are pre-configured if you do not wish
207 | // to use the Usemin blocks.
208 | // cssmin: {
209 | // dist: {
210 | // files: {
211 | // '<%= config.dist %>/styles/main.css': [
212 | // '<%= config.app %>/styles/{,*/}*.css'
213 | // ]
214 | // }
215 | // }
216 | // },
217 | // uglify: {
218 | // dist: {
219 | // files: {
220 | // '<%= config.dist %>/scripts/scripts.js': [
221 | // '<%= config.dist %>/scripts/scripts.js'
222 | // ]
223 | // }
224 | // }
225 | // },
226 | // concat: {
227 | // dist: {}
228 | // },
229 |
230 | // Copies remaining files to places other tasks can use
231 | copy: {
232 | dist: {
233 | files: [{
234 | expand: true,
235 | dot: true,
236 | cwd: '<%= config.app %>',
237 | dest: '<%= config.dist %>',
238 | src: [
239 | '*.{ico,png,txt}',
240 | 'images/{,*/}*.{webp,gif}',
241 | '{,*/}*.html',
242 | 'styles/{,*/}*.css',
243 | 'styles/fonts/{,*/}*.*',
244 | '_locales/{,*/}*.json',
245 | ]
246 | }]
247 | }
248 | },
249 |
250 | // Run some tasks in parallel to speed up build process
251 | concurrent: {
252 | chrome: [
253 | ],
254 | dist: [
255 | 'imagemin',
256 | 'svgmin'
257 | ],
258 | test: [
259 | ]
260 | },
261 |
262 | // Auto buildnumber, exclude debug files. smart builds that event pages
263 | chromeManifest: {
264 | dist: {
265 | options: {
266 | buildnumber: true,
267 | background: {
268 | target: 'scripts/background.js',
269 | exclude: [
270 | 'scripts/chromereload.js'
271 | ]
272 | }
273 | },
274 | src: '<%= config.app %>',
275 | dest: '<%= config.dist %>'
276 | }
277 | },
278 |
279 | // Compres dist files to package
280 | compress: {
281 | dist: {
282 | options: {
283 | archive: function() {
284 | var manifest = grunt.file.readJSON('app/manifest.json');
285 | return 'package/gatechomscsclass-' + manifest.version + '.zip';
286 | }
287 | },
288 | files: [{
289 | expand: true,
290 | cwd: 'dist/',
291 | src: ['**'],
292 | dest: ''
293 | }]
294 | }
295 | }
296 | });
297 |
298 | grunt.registerTask('debug', function () {
299 | grunt.task.run([
300 | 'jshint',
301 | 'concurrent:chrome',
302 | 'connect:chrome',
303 | 'watch'
304 | ]);
305 | });
306 |
307 | grunt.registerTask('test', [
308 | 'connect:test',
309 | 'mocha'
310 | ]);
311 |
312 | grunt.registerTask('build', [
313 | 'clean:dist',
314 | 'chromeManifest:dist',
315 | 'useminPrepare',
316 | 'concurrent:dist',
317 | 'cssmin',
318 | 'concat',
319 | 'uglify',
320 | 'copy',
321 | 'usemin',
322 | 'compress'
323 | ]);
324 |
325 | grunt.registerTask('default', [
326 | 'jshint',
327 | 'test',
328 | 'build'
329 | ]);
330 | };
331 |
--------------------------------------------------------------------------------