2012-04-12 01:26:10 +00:00
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2012-03-15 10:43:45 +00:00
< html >
< head >
2012-04-12 01:26:10 +00:00
< meta http-equiv = "Content-type" content = "text/html;charset=UTF-8" >
< title > fish shell configuration< / title >
2012-03-15 10:43:45 +00:00
< style type = "text/css" >
body {
background-color: #292929;
font-family: Courier, "Courier New", monospace;
color: white;
}
#ancestor {
width: 800px;
margin-left: auto;
margin-right: auto;
margin-top: 25px;
}
#parent {
width: 100%;
2012-03-17 00:21:37 +00:00
min-height: 480px;
2012-03-22 17:23:07 +00:00
margin-top: 12px;
2012-03-15 10:43:45 +00:00
}
#tab_parent {
2012-03-26 05:41:22 +00:00
display: table;
2012-03-15 10:43:45 +00:00
width: 100%;
2012-03-26 05:41:22 +00:00
height: 50px;;
2012-03-15 10:43:45 +00:00
}
2012-03-16 10:03:43 +00:00
.tab {
2012-03-26 05:41:22 +00:00
display: table-cell;
border: 1px solid #111;
border-right: none;
padding-bottom: 15px;
padding-top: 15px;
2012-03-15 10:43:45 +00:00
font-size: 17pt;
text-align: center;
width: 25%;
background-color: #292929;
2012-03-16 10:03:43 +00:00
cursor: pointer;
2012-03-15 10:43:45 +00:00
}
2012-03-26 05:41:22 +00:00
#tab_parent :first-child {
border-top-left-radius: 8px;
}
#tab_parent :last-child {
border-right: 1px solid #111;
border-top-right-radius: 8px;
}
.tab_first {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.tab_last {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
2012-03-15 10:43:45 +00:00
.selected_tab {
2012-03-26 05:41:22 +00:00
background-color: black;
border-color: black;
}
#tab_contents {
padding-top: 35px;
width: 100%;
background-color: black;
border-bottom-left-radius: 8px;
border-bottom-right-radius: 8px;
margin-bottom: 20px;
2012-03-15 10:43:45 +00:00
}
.footer {
clear: both;
height: 30px;
}
2012-03-25 10:00:38 +00:00
#master_detail_table {
display: table;
margin-top: 10px;
2012-03-25 22:56:43 +00:00
margin-left: 12px;
margin-right: 12px;
2012-03-22 17:23:07 +00:00
}
2012-03-15 10:43:45 +00:00
#master {
2012-03-25 10:00:38 +00:00
display: table-cell;
2012-03-15 10:43:45 +00:00
text-align: right;
2012-03-17 00:21:37 +00:00
min-width: 200px;
2012-03-15 10:43:45 +00:00
font-size: 16pt;
2012-03-26 05:41:22 +00:00
padding-bottom: 5px;
2012-03-22 17:23:07 +00:00
margin-top: -7px;
2012-03-15 10:43:45 +00:00
}
2012-03-25 10:00:38 +00:00
#detail {
display: table-cell;
border: 1px solid #555;
background-color: #181818;
padding-top: 30px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
2012-03-26 05:41:22 +00:00
border-radius: 5;
2012-07-27 07:31:00 +00:00
width: 100%;
2012-03-25 10:00:38 +00:00
}
#detail_function {
2012-03-25 22:56:43 +00:00
white-space: pre-wrap;
2012-03-25 10:00:38 +00:00
width: 100%;
2012-03-25 22:56:43 +00:00
font-size: 11pt;
color: #BBB;
2012-03-25 10:00:38 +00:00
}
2012-03-15 10:43:45 +00:00
.master_element {
2012-03-25 10:00:38 +00:00
padding-top: 6px;
padding-bottom: 11px;
2012-03-15 10:43:45 +00:00
padding-left: 5px;
2012-03-25 22:56:43 +00:00
padding-right: 22px;
2012-03-17 00:21:37 +00:00
font-size: 12pt;
2012-03-25 10:00:38 +00:00
/* Make our border overlap the detail, even if we're unselected (so it doesn't jump when selected) */
position: relative;
left: 1px;
2012-05-09 00:10:38 +00:00
border-bottom-style: solid;
border-bottom-width: 0px;
2012-03-15 10:43:45 +00:00
}
2012-03-22 17:23:07 +00:00
.selected_master_elem {
border: 1px solid #555;
border-right: none;
2012-03-25 10:00:38 +00:00
background-color: #181818;
2012-03-26 05:41:22 +00:00
border-top-left-radius: 5;
border-bottom-left-radius: 5;
2012-03-25 10:00:38 +00:00
/* Pad one less than .master_element, to accomodate our border. */
padding-top: 5px;
padding-bottom: 10px;
2012-03-25 22:56:43 +00:00
padding-left: 4px;
2012-03-22 17:23:07 +00:00
}
2012-03-15 10:43:45 +00:00
.master_element_text {
text-decoration: none;
padding-bottom: 1px;
2012-05-09 00:10:38 +00:00
border-bottom-style: inherit;
border-bottom-color: inherit;
border-bottom-width: 1px;
2012-03-15 10:43:45 +00:00
}
2012-05-09 00:10:38 +00:00
.master_element_description {
text-decoration: none;
padding-top: 15px;
font-size: 10pt;
border-bottom-style: inherit;
border-bottom-color: inherit;
border-bottom-width: 1px;
display: none;
}
.selected_master_elem > .master_element_description {
display: inline;
}
/* We have a newline between the label and description; hide it initially, but show it when it's selected */
.master_element > br { display: none; }
.selected_master_elem > br { display: inherit; }
/* Set this class to suppress the border bottom on master_element_texts with visible descriptions */
.master_element_no_border { border-bottom-width: 0 }
2012-03-19 07:03:21 +00:00
#colorpicker_term256 {
2012-03-25 10:00:38 +00:00
border: solid #444 1px;
}
.colorpicker_modifiers {
margin-top: 10px;
display:inline-block;
margin-left: auto;
margin-right: auto;
color: #AAA;
font-size: smaller;
}
.colorpicker_modifier_cell {
cursor: pointer;
display:inline-block;
text-align: center;
2012-03-26 05:41:22 +00:00
border: groove #333 2px;
2012-03-25 10:00:38 +00:00
padding: 5px;
margin-top: 5px;
margin-left: auto;
margin-right: auto;
}
.modifier_cell_selected {
color: #CCC;
border-color: #AAA;
background-color: #444;
2012-03-19 07:03:21 +00:00
}
2012-03-17 00:21:37 +00:00
#data_table {
table-layout:fixed;
2012-03-25 22:56:43 +00:00
color: #CCC;
2012-03-17 00:21:37 +00:00
width: 100%;
padding-left: 10px;
padding-right: 10px;
}
.data_table_row {
}
.data_table_cell {
2012-03-19 18:51:44 +00:00
padding-top: 5px;
padding-bottom: 5px;
2012-03-26 05:41:22 +00:00
vertical-align: top;
2012-03-17 00:21:37 +00:00
overflow:hidden;
2012-03-19 18:51:44 +00:00
border-bottom: #444 dotted 1px;
2012-03-25 22:56:43 +00:00
word-wrap: break-word;
2012-03-19 18:51:44 +00:00
}
2012-07-27 07:31:00 +00:00
/* The CSS we apply when a table row is filtered */
.data_table_row_filtered {
display: none;
}
2012-03-19 18:51:44 +00:00
.no_overflow {
2012-03-17 00:21:37 +00:00
text-overflow: ellipsis;
2012-03-25 22:56:43 +00:00
white-space: nowrap;
2012-03-17 00:21:37 +00:00
}
2012-03-26 05:41:22 +00:00
.colorpicker_target {
2012-04-01 08:31:38 +00:00
margin: 0 0 -50px 0;
position: relative;
bottom: 47px;
float: left; /* for some reason this makes the cells that it overlaps (before adjusting its bottom) clickable in Safari */
2012-03-25 10:00:38 +00:00
}
2012-03-26 05:41:22 +00:00
.colorpicker_target_tab {
2012-03-25 10:00:38 +00:00
cursor: pointer;
2012-03-26 05:41:22 +00:00
color: #555;
border: solid 1px #555;
2012-03-25 10:00:38 +00:00
padding-top: 5px;
padding-bottom: 5px;
padding-left: 7px;
padding-right: 7px;
display: inline-block;
background-color: black;
margin-right: -2px;
min-width: 110px;
text-align: center;
}
2012-03-26 05:41:22 +00:00
.colorpicker_target_selected {
background-color: #181818; /* same as #detail */
2012-03-25 10:00:38 +00:00
color: white;
}
2012-03-17 00:21:37 +00:00
.colorpicker_term256_row {
}
.colorpicker_term256_cell {
2012-03-28 02:00:03 +00:00
width: 29;
height: 29;
2012-03-17 00:21:37 +00:00
}
.colorpicker_cell_selected {
2012-03-25 10:00:38 +00:00
border: dashed white 3px;
2012-03-28 02:00:03 +00:00
width: 23;
height: 23;
2012-03-17 00:21:37 +00:00
}
2012-03-22 17:23:07 +00:00
.error_msg {
color: red;
font-size: 12pt;
margin-left: 24pt;
margin-top: 5pt;
margin-bottom: 5pt;
}
2012-07-27 07:31:00 +00:00
img.delete_icon {
width: 20px;
height: 20px;
cursor: pointer;
text-decoration: none;
border: none;
}
#table_filter_container {
/* top right bottom left*/
padding: 0 10 10 30;
text-align: right;
position: relative;
bottom: 10px;
}
2012-08-20 18:58:54 +00:00
#table_filter_text_box {
}
.filter_text_box {
2012-07-27 07:31:00 +00:00
width: 250px;
padding: 5 10 5 10;
background-color: #888;
border: #222 solid 3px;
border-radius: 15px;
font-size: 12pt;
color: white;
font-weight: bold;
}
.text_box_transient {
color: #C8C8C8;
}
2012-03-15 10:43:45 +00:00
< / style >
< script type = "text/javascript" src = "jquery.js" > < / script >
< script type = "text/javascript" >
2012-03-25 10:00:38 +00:00
function show_error(msg) {
$('#global_error').text(msg)
}
2012-03-22 17:23:07 +00:00
function request_failed(jqXHR, textStatus, errorThrown) {
msg = ''
if (textStatus == "timeout") {
2012-03-26 05:41:22 +00:00
msg = 'The request timed out. Perhaps the server has shut down or is hung.'
2012-03-22 17:23:07 +00:00
} else if (textStatus == "error") {
msg = 'The request received an error.'
if (jqXHR.status == 0)
2012-03-26 05:41:22 +00:00
msg = msg + ' Perhaps the server has shut down.'
2012-03-22 17:23:07 +00:00
} else if (msg == 'abort') {
msg = 'The request aborted.'
} else if (msg == 'parsererror') {
msg = 'The request experienced a parser error.'
} else {
msg = 'The request had an unknown error "' + textStatus + '."'
}
if (errorThrown.length > 0) {
msg = msg + ' The HTTP reply returned ' + errorThrown
}
2012-03-25 10:00:38 +00:00
show_error(msg)
2012-03-16 10:03:43 +00:00
}
2012-03-17 00:21:37 +00:00
/* Runs a GET request, parses the JSON, and invokes the handler for each element in it. The JSON result is assumed to be an array. */
2012-07-27 07:31:00 +00:00
function run_get_request_with_bulk_handler(url, handler) {
2012-03-17 00:21:37 +00:00
$.ajax({
type: "GET",
url: url,
success: function(data){
2012-03-22 17:23:07 +00:00
$('#global_error').text('')
2012-07-27 07:31:00 +00:00
handler($.parseJSON(data))
2012-03-17 00:21:37 +00:00
},
2012-03-22 17:23:07 +00:00
error: request_failed
2012-03-17 00:21:37 +00:00
})
}
2012-07-27 07:31:00 +00:00
function run_get_request(url, handler) {
run_get_request_with_bulk_handler(url, function(json_contents){
$.each(json_contents, function(idx, contents){
handler(contents)
})
})
}
2012-03-25 10:00:38 +00:00
/* As above but with POST request. */
function run_post_request(url, data_map, handler) {
$.ajax({
type: "POST",
url: url,
data: data_map,
success: function(data){
$('#global_error').text('')
$.each($.parseJSON(data), function(idx, contents) {
handler(contents)
})
},
error: request_failed
})
}
function rgb_to_hsl(r, g, b){
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if(max == min){
h = s = 0; // achromatic
}else{
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch(max){
case r: h = (g - b) / d + (g < b ? 6 : 0 ) ; break ;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [h, s, l];
}
function hsl_to_rgb(h, s, l){
var r, g, b;
if(s == 0){
r = g = b = l; // achromatic
}else{
function hue2rgb(p, q, t){
if(t < 0 ) t + = 1 ;
if(t > 1) t -= 1;
if(t < 1 / 6 ) return p + ( q - p ) * 6 * t ;
if(t < 1 / 2 ) return q ;
if(t < 2 / 3 ) return p + ( q - p ) * ( 2 / 3 - t ) * 6 ;
return p;
}
var q = l < 0.5 ? l * ( 1 + s ) : l + s - l * s ;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1.0/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1.0/3);
}
return [r * 255, g * 255, b * 255]
}
/* Given an RGB color as a hex string, like FF0033, convert to HSL, apply the function to adjust its lightness, then return the new color as an RGB string */
function adjust_lightness(color_str, func) {
/* Hack to handle for example F00 */
if (color_str.length == 3) {
color_str = color_str[0] + color_str[0] + color_str[1] + color_str[1] + color_str[2] + color_str[2]
}
rgb = parseInt(color_str, 16)
r = (rgb >> 16) & 0xFF
g = (rgb >> 8) & 0xFF
b = (rgb >> 0) & 0xFF
hsl = rgb_to_hsl(r, g, b)
new_lightness = func(hsl[2])
function to_int_str(val) {
str = Math.round(val).toString(16)
while (str.length < 2 )
str = '0' + str
return str
}
new_rgb = hsl_to_rgb(hsl[0], hsl[1], new_lightness)
return to_int_str(new_rgb[0]) + to_int_str(new_rgb[1]) + to_int_str(new_rgb[2])
}
/* Given a color, compute the master text color for it, by giving it a minimum brightness */
function master_color_for_color(color_str) {
return adjust_lightness(color_str, function(lightness){
if (lightness < .33 ) {
lightness = .33
}
return lightness
})
}
2012-03-16 10:03:43 +00:00
function switch_tab(new_tab) {
/* Switch selected tab */
$(".selected_tab").removeClass("selected_tab")
$('#' + new_tab).addClass("selected_tab")
/* Empty master element */
$('#master').empty()
2012-03-25 10:00:38 +00:00
/* Unselect some things */
$(".colorpicker_cell_selected").removeClass('colorpicker_cell_selected')
2012-03-17 00:21:37 +00:00
/* Hide some things */
2012-03-25 10:00:38 +00:00
$('#master_detail_table').hide()
$('#detail_colorpicker').hide()
$('#detail_function').hide()
2012-03-17 00:21:37 +00:00
$('#data_table').hide()
2012-08-20 18:58:54 +00:00
$('#table_filter_container').hide()
2012-03-19 18:51:44 +00:00
$('#data_table').empty()
2012-03-17 00:21:37 +00:00
2012-08-20 18:58:54 +00:00
/* Determine if we will want to show the data table (and associated filter box) */
var wants_data_table = false
2012-03-16 10:03:43 +00:00
/* Load something new */
if (new_tab == 'tab_colors') {
2012-03-25 10:00:38 +00:00
/* Keep track of whether this is the first element */
var first = true
run_get_request('/colors/', function(key_and_values){
2012-05-09 00:10:38 +00:00
/* Result is name, description, value */
2012-03-25 10:00:38 +00:00
var key = key_and_values[0]
2012-05-09 00:10:38 +00:00
var description = key_and_values[1]
var style = new Style(key_and_values[2])
2012-03-25 10:00:38 +00:00
style_map[key] = style
2012-05-09 00:10:38 +00:00
elem = create_master_element(key, description, style.color, '', select_color_master_element)
2012-03-25 10:00:38 +00:00
if (first) {
/* It's the first element, so select it, so something gets selected */
select_color_master_element(elem)
first = false
}
2012-03-16 10:03:43 +00:00
})
2012-03-25 10:00:38 +00:00
$('#detail_colorpicker').show()
$('#master_detail_table').show()
2012-08-20 18:58:54 +00:00
wants_data_table = false
2012-03-25 22:56:43 +00:00
} else if (new_tab == 'tab_functions') {
/* Keep track of whether this is the first element */
var first = true
2012-03-17 00:21:37 +00:00
run_get_request('/functions/', function(contents){
2012-05-09 00:10:38 +00:00
elem = create_master_element(contents, false/* description */, 'AAAAAA', '11pt', select_function_master_element)
2012-03-25 22:56:43 +00:00
if (first) {
/* It's the first element, so select it, so something gets selected */
select_function_master_element(elem)
first = false
}
2012-03-16 10:03:43 +00:00
})
2012-03-25 10:00:38 +00:00
$('#detail_function').show()
$('#master_detail_table').show()
2012-08-20 18:58:54 +00:00
wants_data_table = false
2012-03-16 10:03:43 +00:00
} else if (new_tab == 'tab_variables') {
2012-07-27 07:31:00 +00:00
run_get_request_with_bulk_handler('/variables/', function(json_contents){
var rows = new Array()
for (var i = 0; i < json_contents.length ; i + + ) {
var contents = json_contents[i]
var name = contents[0]
var value = contents[1]
var flags = contents[2]
var row = create_data_table_element_text([name, value], false)
rows[i] = row
}
$('#data_table').append(rows.join(''))
2012-03-17 00:21:37 +00:00
})
2012-08-20 18:58:54 +00:00
wants_data_table = true
2012-03-16 10:03:43 +00:00
} else if (new_tab == 'tab_history') {
2012-07-27 07:31:00 +00:00
// Clear the history map
history_element_map.length = 0
run_get_request_with_bulk_handler('/history/', function(json_contents){
start = new Date().getTime()
var rows = new Array()
for (var i = 0; i < json_contents.length ; i + + ) {
var history_text = json_contents[i]
rows[i] = create_data_table_element_text([history_text], true)
history_element_map[last_global_element_identifier] = history_text
}
$('#data_table').append(rows.join(''))
end = new Date().getTime()
//alert(rows.length + " rows in " + (end - start) + " msec")
2012-03-19 18:51:44 +00:00
})
2012-08-20 18:58:54 +00:00
wants_data_table = true
2012-03-16 10:03:43 +00:00
} else {
alert("Unknown tab");
}
2012-08-20 18:58:54 +00:00
/* Show or hide the data table and its search field */
if (wants_data_table) {
$('#data_table').show()
$('#table_filter_container').show()
} else {
$('#data_table').hide()
$('#table_filter_container').hide()
}
2012-03-16 10:03:43 +00:00
return false
}
2012-03-25 10:00:38 +00:00
function current_master_element_name() {
/* Get the name of the current color variable, like 'autosuggestion' */
var elems = $('.selected_master_elem')
if (elems.length == 0) {
return ''
}
elem = elems[0]
if (elem.id.indexOf('master_') != 0) {
show_error('Unknown color variable')
return ''
}
return elem.id.substring(7)
}
function is_foreground() {
/* Returns true if the selected tab is foreground, false if it's background */
2012-03-26 05:41:22 +00:00
who = $('.colorpicker_target_selected')
2012-03-25 10:00:38 +00:00
if (who.length == 0) {
show_error('Not sure if we are in foreground or background')
return false
}
return who[0].id == 'foreground'
}
function current_style() {
/* Returns the style object corresponding to the current color variable */
return style_map[current_master_element_name()]
}
function reflect_style() {
/* Unselect everything */
$('.colorpicker_cell_selected').removeClass('colorpicker_cell_selected')
$('.modifier_cell_selected').removeClass('modifier_cell_selected')
2012-05-09 00:10:38 +00:00
$('.master_element_no_border').removeClass('master_element_no_border')
2012-03-25 10:00:38 +00:00
/* Now update the color picker with the current style (if we have one) */
style = current_style()
if (style) {
2012-03-28 02:00:03 +00:00
/* Use this function to make a color that contrasts well with the given color */
2012-03-25 10:00:38 +00:00
var adjust = .5
function compute_constrast(lightness){
var new_lightness = lightness + adjust
if (new_lightness > 1.0 || new_lightness < 0.0 ) {
new_lightness -= 2 * adjust
}
return new_lightness
}
color = is_foreground() ? style.color : style.background_color
var color_cell = $('#color_' + color)
color_cell.addClass('colorpicker_cell_selected')
color_cell.css('border-color', adjust_lightness(is_foreground() ? style.color : style.background_color, compute_constrast))
if (style.underline) {
$('#modifier_underline').addClass('modifier_cell_selected')
}
/* In the master list, ensure the color is visible against the dark background. If we're deselecting, use COLOR_NORMAL */
master_color = style.color ? master_color_for_color(style.color) : COLOR_NORMAL
2012-05-09 00:10:38 +00:00
//$('.selected_master_elem').children('.master_element_text').css({'color': master_color, 'border-bottom-color': master_color})
var selected_elem = $('.selected_master_elem');
var desc_elems = selected_elem.children('.master_element_description')
selected_elem.css({'color': master_color})
selected_elem.children().css({'border-bottom-color': master_color})
if (desc_elems.length) {
/* We have a description element, so hide the bottom border of the master element */
selected_elem.children('.master_element_text').addClass('master_element_no_border')
}
2012-03-25 10:00:38 +00:00
}
}
2012-03-22 17:23:07 +00:00
function select_master_element(elem) {
2012-03-25 10:00:38 +00:00
$('.selected_master_elem').removeClass('selected_master_elem')
$(elem).addClass('selected_master_elem')
}
2012-03-22 17:23:07 +00:00
2012-03-25 10:00:38 +00:00
function select_color_master_element(elem) {
select_master_element(elem)
/* This changed the current style; reflect that */
reflect_style()
2012-03-22 17:23:07 +00:00
}
2012-03-25 10:00:38 +00:00
function select_function_master_element(elem) {
select_master_element(elem)
run_post_request('/get_function/', {
what: current_master_element_name()
}, function(contents){
2012-03-25 22:56:43 +00:00
/* Replace leading tabs and groups of four spaces at the beginning of a line with two spaces. */
lines = contents.split('\n')
rx = /^[\t ]+/
for (var i=0; i < lines.length ; i + + ) {
line = lines[i]
2012-03-26 05:41:22 +00:00
/* Get leading tabs and spaces */
2012-03-25 22:56:43 +00:00
whitespace_arr = rx.exec(line)
if (whitespace_arr) {
/* Replace four spaces with two spaces, and tabs with two spaces */
var whitespace = whitespace_arr[0]
new_whitespace = whitespace.replace(/( )|(\t)/g, ' ')
lines[i] = new_whitespace + line.slice(whitespace.length)
}
}
munged_contents = lines.join('\n')
$('#detail_function').text(munged_contents)
2012-03-25 10:00:38 +00:00
});
}
function post_style_to_server() {
style = current_style()
if (! style)
return
run_post_request('/set_color/', {
what: current_master_element_name(),
color: style.color,
background_color: style.background_color,
bold: style.bold,
underline: style.underline
}, function(contents){
})
}
function picked_color_cell(cell) {
/* Get the color to set */
if (cell.id.indexOf('color_') != 0) {
show_error('Unknown cell')
return
}
color = cell.id.substring(6)
/* Determine whether we are going to select or unselect this cell */
var deselect = $(cell).hasClass('colorpicker_cell_selected')
/* Get the current style */
style = current_style()
if (! style)
return
/* Change the color */
if (is_foreground()) {
style.color = deselect ? '' : color
} else {
style.background_color = deselect ? '' : color
}
/* Show our changes */
reflect_style()
/* Tell the server */
post_style_to_server()
}
2012-03-20 10:01:00 +00:00
2012-03-25 10:00:38 +00:00
function picked_modifier(cell) {
style = current_style()
if (! style)
return
if (cell.id == 'modifier_underline') {
style.underline = ! style.underline
} else if (cell.id == 'modifier_bold') {
style.bold = ! style.bold
} else {
show_error('Unknown cell')
}
reflect_style()
post_style_to_server()
}
2012-03-26 05:41:22 +00:00
function picked_colorpicker_target(tab) {
2012-03-25 10:00:38 +00:00
/* The function that gets called when a tab is selected */
2012-03-26 05:41:22 +00:00
$('.colorpicker_target_selected').removeClass('colorpicker_target_selected')
$(tab).addClass('colorpicker_target_selected')
2012-03-25 10:00:38 +00:00
reflect_style()
}
2012-03-31 22:17:14 +00:00
/* Given a color name, like 'normal' or 'red' or 'FF00F0', return an RGB color string (or empty string) */
function interpret_color(str) {
str = str.toLowerCase()
if (str == 'black') return '000000'
if (str == 'red') return 'FF0000'
if (str == 'green') return '00FF00'
if (str == 'brown') return '725000'
if (str == 'yellow') return 'FFFF00'
if (str == 'blue') return '0000FF'
if (str == 'magenta') return 'FF00FF'
if (str == 'purple') return 'FF00FF'
if (str == 'cyan') return '00FFFF'
if (str == 'white') return 'FFFFFF'
if (str == 'normal') return ''
return str
}
2012-03-25 10:00:38 +00:00
/* Class representing a color style */
function Style(stuff) {
2012-03-31 22:17:14 +00:00
this.color = interpret_color(stuff[0])
this.background_color = interpret_color(stuff[1])
2012-03-25 10:00:38 +00:00
this.bold = stuff[2]
this.underline = stuff[3]
}
var style_map = new Array();
/* The first index here corresponds to value 16 */
term256_colors = [ //247
2012-03-20 10:01:00 +00:00
"ffd7d7",
"d7afaf",
"af8787",
"875f5f",
"5f0000",
"870000",
"af0000",
"d70000",
"ff0000",
"ff5f5f",
2012-03-20 10:05:00 +00:00
"d75f5f",
"d78787",
2012-03-20 10:01:00 +00:00
"ff8787",
"ffafaf",
"ffaf87",
"ffaf5f",
"ffaf00",
2012-03-20 18:33:24 +00:00
"ff875f",
2012-03-20 10:01:00 +00:00
"ff8700",
"ff5f00",
"d75f00",
"af5f5f",
"af5f00",
"d78700",
"d7875f",
"af875f",
"af8700",
"875f00",
"d7af87",
"ffd7af",
"ffd787",
"ffd75f",
"d7af00",
"d7af5f",
"ffd700",
"ffff5f",
"ffff00",
"ffff87",
"ffffaf",
"ffffd7",
"d7ff00",
"afd75f",
"d7d700",
"d7d787",
"d7d7af",
"afaf87",
"87875f",
"5f5f00",
"878700",
"afaf00",
"afaf5f",
"d7d75f",
"d7ff5f",
"d7ff87",
"87ff00",
"afff00",
"afff5f",
"afd700",
"87d700",
"87af00",
"5f8700",
"87af5f",
"5faf00",
"afd787",
"d7ffd7",
"d7ffaf",
"afffaf",
"afff87",
"5fff00",
"5fd700",
"87d75f",
"5fd75f",
"87ff5f",
"5fff5f",
"87ff87",
"afd7af",
"87d787",
"87d7af",
"87af87",
"5f875f",
"5faf5f",
"005f00",
"008700",
"00af00",
"00d700",
"00ff00",
"00ff5f",
"5fff87",
"00ff87",
"87ffaf",
"afffd7",
"5fd787",
"00d75f",
"5faf87",
"00af5f",
"5fffaf",
"00ffaf",
"5fd7af",
"00d787",
"00875f",
"00af87",
"00d7af",
"5fffd7",
"87ffd7",
"00ffd7",
"d7ffff",
"afd7d7",
"87afaf",
"5f8787",
"5fafaf",
"87d7d7",
"5fd7d7",
"5fffff",
"00ffff",
"87ffff",
"afffff",
"00d7d7",
"00d7ff",
"5fd7ff",
"5fafd7",
"00afd7",
"00afff",
"0087af",
"00afaf",
"008787",
"005f5f",
"005f87",
"0087d7",
"0087ff",
"5fafff",
"87afff",
"5f87d7",
"5f87ff",
"005fd7",
"005fff",
"005faf",
"5f87af",
"87afd7",
"afd7ff",
"87d7ff",
"d7d7ff",
"afafd7",
"8787af",
"afafff",
"8787d7",
"8787ff",
"5f5fff",
"5f5fd7",
"5f5faf",
"5f5f87",
"00005f",
"000087",
"0000af",
"0000d7",
"0000ff",
"5f00ff",
"5f00d7",
"5f00af",
"5f0087",
"8700af",
"8700d7",
"8700ff",
"af00ff",
"af00d7",
"d700ff",
"d75fff",
"d787ff",
"ffafd7",
"ffafff",
"ffd7ff",
"d7afff",
"d7afd7",
"af87af",
"af87d7",
"af87ff",
"875fd7",
"875faf",
"875fff",
"af5fff",
"af5fd7",
"af5faf",
"d75fd7",
"d787d7",
"ff87ff",
"ff5fff",
"ff5fd7",
"ff00ff",
"ff00af",
"ff00d7",
"d700af",
"d700d7",
"af00af",
"870087",
"5f005f",
"87005f",
"af005f",
"af0087",
"d70087",
"d7005f",
"ff0087",
"ff005f",
"ff5f87",
"d75f87",
"d75faf",
"ff5faf",
"ff87af",
"ff87d7",
"d787af",
"af5f87",
"875f87",
"000000",
"080808",
"121212",
"1c1c1c",
"262626",
"303030",
"3a3a3a",
"444444",
"4e4e4e",
"585858",
"5f5f5f",
"626262",
"6c6c6c",
"767676",
"808080",
"878787",
"8a8a8a",
"949494",
"9e9e9e",
"a8a8a8",
"afafaf",
"b2b2b2",
"bcbcbc",
"c6c6c6",
"d0d0d0",
"d7d7d7",
"dadada",
"e4e4e4",
"eeeeee",
"ffffff",
]
var items_per_row = 15
2012-03-20 18:33:24 +00:00
var show_labels = 0
2012-03-17 00:21:37 +00:00
2012-03-31 22:17:14 +00:00
var COLOR_NORMAL = 'CCC'
2012-03-25 10:00:38 +00:00
2012-03-15 10:43:45 +00:00
/* Adds a new element to master */
2012-05-09 00:10:38 +00:00
function create_master_element(contents, description_or_false, color, font_size, click_handler) {
2012-03-25 10:00:38 +00:00
/* In the master list, ensure the color is visible against the dark background */
2012-03-31 22:17:14 +00:00
var master_color = color ? master_color_for_color(color) : COLOR_NORMAL
2012-05-09 00:10:38 +00:00
var master_style = 'color: #' + master_color
var master_children_style = 'border-bottom-color: #' + master_color
var text_style = ''
2012-03-25 10:00:38 +00:00
2012-03-25 22:56:43 +00:00
if (font_size.length > 0) {
2012-05-09 00:10:38 +00:00
text_style += 'font-size: ' + font_size + ';'
2012-03-25 22:56:43 +00:00
}
if (contents.length >= 20) {
2012-05-09 00:10:38 +00:00
text_style += 'letter-spacing:-2px;'
2012-03-25 22:56:43 +00:00
}
2012-03-25 10:00:38 +00:00
elem = $('< div / > ', {
2012-03-15 10:43:45 +00:00
class: 'master_element',
2012-03-25 10:00:38 +00:00
id: 'master_' + contents,
2012-05-09 00:10:38 +00:00
style: master_style,
2012-03-15 10:43:45 +00:00
click: function(){
2012-03-25 10:00:38 +00:00
click_handler(this)
2012-03-15 10:43:45 +00:00
}
}).append(
$("< span / > ", {
class: 'master_element_text',
2012-05-09 00:10:38 +00:00
style: text_style,
2012-03-22 17:23:07 +00:00
text: contents,
2012-03-15 10:43:45 +00:00
})
2012-03-25 10:00:38 +00:00
)
2012-05-09 00:10:38 +00:00
/* Append description if we have one */
if (description_or_false) {
/* Newline between label and description */
elem.append($('< br / > '))
elem.append(
$('< span / > ', {
class: 'master_element_description',
text: description_or_false
})
)
}
/* Update border color of the master element's children */
elem.children().css(master_children_style)
2012-03-25 10:00:38 +00:00
elem.appendTo('#master')
return elem
2012-03-15 10:43:45 +00:00
}
2012-03-19 18:51:44 +00:00
/* Toggle the no_overflow class */
function toggle_overflow(who) {
$(who).toggleClass('no_overflow')
}
2012-07-27 07:31:00 +00:00
function escape_HTML(foo) {
return foo.replace(/&/g,'& ').replace(/< /g,'< ').replace(/>/g,'> ');
}
/* Given the image, walk up to the table */
function tell_fish_to_delete_element(idx) {
var row_elem = $('#data_table_row_' + idx)
var txt = history_element_map[idx]
run_post_request('/delete_history_item/', {
what: txt
}, function(contents){
if (contents == "OK") {
row_elem.remove();
} else {
show_error(contents)
}
});
}
2012-03-17 00:21:37 +00:00
/* Creates a new row in the data table */
2012-07-27 07:31:00 +00:00
var last_global_element_identifier = 0
var history_element_map = new Array();
function create_data_table_element_text(contents_list, show_delete_button) {
var element_identifier = (++last_global_element_identifier).toString()
lines = new Array()
var result_str = '< tr class = "data_table_row" id = "data_table_row_' + element_identifier + '" > '
2012-03-17 00:21:37 +00:00
for (idx = 0; idx < contents_list.length ; idx + + ) {
2012-03-19 18:51:44 +00:00
/* If we have more than one, then align the first one right, subsequent ones left */
if (idx == 0 & & contents_list.length > 1) {
2012-07-27 07:31:00 +00:00
result_str += '< td class = "data_table_cell no_overflow" style = "text-align: right; padding-right: 30px;" > '
2012-03-17 00:21:37 +00:00
} else {
2012-07-27 07:31:00 +00:00
result_str += '< td class = "data_table_cell no_overflow" style = "text-align: left; padding-right: 30px;" onClick: " toggle_overflow ( this ) " > '
2012-03-17 00:21:37 +00:00
}
2012-03-19 18:51:44 +00:00
text_list = contents_list[idx].split("\n")
for (j=0; j < text_list.length ; j + + ) {
2012-07-27 07:31:00 +00:00
if (j > 0) result_str += '< br > '
result_str += escape_HTML(text_list[j]);
2012-03-19 18:51:44 +00:00
}
2012-07-27 07:31:00 +00:00
result_str += '< / td > '
2012-03-17 00:21:37 +00:00
}
2012-07-27 07:31:00 +00:00
if (show_delete_button) {
result_str += '< td class = "data_table_cell" style = "text-align: right; width: 25px" > < a onClick = "tell_fish_to_delete_element(' + element_identifier + ')" > < img class = "delete_icon" src = "delete.png" > < / a > < / td > '
}
result_str += '< / tr > '
return result_str
2012-03-17 00:21:37 +00:00
}
/* Put stuff in colorpicker_term256 */
function populate_colorpicker_term256() {
2012-04-12 01:26:10 +00:00
$('#colorpicker_term256').empty()
2012-03-17 00:21:37 +00:00
var idx
for (idx = 0; idx < term256_colors.length ; idx + = items_per_row ) {
var row = $('< tr > ', {
class: 'colorpicker_term256_row'
})
2012-03-25 10:00:38 +00:00
for (var subidx = 0; subidx < items_per_row & & idx + subidx < term256_colors . length ; subidx + + ) {
2012-03-17 00:21:37 +00:00
cell_style = 'background-color: #' + term256_colors[idx + subidx]
2012-03-28 02:00:03 +00:00
var cell = $('< td > ', {
2012-03-17 00:21:37 +00:00
class: 'colorpicker_term256_cell',
style: cell_style,
2012-03-25 10:00:38 +00:00
id: 'color_' + term256_colors[idx + subidx],
text: show_labels ? String(subidx + idx + 223) : '',
onClick: 'picked_color_cell(this)'
2012-03-28 02:00:03 +00:00
})
/* For reasons I don't understand, this makes the selected cell border appear in Firefox */
cell.append($('< div > ', {
style: 'width: 100%; height: 100%'
2012-03-17 00:21:37 +00:00
}))
2012-03-28 02:00:03 +00:00
row.append(cell)
2012-03-17 00:21:37 +00:00
}
$('#colorpicker_term256').append(row)
2012-03-25 10:00:38 +00:00
}
2012-03-17 00:21:37 +00:00
}
2012-07-27 07:31:00 +00:00
/* Update the filter text box */
function update_table_filter_text_box(allow_transient_message) {
2012-08-20 18:58:54 +00:00
var box = $('#table_filter_text_box')
2012-07-27 07:31:00 +00:00
var has_transient = box.hasClass('text_box_transient')
if (! allow_transient_message & & has_transient) {
box.val('')
box.removeClass('text_box_transient')
has_transient = false
} else if (allow_transient_message & & ! has_transient & & ! box.val().length) {
box.val('Filter')
box.addClass('text_box_transient')
has_transient = true
}
var search_text = box.val()
if (has_transient || search_text.length == 0) {
/* Unfilter all */
$('.data_table_row_filtered').removeClass('data_table_row_filtered')
} else {
/* Helper function to return whether a node (or its descendants) matches the given text */
function match_text(node) {
if (node.nodeType == 3) {
return node.nodeValue.indexOf(search_text) != -1
} else {
for (var i = 0, len = node.childNodes.length; i < len ; + + i ) {
if (match_text(node.childNodes[i])) {
return true;
}
}
}
return false
}
$('.data_table_row').each(function(idx) {
var row = $(this)
var is_hidden = row.hasClass('data_table_row_filtered')
var should_be_hidden = ! match_text(this)
if (is_hidden & & ! should_be_hidden) {
row.removeClass('data_table_row_filtered')
} else if (! is_hidden & & should_be_hidden) {
row.addClass('data_table_row_filtered')
}
})
}
return true
}
2012-03-15 10:43:45 +00:00
$(document).ready(function() {
2012-03-17 00:21:37 +00:00
populate_colorpicker_term256()
2012-07-27 20:40:43 +00:00
var tab_name
switch (window.location.hash) {
case '#functions':
tab_name = 'tab_functions'
break
case '#variables':
tab_name = 'tab_variables'
break
case '#history':
tab_name = 'tab_history'
break
case '#colors':
default:
tab_name = 'tab_colors'
break;
}
switch_tab(tab_name)
2012-03-15 10:43:45 +00:00
})
2012-03-17 00:21:37 +00:00
< / script >
2012-03-15 10:43:45 +00:00
< / head >
< body >
< div id = "ancestor" >
2012-03-22 17:23:07 +00:00
< span style = "font-size: 30pt" > fish< / span > < p id = "global_error" class = "error_msg" > < / p >
2012-03-15 10:43:45 +00:00
< div id = "parent" >
< div id = "tab_parent" >
2012-03-19 18:51:44 +00:00
< div class = "tab selected_tab" id = "tab_colors" onClick = "switch_tab('tab_colors')" > colors< / div >
2012-03-26 05:41:22 +00:00
< div class = "tab" id = "tab_functions" onClick = "switch_tab('tab_functions')" > functions< / div >
2012-03-19 18:51:44 +00:00
< div class = "tab" id = "tab_variables" onClick = "switch_tab('tab_variables')" > variables< / div >
< div class = "tab" id = "tab_history" onClick = "switch_tab('tab_history')" > history< / div >
2012-03-15 10:43:45 +00:00
< / div >
2012-03-26 05:41:22 +00:00
< div id = "tab_contents" >
< div id = "master_detail_table" >
< div id = "master" > < / div >
< div id = "detail" >
< div id = "detail_colorpicker" >
< div class = "colorpicker_target" >
< div class = "colorpicker_target_tab tab_first colorpicker_target_selected" id = "foreground" onClick = "picked_colorpicker_target(this)" > Text< / div > < div class = "colorpicker_target_tab tab_last" id = "background" onClick = "picked_colorpicker_target(this)" > Background< / div >
< / div >
2012-04-12 01:26:10 +00:00
< table id = "colorpicker_term256" > < tr > < td > < / td > < / tr >
2012-03-26 05:41:22 +00:00
< / table >
< div class = "colorpicker_modifiers" >
< div class = "colorpicker_modifier_cell" id = "modifier_underline" style = "text-decoration: underline" onClick = 'picked_modifier(this)' > Underline< / div >
< / div >
2012-03-25 10:00:38 +00:00
< / div >
2012-03-26 05:41:22 +00:00
< div id = "detail_function" > < / div >
2012-03-25 10:00:38 +00:00
< / div >
< / div >
2012-07-27 07:31:00 +00:00
< table id = "data_table" >
< div id = "table_filter_container" >
2012-08-20 18:58:54 +00:00
< input type = "text" id = "table_filter_text_box" class = "filter_text_box text_box_transient" value = "Filter" onInput = "update_table_filter_text_box(false)" onFocus = "update_table_filter_text_box(false)" onBlur = "update_table_filter_text_box(true)" >
2012-07-27 07:31:00 +00:00
< / div >
< tr > < td >
< / td > < / tr >
< tr > < td > < / td > < / tr >
2012-04-12 01:26:10 +00:00
< / table >
2012-03-26 05:41:22 +00:00
< div class = "footer" >
< / div >
< / div >
2012-03-15 10:43:45 +00:00
< / div >
< / div >
< / body > < / html >