Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/bootstrap.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Welton <thomaswelton@me.com>2014-06-11 14:06:32 +0400
committerChris Rebert <code@rebertia.com>2014-07-31 22:45:21 +0400
commit9739271c04646ca49d8937043e45a6c9f6930bbc (patch)
tree0d7df4a11e2ddbc46788b82a1ec58f63c2adaf83 /docs/assets/js/src/customizer.js
parentf026cfb8310f31db94823d031a382de5d5b0520b (diff)
Add drag and drop config import; closes #11004
Closes #13790 by merging a rebased version of it.
Diffstat (limited to 'docs/assets/js/src/customizer.js')
-rw-r--r--docs/assets/js/src/customizer.js100
1 files changed, 84 insertions, 16 deletions
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) {
$('<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.