fish-shell/share/tools/web_config/index.html
2012-09-06 01:30:26 -07:00

1425 lines
33 KiB
HTML

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>fish shell configuration</title>
<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%;
min-height: 480px;
margin-top: 12px;
}
#tab_parent {
display: table;
width: 100%;
height: 50px;;
}
.tab {
display: table-cell;
border: 1px solid #111;
border-right: none;
padding-bottom: 15px;
padding-top: 15px;
font-size: 17pt;
text-align: center;
width: 20%;
background-color: #292929;
cursor: pointer;
}
#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;
}
.selected_tab {
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;
}
.footer {
clear: both;
height: 30px;
}
#master_detail_table {
display: table;
margin-top: 10px;
margin-left: 12px;
margin-right: 12px;
}
#master {
display: table-cell;
text-align: right;
min-width: 200px;
font-size: 16pt;
padding-bottom: 20px;
padding-top: 35px;
vertical-align: top;
}
#detail {
display: table-cell;
border: 1px solid #555;
background-color: #181818;
padding-top: 30px;
padding-bottom: 20px;
padding-left: 30px;
padding-right: 30px;
border-radius: 5;
width: 100%;
}
#detail_function {
white-space: pre-wrap;
width: 100%;
font-size: 11pt;
color: #BBB;
}
.master_element {
padding-top: 6px;
padding-bottom: 11px;
padding-left: 5px;
padding-right: 22px;
font-size: 12pt;
/* Make our border overlap the detail, even if we're unselected (so it doesn't jump when selected) */
position: relative;
left: 1px;
border-bottom-style: solid;
border-bottom-width: 0px;
}
.selected_master_elem {
border: 1px solid #555;
border-right: none;
background-color: #181818;
border-top-left-radius: 5;
border-bottom-left-radius: 5;
/* Pad one less than .master_element, to accomodate our border. */
padding-top: 5px;
padding-bottom: 10px;
padding-left: 4px;
}
.master_element_text {
text-decoration: none;
padding-bottom: 1px;
border-bottom-style: inherit;
border-bottom-color: inherit;
border-bottom-width: 1px;
}
.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 }
#colorpicker_term256 {
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;
border: groove #333 2px;
padding: 5px;
margin-top: 5px;
margin-left: auto;
margin-right: auto;
}
.modifier_cell_selected {
color: #CCC;
border-color: #AAA;
background-color: #444;
}
#data_table {
table-layout:fixed;
color: #CCC;
width: 100%;
padding-left: 10px;
padding-right: 10px;
}
.data_table_row {
}
.data_table_cell {
padding-top: 5px;
padding-bottom: 5px;
vertical-align: top;
overflow:hidden;
border-bottom: #444 dotted 1px;
word-wrap: break-word;
}
/* The CSS we apply when a table row is filtered */
.data_table_row_filtered {
display: none;
}
.no_overflow {
text-overflow: ellipsis;
white-space: nowrap;
}
.colorpicker_target {
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 */
}
.colorpicker_target_tab {
cursor: pointer;
color: #555;
border: solid 1px #555;
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;
}
.colorpicker_target_selected {
background-color: #181818; /* same as #detail */
color: white;
}
.colorpicker_term256_row {
}
.colorpicker_term256_cell {
width: 29;
height: 29;
}
.colorpicker_cell_selected {
border: dashed white 3px;
width: 23;
height: 23;
}
.error_msg {
color: red;
font-size: 12pt;
margin-left: 24pt;
margin-top: 5pt;
margin-bottom: 5pt;
}
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;
}
#table_filter_text_box {
}
.filter_text_box {
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;
}
.prompt_demo {
/* This is the div that holds what the prompt looks like */
width: 100%;
background-color: black;
border-radius: 5px;
display: table;
}
.prompt_save_button {
border-radius: 5px;
border: solid #474747 1px;
text-shadow: 0px 1px #000;
padding: 5px 8px;
font-size: 12pt;
display: inline-block;
margin-top: 12px;
background-color: #282828;
color: #DDD;
cursor: pointer;
}
.prompt_save_button:hover {
background-color: #333;
border: solid #525252 1px;
color: #EEE;
}
.prompt_demo_text {
white-space: pre;
line-height: 170%;
padding: 4px 12px;
font-size: 14pt;
top: 0px;
bottom: 0px;
vertical-align: middle;
display: table-cell;
height: 72px; /* this is really the min height */
}
.prompt_function {
/* This is the div that holds the prompt function's definition */
width: 100%;
color: #BBB;
font-size: 10pt;
}
.prompt_function_text {
white-space: pre-wrap;
padding: 25px 3px;
}
</style>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript">
function show_error(msg) {
$('#global_error').text(msg)
}
function request_failed(jqXHR, textStatus, errorThrown) {
msg = ''
if (textStatus == "timeout") {
msg = 'The request timed out. Perhaps the server has shut down or is hung.'
} else if (textStatus == "error") {
msg = 'The request received an error.'
if (jqXHR.status == 0)
msg = msg + ' Perhaps the server has shut down.'
} 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
}
show_error(msg)
}
/* 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. */
function run_get_request_with_bulk_handler(url, handler) {
$.ajax({
type: "GET",
url: url,
success: function(data){
$('#global_error').text('')
handler($.parseJSON(data))
},
error: request_failed
})
}
function run_get_request(url, handler) {
run_get_request_with_bulk_handler(url, function(json_contents){
$.each(json_contents, function(idx, contents){
handler(contents)
})
})
}
/* 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
})
}
/* Update prompt_demo_text with the given text, adjusting the font */
function set_prompt_demo_text(txt, font_size) {
/* Set the font size and the text */
var prompt_demo_text = $('.prompt_demo_text')
prompt_demo_text.css('font-size', font_size)
prompt_demo_text.html(txt)
}
function switch_tab(new_tab) {
/* Switch selected tab */
$(".selected_tab").removeClass("selected_tab")
$('#' + new_tab).addClass("selected_tab")
/* Empty master element */
$('#master').empty()
/* Unselect some things */
$(".colorpicker_cell_selected").removeClass('colorpicker_cell_selected')
/* Hide some things */
$('#master_detail_table').hide()
$('#detail_colorpicker').hide()
$('#detail_prompt').hide()
$('#detail_function').hide()
$('#data_table').hide()
$('#table_filter_container').hide()
$('#data_table').empty()
/* Determine if we will want to show the data table (and associated filter box) */
var wants_data_table = false
/* Load something new */
if (new_tab == 'tab_colors') {
/* Keep track of whether this is the first element */
var first = true
run_get_request('/colors/', function(key_and_values){
/* Result is name, description, value */
var key = key_and_values[0]
var description = key_and_values[1]
var style = new Style(key_and_values[2])
style_map[key] = style
elem = create_master_element(key, description, style.color, '', select_color_master_element)
if (first) {
/* It's the first element, so select it, so something gets selected */
select_color_master_element(elem)
first = false
}
})
$('#detail_colorpicker').show()
$('#master_detail_table').show()
wants_data_table = false
} else if (new_tab == 'tab_prompt') {
/* Get rid of all sample prompts */
sample_prompts.length = 0
/* Color the first one blue */
var first = true;
run_get_request('/sample_prompts/', function(sample_prompt){
var name = sample_prompt['name']
sample_prompts[name] = sample_prompt
var color = first ? '66F' : 'AAA'
var func = first ? select_current_prompt_master_element : select_sample_prompt_master_element;
var elem = create_master_element(name, false/* description */, color, '13pt', func)
if (first) {
elem.children('.master_element_text').css('border-bottom-color', color)
select_current_prompt_master_element(elem)
}
first = false;
})
$('#detail_prompt').show()
$('#master_detail_table').show()
} else if (new_tab == 'tab_functions') {
/* Keep track of whether this is the first element */
var first = true
run_get_request('/functions/', function(contents){
var elem = create_master_element(contents, false/* description */, 'AAAAAA', '11pt', select_function_master_element)
if (first) {
/* It's the first element, so select it, so something gets selected */
select_function_master_element(elem)
first = false
}
})
$('#detail_function').show()
$('#master_detail_table').show()
wants_data_table = false
} else if (new_tab == 'tab_variables') {
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(''))
})
wants_data_table = true
} else if (new_tab == 'tab_history') {
// 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")
})
wants_data_table = true
} else {
alert("Unknown tab");
}
/* 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()
}
return false
}
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 master variable')
return ''
}
return elem.id.substring(7)
}
function is_foreground() {
/* Returns true if the selected tab is foreground, false if it's background */
who = $('.colorpicker_target_selected')
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')
$('.master_element_no_border').removeClass('master_element_no_border')
/* Now update the color picker with the current style (if we have one) */
style = current_style()
if (style) {
/* Use this function to make a color that contrasts well with the given color */
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
//$('.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')
}
}
}
function cleanup_fish_function(contents) {
/* 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]
/* Get leading tabs and spaces */
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)
}
}
return lines.join('\n')
}
function select_master_element(elem) {
$('.selected_master_elem').removeClass('selected_master_elem')
$(elem).addClass('selected_master_elem')
}
function select_color_master_element(elem) {
select_master_element(elem)
/* This changed the current style; reflect that */
reflect_style()
}
function select_function_master_element(elem) {
select_master_element(elem)
run_post_request('/get_function/', {
what: current_master_element_name()
}, function(contents){
/* Replace leading tabs and groups of four spaces at the beginning of a line with two spaces. */
munged_contents = cleanup_fish_function(contents)
$('#detail_function').text(munged_contents)
});
}
var sample_prompts = new Array();
function select_sample_prompt_master_element(elem) {
$('.prompt_save_button').show()
select_master_element(elem)
var name = current_master_element_name()
sample_prompt = sample_prompts[name]
run_post_request('/get_sample_prompt/', {
what: sample_prompt['function']
}, function(keys_and_values){
var prompt_func = keys_and_values['function']
var prompt_demo = keys_and_values['demo']
var prompt_font_size = keys_and_values['font_size']
set_prompt_demo_text(prompt_demo, prompt_font_size)
//$('.prompt_demo_text').html(prompt_demo)
$('.prompt_function_text').text(cleanup_fish_function(prompt_func))
})
}
function select_current_prompt_master_element(elem) {
$('.prompt_save_button').hide()
select_master_element(elem)
run_get_request_with_bulk_handler('/current_prompt/', function(keys_and_values){
var prompt_func = keys_and_values['function']
var prompt_demo = keys_and_values['demo']
var prompt_font_size = keys_and_values['font_size']
set_prompt_demo_text(prompt_demo, prompt_font_size)
$('.prompt_function_text').text(cleanup_fish_function(prompt_func))
})
}
/* Applies the current prompt */
function save_current_prompt() {
var name = current_master_element_name()
var sample_prompt = sample_prompts[name]
run_post_request('/set_prompt/', {
what: sample_prompt['function']
}, function(contents){
if (contents == "OK") {
select_current_prompt_master_element($('#master_Current'))
} else {
show_error(contents)
}
})
}
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()
}
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()
}
function picked_colorpicker_target(tab) {
/* The function that gets called when a tab is selected */
$('.colorpicker_target_selected').removeClass('colorpicker_target_selected')
$(tab).addClass('colorpicker_target_selected')
reflect_style()
}
/* 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
}
/* Class representing a color style */
function Style(stuff) {
this.color = interpret_color(stuff[0])
this.background_color = interpret_color(stuff[1])
this.bold = stuff[2]
this.underline = stuff[3]
}
var style_map = new Array();
/* The first index here corresponds to value 16 */
term256_colors = [ //247
"ffd7d7",
"d7afaf",
"af8787",
"875f5f",
"5f0000",
"870000",
"af0000",
"d70000",
"ff0000",
"ff5f5f",
"d75f5f",
"d78787",
"ff8787",
"ffafaf",
"ffaf87",
"ffaf5f",
"ffaf00",
"ff875f",
"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
var show_labels = 0
var COLOR_NORMAL = 'CCC'
/* Adds a new element to master */
function create_master_element(contents, description_or_false, color, font_size, click_handler) {
/* In the master list, ensure the color is visible against the dark background */
var master_color = color ? master_color_for_color(color) : COLOR_NORMAL
var master_style = 'color: #' + master_color
var master_children_style = 'border-bottom-color: #' + master_color
var text_style = ''
if (font_size.length > 0) {
text_style += 'font-size: ' + font_size + ';'
}
if (contents.length >= 20) {
text_style += 'letter-spacing:-2px;'
}
elem = $('<div/>', {
class: 'master_element',
id: 'master_' + contents,
style: master_style,
click: function(){
click_handler(this)
}
}).append(
$("<span/>", {
class: 'master_element_text',
style: text_style,
text: contents,
})
)
/* 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)
elem.appendTo('#master')
return elem
}
/* Toggle the no_overflow class */
function toggle_overflow(who) {
$(who).toggleClass('no_overflow')
}
function escape_HTML(foo) {
return foo.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
/* 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)
}
});
}
/* Creates a new row in the data table */
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 + '">'
for (idx = 0; idx < contents_list.length; idx++) {
/* If we have more than one, then align the first one right, subsequent ones left */
if (idx == 0 && contents_list.length > 1) {
result_str += '<td class="data_table_cell no_overflow" style="text-align: right; padding-right: 30px;">'
} else {
result_str += '<td class="data_table_cell no_overflow" style="text-align: left; padding-right: 30px;" onClick:"toggle_overflow(this)">'
}
text_list = contents_list[idx].split("\n")
for (j=0; j < text_list.length; j++) {
if (j > 0) result_str += '<br>'
result_str += escape_HTML(text_list[j]);
}
result_str += '</td>'
}
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
}
/* Put stuff in colorpicker_term256 */
function populate_colorpicker_term256() {
$('#colorpicker_term256').empty()
var idx
for (idx = 0; idx < term256_colors.length; idx += items_per_row) {
var row = $('<tr>', {
class: 'colorpicker_term256_row'
})
for (var subidx = 0; subidx < items_per_row && idx + subidx < term256_colors.length; subidx++) {
cell_style = 'background-color: #' + term256_colors[idx + subidx]
var cell = $('<td>', {
class: 'colorpicker_term256_cell',
style: cell_style,
id: 'color_' + term256_colors[idx + subidx],
text: show_labels ? String(subidx + idx + 223) : '',
onClick: 'picked_color_cell(this)'
})
/* For reasons I don't understand, this makes the selected cell border appear in Firefox */
cell.append($('<div>', {
style: 'width: 100%; height: 100%'
}))
row.append(cell)
}
$('#colorpicker_term256').append(row)
}
}
/* Update the filter text box */
function update_table_filter_text_box(allow_transient_message) {
var box = $('#table_filter_text_box')
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
}
$(document).ready(function() {
populate_colorpicker_term256()
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 '#prompt':
tab_name = 'tab_prompt'
break
case '#colors':
default:
tab_name = 'tab_colors'
break;
}
switch_tab(tab_name)
})
</script>
</head>
<body>
<div id="ancestor">
<span style="font-size: 30pt">fish</span><p id="global_error" class="error_msg"></p>
<div id="parent">
<div id="tab_parent">
<div class="tab selected_tab" id="tab_colors" onClick="switch_tab('tab_colors')">colors</div>
<div class="tab" id="tab_prompt" onClick="switch_tab('tab_prompt')">prompt</div>
<div class="tab" id="tab_functions" onClick="switch_tab('tab_functions')">functions</div>
<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>
</div>
<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>
<table id="colorpicker_term256"><tr><td></td></tr>
</table>
<div class="colorpicker_modifiers">
<div class="colorpicker_modifier_cell" id="modifier_underline" style="text-decoration: underline" onClick='picked_modifier(this)'>Underline</div>
</div>
</div>
<div id="detail_function"></div>
<div id="detail_prompt">
<div class="prompt_demo">
<div class="prompt_demo_text">
</div>
</div>
<div style="text-align: right">
<span class="prompt_save_button" onClick="save_current_prompt()">
use prompt
</span>
</div>
<div class="prompt_function">
<div class="prompt_function_text">
</div>
</div>
</div>
</div>
</div>
<table id="data_table">
<div id="table_filter_container">
<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)">
</div>
<tr><td>
</td></tr>
<tr><td></td></tr>
</table>
<div class="footer">
</div>
</div>
</div>
</div>
</body></html>