Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Commit

Permalink
fix(demo): make custom builds work
Browse files Browse the repository at this point in the history
Part of #2892

Fixes #2960
Fixes #2847
Fixes #2625
Fixes #2489
Fixes #2357
Fixes #2176
  • Loading branch information
chrisirhc committed Nov 14, 2014
1 parent f07fecb commit e10a1e6
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 13 deletions.
211 changes: 200 additions & 11 deletions assets/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* global FastClick, smoothScroll */
angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'plunker', 'ngTouch'], function($httpProvider){
FastClick.attach(document.body);
delete $httpProvider.defaults.headers.common['X-Requested-With'];
Expand All @@ -8,7 +9,39 @@ angular.module('ui.bootstrap.demo', ['ui.bootstrap', 'plunker', 'ngTouch'], func
location.replace(el.id);
});
}
}]);
}]).factory('buildFilesService', function ($http, $q) {

var moduleMap;
var rawFiles;

return {
getModuleMap: getModuleMap,
getRawFiles: getRawFiles,
get: function () {
return $q.all({
moduleMap: getModuleMap(),
rawFiles: getRawFiles(),
});
}
};

function getModuleMap() {
return moduleMap ? $q.when(moduleMap) : $http.get('assets/module-mapping.json')
.then(function (result) {
moduleMap = result.data;
return moduleMap;
});
}

function getRawFiles() {
return rawFiles ? $q.when(rawFiles) : $http.get('assets/raw-files.json')
.then(function (result) {
rawFiles = result.data;
return rawFiles;
});
}

});

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

Expand All @@ -18,10 +51,11 @@ function MainCtrl($scope, $http, $document, $modal, orderByFilter) {
templateUrl: 'buildModal.html',
controller: 'SelectModulesCtrl',
resolve: {
modules: function() {
return $http.get(builderUrl + "/api/bootstrap").then(function(response) {
return response.data.modules;
});
modules: function(buildFilesService) {
return buildFilesService.getModuleMap()
.then(function (moduleMap) {
return Object.keys(moduleMap);
});
}
}
});
Expand All @@ -35,7 +69,7 @@ function MainCtrl($scope, $http, $document, $modal, orderByFilter) {
};
}

var SelectModulesCtrl = function($scope, $modalInstance, modules) {
var SelectModulesCtrl = function($scope, $modalInstance, modules, buildFilesService) {
$scope.selectedModules = [];
$scope.modules = modules;

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

$scope.download = function (selectedModules) {
var downloadUrl = builderUrl + "/api/bootstrap/download?";
angular.forEach(selectedModules, function(module) {
downloadUrl += "modules=" + module + "&";
$scope.isOldBrowser = function () {
return isOldBrowser;
};

$scope.build = function (selectedModules, version) {
/* global JSZip, saveAs */
var moduleMap, rawFiles;

buildFilesService.get().then(function (buildFiles) {
moduleMap = buildFiles.moduleMap;
rawFiles = buildFiles.rawFiles;

generateBuild();
});
return downloadUrl;

function generateBuild() {
var srcModuleNames = selectedModules
.map(function (module) {
return moduleMap[module];
})
.reduce(function (toBuild, module) {
addIfNotExists(toBuild, module.name);

module.dependencies.forEach(function (depName) {
addIfNotExists(toBuild, depName);
});
return toBuild;
}, []);

var srcModules = srcModuleNames
.map(function (moduleName) {
return moduleMap[moduleName];
});

var srcModuleFullNames = srcModules
.map(function (module) {
return module.moduleName;
});

var srcJsContent = srcModules
.reduce(function (buildFiles, module) {
return buildFiles.concat(module.srcFiles);
}, [])
.map(getFileContent)
.join('\n')
;

var jsFile = createNoTplFile(srcModuleFullNames, srcJsContent);

var tplModuleNames = srcModules
.reduce(function (tplModuleNames, module) {
return tplModuleNames.concat(module.tplModules);
}, []);

var tplJsContent = srcModules
.reduce(function (buildFiles, module) {
return buildFiles.concat(module.tpljsFiles);
}, [])
.map(getFileContent)
.join('\n')
;

var jsTplFile = createWithTplFile(srcModuleFullNames, srcJsContent, tplModuleNames, tplJsContent);

var zip = new JSZip();
zip.file('ui-bootstrap-custom-' + version + '.js', rawFiles.banner + jsFile);
zip.file('ui-bootstrap-custom-' + version + '.min.js', rawFiles.banner + uglify(jsFile));
zip.file('ui-bootstrap-custom-tpls-' + version + '.js', rawFiles.banner + jsTplFile);
zip.file('ui-bootstrap-custom-tpls-' + version + '.min.js', rawFiles.banner + uglify(jsTplFile));

saveAs(zip.generate({type: 'blob'}), 'ui-bootstrap-custom-build.zip');
}

function createNoTplFile(srcModuleNames, srcJsContent) {
return 'angular.module("ui.bootstrap", [' + srcModuleNames.join(',') + ']);\n' +
srcJsContent;
}

function createWithTplFile(srcModuleNames, srcJsContent, tplModuleNames, tplJsContent) {
var depModuleNames = srcModuleNames.slice();
depModuleNames.unshift('"ui.bootstrap.tpls"');

return 'angular.module("ui.bootstrap", [' + depModuleNames.join(',') + ']);\n' +
'angular.module("ui.bootstrap.tpls", [' + tplModuleNames.join(',') + ']);\n' +
srcJsContent + '\n' + tplJsContent;

}

function addIfNotExists(array, element) {
if (array.indexOf(element) == -1) {
array.push(element);
}
}

function getFileContent(fileName) {
return rawFiles.files[fileName];
}

function uglify(js) {
/* global UglifyJS */

var ast = UglifyJS.parse(js);
ast.figure_out_scope();

var compressor = UglifyJS.Compressor();
var compressedAst = ast.transform(compressor);

compressedAst.figure_out_scope();
compressedAst.compute_char_frequency();
compressedAst.mangle_names();

var stream = UglifyJS.OutputStream();
compressedAst.print(stream);

return stream.toString();
}
};
};

Expand Down Expand Up @@ -90,3 +234,48 @@ var DownloadCtrl = function($scope, $modalInstance) {
$modalInstance.dismiss();
};
};

/*
* The following compatibility check is from:
*
* Bootstrap Customizer (http://getbootstrap.com/customize/)
* Copyright 2011-2014 Twitter, Inc.
*
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
var isOldBrowser;
(function () {

var supportsFile = (window.File && window.FileReader && window.FileList && window.Blob);
function failback() {
isOldBrowser = true;
}
/**
* Based on:
* Blob Feature Check v1.1.0
* https://github.com/ssorallen/blob-feature-check/
* License: Public domain (http://unlicense.org)
*/
var url = window.webkitURL || window.URL; // Safari 6 uses "webkitURL".
var svg = new Blob(
['<svg xmlns=\'http://www.w3.org/2000/svg\'></svg>'],
{ type: 'image/svg+xml;charset=utf-8' }
);
var objectUrl = url.createObjectURL(svg);

if (/^blob:/.exec(objectUrl) === null || !supportsFile) {
// `URL.createObjectURL` created a URL that started with something other
// than "blob:", which means it has been polyfilled and is not supported by
// this browser.
failback();
} else {
angular.element('<img/>')
.on('load', function () {
isOldBrowser = false;
})
.on('error', failback)
.attr('src', objectUrl);
}

})();
1 change: 1 addition & 0 deletions assets/module-mapping.json
Original file line number Diff line number Diff line change
@@ -0,0 +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"]}}
1 change: 1 addition & 0 deletions assets/raw-files.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions assets/uglifyjs.js

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
<meta name="google-site-verification" content="7lc5HyceLDqpV_6oNHteYFfxDJH7-S3DwnJKtNUKcRg" />

<script src="//cdnjs.cloudflare.com/ajax/libs/fastclick/0.6.7/fastclick.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.0.0/FileSaver.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jszip/2.4.0/jszip.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-touch.min.js"></script>
<script src="ui-bootstrap-tpls-0.11.2.min.js"></script>
Expand Down Expand Up @@ -2737,10 +2739,15 @@ <h4>
</h4>
</div>
<div class="modal-body">
<div ng-show="isOldBrowser()">
Your current browser doesn't support creating custom builds.
Please take a second to <a href="http://browsehappy.com/">upgrade to a
more modern browser</a> (other than Safari).
</div>
<div ng-show="buildErrorText">
<h4 style="text-align: center;">{{buildErrorText}}</h4>
</div>
<div ng-hide="buildErrorText">
<div ng-hide="buildErrorText || isOldBrowser()">


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

</script>
<script src="assets/smoothscroll-angular-custom.js"></script>
<script src="assets/uglifyjs.js"></script>
</body>
</html>

0 comments on commit e10a1e6

Please sign in to comment.