1+ /* global FastClick, smoothScroll */
12angular . 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
1346var 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 ( / ^ b l o b : / . 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+ } ) ( ) ;
0 commit comments