2013-08-12 03:42:13 +02:00
window . onload = function ( ) { // wait for load in a dumb way because B-0
var cw = '/*!\n * Bootstrap v3.0.0-rc.2\n *\n * Copyright 2013 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world @twitter by @mdo and @fat.\n */\n\n'
2013-08-18 04:04:41 +02:00
function showError ( msg , err ) {
$ ( ' < div id = "bsCustomizerAlert" class = "bs-customizer-alert" > \
< div class = "container" > \
< a href = "#bsCustomizerAlert" data - dismiss = "alert" class = "close pull-right" > & times ; < / a > \
< p class = "bs-customizer-alert-text" > ' + msg + ' < / p > ' +
( err . extract ? '<pre class="bs-customizer-alert-extract">' + err . extract . join ( '\n' ) + '</pre>' : '' ) + ' \
< / d i v > \
< / d i v > ' ) . a p p e n d T o ( ' b o d y ' ) . a l e r t ( )
throw err
}
2013-08-18 03:41:36 +02:00
function getQueryParam ( key ) {
key = key . replace ( /[*+?^$.\[\]{}()|\\\/]/g , "\\$&" ) ; // escape RegEx meta chars
var match = location . search . match ( new RegExp ( "[?&]" + key + "=([^&]+)(&|$)" ) ) ;
return match && decodeURIComponent ( match [ 1 ] . replace ( /\+/g , " " ) ) ;
}
function createGist ( configData ) {
var data = {
"description" : "Bootstrap Customizer Config" ,
"public" : true ,
"files" : {
"config.json" : {
"content" : JSON . stringify ( configData )
}
}
}
$ . ajax ( {
url : 'https://api.github.com/gists' ,
type : 'POST' ,
dataType : 'json' ,
data : JSON . stringify ( data )
} )
2013-08-18 04:07:59 +02:00
. success ( function ( result ) {
history . replaceState ( false , document . title , window . location . origin + window . location . pathname + '?id=' + result . id )
2013-08-18 03:41:36 +02:00
} )
2013-08-18 04:04:41 +02:00
. error ( function ( err ) {
showError ( '<strong>Error</strong> Could not save gist file, configuration not saved.' , err )
2013-08-18 03:41:36 +02:00
} )
}
2013-08-12 03:42:13 +02:00
function generateUrl ( ) {
var vars = { }
$ ( '#less-variables-section input' )
. each ( function ( ) {
$ ( this ) . val ( ) && ( vars [ $ ( this ) . prev ( ) . text ( ) ] = $ ( this ) . val ( ) )
} )
var data = {
vars : vars ,
2013-08-18 03:41:36 +02:00
css : $ ( '#less-section input:checked' ) . map ( function ( ) { return this . value } ) . toArray ( ) ,
js : $ ( '#plugin-section input:checked' ) . map ( function ( ) { return this . value } ) . toArray ( )
2013-08-12 03:42:13 +02:00
}
if ( $ . isEmptyObject ( data . vars ) && ! data . css . length && ! data . js . length ) return
2013-08-18 03:41:36 +02:00
createGist ( data )
2013-08-12 03:42:13 +02:00
}
function parseUrl ( ) {
2013-08-18 03:41:36 +02:00
var id = getQueryParam ( 'id' )
2013-08-12 03:42:13 +02:00
2013-08-18 03:41:36 +02:00
if ( ! id ) return
2013-08-12 03:42:13 +02:00
2013-08-18 03:41:36 +02:00
$ . ajax ( {
url : 'https://api.github.com/gists/' + id ,
type : 'GET' ,
dataType : 'json'
} )
. success ( function ( result ) {
var data = JSON . parse ( result . files [ 'config.json' ] . content )
if ( data . js ) {
$ ( '#plugin-section input' ) . each ( function ( ) {
$ ( this ) . prop ( 'checked' , ~ $ . inArray ( this . value , data . js ) )
} )
2013-08-12 03:42:13 +02:00
}
2013-08-18 03:41:36 +02:00
if ( data . css ) {
$ ( '#less-section input' ) . each ( function ( ) {
$ ( this ) . prop ( 'checked' , ~ $ . inArray ( this . value , data . css ) )
} )
}
if ( data . vars ) {
for ( var i in data . vars ) {
$ ( 'input[data-var="' + i + '"]' ) . val ( data . vars [ i ] )
}
}
} )
2013-08-18 04:04:41 +02:00
. error ( function ( err ) {
showError ( 'Error fetching bootstrap config file' , err )
2013-08-18 03:41:36 +02:00
} )
2013-08-12 03:42:13 +02:00
}
function generateZip ( css , js , complete ) {
2013-08-18 04:04:41 +02:00
if ( ! css && ! js ) return showError ( '<strong>Error</strong> No Bootstrap files selected.' , new Error ( 'no Bootstrap' ) )
2013-08-12 03:42:13 +02:00
var zip = new JSZip ( )
if ( css ) {
var cssFolder = zip . folder ( 'css' )
for ( var fileName in css ) {
cssFolder . file ( fileName , css [ fileName ] )
}
}
if ( js ) {
var jsFolder = zip . folder ( 'js' )
for ( var fileName in js ) {
jsFolder . file ( fileName , js [ fileName ] )
}
}
var content = zip . generate ( )
location . href = 'data:application/zip;base64,' + content
complete ( )
}
function generateCustomCSS ( vars ) {
var result = ''
for ( var key in vars ) {
result += key + ': ' + vars [ key ] + ';\n'
}
return result + '\n\n'
}
function generateCSS ( ) {
var $checked = $ ( '#less-section input:checked' )
if ( ! $checked . length ) return false
var result = { }
var vars = { }
var css = ''
$ ( '#less-variables-section input' )
. each ( function ( ) {
$ ( this ) . val ( ) && ( vars [ $ ( this ) . prev ( ) . text ( ) ] = $ ( this ) . val ( ) )
} )
css += _ _less [ 'variables.less' ]
if ( vars ) css += generateCustomCSS ( vars )
css += _ _less [ 'mixins.less' ]
css += $checked
. map ( function ( ) { return _ _less [ this . value ] } )
. toArray ( )
. join ( '\n' )
css = css . replace ( /@import[^\n]*/gi , '' ) //strip any imports
try {
var parser = new less . Parser ( {
paths : [ 'variables.less' , 'mixins.less' ]
, optimization : 0
, filename : 'bootstrap.css'
} ) . parse ( css , function ( err , tree ) {
2013-08-18 04:04:41 +02:00
if ( err ) {
return showError ( '<strong>Error</strong> Could not parse less files.' , err )
}
2013-08-12 03:42:13 +02:00
result = {
'bootstrap.css' : cw + tree . toCSS ( ) ,
'bootstrap.min.css' : cw + tree . toCSS ( { compress : true } )
}
} )
} catch ( err ) {
2013-08-18 04:04:41 +02:00
return showError ( '<strong>Error</strong> Could not parse less files.' , err )
2013-08-12 03:42:13 +02:00
}
return result
}
function generateJavascript ( ) {
var $checked = $ ( '#plugin-section input:checked' )
if ( ! $checked . length ) return false
var js = $checked
. map ( function ( ) { return _ _js [ this . value ] } )
. toArray ( )
. join ( '\n' )
return {
'bootstrap.js' : js ,
'bootstrap.min.js' : cw + uglify ( js )
}
}
var $downloadBtn = $ ( '#btn-download' ) . on ( 'click' , function ( e ) {
e . preventDefault ( )
$downloadBtn . addClass ( 'loading' )
generateZip ( generateCSS ( ) , generateJavascript ( ) , function ( ) {
$downloadBtn . removeClass ( 'loading' )
2013-08-18 03:41:36 +02:00
setTimeout ( generateUrl , 500 )
2013-08-12 03:42:13 +02:00
} )
} )
var inputsComponent = $ ( '#less-section input' )
var inputsPlugin = $ ( '#plugin-section input' )
var inputsVariables = $ ( '#less-variables-section input' )
$ ( '#less-section .toggle' ) . on ( 'click' , function ( e ) {
e . preventDefault ( )
inputsComponent . prop ( 'checked' , ! inputsComponent . is ( ':checked' ) )
} )
$ ( '#plugin-section .toggle' ) . on ( 'click' , function ( e ) {
e . preventDefault ( )
inputsPlugin . prop ( 'checked' , ! inputsPlugin . is ( ':checked' ) )
} )
$ ( '#less-variables-section .toggle' ) . on ( 'click' , function ( e ) {
e . preventDefault ( )
inputsVariables . val ( '' )
} )
2013-08-18 03:41:36 +02:00
parseUrl ( )
2013-08-12 03:42:13 +02:00
}