More robust fetch code, download buttons
- Fetch code now handles github, local, or http: access - Download button creates a time-stamped inline download - More complete error messages - Show warnings when approaching the hourly fetch quota (limit reloading!) - Added my test domain (where the _htaccess is deployed) - `_htaccess` file added to set Access-Control-Allow-Origin “*” - Marlin logo with css - Limit selectable areas to avoid annoying selections - Messages now persist until dismissed - Default repo for files set to thinkyhead, ‘marlin_configurator’ branch - Cosmetic changes
This commit is contained in:
parent
52c3cf6d34
commit
e74138b2be
@ -51,6 +51,7 @@ Here are some standard links for getting your machine calibrated:
|
|||||||
#define SERIAL_PORT 0
|
#define SERIAL_PORT 0
|
||||||
|
|
||||||
// This determines the communication speed of the printer
|
// This determines the communication speed of the printer
|
||||||
|
// :[2400,9600,19200,38400,57600,115200,250000]
|
||||||
#define BAUDRATE 250000
|
#define BAUDRATE 250000
|
||||||
|
|
||||||
// This enables the serial port associated to the Bluetooth interface
|
// This enables the serial port associated to the Bluetooth interface
|
||||||
|
1
Marlin/configurator/config/_htaccess
Normal file
1
Marlin/configurator/config/_htaccess
Normal file
@ -0,0 +1 @@
|
|||||||
|
Header set Access-Control-Allow-Origin "*"
|
@ -1,22 +1,82 @@
|
|||||||
/* configurator.css */
|
/* configurator.css */
|
||||||
/* Styles for Marlin Configurator */
|
/* Styles for Marlin Configurator */
|
||||||
|
|
||||||
body { margin: 0; padding: 0; background: #56A; color: #FFC; font-family: sans-serif; }
|
.clear { clear: both; }
|
||||||
fieldset { height: 16.1em; overflow: auto; margin-top: 10px; }
|
|
||||||
#main { max-width: 1000px; margin: 0 auto; }
|
/* Prevent selection except PRE tags */
|
||||||
#main { padding: 0 4%; width: 92%; }
|
* {
|
||||||
#main { font-family: monospace; }
|
-webkit-touch-callout: none;
|
||||||
h1, #message { text-align: center; }
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
pre {
|
||||||
|
-webkit-touch-callout: text;
|
||||||
|
-webkit-user-select: text;
|
||||||
|
-khtml-user-select: text;
|
||||||
|
-moz-user-select: text;
|
||||||
|
-ms-user-select: text;
|
||||||
|
user-select: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
body { margin: 0; padding: 0; background: #56A; color: #000; font-family: monospace; }
|
||||||
|
#main {
|
||||||
|
max-width: 1000px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 4%; width: 92%;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 { clear: both; }
|
||||||
|
|
||||||
|
h1, p.info { font-family: sans-serif; }
|
||||||
|
h1 {
|
||||||
|
background: transparent url(logo.png) right top no-repeat;
|
||||||
|
height: 38px;
|
||||||
|
margin-bottom: -30px;
|
||||||
|
}
|
||||||
|
p.info { padding: 0; color: #000; }
|
||||||
|
p.info span { color: #800; }
|
||||||
|
|
||||||
|
#message { text-align: center; }
|
||||||
#message { width: 80%; margin: 0 auto 0.25em; color: #FF0; }
|
#message { width: 80%; margin: 0 auto 0.25em; color: #FF0; }
|
||||||
#message p { padding: 2px 0; }
|
#message p { padding: 2px 0; }
|
||||||
#message p.error, #message p.message { color: #F00; background: #FF4; font-weight: bold; border-radius: 0.8em; }
|
#message p.error, #message p.message { color: #F00; background: #FF4; font-weight: bold; border-radius: 0.8em; }
|
||||||
#message p.message { color: #080; background: #CFC; }
|
#message p.message { color: #080; background: #CFC; }
|
||||||
|
#message p.message span {
|
||||||
|
color: #A00;
|
||||||
|
background: rgba(255, 255, 255, 1);
|
||||||
|
border: 1px solid rgba(0,0,0,0.5);
|
||||||
|
border-radius: 1em;
|
||||||
|
float: right;
|
||||||
|
margin-right: 0.5em;
|
||||||
|
padding: 0 3px;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: small;
|
||||||
|
position: relative;
|
||||||
|
top: -1px;
|
||||||
|
}
|
||||||
|
|
||||||
.info { color: #AAF; }
|
|
||||||
.info span { color: #FFF; }
|
|
||||||
.info span span { color: #000; font-weight: bold; }
|
|
||||||
#help strong { color: #0DD; }
|
#help strong { color: #0DD; }
|
||||||
img { display: none; }
|
img { display: none; }
|
||||||
|
|
||||||
|
/* Forms */
|
||||||
|
|
||||||
|
#config_form {
|
||||||
|
display: block;
|
||||||
|
background: #EEE;
|
||||||
|
padding: 6px 20px 20px;
|
||||||
|
color: #000;
|
||||||
|
position: relative;
|
||||||
|
border-top-right-radius: 1.5em;
|
||||||
|
}
|
||||||
|
fieldset {
|
||||||
|
height: 16.1em;
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
label, input, select, textarea { display: block; float: left; margin: 1px 0; }
|
label, input, select, textarea { display: block; float: left; margin: 1px 0; }
|
||||||
label.newline, textarea, fieldset { clear: both; }
|
label.newline, textarea, fieldset { clear: both; }
|
||||||
label {
|
label {
|
||||||
@ -28,31 +88,9 @@ label {
|
|||||||
}
|
}
|
||||||
input[type="text"], select { margin: 0.75em 0 0; }
|
input[type="text"], select { margin: 0.75em 0 0; }
|
||||||
input[type="checkbox"], input[type="radio"], input[type="file"] { margin: 1em 0 0; }
|
input[type="checkbox"], input[type="radio"], input[type="file"] { margin: 1em 0 0; }
|
||||||
#config_form {
|
|
||||||
display: block;
|
|
||||||
background: #EEE;
|
|
||||||
padding: 6px 20px 20px;
|
|
||||||
color: #000;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*#config_text, #config_adv_text { font-family: "Andale mono", monospace; clear: both; }*/
|
|
||||||
#config_text, #config_adv_text {
|
|
||||||
height: 25em;
|
|
||||||
padding: 10px;
|
|
||||||
border: 2px solid #888;
|
|
||||||
border-radius: 5px;
|
|
||||||
overflow: auto;
|
|
||||||
background-color: #FFF;
|
|
||||||
color: #000;
|
|
||||||
font-family: "Fira Mono";
|
|
||||||
font-size: small;
|
|
||||||
}
|
|
||||||
input[type="checkbox"], input[type="radio"].enabler { margin-left: 1em; }
|
input[type="checkbox"], input[type="radio"].enabler { margin-left: 1em; }
|
||||||
|
|
||||||
input:disabled { color: #BBB; }
|
input:disabled { color: #BBB; }
|
||||||
.clear { clear: both; }
|
|
||||||
h1, h2, h3, h4, h5, h6 { clear: both; }
|
|
||||||
h2 { margin: 0; padding: 1em 0 0; }
|
|
||||||
|
|
||||||
ul.tabs { padding: 0; list-style: none; }
|
ul.tabs { padding: 0; list-style: none; }
|
||||||
ul.tabs li { display: inline; }
|
ul.tabs li { display: inline; }
|
||||||
@ -100,6 +138,8 @@ fieldset legend { display: none; }
|
|||||||
#serial_stepper { padding-top: 0.75em; display: block; float: left; }
|
#serial_stepper { padding-top: 0.75em; display: block; float: left; }
|
||||||
#SERIAL_PORT { display: none; }
|
#SERIAL_PORT { display: none; }
|
||||||
|
|
||||||
|
/* Tooltips */
|
||||||
|
|
||||||
#tooltip {
|
#tooltip {
|
||||||
display: none;
|
display: none;
|
||||||
max-width: 30em;
|
max-width: 30em;
|
||||||
@ -138,18 +178,61 @@ fieldset legend { display: none; }
|
|||||||
}
|
}
|
||||||
#tooltip>strong { color: #00B; }
|
#tooltip>strong { color: #00B; }
|
||||||
|
|
||||||
span.disclose {
|
/* Tooltips Checkbox */
|
||||||
|
|
||||||
|
#tipson { float: right; font-weight: bold; font-size: 100%; font-family: helvetica; }
|
||||||
|
#tipson input { float: none; display: inline; }
|
||||||
|
|
||||||
|
/* Config Text */
|
||||||
|
|
||||||
|
pre.config {
|
||||||
|
height: 25em;
|
||||||
|
padding: 10px;
|
||||||
|
border: 2px solid #888;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: auto;
|
||||||
|
clear: both;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: #000;
|
||||||
|
font-family: "Fira Mono";
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pre Headers */
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
width: 100%;
|
||||||
|
margin: 12px -300px 4px 0;
|
||||||
|
padding: 0;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Disclosure Widget */
|
||||||
|
|
||||||
|
span.disclose, a.download {︎
|
||||||
|
display: block;
|
||||||
float: right;
|
float: right;
|
||||||
margin-top: -10px;
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.disclose {
|
||||||
|
margin-right: -10px; /* total width */
|
||||||
|
margin-left: 14px;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
position: relative;
|
||||||
|
left: 3px;
|
||||||
|
top: 3px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-left: 8px solid transparent;
|
border-left: 8px solid transparent;
|
||||||
border-right: 8px solid transparent;
|
border-right: 8px solid transparent;
|
||||||
border-top: 10px solid #000;
|
border-top: 10px solid #000;
|
||||||
}
|
}
|
||||||
span.disclose.closed {
|
span.disclose.closed {
|
||||||
margin: -14px 4px 0 0;
|
margin-right: -8px; /* total width */
|
||||||
|
margin-left: 10px;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
border-top: 8px solid transparent;
|
border-top: 8px solid transparent;
|
||||||
border-bottom: 8px solid transparent;
|
border-bottom: 8px solid transparent;
|
||||||
border-right: 10px solid #000;
|
border-right: 10px solid #000;
|
||||||
@ -160,9 +243,26 @@ span.disclose.almost {
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
}
|
}
|
||||||
span.disclose.closed.almost {
|
span.disclose.closed.almost {
|
||||||
|
left: 1px;
|
||||||
|
top: 3px;
|
||||||
-ms-transform: rotate(315deg); /* IE 9 */
|
-ms-transform: rotate(315deg); /* IE 9 */
|
||||||
-webkit-transform: rotate(315deg); /* Chrome, Safari, Opera */
|
-webkit-transform: rotate(315deg); /* Chrome, Safari, Opera */
|
||||||
transform: rotate(315deg);
|
transform: rotate(315deg);
|
||||||
}
|
}
|
||||||
#tipson { float: right; font-weight: bold; font-size: 100%; font-family: helvetica; }
|
|
||||||
#tipson input { float: none; display: inline; }
|
/* Download Button */
|
||||||
|
|
||||||
|
a.download {
|
||||||
|
visibility: hidden;
|
||||||
|
padding: 2px;
|
||||||
|
border: 1px solid #494;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin: 12px 0 0;
|
||||||
|
background: #FFF;
|
||||||
|
color: #494;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: small;
|
||||||
|
font-weight: bold;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
BIN
Marlin/configurator/css/logo.png
Normal file
BIN
Marlin/configurator/css/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -2,7 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Marlin Configurator</title>
|
<title>Marlin Firmware Configurator</title>
|
||||||
<link href='http://fonts.googleapis.com/css?family=Fira+Mono&subset=latin,latin-ext' rel='stylesheet' type='text/css' />
|
<link href='http://fonts.googleapis.com/css?family=Fira+Mono&subset=latin,latin-ext' rel='stylesheet' type='text/css' />
|
||||||
<script src="js/jquery-2.1.3.min.js"></script>
|
<script src="js/jquery-2.1.3.min.js"></script>
|
||||||
<script src="js/binarystring.js"></script>
|
<script src="js/binarystring.js"></script>
|
||||||
@ -15,11 +15,9 @@
|
|||||||
<body>
|
<body>
|
||||||
<section id="main">
|
<section id="main">
|
||||||
<h1>Marlin Configurator</h1>
|
<h1>Marlin Configurator</h1>
|
||||||
|
<p class="info">Select presets (coming soon), modify, and download.</p>
|
||||||
|
|
||||||
<div id="message">
|
<div id="message"></div>
|
||||||
<p class="info">Enter values in the form, get a Marlin configuration.<br/>Will include a drop-down of known configurations.</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="tabs"></div>
|
<div id="tabs"></div>
|
||||||
|
|
||||||
<form id="config_form">
|
<form id="config_form">
|
||||||
@ -83,10 +81,19 @@
|
|||||||
<legend>More…</legend>
|
<legend>More…</legend>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|
||||||
<h2>Marlin/Configuration.h</h2><span class="disclose"></span>
|
<section id="config_text">
|
||||||
<pre id="config_text" class="hilightable"></pre>
|
<h2>Configuration.h</h2>
|
||||||
<h2>Marlin/Configuration_adv.h</h2><span class="disclose"></span>
|
<span class="disclose"></span>
|
||||||
<pre id="config_adv_text" class="hilightable"></pre>
|
<a href="" class="download">Download</a>
|
||||||
|
<pre class="hilightable config"></pre>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section id="config_adv_text">
|
||||||
|
<h2>Configuration_adv.h</h2>
|
||||||
|
<span class="disclose"></span>
|
||||||
|
<a href="" class="download">Download</a>
|
||||||
|
<pre class="hilightable config"></pre>
|
||||||
|
</section>
|
||||||
|
|
||||||
<br class="clear" />
|
<br class="clear" />
|
||||||
</form>
|
</form>
|
||||||
|
@ -16,7 +16,62 @@
|
|||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
||||||
var marlin_config = 'https://api.github.com/repos/MarlinFirmware/Marlin/contents/Marlin';
|
/**
|
||||||
|
* Github API useful GET paths. (Start with "https://api.github.com/repos/:owner/:repo/")
|
||||||
|
*
|
||||||
|
* contributors Get a list of contributors
|
||||||
|
* tags Get a list of tags
|
||||||
|
* contents/[path]?ref=branch/tag/commit Get the contents of a file
|
||||||
|
*/
|
||||||
|
|
||||||
|
// GitHub
|
||||||
|
// Warning! Limited to 60 requests per hour!
|
||||||
|
var config = {
|
||||||
|
type: 'github',
|
||||||
|
host: 'https://api.github.com',
|
||||||
|
owner: 'thinkyhead',
|
||||||
|
repo: 'Marlin',
|
||||||
|
ref: 'marlin_configurator',
|
||||||
|
path: 'Marlin/configurator/config'
|
||||||
|
};
|
||||||
|
/**/
|
||||||
|
|
||||||
|
/* // Remote
|
||||||
|
var config = {
|
||||||
|
type: 'remote',
|
||||||
|
host: 'http://www.thinkyhead.com',
|
||||||
|
path: '_marlin/config'
|
||||||
|
};
|
||||||
|
/**/
|
||||||
|
|
||||||
|
/* // Local
|
||||||
|
var config = {
|
||||||
|
type: 'local',
|
||||||
|
path: 'config'
|
||||||
|
};
|
||||||
|
/**/
|
||||||
|
|
||||||
|
function github_command(conf, command, path) {
|
||||||
|
var req = conf.host+'/repos/'+conf.owner+'/'+conf.repo+'/'+command;
|
||||||
|
if (path) req += '/' + path;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
function config_path(item) {
|
||||||
|
var path = '', ref = '';
|
||||||
|
switch(config.type) {
|
||||||
|
case 'github':
|
||||||
|
path = github_command(config, 'contents', config.path);
|
||||||
|
if (config.ref !== undefined) ref = '?ref=' + config.ref;
|
||||||
|
break;
|
||||||
|
case 'remote':
|
||||||
|
path = config.host + '/' + config.path + '/';
|
||||||
|
break;
|
||||||
|
case 'local':
|
||||||
|
path = config.path + '/';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return path + '/' + item + ref;
|
||||||
|
}
|
||||||
|
|
||||||
// Extend builtins
|
// Extend builtins
|
||||||
String.prototype.lpad = function(len, chr) {
|
String.prototype.lpad = function(len, chr) {
|
||||||
@ -25,6 +80,7 @@ String.prototype.lpad = function(len, chr) {
|
|||||||
if (need > 0) { s = new Array(need+1).join(chr) + s; }
|
if (need > 0) { s = new Array(need+1).join(chr) + s; }
|
||||||
return s;
|
return s;
|
||||||
};
|
};
|
||||||
|
|
||||||
String.prototype.prePad = function(len, chr) { return len ? this.lpad(len, chr) : this; };
|
String.prototype.prePad = function(len, chr) { return len ? this.lpad(len, chr) : this; };
|
||||||
String.prototype.zeroPad = function(len) { return this.prePad(len, '0'); };
|
String.prototype.zeroPad = function(len) { return this.prePad(len, '0'); };
|
||||||
String.prototype.toHTML = function() { return jQuery('<div>').text(this).html(); };
|
String.prototype.toHTML = function() { return jQuery('<div>').text(this).html(); };
|
||||||
@ -36,6 +92,19 @@ Number.prototype.limit = function(m1, m2) {
|
|||||||
if (m2 == null) return this > m1 ? m1 : this;
|
if (m2 == null) return this > m1 ? m1 : this;
|
||||||
return this < m1 ? m1 : this > m2 ? m2 : this;
|
return this < m1 ? m1 : this > m2 ? m2 : this;
|
||||||
};
|
};
|
||||||
|
Date.prototype.fileStamp = function(filename) {
|
||||||
|
var fs = this.getFullYear()
|
||||||
|
+ ((this.getMonth()+1)+'').zeroPad(2)
|
||||||
|
+ (this.getDate()+'').zeroPad(2)
|
||||||
|
+ (this.getHours()+'').zeroPad(2)
|
||||||
|
+ (this.getMinutes()+'').zeroPad(2)
|
||||||
|
+ (this.getSeconds()+'').zeroPad(2);
|
||||||
|
|
||||||
|
if (filename !== undefined)
|
||||||
|
return filename.replace(/^(.+)(\.\w+)$/g, '$1-['+fs+']$2');
|
||||||
|
|
||||||
|
return fs;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* selectField.addOptions takes an array or keyed object
|
* selectField.addOptions takes an array or keyed object
|
||||||
@ -49,6 +118,12 @@ $.fn.extend({
|
|||||||
sel.append( $('<option>',{value:isArr?v:k}).text(v) );
|
sel.append( $('<option>',{value:isArr?v:k}).text(v) );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
noSelect: function() {
|
||||||
|
return this
|
||||||
|
.attr('unselectable', 'on')
|
||||||
|
.css('user-select', 'none')
|
||||||
|
.on('selectstart', false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -62,10 +137,11 @@ var configuratorApp = (function(){
|
|||||||
boards_file = 'boards.h',
|
boards_file = 'boards.h',
|
||||||
config_file = 'Configuration.h',
|
config_file = 'Configuration.h',
|
||||||
config_adv_file = 'Configuration_adv.h',
|
config_adv_file = 'Configuration_adv.h',
|
||||||
|
$msgbox = $('#message'),
|
||||||
$form = $('#config_form'),
|
$form = $('#config_form'),
|
||||||
$tooltip = $('#tooltip'),
|
$tooltip = $('#tooltip'),
|
||||||
$config = $('#config_text'),
|
$config = $('#config_text pre'),
|
||||||
$config_adv = $('#config_adv_text'),
|
$config_adv = $('#config_adv_text pre'),
|
||||||
define_list = [[],[]],
|
define_list = [[],[]],
|
||||||
boards_list = {},
|
boards_list = {},
|
||||||
therms_list = {},
|
therms_list = {},
|
||||||
@ -88,6 +164,9 @@ var configuratorApp = (function(){
|
|||||||
// Make tabs for all the fieldsets
|
// Make tabs for all the fieldsets
|
||||||
this.makeTabsForFieldsets();
|
this.makeTabsForFieldsets();
|
||||||
|
|
||||||
|
// No selection on errors
|
||||||
|
$msgbox.noSelect();
|
||||||
|
|
||||||
// Make a droppable file uploader, if possible
|
// Make a droppable file uploader, if possible
|
||||||
var $uploader = $('#file-upload');
|
var $uploader = $('#file-upload');
|
||||||
var fileUploader = new BinaryFileUploader({
|
var fileUploader = new BinaryFileUploader({
|
||||||
@ -99,41 +178,98 @@ var configuratorApp = (function(){
|
|||||||
|
|
||||||
// Make the disclosure items work
|
// Make the disclosure items work
|
||||||
$('.disclose').click(function(){
|
$('.disclose').click(function(){
|
||||||
var $dis = $(this), $pre = $dis.next('pre');
|
var $dis = $(this), $pre = $dis.nextAll('pre:first');
|
||||||
var didAnim = function() {$dis.toggleClass('closed almost');};
|
var didAnim = function() {$dis.toggleClass('closed almost');};
|
||||||
$dis.addClass('almost').hasClass('closed')
|
$dis.addClass('almost').hasClass('closed')
|
||||||
? $pre.slideDown(500, didAnim)
|
? $pre.slideDown(200, didAnim)
|
||||||
: $pre.slideUp(500, didAnim);
|
: $pre.slideUp(200, didAnim);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Read boards.h, Configuration.h, Configuration_adv.h
|
// Read boards.h, Configuration.h, Configuration_adv.h
|
||||||
var ajax_count = 0, success_count = 0;
|
var ajax_count = 0, success_count = 0;
|
||||||
var loaded_items = {};
|
var loaded_items = {};
|
||||||
var config_files = [boards_file, config_file, config_adv_file];
|
var config_files = [boards_file, config_file, config_adv_file];
|
||||||
var isGithub = marlin_config.match('api.github');
|
var isGithub = config.type == 'github';
|
||||||
|
var rateLimit = 0;
|
||||||
$.each(config_files, function(i,fname){
|
$.each(config_files, function(i,fname){
|
||||||
|
var url = config_path(fname);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: marlin_config+'/'+fname,
|
url: url,
|
||||||
type: 'GET',
|
type: 'GET',
|
||||||
dataType: isGithub ? 'jsonp' : 'script',
|
dataType: isGithub ? 'jsonp' : undefined,
|
||||||
async: true,
|
async: true,
|
||||||
cache: false,
|
cache: false,
|
||||||
|
error: function(req, stat, err) {
|
||||||
|
self.log(req, 1);
|
||||||
|
if (req.status == 200) {
|
||||||
|
if (typeof req.responseText === 'string') {
|
||||||
|
var txt = req.responseText;
|
||||||
|
loaded_items[fname] = function(){ self.fileLoaded(fname, txt); };
|
||||||
|
success_count++;
|
||||||
|
// self.setMessage('The request for "'+fname+'" may be malformed.', 'error');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.setRequestError(req.status ? req.status : '(Access-Control-Allow-Origin?)', url);
|
||||||
|
}
|
||||||
|
},
|
||||||
success: function(txt) {
|
success: function(txt) {
|
||||||
|
if (isGithub && typeof txt.meta.status !== undefined && txt.meta.status != 200) {
|
||||||
|
self.setRequestError(txt.meta.status, url);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// self.log(txt, 1);
|
||||||
|
if (isGithub) {
|
||||||
|
rateLimit = {
|
||||||
|
quota: 1 * txt.meta['X-RateLimit-Remaining'],
|
||||||
|
timeLeft: Math.floor(txt.meta['X-RateLimit-Reset'] - Date.now()/1000),
|
||||||
|
};
|
||||||
|
}
|
||||||
loaded_items[fname] = function(){ self.fileLoaded(fname, isGithub ? atob(txt.data.content) : txt); };
|
loaded_items[fname] = function(){ self.fileLoaded(fname, isGithub ? atob(txt.data.content) : txt); };
|
||||||
success_count++;
|
success_count++;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
complete: function() {
|
complete: function() {
|
||||||
ajax_count++;
|
ajax_count++;
|
||||||
if (ajax_count >= 3) {
|
if (ajax_count >= 3) {
|
||||||
$.each(config_files, function(){ if (loaded_items[this]) loaded_items[this](); });
|
$.each(config_files, function(){ if (loaded_items[this]) loaded_items[this](); });
|
||||||
if (success_count < ajax_count)
|
if (success_count < ajax_count)
|
||||||
self.setMessage('Unable to load configurations. Use the upload field instead.', 'error');
|
self.setMessage('Unable to load configurations. Try the upload field.', 'error');
|
||||||
|
var r;
|
||||||
|
if (r = rateLimit) {
|
||||||
|
if (r.quota < 20) {
|
||||||
|
self.setMessage(
|
||||||
|
'Approaching request limit (' +
|
||||||
|
r.quota + ' remaining.' +
|
||||||
|
' Reset in ' + Math.floor(r.timeLeft/60) + ':' + (r.timeLeft%60+'').zeroPad(2) + ')'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
createDownloadLink: function(adv) {
|
||||||
|
var $c = adv ? $config_adv : $config, txt = $c.text();
|
||||||
|
var filename = (adv ? config_adv_file : config_file);
|
||||||
|
$c.prevAll('.download:first')
|
||||||
|
.mouseover(function() {
|
||||||
|
var d = new Date(), fn = d.fileStamp(filename);
|
||||||
|
$(this).attr({ download:fn, href:'download:'+fn, title:'download:'+fn });
|
||||||
|
})
|
||||||
|
.click(function(){
|
||||||
|
var $button = $(this);
|
||||||
|
$(this).attr({ href:'data:text/plain;charset=utf-8,' + encodeURIComponent($c.text()) });
|
||||||
|
setTimeout(function(){
|
||||||
|
$button.attr({ href:$button.attr('title') });
|
||||||
|
}, 100);
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.css({visibility:'visible'});
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init the boards array from a boards.h file
|
* Init the boards array from a boards.h file
|
||||||
*/
|
*/
|
||||||
@ -239,6 +375,7 @@ var configuratorApp = (function(){
|
|||||||
this.log(define_list[0], 2);
|
this.log(define_list[0], 2);
|
||||||
this.createFieldsForDefines(0);
|
this.createFieldsForDefines(0);
|
||||||
this.refreshConfigForm();
|
this.refreshConfigForm();
|
||||||
|
this.createDownloadLink(false);
|
||||||
has_config = true;
|
has_config = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -253,6 +390,7 @@ var configuratorApp = (function(){
|
|||||||
define_list[1] = this.getDefinesFromText(txt);
|
define_list[1] = this.getDefinesFromText(txt);
|
||||||
this.log(define_list[1], 2);
|
this.log(define_list[1], 2);
|
||||||
this.refreshConfigForm();
|
this.refreshConfigForm();
|
||||||
|
this.createDownloadLink(true);
|
||||||
has_config_adv = true;
|
has_config_adv = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -289,7 +427,7 @@ var configuratorApp = (function(){
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Get all 'switchable' class items and add a checkbox
|
// Get all 'switchable' class items and add a checkbox
|
||||||
$('#config_form .switchable').each(function(){
|
$form.find('.switchable').each(function(){
|
||||||
$(this).after(
|
$(this).after(
|
||||||
$('<input>',{type:'checkbox',value:'1',class:'enabler'}).prop('checked',true)
|
$('<input>',{type:'checkbox',value:'1',class:'enabler'}).prop('checked',true)
|
||||||
.attr('id',this.id + '-switch')
|
.attr('id',this.id + '-switch')
|
||||||
@ -651,6 +789,7 @@ var configuratorApp = (function(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Success?
|
||||||
if (info.type) {
|
if (info.type) {
|
||||||
// Get the end-of-line comment, if there is one
|
// Get the end-of-line comment, if there is one
|
||||||
var tooltip = '';
|
var tooltip = '';
|
||||||
@ -668,11 +807,11 @@ var configuratorApp = (function(){
|
|||||||
tooltip = '';
|
tooltip = '';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tooltip += ' ' + s[1] + "\n";
|
tooltip += ' ' + s[1] + '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findDef = new RegExp('^[ \\t]*'+name+'[ \\t]*', 'm');
|
findDef = new RegExp('^[ \\t]*'+name); // To strip the name from the start
|
||||||
$.extend(info, {
|
$.extend(info, {
|
||||||
tooltip: '<strong>'+name+'</strong> '+tooltip.replace(findDef,'').trim().toHTML(),
|
tooltip: '<strong>'+name+'</strong> '+tooltip.replace(findDef,'').trim().toHTML(),
|
||||||
lineNum: this.getLineNumberOfText(info.line, txt)
|
lineNum: this.getLineNumberOfText(info.line, txt)
|
||||||
@ -700,24 +839,22 @@ var configuratorApp = (function(){
|
|||||||
setMessage: function(msg,type) {
|
setMessage: function(msg,type) {
|
||||||
if (msg) {
|
if (msg) {
|
||||||
if (type === undefined) type = 'message';
|
if (type === undefined) type = 'message';
|
||||||
var $err = $('<p class="'+type+'">'+msg+'</p>'), err = $err[0];
|
var $err = $('<p class="'+type+'">'+msg+'<span>x</span></p>').appendTo($msgbox), err = $err[0];
|
||||||
$('#message').prepend($err);
|
|
||||||
var baseColor = $err.css('color').replace(/rgba?\(([^),]+,[^),]+,[^),]+).*/, 'rgba($1,');
|
var baseColor = $err.css('color').replace(/rgba?\(([^),]+,[^),]+,[^),]+).*/, 'rgba($1,');
|
||||||
var d = new Date();
|
|
||||||
err.pulse_offset = (pulse_offset += 200);
|
err.pulse_offset = (pulse_offset += 200);
|
||||||
err.startTime = d.getTime() + pulse_offset;
|
err.startTime = Date.now() + pulse_offset;
|
||||||
err.pulser = setInterval(function(){
|
err.pulser = setInterval(function(){
|
||||||
d = new Date();
|
var pulse_time = Date.now() + err.pulse_offset;
|
||||||
var pulse_time = d.getTime() + err.pulse_offset;
|
var opac = 0.5+Math.sin(pulse_time/200)*0.4;
|
||||||
$err.css({color:baseColor+(0.5+Math.sin(pulse_time/200)*0.4)+')'});
|
$err.css({color:baseColor+(opac)+')'});
|
||||||
if (pulse_time - err.startTime > 5000) {
|
if (pulse_time - err.startTime > 2500 && opac > 0.899) {
|
||||||
clearInterval(err.pulser);
|
clearInterval(err.pulser);
|
||||||
$err.remove();
|
|
||||||
}
|
}
|
||||||
}, 50);
|
}, 50);
|
||||||
|
$err.click(function(e) { $(this).remove(); return false; }).css({cursor:'pointer'});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$('#message p.error, #message p.warning').each(function() {
|
$msgbox.find('p.error, p.warning').each(function() {
|
||||||
if (this.pulser !== undefined && this.pulser)
|
if (this.pulser !== undefined && this.pulser)
|
||||||
clearInterval(this.pulser);
|
clearInterval(this.pulser);
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
@ -725,6 +862,10 @@ var configuratorApp = (function(){
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setRequestError: function(stat, path) {
|
||||||
|
self.setMessage('Error '+stat+' – ' + path.replace(/^(https:\/\/[^\/]+\/)?.+(\/[^\/]+)$/, '$1...$2'), 'error');
|
||||||
|
},
|
||||||
|
|
||||||
log: function(o,l) {
|
log: function(o,l) {
|
||||||
if (l === undefined) l = 0;
|
if (l === undefined) l = 0;
|
||||||
if (this.logging>=l*1) console.log(o);
|
if (this.logging>=l*1) console.log(o);
|
||||||
|
Loading…
Reference in New Issue
Block a user