function initFields() {
$('#upload-file').filestyle('clear');
$(':input','#filesubmit')
.removeAttr('checked')
.removeAttr('selected')
.not(':button, :submit, :reset, :hidden, :radio, :checkbox')
.val('');
$('.container')
.removeClass("opt")
.removeClass("no-cert");
$(".winmsg").addClass("hidden");
$('Select').val('0');
$('#flash-messages').empty();
$("#image").empty();
$("#maininfo").empty();
$('#qrcode').empty();
}
/*jslint vars: true browser: true*/
/*global $, jQuery, alert, FileReader, FormData*/
/*
* Handle the file/url upload UI. Close
*/
function handleLevelSelectedUI($uploadfile, $uploadurl) {
"use strict";
// File Upload style plugin : http://markusslima.github.io/bootstrap-filestyle/
$uploadfile.filestyle({buttonBefore: true, buttonName: "btn-primary", buttonText: " Choose a level file", badge: false, placeholder: "No file"});
var $filestyle = $uploadfile.next('.bootstrap-filestyle'),
x_html = '×';
$uploadfile.on('change', function () {
$('#dismiss-upload').remove();
$(x_html).appendTo($filestyle);
$uploadurl.slideUp();
$uploadurl.find("input").val("");
$('#dismiss-upload').on('click', function () {
$uploadfile.filestyle('clear');
$uploadurl.slideDown();
initFields();
$(this).remove();
});
});
}
// apply automatically to pages using the standard names
(function () {
"use strict";
var $uploadfile = $("#upload-file"),
$uploadurl = $("#upload-url");
if ($uploadfile.length === 1 && $uploadurl.length === 1) {
handleLevelSelectedUI($uploadfile, $uploadurl);
}
}());
function validateJSON(file) {
try {
var fileReader = new FileReader();
fileReader.onload = function (fileLoadedEvent) {
var textFromFileLoaded = fileLoadedEvent.target.result;
var data = JSON.parse(textFromFileLoaded);
};
fileReader.readAsText(file, "UTF-8");
// if came to here, then valid
return true;
} catch(e) {
// failed to parse
return false;
}
}
/* Guess whether a file is "image", "json", or "unknown" mime type
*/
function fileType(file) {
"use strict";
// console.log(file);
if (file.type.startsWith("image/")) {
return "image";
// } else if (file.type.indexOf("json") !== -1) {
} else if (validateJSON(file)) {
return "json";
} else {
return "unknown";
}
}
/* Create a jQuery image object from file data
*/
function imageFromFile(file) {
"use strict";
if (!file.type.match(/^image/)) {
throw "File Type must be an image";
}
var $img = $("", {
"class": 'img-responsive'
});
// Using FileReader to display the image content
var reader = new FileReader();
reader.onload = (function (aImg) {
return function (e) { aImg.attr('src', e.target.result); };
}($img));
reader.readAsDataURL(file);
return $img;
}
/* Create a jQuery image object with a src url
*/
function imageFromURL(src) {
"use strict";
var $img = $("
", {
"class": 'img-responsive',
"src": src
});
return $img;
}
/* Upload a file to the specified URL
* Returns a deferred object that will receive the level json upon resolution
*/
function uploadFile(url, file) {
"use strict";
var deferredLevel = jQuery.Deferred();
var xhr = new XMLHttpRequest();
var fd = new FormData();
xhr.open("POST", url, true);
xhr.onreadystatechange = (function (deferred) {
return function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// Every thing ok, file uploaded
//console.log(xhr.responseText); // handle response.
var levelJson = xhr.responseText;
var level = JSON.parse(levelJson);
deferred.resolve(level);
} else {
deferred.reject(xhr.responseText);
}
}
};
}(deferredLevel));
fd.append("file", file);
xhr.send(fd);
return deferredLevel;
}
/*
* uploadFile: DOM object of the upload-file input
* imageCallback: function($img) called immediately upon upload with a jQuery image tag
* jsonCallback: function(json) called after the upload finishes with the reponse JSON
*
* throws error strings if no files selected or unsupported file format
*/
function handleLevelSelectedFile(files, imageCallback, jsonCallback) {
"use strict";
if (!files || files.length < 1) {
throw "No file specified";
}
var $img, src, ftype = fileType(files[0]);
// console.log(ftype);
// Fast client-side response
switch (ftype) {
case "image":
// If image, display client-side
$img = imageFromFile(files[0]);
$("#maininfo").empty().text("Parsing level...");
// Begin upload
uploadFile("/decode.json", files[0])
.then(jsonCallback)
.done(function(){
imageCallback($img);
})
.fail(function (err) {
var data = JSON.parse(err);
if (data.hasOwnProperty('message')) {
flash_message(data.message, 'danger');
}
});
break;
default:
try {
// JSON? We need to load asynchronously the file (onload)
var fileReader = new FileReader();
fileReader.onload = function (fileLoadedEvent) {
// This part is not sequencial so when need to do this from inside
var textFromFileLoaded = fileLoadedEvent.target.result;
var data = JSON.parse(textFromFileLoaded);
// No image file so a random one
if (Math.random() < 0.5) {
src = "/static/images/JSON_Upload_brackets.png";
} else {
src = "/static/images/JSON_Upload_escher.png";
}
$img = imageFromURL(src);
$("#maininfo").empty().text("Parsing level...");
// Begin upload
uploadFile("/decode.json", files[0])
.then(jsonCallback)
.done(function(){
imageCallback($img);
})
.fail(function (err) {
var data = JSON.parse(err);
if (data.hasOwnProperty('message')) {
flash_message(data.message, 'danger');
}
});
};
fileReader.readAsText(files[0], "UTF-8");
} catch(e) {
throw "Unsupported file format";
}
}
}
/*
* uploadFile: DOM object of the upload-file input
* imageCallback: function($img) called immediately upon upload with a jQuery image tag
* jsonCallback: function(json) called after the upload finishes with the reponse JSON
*
* throws error strings if no files selected or unsupported file format
*/
function handleLevelSelectedUrl(src, imageCallback, jsonCallback, errorCallback) {
"use strict";
var $img = imageFromURL(src);
imageCallback($img);
// Fetch level
var data = {
"upload-url": src,
"name": "file",
"filename": ""
}
//jQuery.post("/decode.json", data, jsonCallback, "json");
$.post("/decode.json", data, jsonCallback, "json")
.fail(function() {
flash_message("Sorry, an error occurred... :(", "danger");
if (errorCallback) {errorCallback();}
});
}
/* Create a collapsible button and div
* id: ID for the collabsible div. must be unique
* header: Text for the button
* contents: jQuery object with the contents
*/
function mkCollapsable(id, header, contents) {
"use strict";
var $button = $("", {
"data-toggle": "collapse",
"data-target": "#" + id,
"class": "btn btn-primary"
}).text(header);
// var $scroller = $("
Loading...
'); var startDownload = false; var $pgDownload = undefined; var $gencode = $("#gencode"); $gencode.prop('disabled', true); var sendxhr = $.ajax({ xhr: function() { var xhr = new window.XMLHttpRequest(); // Upload progress xhr.upload.addEventListener("progress", function(evt){ if (evt.lengthComputable) { var percentComplete = Math.ceil(100 * evt.loaded / evt.total); if (percentComplete < 100) { $gencode.val('Sending card... '+percentComplete+'%'); } else { $gencode.val('Processing...'); } } }, false); // Download progress xhr.addEventListener("progress", function(evt){ if (evt.lengthComputable) { if (!startDownload) { pg = 'Error...
'; } $qrcode.html(qrcode); } else { var msg = JSON.parse(data); flash_message(msg.message, msg.category); $qrcode.empty(); } } }) .fail(function (jqXHR, textStatus, error) { var err = textStatus + ', ' + error; console.log('JSON: request failed: ' + err); data = 'Error...
'; $qrcode.html(data); jqXHR.abort(); }) .always(function() { console.log('JSON: complete'); $gencode.val('Generate').prop('disabled', false); }); });