OLD | NEW |
| (Empty) |
1 module.exports = function(grunt) { | |
2 grunt.loadNpmTasks('grunt-contrib-uglify'); | |
3 grunt.loadNpmTasks('grunt-gjslint'); | |
4 grunt.loadNpmTasks('grunt-checkrepo'); | |
5 grunt.loadNpmTasks('grunt-karma'); | |
6 grunt.loadNpmTasks('grunt-saucelabs'); | |
7 grunt.loadNpmTasks('grunt-git-status'); | |
8 grunt.loadNpmTasks('grunt-template'); | |
9 | |
10 var targetConfig = require('./target-config.js'); | |
11 | |
12 var sourceMap = require('source-map'); | |
13 | |
14 var config = { | |
15 uglify: {}, | |
16 template: {}, | |
17 wrap: {}, | |
18 sourceMapConcat: {}, | |
19 }; | |
20 | |
21 function concat(sources, target, defines) { | |
22 config.uglify[target] = { | |
23 options: { | |
24 sourceMap: true, | |
25 sourceMapName: target + '.map', | |
26 wrap: false, | |
27 compress: { | |
28 global_defs: defines, | |
29 dead_code: false | |
30 }, | |
31 mangle: false | |
32 }, | |
33 nonull: true, | |
34 dest: target, | |
35 src: sources | |
36 }; | |
37 return 'uglify:' + target; | |
38 } | |
39 | |
40 function compress(source, target, defines) { | |
41 var name = concat([source], target, defines); | |
42 var record = config.uglify[target]; | |
43 record.options.sourceMapIn = source + '.map'; | |
44 record.options.banner = grunt.file.read('templates/boilerplate'); | |
45 record.options.wrap = true; | |
46 record.options.compress.dead_code = true; | |
47 record.options.mangle = { eval: true }; | |
48 return name; | |
49 } | |
50 | |
51 function genTarget(target) { | |
52 var config = targetConfig[target]; | |
53 var newGens = [ | |
54 generateFromTemplate('templates/web-animations.js', {target: target}, targ
et + '.dev.js'), | |
55 generateFromTemplate('templates/web-animations.html', {src: config.src}, t
arget + '.dev.html'), | |
56 generateFromTemplate('templates/runner.html', {target: target}, 'test/runn
er-' + target + '.html')]; | |
57 return newGens; | |
58 } | |
59 | |
60 function generateFromTemplate(source, data, target) { | |
61 var targetSpec = {}; | |
62 targetSpec[target] = [source]; | |
63 config.template[target] = { | |
64 options: { | |
65 data: data | |
66 }, | |
67 files: targetSpec | |
68 } | |
69 return 'template:' + target; | |
70 } | |
71 | |
72 function guard(source, target) { | |
73 config.wrap[target] = { | |
74 source: source, | |
75 preamble: '(function() {\n' + | |
76 ' if (document.documentElement.animate) {\n' + | |
77 ' var player = document.documentElement.animate([], 0);\n' + | |
78 ' var load = true;\n' + | |
79 ' if (player) {\n' + | |
80 ' load = false;\n' + | |
81 ' "play|currentTime|pause|reverse|playbackRate|cancel|finis
h|startTime|playState".split("|").forEach(function(t) {\n' + | |
82 ' if (player[t] === undefined) {\n' + | |
83 ' load = true;\n' + | |
84 ' }\n' + | |
85 ' });\n' + | |
86 ' }\n' + | |
87 ' if (!load) { return; }' + | |
88 ' }\n', | |
89 postamble: '})();' | |
90 }; | |
91 return 'wrap:' + target; | |
92 } | |
93 | |
94 function concatWithMaps(sources, target) { | |
95 config.sourceMapConcat[target] = { | |
96 sources: sources | |
97 } | |
98 return 'sourceMapConcat:' + target; | |
99 }; | |
100 | |
101 var concatDefines = { | |
102 WEB_ANIMATIONS_TESTING: false | |
103 }; | |
104 | |
105 function buildWebAnimations1(target) { | |
106 var config = targetConfig[target]; | |
107 return genTarget(target).concat([ | |
108 concat(config.scopeSrc.concat(config.sharedSrc).concat(config.webAnimation
s1Src), 'inter-raw-' + target + '.js', concatDefines), | |
109 guard('inter-raw-' + target + '.js', 'inter-' + target + '.js'), | |
110 compress('inter-' + target + '.js', target + '.min.js', concatDefines) | |
111 ]); | |
112 } | |
113 | |
114 function buildWebAnimationsNext(target) { | |
115 var config = targetConfig[target]; | |
116 return genTarget(target).concat([ | |
117 concat(config.scopeSrc.concat(config.sharedSrc), 'inter-' + target + '-pre
amble.js', concatDefines), | |
118 concat(config.webAnimations1Src, 'inter-component-' + target + 'web-animat
ions-1.js', concatDefines), | |
119 guard('inter-component-' + target + 'web-animations-1.js', 'inter-guarded-
' + target + '-web-animations-1.js'), | |
120 concat(config.webAnimationsNextSrc, 'inter-component-' + target + '.js', c
oncatDefines), | |
121 concatWithMaps(['inter-' + target + '-preamble.js', 'inter-guarded-' + tar
get + '-web-animations-1.js', 'inter-component-' + target + '.js'], | |
122 'inter-' + target + '.js'), | |
123 compress('inter-' + target + '.js', target + '.min.js', concatDefines) | |
124 ]); | |
125 } | |
126 | |
127 grunt.registerTask('web-animations', buildWebAnimations1('web-animations')); | |
128 grunt.registerTask('web-animations-next', buildWebAnimationsNext('web-animatio
ns-next')); | |
129 grunt.registerTask('web-animations-next-lite', buildWebAnimationsNext('web-ani
mations-next-lite')); | |
130 | |
131 var testTargets = {'web-animations': {}, 'web-animations-next': {}}; | |
132 | |
133 grunt.initConfig({ | |
134 uglify: config.uglify, | |
135 template: config.template, | |
136 wrap: config.wrap, | |
137 sourceMapConcat: config.sourceMapConcat, | |
138 checkrepo: { | |
139 all: { | |
140 clean: true, | |
141 }, | |
142 }, | |
143 'git-status': { | |
144 all: { | |
145 }, | |
146 }, | |
147 gjslint: { | |
148 options: { | |
149 flags: [ | |
150 '--nojsdoc', | |
151 '--strict', | |
152 '--disable 7,121,110', // 7: Wrong blank line count | |
153 // 121: Illegal comma at end of object literal | |
154 // 110: Line too long | |
155 ], | |
156 reporter: { | |
157 name: 'console' | |
158 } | |
159 }, | |
160 all: { | |
161 src: [ | |
162 'src/*.js', | |
163 'test/*.js', | |
164 'test/js/*.js', | |
165 ], | |
166 } | |
167 }, | |
168 test: testTargets, | |
169 sauce: testTargets, | |
170 }); | |
171 | |
172 | |
173 grunt.task.registerMultiTask('test', 'Run <target> tests under Karma', functio
n() { | |
174 var done = this.async(); | |
175 var karmaConfig = require('karma/lib/config').parseConfig(require('path').re
solve('test/karma-config.js'), {}); | |
176 var config = targetConfig[this.target]; | |
177 karmaConfig.files = ['test/runner.js'].concat(config.src, config.test); | |
178 var karmaServer = require('karma').server; | |
179 karmaServer.start(karmaConfig, function(exitCode) { | |
180 done(exitCode === 0); | |
181 }); | |
182 }); | |
183 | |
184 grunt.task.registerMultiTask('sauce', 'Run <target> tests under Karma on Sauce
labs', function() { | |
185 var done = this.async(); | |
186 var karmaConfig = require('karma/lib/config').parseConfig(require('path').re
solve('test/karma-config-ci.js'), {}); | |
187 var config = targetConfig[this.target]; | |
188 karmaConfig.files = ['test/runner.js'].concat(config.src, config.test); | |
189 karmaConfig.sauceLabs.testName = 'web-animation-next ' + this.target + ' Uni
t tests'; | |
190 var karmaServer = require('karma').server; | |
191 karmaServer.start(karmaConfig, function(exitCode) { | |
192 done(exitCode === 0); | |
193 }); | |
194 }); | |
195 | |
196 grunt.task.registerMultiTask('sourceMapConcat', 'concat source files and produ
ce combined source map', | |
197 function() { | |
198 var sources = this.data.sources.map(grunt.file.read); | |
199 var sourceMaps = this.data.sources.map(function(f) { return grunt.file.rea
d(f + '.map'); }); | |
200 var out = ""; | |
201 var outMapGenerator = new sourceMap.SourceMapGenerator({file: this.target}
); | |
202 var lineDelta = 0; | |
203 for (var i = 0; i < sources.length; i++) { | |
204 out += sources[i]; | |
205 new sourceMap.SourceMapConsumer(sourceMaps[i]).eachMapping(function(mapp
ing) { | |
206 outMapGenerator.addMapping({ | |
207 generated: {line: mapping.generatedLine + lineDelta, column: mapping
.generatedColumn}, | |
208 original: {line: mapping.originalLine, column: mapping.originalColum
n}, | |
209 source: mapping.source, name: mapping.name}); | |
210 }); | |
211 var sourceLines = sources[i].split('\n'); | |
212 lineDelta += sourceLines.length; | |
213 if (sources[i][sources[i].length - 1] !== '\n') { | |
214 out += '\n'; | |
215 } | |
216 } | |
217 grunt.file.write(this.target, out); | |
218 grunt.file.write(this.target + '.map', outMapGenerator.toString()); | |
219 }); | |
220 | |
221 grunt.task.registerMultiTask('wrap', 'Wrap <target> source file and update sou
rce map', | |
222 function() { | |
223 var inFile = grunt.file.read(this.data.source); | |
224 var inMap = grunt.file.read(this.data.source + '.map'); | |
225 var inLines = inFile.split('\n'); | |
226 var i = 0; | |
227 | |
228 // Discover copyright header | |
229 while (inLines[i].length < 2 || inLines[i].substring(0, 2) == '//') { | |
230 i++; | |
231 } | |
232 | |
233 // Fix mapping footer | |
234 var postamble = this.data.postamble; | |
235 if (inLines[inLines.length - 1].substring(0, 21) == '//# sourceMappingURL=
') { | |
236 postamble += '\n//# sourceMappingURL=' + this.target + '.map'; | |
237 } | |
238 | |
239 if (i > 0) { | |
240 var banner = inLines.slice(0, i).join('\n') + '\n'; | |
241 } else { | |
242 var banner = ''; | |
243 } | |
244 | |
245 var source = inLines.slice(i, inLines.length - 1).join('\n'); | |
246 | |
247 grunt.file.write(this.target, banner + this.data.preamble + source + posta
mble); | |
248 var preLines = this.data.preamble.split('\n'); | |
249 var lineDelta = preLines.length; | |
250 if (this.data.preamble[this.data.preamble.length - 1] == '\n') { | |
251 var charDelta = 0; | |
252 } else { | |
253 var charDelta = preLines[lineDelta - 1].length; | |
254 lineDelta -= 1; | |
255 } | |
256 var inMapConsumer = new sourceMap.SourceMapConsumer(inMap); | |
257 var outMapGenerator = new sourceMap.SourceMapGenerator({file: this.target}
); | |
258 inMapConsumer.eachMapping(function(mapping) { | |
259 if (mapping.generatedLine == i + 1) { | |
260 mapping.generatedColumn += charDelta; | |
261 } | |
262 mapping.generatedLine += lineDelta; | |
263 outMapGenerator.addMapping( | |
264 {generated: {line: mapping.generatedLine, column: mapping.generatedCol
umn}, | |
265 original: {line: mapping.originalLine, column: mapping.originalColumn}
, | |
266 source: mapping.source, name: mapping.name}); | |
267 }); | |
268 grunt.file.write(this.target + '.map', outMapGenerator.toString()); | |
269 }); | |
270 | |
271 grunt.task.registerTask('clean', 'Remove files generated by grunt', function()
{ | |
272 grunt.file.expand('web-animations*').concat(grunt.file.expand('test/runner-*
.html')).concat(grunt.file.expand('inter-*')).forEach(function(file) { | |
273 grunt.file.delete(file); | |
274 grunt.log.writeln('File ' + file + ' removed'); | |
275 }); | |
276 }); | |
277 | |
278 grunt.task.registerTask('default', ['web-animations', 'web-animations-next', '
web-animations-next-lite', 'gjslint']); | |
279 }; | |
OLD | NEW |