0
0
mirror of https://github.com/twbs/bootstrap.git synced 2024-11-29 11:24:18 +01:00

Merge branch 'thomaswelton/11004-import-config'

This commit is contained in:
Chris Rebert 2014-07-31 11:46:17 -07:00
commit 87ce371018
4 changed files with 122 additions and 18 deletions

View File

@ -1,4 +1,6 @@
// NOTE: DO NOT EDIT THE FOLLOWING SECTION DIRECTLY! It is autogenerated via the `build-customizer-html` Grunt task using the customizer-nav.jade template.
li
a(href='#import') Import
li
a(href='#less') Less components
li

View File

@ -1378,6 +1378,30 @@ h1[id] {
box-shadow: inset 0 2px 4px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);
}
.bs-dropzone {
position: relative;
padding: 20px;
margin-bottom: 20px;
color: #777;
text-align: center;
border: 2px dashed #eee;
border-radius: 4px;
}
.bs-dropzone h2 {
margin-top: 0;
margin-bottom: 5px;
}
.bs-dropzone .lead {
margin-bottom: 10px;
font-weight: normal;
color: #333;
}
.bs-dropzone hr {
width: 100px;
}
.bs-dropzone p:last-child {
margin-bottom: 0;
}
/*
* Brand guidelines

View File

@ -16,6 +16,9 @@ window.onload = function () { // wait for load in a dumb way because B-0
' * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n' +
' */\n\n'
var supportsFile = (window.File && window.FileReader && window.FileList && window.Blob)
var importDropTarget = $('#import-drop-target')
function showError(msg, err) {
$('<div id="bsCustomizerAlert" class="bs-customizer-alert">' +
'<div class="container">' +
@ -46,6 +49,11 @@ window.onload = function () { // wait for load in a dumb way because B-0
}
}
function showAlert(type, msg, insertAfter) {
$('<div class="alert alert-' + type + '">' + msg + '<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button></div>')
.insertAfter(insertAfter)
}
function getQueryParam(key) {
key = key.replace(/[*+?^$.\[\]{}()|\\\/]/g, '\\$&') // escape RegEx meta chars
var match = location.search.match(new RegExp('[?&]' + key + '=([^&]+)(&|$)'))
@ -106,6 +114,24 @@ window.onload = function () { // wait for load in a dumb way because B-0
return data
}
function updateCustomizerFromJson(data) {
if (data.js) {
$('#plugin-section input').each(function () {
$(this).prop('checked', ~$.inArray(this.value, data.js))
})
}
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])
}
}
}
function parseUrl() {
var id = getQueryParam('id')
@ -118,21 +144,7 @@ window.onload = function () { // wait for load in a dumb way because B-0
})
.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))
})
}
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])
}
}
updateCustomizerFromJson(data)
})
.error(function (err) {
showError('Error fetching bootstrap config file', err)
@ -324,6 +336,61 @@ window.onload = function () { // wait for load in a dumb way because B-0
}
}
function removeImportAlerts() {
importDropTarget.nextAll('.alert').remove()
}
function handleConfigFileSelect(e) {
e.stopPropagation()
e.preventDefault()
var file = (e.originalEvent.hasOwnProperty('dataTransfer')) ? e.originalEvent.dataTransfer.files[0] : e.originalEvent.target.files[0]
if (!file.type.match('application/json')) {
return showAlert('danger', '<strong>Ruh roh.</strong> We can only read <code>.json</code> files. Please try again.', importDropTarget)
}
var reader = new FileReader()
reader.onload = (function () {
return function (e) {
var text = e.target.result
try {
var json = JSON.parse(text)
if (typeof json != 'object') {
throw new Error('JSON data from config file is not an object.')
}
updateCustomizerFromJson(json)
showAlert('success', '<strong>Woohoo!</strong> Your configuration was successfully uploaded. Tweak your settings, then hit Download.', importDropTarget)
} catch (err) {
return showAlert('danger', '<strong>Shucks.</strong> We can only read valid <code>.json</code> files. Please try again.', importDropTarget)
}
}
})(file)
reader.readAsText(file)
}
function handleConfigDragOver(e) {
e.stopPropagation()
e.preventDefault()
e.originalEvent.dataTransfer.dropEffect = 'copy'
removeImportAlerts()
}
if (supportsFile) {
importDropTarget
.on('dragover', handleConfigDragOver)
.on('drop', handleConfigFileSelect)
}
$('#import-file-select').on('select', handleConfigFileSelect)
$('#import-manual-trigger').on('click', removeImportAlerts)
var inputsComponent = $('#less-section input')
var inputsPlugin = $('#plugin-section input')
var inputsVariables = $('#less-variables-section input')
@ -410,7 +477,8 @@ window.onload = function () { // wait for load in a dumb way because B-0
{ type: 'image/svg+xml;charset=utf-8' }
)
var objectUrl = url.createObjectURL(svg);
if (/^blob:/.exec(objectUrl) === null) {
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.

View File

@ -12,6 +12,7 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
<!--[if lt IE 9]>
<style>
.bs-customizer,
.bs-customizer-import,
.bs-docs-sidebar {
display: none;
}
@ -23,6 +24,17 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
<![endif]-->
<!-- Customizer form -->
<div class="bs-docs-section bs-customizer-import">
<div id="import-drop-target" class="bs-dropzone">
<h2></h2>
<p class="lead">Have an existing configuration? Upload your <code>config.json</code> to import it.</p>
<p>Drag and drop here, or <label id="import-manual-trigger" class="btn-link">manually upload<input type="file" id="import-file-select" class="hidden"></label>.</p>
<hr>
<p><strong>Don't have one?</strong> That's okay—just start customizing the fields below.</p>
</div>
</div><!-- /import -->
<form class="bs-customizer" role="form">
<div class="bs-docs-section" id="less-section">
<button class="btn btn-default toggle" type="button">Toggle all</button>
@ -358,8 +370,6 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
{% include customizer-variables.html %}
</div>
<div class="bs-docs-section">
<h1 id="download" class="page-header">Download</h1>