Find nearby comments and make them into tooltips

This commit is contained in:
Scott Lahteine 2015-02-07 06:20:04 -08:00
parent 90fa1345b0
commit 1a548c1bc1
2 changed files with 105 additions and 27 deletions

View file

@ -72,3 +72,52 @@ fieldset legend { display: none; }
#serial_stepper { padding-top: 0.75em; display: block; float: left; }
#SERIAL_PORT { display: none; }
.tooltip { position: relative; }
.tooltip::before {
content: attr(data-tooltip);
font-family: sans-serif;
font-size: 85%;
text-align: left;
position: absolute;
z-index: 999;
/*white-space:pre-wrap;*/
bottom: 9999px;
left: 110px;
color: #000;
padding: 8px;
line-height: 1.1;
max-width: 30em;
opacity: 0;
border-radius: 1em;
border: 2px solid #73d699;
background: #e2ff99; /* Old browsers */
background: -moz-linear-gradient(top, #e2ff99 0%, #73d699 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#e2ff99), color-stop(100%,#73d699)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #e2ff99 0%,#73d699 100%); /* IE10+ */
background: linear-gradient(to bottom, #e2ff99 0%,#73d699 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#e2ff99', endColorstr='#73d699',GradientType=0 ); /* IE6-9 */
-webkit-box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
box-shadow: 0px 6px 25px -4px rgba(0,0,0,0.75);
}
.tooltip:hover::before {
opacity: 1;
bottom: 30px;
}
.tooltip:hover::after {
content: "";
opacity: 1;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid #73d699;
z-index: 999;
position: absolute;
/*white-space: nowrap;*/
top: 2px;
left: 130px;
}

View file

@ -28,7 +28,7 @@ String.prototype.lpad = function(len, chr) {
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.regEsc = function() { return this.replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&"); }
String.prototype.lineCount = function() { return this.split(/\r?\n|\r/).length; };
String.prototype.lineCount = function() { var len = this.split(/\r?\n|\r/).length; return len > 0 ? len - 1 : len; };
/**
* selectField.addOptions takes an array or keyed object
@ -206,6 +206,9 @@ var configuratorApp = (function(){
}
},
/**
* Process a file after it's been successfully loaded
*/
fileLoaded: function(filename, txt) {
this.log("fileLoaded:"+filename,4);
switch(filename) {
@ -263,10 +266,8 @@ var configuratorApp = (function(){
var name = $(this).attr('name');
$(this).attr({id: name});
// Attach its label sibling
var $label = $(this).prev();
if ($label[0].tagName == 'LABEL') {
$label.attr('for',name);
}
var $label = $(this).prev('label');
if ($label.length) $label.attr('for',name);
});
// Get all 'switchable' class items and add a checkbox
@ -300,6 +301,9 @@ var configuratorApp = (function(){
});
},
/**
* Update all fields on the form after loading a configuration
*/
refreshConfigForm: function() {
/**
@ -345,11 +349,6 @@ var configuratorApp = (function(){
this.initField('TEMP_RESIDENCY_TIME');
},
setTextAndHighlight: function($field, txt, name) {
var $elm = $('#'+name), elm = $elm[0], inf = elm.defineInfo;
if (inf == null) return;
},
/**
* Make a field responsive and initialize its defineInfo
*/
@ -357,8 +356,15 @@ var configuratorApp = (function(){
this.log("initField:"+name,4);
var $elm = $('#'+name), elm = $elm[0];
if (elm.defineInfo == null) {
elm.defineInfo = this.getDefineInfo(name, adv);
var inf = elm.defineInfo = this.getDefineInfo(name, adv);
$elm.on($elm.attr('type') == 'text' ? 'input' : 'change', this.handleChange);
var comm = inf.comment;
var $tipme = $elm.prev('label');
if ($tipme.length) {
comm ?
$tipme.addClass('tooltip').attr('data-tooltip',comm) :
$tipme.removeClass('tooltip').removeAttr('data-tooltip');
}
}
this.setFieldFromDefine(name);
},
@ -551,13 +557,14 @@ var configuratorApp = (function(){
getDefineInfo: function(name, adv) {
if (adv === undefined) adv = false;
this.log('getDefineInfo:'+name,4);
var $elm = $('#'+name), elm = $elm[0];
var $c = adv ? $config_adv : $config;
var $elm = $('#'+name), elm = $elm[0],
$c = adv ? $config_adv : $config,
txt = $c.text();
// a switch line with no value
var findDef = new RegExp('^(.*//)?(.*#define[ \\t]+' + elm.id + ')([ \\t]*/[*/].*)?$', 'm');
var result = findDef.exec($c.text());
var info = { type:0, adv:adv, field:$c[0], val_i: 2 };
var findDef = new RegExp('^([ \\t]*//)?([ \\t]*#define[ \\t]+' + elm.id + ')([ \\t]*/[*/].*)?$', 'm'),
result = findDef.exec(txt),
info = { type:0, adv:adv, field:$c[0], val_i: 2 };
if (result !== null) {
$.extend(info, {
val_i: 1,
@ -567,13 +574,13 @@ var configuratorApp = (function(){
define: result[2],
post: result[3] === undefined ? '' : result[3]
});
info.regex = new RegExp('( *//)?( *' + info.define.regEsc() + info.post.regEsc() + ')', 'm');
info.repl = new RegExp('( *)(\/\/)?( *' + info.define.regEsc() + info.post.regEsc() + ')', 'm');
info.regex = new RegExp('([ \\t]*//)?([ \\t]*' + info.define.regEsc() + info.post.regEsc() + ')', 'm');
info.repl = new RegExp('([ \\t]*)(\/\/)?([ \\t]*' + info.define.regEsc() + info.post.regEsc() + ')', 'm');
}
else {
// a define with quotes
findDef = new RegExp('^(.*//)?(.*#define[ \\t]+' + elm.id + '[ \\t]+)("[^"]*")([ \\t]*/[*/].*)?$', 'm');
result = findDef.exec($c.text());
result = findDef.exec(txt);
if (result !== null) {
$.extend(info, {
type: 'quoted',
@ -582,13 +589,13 @@ var configuratorApp = (function(){
define: result[2],
post: result[4] === undefined ? '' : result[4]
});
info.regex = new RegExp('( *//)? *' + info.define.regEsc() + '"([^"]*)"' + info.post.regEsc(), 'm');
info.repl = new RegExp('(( *//)? *' + info.define.regEsc() + '")[^"]*("' + info.post.regEsc() + ')', 'm');
info.regex = new RegExp('([ \\t]*//)?[ \\t]*' + info.define.regEsc() + '"([^"]*)"' + info.post.regEsc(), 'm');
info.repl = new RegExp('(([ \\t]*//)?[ \\t]*' + info.define.regEsc() + '")[^"]*("' + info.post.regEsc() + ')', 'm');
}
else {
// a define with no quotes
findDef = new RegExp('^( *//)?( *#define[ \\t]+' + elm.id + '[ \\t]+)(\\S*)([ \\t]*/[*/].*)?$', 'm');
result = findDef.exec($c.text());
findDef = new RegExp('^([ \\t]*//)?([ \\t]*#define[ \\t]+' + elm.id + '[ \\t]+)(\\S*)([ \\t]*/[*/].*)?$', 'm');
result = findDef.exec(txt);
if (result !== null) {
$.extend(info, {
type: 'plain',
@ -597,19 +604,41 @@ var configuratorApp = (function(){
define: result[2],
post: result[4] === undefined ? '' : result[4]
});
info.regex = new RegExp('( *//)? *' + info.define.regEsc() + '(\\S*)' + info.post.regEsc(), 'm');
info.repl = new RegExp('(( *//)? *' + info.define.regEsc() + ')\\S*(' + info.post.regEsc() + ')', 'm');
info.regex = new RegExp('([ \\t]*//)?[ \\t]*' + info.define.regEsc() + '(\\S*)' + info.post.regEsc(), 'm');
info.repl = new RegExp('(([ \\t]*//)?[ \\t]*' + info.define.regEsc() + ')\\S*(' + info.post.regEsc() + ')', 'm');
}
}
}
if (info.type) {
info.lineNum = this.getLineNumberOfText(info.line, $c.text());
this.log(info,2);
var comment = '';
// Get the end-of-line comment, if there is one
findDef = new RegExp('.*#define[ \\t].*/[/*]+[ \\t]*(.*)');
if (info.line.search(findDef) >= 0) {
comment = info.line.replace(findDef, '$1');
}
else {
// Get all the comments immediately before the item
var r, s;
findDef = new RegExp('([ \\t]*(//|#)[^\n]+\n){1,4}\\s{0,1}' + info.line, 'g');
if (r = findDef.exec(txt)) {
findDef = new RegExp('^[ \\t]*//+[ \\t]*(.*)[ \\t]*$', 'gm');
while((s = findDef.exec(r[0])) !== null) {
if (s[1].match(/\/\/[ \\t]*#define/) == null)
comment += s[1] + "\n";
}
}
}
$.extend(info, {
comment: comment.trim(),
lineNum: this.getLineNumberOfText(info.line, txt)
});
}
else
info = null;
this.log(info,2);
return info;
},