blob: 5c8580cd46f30408dab26093bde500f6b8559d25 [file] [log] [blame]
Matteo Scandolo7cd88ba2015-12-16 14:23:08 -08001/* global FastClick, smoothScroll */
2angular.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
49function 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
79function 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
245function 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 */
281var 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 })();