| 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 |