diff --git a/docs/_jade/customizer-nav.jade b/docs/_jade/customizer-nav.jade index c4f6ddf105..eba71ef6bf 100644 --- a/docs/_jade/customizer-nav.jade +++ b/docs/_jade/customizer-nav.jade @@ -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 diff --git a/docs/assets/css/src/docs.css b/docs/assets/css/src/docs.css index 142519bd5f..ea0739893d 100644 --- a/docs/assets/css/src/docs.css +++ b/docs/assets/css/src/docs.css @@ -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 diff --git a/docs/assets/js/src/customizer.js b/docs/assets/js/src/customizer.js index c3a212f2c7..7340f1668f 100644 --- a/docs/assets/js/src/customizer.js +++ b/docs/assets/js/src/customizer.js @@ -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) { $('
.json
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', 'Woohoo! Your configuration was successfully uploaded. Tweak your settings, then hit Download.', importDropTarget)
+ } catch (err) {
+ return showAlert('danger', 'Shucks. We can only read valid .json
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.
diff --git a/docs/customize.html b/docs/customize.html
index 2e067b8f48..2e918bd6ee 100644
--- a/docs/customize.html
+++ b/docs/customize.html
@@ -12,6 +12,7 @@ lead: Customize Bootstrap's components, Less variables, and jQuery plugins to ge
+
+Have an existing configuration? Upload your config.json
to import it.
Drag and drop here, or .
+Don't have one? That's okay—just start customizing the fields below.
+