Skip to content

Commit e10a1e6

Browse files
committed
fix(demo): make custom builds work
Part of angular-ui#2892 Fixes angular-ui#2960 Fixes angular-ui#2847 Fixes angular-ui#2625 Fixes angular-ui#2489 Fixes angular-ui#2357 Fixes angular-ui#2176
1 parent f07fecb commit e10a1e6

File tree

5 files changed

+218
-13
lines changed

5 files changed

+218
-13
lines changed

Diff for: assets/app.js

+200-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* global FastClick, smoothScroll */
12
angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'plunker', 'ngTouch'], function($httpProvider){
23
FastClick.attach(document.body);
34
delete $httpProvider.defaults.headers.common['X-Requested-With'];
@@ -8,7 +9,39 @@ angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'plunker', 'ngTouch'], func
89
location.replace(el.id);
910
});
1011
}
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+
});
1245

1346
var builderUrl = "http://50.116.42.77:3001";
1447

@@ -18,10 +51,11 @@ function MainCtrl($scope, $http, $document, $modal, orderByFilter) {
1851
templateUrl: 'buildModal.html',
1952
controller: 'SelectModulesCtrl',
2053
resolve: {
21-
modules: function() {
22-
return $http.get(builderUrl + "/api/bootstrap").then(function(response) {
23-
return response.data.modules;
24-
});
54+
modules: function(buildFilesService) {
55+
return buildFilesService.getModuleMap()
56+
.then(function (moduleMap) {
57+
return Object.keys(moduleMap);
58+
});
2559
}
2660
}
2761
});
@@ -35,7 +69,7 @@ function MainCtrl($scope, $http, $document, $modal, orderByFilter) {
3569
};
3670
}
3771

38-
var SelectModulesCtrl = function($scope, $modalInstance, modules) {
72+
var SelectModulesCtrl = function($scope, $modalInstance, modules, buildFilesService) {
3973
$scope.selectedModules = [];
4074
$scope.modules = modules;
4175

@@ -55,12 +89,122 @@ var SelectModulesCtrl = function($scope, $modalInstance, modules) {
5589
$modalInstance.dismiss();
5690
};
5791

58-
$scope.download = function (selectedModules) {
59-
var downloadUrl = builderUrl + "/api/bootstrap/download?";
60-
angular.forEach(selectedModules, function(module) {
61-
downloadUrl += "modules=" + module + "&";
92+
$scope.isOldBrowser = function () {
93+
return isOldBrowser;
94+
};
95+
96+
$scope.build = function (selectedModules, version) {
97+
/* global JSZip, saveAs */
98+
var moduleMap, rawFiles;
99+
100+
buildFilesService.get().then(function (buildFiles) {
101+
moduleMap = buildFiles.moduleMap;
102+
rawFiles = buildFiles.rawFiles;
103+
104+
generateBuild();
62105
});
63-
return downloadUrl;
106+
107+
function generateBuild() {
108+
var srcModuleNames = selectedModules
109+
.map(function (module) {
110+
return moduleMap[module];
111+
})
112+
.reduce(function (toBuild, module) {
113+
addIfNotExists(toBuild, module.name);
114+
115+
module.dependencies.forEach(function (depName) {
116+
addIfNotExists(toBuild, depName);
117+
});
118+
return toBuild;
119+
}, []);
120+
121+
var srcModules = srcModuleNames
122+
.map(function (moduleName) {
123+
return moduleMap[moduleName];
124+
});
125+
126+
var srcModuleFullNames = srcModules
127+
.map(function (module) {
128+
return module.moduleName;
129+
});
130+
131+
var srcJsContent = srcModules
132+
.reduce(function (buildFiles, module) {
133+
return buildFiles.concat(module.srcFiles);
134+
}, [])
135+
.map(getFileContent)
136+
.join('\n')
137+
;
138+
139+
var jsFile = createNoTplFile(srcModuleFullNames, srcJsContent);
140+
141+
var tplModuleNames = srcModules
142+
.reduce(function (tplModuleNames, module) {
143+
return tplModuleNames.concat(module.tplModules);
144+
}, []);
145+
146+
var tplJsContent = srcModules
147+
.reduce(function (buildFiles, module) {
148+
return buildFiles.concat(module.tpljsFiles);
149+
}, [])
150+
.map(getFileContent)
151+
.join('\n')
152+
;
153+
154+
var jsTplFile = createWithTplFile(srcModuleFullNames, srcJsContent, tplModuleNames, tplJsContent);
155+
156+
var zip = new JSZip();
157+
zip.file('ui-bootstrap-custom-' + version + '.js', rawFiles.banner + jsFile);
158+
zip.file('ui-bootstrap-custom-' + version + '.min.js', rawFiles.banner + uglify(jsFile));
159+
zip.file('ui-bootstrap-custom-tpls-' + version + '.js', rawFiles.banner + jsTplFile);
160+
zip.file('ui-bootstrap-custom-tpls-' + version + '.min.js', rawFiles.banner + uglify(jsTplFile));
161+
162+
saveAs(zip.generate({type: 'blob'}), 'ui-bootstrap-custom-build.zip');
163+
}
164+
165+
function createNoTplFile(srcModuleNames, srcJsContent) {
166+
return 'angular.module("ui.bootstrap", [' + srcModuleNames.join(',') + ']);\n' +
167+
srcJsContent;
168+
}
169+
170+
function createWithTplFile(srcModuleNames, srcJsContent, tplModuleNames, tplJsContent) {
171+
var depModuleNames = srcModuleNames.slice();
172+
depModuleNames.unshift('"ui.bootstrap.tpls"');
173+
174+
return 'angular.module("ui.bootstrap", [' + depModuleNames.join(',') + ']);\n' +
175+
'angular.module("ui.bootstrap.tpls", [' + tplModuleNames.join(',') + ']);\n' +
176+
srcJsContent + '\n' + tplJsContent;
177+
178+
}
179+
180+
function addIfNotExists(array, element) {
181+
if (array.indexOf(element) == -1) {
182+
array.push(element);
183+
}
184+
}
185+
186+
function getFileContent(fileName) {
187+
return rawFiles.files[fileName];
188+
}
189+
190+
function uglify(js) {
191+
/* global UglifyJS */
192+
193+
var ast = UglifyJS.parse(js);
194+
ast.figure_out_scope();
195+
196+
var compressor = UglifyJS.Compressor();
197+
var compressedAst = ast.transform(compressor);
198+
199+
compressedAst.figure_out_scope();
200+
compressedAst.compute_char_frequency();
201+
compressedAst.mangle_names();
202+
203+
var stream = UglifyJS.OutputStream();
204+
compressedAst.print(stream);
205+
206+
return stream.toString();
207+
}
64208
};
65209
};
66210

@@ -90,3 +234,48 @@ var DownloadCtrl = function($scope, $modalInstance) {
90234
$modalInstance.dismiss();
91235
};
92236
};
237+
238+
/*
239+
* The following compatibility check is from:
240+
*
241+
* Bootstrap Customizer (http://getbootstrap.com/customize/)
242+
* Copyright 2011-2014 Twitter, Inc.
243+
*
244+
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
245+
* details, see http://creativecommons.org/licenses/by/3.0/.
246+
*/
247+
var isOldBrowser;
248+
(function () {
249+
250+
var supportsFile = (window.File && window.FileReader && window.FileList && window.Blob);
251+
function failback() {
252+
isOldBrowser = true;
253+
}
254+
/**
255+
* Based on:
256+
* Blob Feature Check v1.1.0
257+
* https://github.com/ssorallen/blob-feature-check/
258+
* License: Public domain (http://unlicense.org)
259+
*/
260+
var url = window.webkitURL || window.URL; // Safari 6 uses "webkitURL".
261+
var svg = new Blob(
262+
['<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>'],
263+
{ type: 'image/svg+xml;charset=utf-8' }
264+
);
265+
var objectUrl = url.createObjectURL(svg);
266+
267+
if (/^blob:/.exec(objectUrl) === null || !supportsFile) {
268+
// `URL.createObjectURL` created a URL that started with something other
269+
// than "blob:", which means it has been polyfilled and is not supported by
270+
// this browser.
271+
failback();
272+
} else {
273+
angular.element('<img/>')
274+
.on('load', function () {
275+
isOldBrowser = false;
276+
})
277+
.on('error', failback)
278+
.attr('src', objectUrl);
279+
}
280+
281+
})();

Diff for: assets/module-mapping.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"transition":{"name":"transition","moduleName":"\"ui.bootstrap.transition\"","displayName":"Transition","srcFiles":["src/transition/transition.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"collapse":{"name":"collapse","moduleName":"\"ui.bootstrap.collapse\"","displayName":"Collapse","srcFiles":["src/collapse/collapse.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":["transition"]},"accordion":{"name":"accordion","moduleName":"\"ui.bootstrap.accordion\"","displayName":"Accordion","srcFiles":["src/accordion/accordion.js"],"tplFiles":["template/accordion/accordion-group.html","template/accordion/accordion.html"],"tpljsFiles":["template/accordion/accordion-group.html.js","template/accordion/accordion.html.js"],"tplModules":["\"template/accordion/accordion-group.html\"","\"template/accordion/accordion.html\""],"dependencies":["collapse","transition"]},"alert":{"name":"alert","moduleName":"\"ui.bootstrap.alert\"","displayName":"Alert","srcFiles":["src/alert/alert.js"],"tplFiles":["template/alert/alert.html"],"tpljsFiles":["template/alert/alert.html.js"],"tplModules":["\"template/alert/alert.html\""],"dependencies":[]},"bindHtml":{"name":"bindHtml","moduleName":"\"ui.bootstrap.bindHtml\"","displayName":"Bind Html","srcFiles":["src/bindHtml/bindHtml.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"buttons":{"name":"buttons","moduleName":"\"ui.bootstrap.buttons\"","displayName":"Buttons","srcFiles":["src/buttons/buttons.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"carousel":{"name":"carousel","moduleName":"\"ui.bootstrap.carousel\"","displayName":"Carousel","srcFiles":["src/carousel/carousel.js"],"tplFiles":["template/carousel/carousel.html","template/carousel/slide.html"],"tpljsFiles":["template/carousel/carousel.html.js","template/carousel/slide.html.js"],"tplModules":["\"template/carousel/carousel.html\"","\"template/carousel/slide.html\""],"dependencies":["transition"]},"dateparser":{"name":"dateparser","moduleName":"\"ui.bootstrap.dateparser\"","displayName":"Dateparser","srcFiles":["src/dateparser/dateparser.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"position":{"name":"position","moduleName":"\"ui.bootstrap.position\"","displayName":"Position","srcFiles":["src/position/position.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"datepicker":{"name":"datepicker","moduleName":"\"ui.bootstrap.datepicker\"","displayName":"Datepicker","srcFiles":["src/datepicker/datepicker.js"],"tplFiles":["template/datepicker/datepicker.html","template/datepicker/day.html","template/datepicker/month.html","template/datepicker/popup.html","template/datepicker/year.html"],"tpljsFiles":["template/datepicker/datepicker.html.js","template/datepicker/day.html.js","template/datepicker/month.html.js","template/datepicker/popup.html.js","template/datepicker/year.html.js"],"tplModules":["\"template/datepicker/datepicker.html\"","\"template/datepicker/day.html\"","\"template/datepicker/month.html\"","\"template/datepicker/popup.html\"","\"template/datepicker/year.html\""],"dependencies":["dateparser","position"]},"dropdown":{"name":"dropdown","moduleName":"\"ui.bootstrap.dropdown\"","displayName":"Dropdown","srcFiles":["src/dropdown/dropdown.js"],"tplFiles":[],"tpljsFiles":[],"tplModules":[],"dependencies":[]},"modal":{"name":"modal","moduleName":"\"ui.bootstrap.modal\"","displayName":"Modal","srcFiles":["src/modal/modal.js"],"tplFiles":["template/modal/backdrop.html","template/modal/window.html"],"tpljsFiles":["template/modal/backdrop.html.js","template/modal/window.html.js"],"tplModules":["\"template/modal/backdrop.html\"","\"template/modal/window.html\""],"dependencies":["transition"]},"pagination":{"name":"pagination","moduleName":"\"ui.bootstrap.pagination\"","displayName":"Pagination","srcFiles":["src/pagination/pagination.js"],"tplFiles":["template/pagination/pager.html","template/pagination/pagination.html"],"tpljsFiles":["template/pagination/pager.html.js","template/pagination/pagination.html.js"],"tplModules":["\"template/pagination/pager.html\"","\"template/pagination/pagination.html\""],"dependencies":[]},"tooltip":{"name":"tooltip","moduleName":"\"ui.bootstrap.tooltip\"","displayName":"Tooltip","srcFiles":["src/tooltip/tooltip.js"],"tplFiles":["template/tooltip/tooltip-html-unsafe-popup.html","template/tooltip/tooltip-popup.html"],"tpljsFiles":["template/tooltip/tooltip-html-unsafe-popup.html.js","template/tooltip/tooltip-popup.html.js"],"tplModules":["\"template/tooltip/tooltip-html-unsafe-popup.html\"","\"template/tooltip/tooltip-popup.html\""],"dependencies":["position","bindHtml"]},"popover":{"name":"popover","moduleName":"\"ui.bootstrap.popover\"","displayName":"Popover","srcFiles":["src/popover/popover.js"],"tplFiles":["template/popover/popover.html"],"tpljsFiles":["template/popover/popover.html.js"],"tplModules":["\"template/popover/popover.html\""],"dependencies":["tooltip","position","bindHtml"]},"progressbar":{"name":"progressbar","moduleName":"\"ui.bootstrap.progressbar\"","displayName":"Progressbar","srcFiles":["src/progressbar/progressbar.js"],"tplFiles":["template/progressbar/bar.html","template/progressbar/progress.html","template/progressbar/progressbar.html"],"tpljsFiles":["template/progressbar/bar.html.js","template/progressbar/progress.html.js","template/progressbar/progressbar.html.js"],"tplModules":["\"template/progressbar/bar.html\"","\"template/progressbar/progress.html\"","\"template/progressbar/progressbar.html\""],"dependencies":[]},"rating":{"name":"rating","moduleName":"\"ui.bootstrap.rating\"","displayName":"Rating","srcFiles":["src/rating/rating.js"],"tplFiles":["template/rating/rating.html"],"tpljsFiles":["template/rating/rating.html.js"],"tplModules":["\"template/rating/rating.html\""],"dependencies":[]},"tabs":{"name":"tabs","moduleName":"\"ui.bootstrap.tabs\"","displayName":"Tabs","srcFiles":["src/tabs/tabs.js"],"tplFiles":["template/tabs/tab.html","template/tabs/tabset.html"],"tpljsFiles":["template/tabs/tab.html.js","template/tabs/tabset.html.js"],"tplModules":["\"template/tabs/tab.html\"","\"template/tabs/tabset.html\""],"dependencies":[]},"timepicker":{"name":"timepicker","moduleName":"\"ui.bootstrap.timepicker\"","displayName":"Timepicker","srcFiles":["src/timepicker/timepicker.js"],"tplFiles":["template/timepicker/timepicker.html"],"tpljsFiles":["template/timepicker/timepicker.html.js"],"tplModules":["\"template/timepicker/timepicker.html\""],"dependencies":[]},"typeahead":{"name":"typeahead","moduleName":"\"ui.bootstrap.typeahead\"","displayName":"Typeahead","srcFiles":["src/typeahead/typeahead.js"],"tplFiles":["template/typeahead/typeahead-match.html","template/typeahead/typeahead-popup.html"],"tpljsFiles":["template/typeahead/typeahead-match.html.js","template/typeahead/typeahead-popup.html.js"],"tplModules":["\"template/typeahead/typeahead-match.html\"","\"template/typeahead/typeahead-popup.html\""],"dependencies":["position","bindHtml"]}}

Diff for: assets/raw-files.json

+1
Large diffs are not rendered by default.

Diff for: assets/uglifyjs.js

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: index.html

+12-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
<meta name="google-site-verification" content="7lc5HyceLDqpV_6oNHteYFfxDJH7-S3DwnJKtNUKcRg" />
1010

1111
<script src="//cdnjs.cloudflare.com/ajax/libs/fastclick/0.6.7/fastclick.min.js"></script>
12+
<script src="//cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.0.0/FileSaver.min.js"></script>
13+
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.min.js"></script>
1214
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
1315
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-touch.min.js"></script>
1416
<script src="ui-bootstrap-tpls-0.11.2.min.js"></script>
@@ -2737,10 +2739,15 @@ <h4>
27372739
</h4>
27382740
</div>
27392741
<div class="modal-body">
2742+
<div ng-show="isOldBrowser()">
2743+
Your current browser doesn't support creating custom builds.
2744+
Please take a second to <a href="http://browsehappy.com/">upgrade to a
2745+
more modern browser</a> (other than Safari).
2746+
</div>
27402747
<div ng-show="buildErrorText">
27412748
<h4 style="text-align: center;">{{buildErrorText}}</h4>
27422749
</div>
2743-
<div ng-hide="buildErrorText">
2750+
<div ng-hide="buildErrorText || isOldBrowser()">
27442751

27452752

27462753
<div class="btn-group" style="width: 100%;">
@@ -2992,7 +2999,9 @@ <h4 style="text-align: center;">{{buildErrorText}}</h4>
29922999
</div>
29933000
<div class="modal-footer">
29943001
<a class="btn btn-default" ng-click="cancel()">Close</a>
2995-
<a class="btn btn-primary" ng-disabled="!selectedModules.length" ng-href="{{selectedModules.length ? download(selectedModules) : ''}}">
3002+
<a class="btn btn-primary" ng-hide="isOldBrowser()"
3003+
ng-disabled="isOldBrowser() !== false && !selectedModules.length"
3004+
ng-click="selectedModules.length && build(selectedModules, '0.11.2')">
29963005
<i class="glyphicon glyphicon-download-alt"></i> Download {{selectedModules.length}} Modules
29973006
</a>
29983007
</div>
@@ -3012,5 +3021,6 @@ <h4 style="text-align: center;">{{buildErrorText}}</h4>
30123021

30133022
</script>
30143023
<script src="assets/smoothscroll-angular-custom.js"></script>
3024+
<script src="assets/uglifyjs.js"></script>
30153025
</body>
30163026
</html>

0 commit comments

Comments
 (0)