Matteo Scandolo | 46b5610 | 2015-12-16 14:23:08 -0800 | [diff] [blame^] | 1 | /* global FastClick, smoothScroll */ |
| 2 | angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'plunker', 'ngTouch', 'ngAnimate', 'ngSanitize'], function($httpProvider){ |
| 3 | FastClick.attach(document.body); |
| 4 | delete $httpProvider.defaults.headers.common['X-Requested-With']; |
| 5 | }).run(['$location', function($location){ |
| 6 | //Allows us to navigate to the correct element on initialization |
| 7 | if ($location.path() !== '' && $location.path() !== '/') { |
| 8 | smoothScroll(document.getElementById($location.path().substring(1)), 500, function(el) { |
| 9 | location.replace('#' + el.id); |
| 10 | }); |
| 11 | } |
| 12 | }]).factory('buildFilesService', function ($http, $q) { |
| 13 | |
| 14 | var moduleMap; |
| 15 | var rawFiles; |
| 16 | |
| 17 | return { |
| 18 | getModuleMap: getModuleMap, |
| 19 | getRawFiles: getRawFiles, |
| 20 | get: function () { |
| 21 | return $q.all({ |
| 22 | moduleMap: getModuleMap(), |
| 23 | rawFiles: getRawFiles() |
| 24 | }); |
| 25 | } |
| 26 | }; |
| 27 | |
| 28 | function getModuleMap() { |
| 29 | return moduleMap ? $q.when(moduleMap) : $http.get('assets/module-mapping.json') |
| 30 | .then(function (result) { |
| 31 | moduleMap = result.data; |
| 32 | return moduleMap; |
| 33 | }); |
| 34 | } |
| 35 | |
| 36 | function getRawFiles() { |
| 37 | return rawFiles ? $q.when(rawFiles) : $http.get('assets/raw-files.json') |
| 38 | .then(function (result) { |
| 39 | rawFiles = result.data; |
| 40 | return rawFiles; |
| 41 | }); |
| 42 | } |
| 43 | |
| 44 | }) |
| 45 | .controller('MainCtrl', MainCtrl) |
| 46 | .controller('SelectModulesCtrl', SelectModulesCtrl) |
| 47 | .controller('DownloadCtrl', DownloadCtrl); |
| 48 | |
| 49 | function MainCtrl($scope, $http, $document, $uibModal, orderByFilter) { |
| 50 | // Grab old version docs |
| 51 | $http.get('/versions-mapping.json') |
| 52 | .then(function(result) { |
| 53 | $scope.oldDocs = result.data; |
| 54 | }); |
| 55 | |
| 56 | $scope.showBuildModal = function() { |
| 57 | var modalInstance = $uibModal.open({ |
| 58 | templateUrl: 'buildModal.html', |
| 59 | controller: 'SelectModulesCtrl', |
| 60 | resolve: { |
| 61 | modules: function(buildFilesService) { |
| 62 | return buildFilesService.getModuleMap() |
| 63 | .then(function (moduleMap) { |
| 64 | return Object.keys(moduleMap); |
| 65 | }); |
| 66 | } |
| 67 | } |
| 68 | }); |
| 69 | }; |
| 70 | |
| 71 | $scope.showDownloadModal = function() { |
| 72 | var modalInstance = $uibModal.open({ |
| 73 | templateUrl: 'downloadModal.html', |
| 74 | controller: 'DownloadCtrl' |
| 75 | }); |
| 76 | }; |
| 77 | } |
| 78 | |
| 79 | function SelectModulesCtrl($scope, $uibModalInstance, modules, buildFilesService) { |
| 80 | $scope.selectedModules = []; |
| 81 | $scope.modules = modules; |
| 82 | |
| 83 | $scope.selectedChanged = function(module, selected) { |
| 84 | if (selected) { |
| 85 | $scope.selectedModules.push(module); |
| 86 | } else { |
| 87 | $scope.selectedModules.splice($scope.selectedModules.indexOf(module), 1); |
| 88 | } |
| 89 | }; |
| 90 | |
| 91 | $scope.downloadBuild = function () { |
| 92 | $uibModalInstance.close($scope.selectedModules); |
| 93 | }; |
| 94 | |
| 95 | $scope.cancel = function () { |
| 96 | $uibModalInstance.dismiss(); |
| 97 | }; |
| 98 | |
| 99 | $scope.isOldBrowser = function () { |
| 100 | return isOldBrowser; |
| 101 | }; |
| 102 | |
| 103 | $scope.build = function (selectedModules, version) { |
| 104 | /* global JSZip, saveAs */ |
| 105 | var moduleMap, rawFiles; |
| 106 | |
| 107 | buildFilesService.get().then(function (buildFiles) { |
| 108 | moduleMap = buildFiles.moduleMap; |
| 109 | rawFiles = buildFiles.rawFiles; |
| 110 | |
| 111 | generateBuild(); |
| 112 | }); |
| 113 | |
| 114 | function generateBuild() { |
| 115 | var srcModuleNames = selectedModules |
| 116 | .map(function (module) { |
| 117 | return moduleMap[module]; |
| 118 | }) |
| 119 | .reduce(function (toBuild, module) { |
| 120 | addIfNotExists(toBuild, module.name); |
| 121 | |
| 122 | module.dependencies.forEach(function (depName) { |
| 123 | addIfNotExists(toBuild, depName); |
| 124 | }); |
| 125 | return toBuild; |
| 126 | }, []); |
| 127 | |
| 128 | var srcModules = srcModuleNames |
| 129 | .map(function (moduleName) { |
| 130 | return moduleMap[moduleName]; |
| 131 | }); |
| 132 | |
| 133 | var srcModuleFullNames = srcModules |
| 134 | .map(function (module) { |
| 135 | return module.moduleName; |
| 136 | }); |
| 137 | |
| 138 | var srcJsContent = srcModules |
| 139 | .reduce(function (buildFiles, module) { |
| 140 | return buildFiles.concat(module.srcFiles); |
| 141 | }, []) |
| 142 | .map(getFileContent) |
| 143 | .join('\n') |
| 144 | ; |
| 145 | |
| 146 | var jsFile = createNoTplFile(srcModuleFullNames, srcJsContent); |
| 147 | |
| 148 | var tplModuleNames = srcModules |
| 149 | .reduce(function (tplModuleNames, module) { |
| 150 | return tplModuleNames.concat(module.tplModules); |
| 151 | }, []); |
| 152 | |
| 153 | var tplJsContent = srcModules |
| 154 | .reduce(function (buildFiles, module) { |
| 155 | return buildFiles.concat(module.tpljsFiles); |
| 156 | }, []) |
| 157 | .map(getFileContent) |
| 158 | .join('\n') |
| 159 | ; |
| 160 | |
| 161 | var jsTplFile = createWithTplFile(srcModuleFullNames, srcJsContent, tplModuleNames, tplJsContent); |
| 162 | |
| 163 | var cssContent = srcModules |
| 164 | .map(function (module) { |
| 165 | return module.css; |
| 166 | }) |
| 167 | .filter(function (css) { |
| 168 | return css; |
| 169 | }) |
| 170 | .join('\n') |
| 171 | ; |
| 172 | |
| 173 | var cssJsContent = srcModules |
| 174 | .map(function (module) { |
| 175 | return module.cssJs; |
| 176 | }) |
| 177 | .filter(function (cssJs) { |
| 178 | return cssJs; |
| 179 | }) |
| 180 | .join('\n') |
| 181 | ; |
| 182 | |
| 183 | var footer = cssJsContent; |
| 184 | |
| 185 | var zip = new JSZip(); |
| 186 | zip.file('ui-bootstrap-custom-' + version + '.js', rawFiles.banner + jsFile + footer); |
| 187 | zip.file('ui-bootstrap-custom-' + version + '.min.js', rawFiles.banner + uglify(jsFile + footer)); |
| 188 | zip.file('ui-bootstrap-custom-tpls-' + version + '.js', rawFiles.banner + jsTplFile + footer); |
| 189 | zip.file('ui-bootstrap-custom-tpls-' + version + '.min.js', rawFiles.banner + uglify(jsTplFile + footer)); |
| 190 | zip.file('ui-bootstrap-custom-tpls-' + version + '.min.js', rawFiles.banner + uglify(jsTplFile + footer)); |
| 191 | |
| 192 | if (cssContent) { |
| 193 | zip.file('ui-bootstrap-custom-' + version + '-csp.css', rawFiles.cssBanner + cssContent); |
| 194 | } |
| 195 | |
| 196 | saveAs(zip.generate({type: 'blob'}), 'ui-bootstrap-custom-build.zip'); |
| 197 | } |
| 198 | |
| 199 | function createNoTplFile(srcModuleNames, srcJsContent) { |
| 200 | return 'angular.module("ui.bootstrap", [' + srcModuleNames.join(',') + ']);\n' + |
| 201 | srcJsContent; |
| 202 | } |
| 203 | |
| 204 | function createWithTplFile(srcModuleNames, srcJsContent, tplModuleNames, tplJsContent) { |
| 205 | var depModuleNames = srcModuleNames.slice(); |
| 206 | depModuleNames.unshift('"ui.bootstrap.tpls"'); |
| 207 | |
| 208 | return 'angular.module("ui.bootstrap", [' + depModuleNames.join(',') + ']);\n' + |
| 209 | 'angular.module("ui.bootstrap.tpls", [' + tplModuleNames.join(',') + ']);\n' + |
| 210 | srcJsContent + '\n' + tplJsContent; |
| 211 | |
| 212 | } |
| 213 | |
| 214 | function addIfNotExists(array, element) { |
| 215 | if (array.indexOf(element) == -1) { |
| 216 | array.push(element); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | function getFileContent(fileName) { |
| 221 | return rawFiles.files[fileName]; |
| 222 | } |
| 223 | |
| 224 | function uglify(js) { |
| 225 | /* global UglifyJS */ |
| 226 | |
| 227 | var ast = UglifyJS.parse(js); |
| 228 | ast.figure_out_scope(); |
| 229 | |
| 230 | var compressor = UglifyJS.Compressor(); |
| 231 | var compressedAst = ast.transform(compressor); |
| 232 | |
| 233 | compressedAst.figure_out_scope(); |
| 234 | compressedAst.compute_char_frequency(); |
| 235 | compressedAst.mangle_names(); |
| 236 | |
| 237 | var stream = UglifyJS.OutputStream(); |
| 238 | compressedAst.print(stream); |
| 239 | |
| 240 | return stream.toString(); |
| 241 | } |
| 242 | }; |
| 243 | } |
| 244 | |
| 245 | function DownloadCtrl($scope, $uibModalInstance) { |
| 246 | $scope.options = { |
| 247 | minified: true, |
| 248 | tpls: true |
| 249 | }; |
| 250 | |
| 251 | $scope.download = function (version) { |
| 252 | var options = $scope.options; |
| 253 | |
| 254 | var downloadUrl = ['ui-bootstrap-']; |
| 255 | if (options.tpls) { |
| 256 | downloadUrl.push('tpls-'); |
| 257 | } |
| 258 | downloadUrl.push(version); |
| 259 | if (options.minified) { |
| 260 | downloadUrl.push('.min'); |
| 261 | } |
| 262 | downloadUrl.push('.js'); |
| 263 | |
| 264 | return downloadUrl.join(''); |
| 265 | }; |
| 266 | |
| 267 | $scope.cancel = function () { |
| 268 | $uibModalInstance.dismiss(); |
| 269 | }; |
| 270 | } |
| 271 | |
| 272 | /* |
| 273 | * The following compatibility check is from: |
| 274 | * |
| 275 | * Bootstrap Customizer (http://getbootstrap.com/customize/) |
| 276 | * Copyright 2011-2014 Twitter, Inc. |
| 277 | * |
| 278 | * Licensed under the Creative Commons Attribution 3.0 Unported License. For |
| 279 | * details, see http://creativecommons.org/licenses/by/3.0/. |
| 280 | */ |
| 281 | var isOldBrowser; |
| 282 | (function () { |
| 283 | |
| 284 | var supportsFile = (window.File && window.FileReader && window.FileList && window.Blob); |
| 285 | function failback() { |
| 286 | isOldBrowser = true; |
| 287 | } |
| 288 | /** |
| 289 | * Based on: |
| 290 | * Blob Feature Check v1.1.0 |
| 291 | * https://github.com/ssorallen/blob-feature-check/ |
| 292 | * License: Public domain (http://unlicense.org) |
| 293 | */ |
| 294 | var url = window.URL; |
| 295 | var svg = new Blob( |
| 296 | ['<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>'], |
| 297 | { type: 'image/svg+xml;charset=utf-8' } |
| 298 | ); |
| 299 | var objectUrl = url.createObjectURL(svg); |
| 300 | |
| 301 | if (/^blob:/.exec(objectUrl) === null || !supportsFile) { |
| 302 | // `URL.createObjectURL` created a URL that started with something other |
| 303 | // than "blob:", which means it has been polyfilled and is not supported by |
| 304 | // this browser. |
| 305 | failback(); |
| 306 | } else { |
| 307 | angular.element('<img/>') |
| 308 | .on('load', function () { |
| 309 | isOldBrowser = false; |
| 310 | }) |
| 311 | .on('error', failback) |
| 312 | .attr('src', objectUrl); |
| 313 | } |
| 314 | |
| 315 | })(); |