Skip to content

Commit

Permalink
Add drag and drop config import; closes twbs#11004
Browse files Browse the repository at this point in the history
Closes twbs#13790 by merging a rebased version of it.
  • Loading branch information
thomaswelton authored and cvrebert committed Jul 31, 2014
1 parent f026cfb commit 9739271
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 18 deletions.
2 changes: 2 additions & 0 deletions docs/_jade/customizer-nav.jade
Original file line number Diff line number Diff line change
@@ -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
Expand Down
24 changes: 24 additions & 0 deletions docs/assets/css/src/docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
100 changes: 84 additions & 16 deletions docs/assets/js/src/customizer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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">' +
Expand Down Expand Up @@ -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 + '=([^&]+)(&|$)'))
Expand Down Expand Up @@ -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')

Expand All @@ -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)
Expand Down Expand Up @@ -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')
Expand Down Expand Up @@ -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.
Expand Down
14 changes: 12 additions & 2 deletions docs/customize.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<!--[if lt IE 9]>
<style>
.bs-customizer,
.bs-customizer-import,
.bs-docs-sidebar {
display: none;
}
Expand All @@ -23,6 +24,17 @@
<![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>
Expand Down Expand Up @@ -358,8 +370,6 @@ <h1 id="less-variables" class="page-header">Less variables</h1>
{% include customizer-variables.html %}
</div>



<div class="bs-docs-section">
<h1 id="download" class="page-header">Download</h1>

Expand Down

0 comments on commit 9739271

Please sign in to comment.