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 buildMinifill(target) { |
| 106 var config = targetConfig[target]; |
| 107 return genTarget(target).concat([ |
| 108 concat(config.scopeSrc.concat(config.sharedSrc).concat(config.minifillSrc)
, '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 buildMaxifill(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.minifillSrc, 'inter-component-' + target + 'minifill.js', co
ncatDefines), |
| 119 guard('inter-component-' + target + 'minifill.js', 'inter-guarded-' + targ
et + '-minifill.js'), |
| 120 concat(config.maxifillSrc, 'inter-component-' + target + '.js', concatDefi
nes), |
| 121 concatWithMaps(['inter-' + target + '-preamble.js', 'inter-guarded-' + tar
get + '-minifill.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', buildMinifill('web-animations')); |
| 128 grunt.registerTask('web-animations-next', buildMaxifill('web-animations-next')
); |
| 129 grunt.registerTask('web-animations-next-lite', buildMaxifill('web-animations-n
ext-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 |