Skip to content
Snippets Groups Projects
Commit 3cccfa12 authored by echicken's avatar echicken
Browse files

Optionally set a maximum height for the suggestion box.

parent b1eac6bb
Branches
Tags
No related merge requests found
/* typeahead.js for Synchronet BBS 3.15+ /* typeahead.js for Synchronet BBS 3.15+
echicken -at- bbs.electronicchicken.com echicken -at- bbs.electronicchicken.com
Provides the Typeahead object, a blocking or non-blocking string input Provides the Typeahead object, a blocking or non-blocking string input
prompt with optional autocomplete suggestions. Somewhat inspired by prompt with optional autocomplete suggestions. Somewhat inspired by
Twitter's library of the same name. Twitter's library of the same name.
Usage: Usage:
load('typeahead.js'); load('typeahead.js');
// All settings are optional // All settings are optional
var options = { var options = {
// x-coordinate (Default: current x position of console cursor) // x-coordinate (Default: current x position of console cursor)
'x' : 1, 'x' : 1,
// y-coordinate (Default: current y position of console cursor) // y-coordinate (Default: current y position of console cursor)
'y' : 1, 'y' : 1,
// Length of input prompt (Default: terminal width - prompt length) // Length of input prompt (Default: terminal width - prompt length)
'len' : 64, 'len' : 64,
// Prompt text (CTRL-A color-codes can be used) (Default: none) // Height of suggestion box (Default: to the bottom of the terminal)
'prompt' : "Type something: ", 'height' : 10,
// Input box foreground color (Default: LIGHTGRAY) // Prompt text (CTRL-A color-codes can be used) (Default: none)
'fg' : LIGHTGRAY, 'prompt' : 'Type something: ',
// Input box background color (Default: BG_BLUE) // Input box foreground color (Default: LIGHTGRAY)
'bg' : BG_BLUE, 'fg' : LIGHTGRAY,
// Autocomplete suggestion foreground color (Default: LIGHTGRAY) // Input box background color (Default: BG_BLUE)
'sfg' : LIGHTGRAY, 'bg' : BG_BLUE,
// Autocomplete suggestion background color (Default: BG_BLUE) // Autocomplete suggestion foreground color (Default: LIGHTGRAY)
'sbg' : BG_BLUE, 'sfg' : LIGHTGRAY,
// Highlighted autocomplete suggestion foreground color (Default: WHITE) // Autocomplete suggestion background color (Default: BG_BLUE)
'hsfg' : WHITE, 'sbg' : BG_BLUE,
// Highlighted autocomplete suggestion background color (Default: BG_CYAN) // Highlighted autocomplete suggestion foreground color (Default: WHITE)
'hsbg' : BG_CYAN, 'hsfg' : WHITE,
// Cursor character (Default: ASCII 219 (full block)) // Highlighted autocomplete suggestion background color (Default: BG_CYAN)
'cursor' : ascii(219), 'hsbg' : BG_CYAN,
// Initial position of cursor within input string (Default: 0) // Cursor character (Default: ASCII 219 (full block))
'position' : 0, 'cursor' : ascii(219),
// Default text of input string (Default: none) // Initial position of cursor within input string (Default: 0)
'text' : "", 'position' : 0,
// An array of datasource functions (see below) (Default: none) // Default text of input string (Default: none)
'datasources' : [ myDataSource ], 'text' : '',
// Seconds of idle input to wait before calling datasources (Default: 1) // An array of datasource functions (see below) (Default: none)
'delay' : 1, 'datasources' : [ myDataSource ],
// Minimum length of input string before datasources are queried (Default: 1) // Seconds of idle input to wait before calling datasources (Default: 1)
'minLength' : 1, 'delay' : 1,
// Parent frame (Default: none) // Minimum length of input string before datasources are queried (Default: 1)
'frame' : someFrameObjectIAlreadyCreated 'minLength' : 1,
}; // Parent frame (Default: none)
'frame' : someFrameObjectIAlreadyCreated
var typeahead = new Typeahead(options); };
Datasource functions: var typeahead = new Typeahead(options);
A datasource function will be called with one argument: the current Datasource functions:
string that is in the input box. The datasource can examine that
string, then return an array of autocomplete suggestions. An A datasource function will be called with one argument: the current
autocomplete suggestion may be either a String or an Object. If it's string that is in the input box. The datasource can examine that
an Object, it must have a 'text' property, which is the text to be string, then return an array of autocomplete suggestions. An
displayed in the list (it can have whatever other properties you want autocomplete suggestion may be either a String or an Object. If it's
to pass along to your script after the user makes a selection.) an Object, it must have a 'text' property, which is the text to be
displayed in the list (it can have whatever other properties you want
to pass along to your script after the user makes a selection.)
Methods:
Typeahead.getstr() Methods:
- Blocking input method a la 'console.getstr()' Typeahead.getstr()
- Returns a String or an Object after the user hits enter
- If an item was selected, the return value will be one of the - Blocking input method a la 'console.getstr()'
values provided by your datasource(s), otherwise the return - Returns a String or an Object after the user hits enter
value is whatever was in the input field - If an item was selected, the return value will be one of the
- Automatically calls Typeahead.close() after enter is pressed, values provided by your datasource(s), otherwise the return
and cleans up the display value is whatever was in the input field
- If you're using this method, you don't need to use any of - Automatically calls Typeahead.close() after enter is pressed,
Typeahead.inkey(), Typeahead.cycle(), Typeahead.updateCursor() and cleans up the display
or Typeahead.close() - If you're using this method, you don't need to use any of
- Use this method if your script doesn't need to do anything else Typeahead.inkey(), Typeahead.cycle(), Typeahead.updateCursor()
while it waits for input from the user or Typeahead.close()
- Use this method if your script doesn't need to do anything else
Typeahead.inkey(str) while it waits for input from the user
- *'Non-blocking' input method, where 'str' is a string of text Typeahead.inkey(str)
already taken from the user (ideally 1 character in length)
- Returns Boolean true if the string was handled by Typeahead - *'Non-blocking' input method, where 'str' is a string of text
- Returns Boolean false if the string was not handled already taken from the user (ideally 1 character in length)
- Returns a String or an Object if the user hit enter - Returns Boolean true if the string was handled by Typeahead
- If no item was selected, the return value will be the - Returns Boolean false if the string was not handled
current text in the input field - Returns a String or an Object if the user hit enter
- If an item was selected, the return value will be either - If no item was selected, the return value will be the
a string or an object representing the selected item current text in the input field
(depending on what your datasource function(s) returned) - If an item was selected, the return value will be either
- Use this method if you want to allow your script to do other a string or an object representing the selected item
things while waiting for the user to press enter (depending on what your datasource function(s) returned)
- Use this method if you want to allow your script to do other
* Non-blocking is a bit of a stretch. This doesn't block for things while waiting for the user to press enter
input from the user, but will block execution for as long as
each datasource lookup takes. * Non-blocking is a bit of a stretch. This doesn't block for
input from the user, but will block execution for as long as
Typeahead.cycle() each datasource lookup takes.
- Housekeeping function to be called during the same loop as Typeahead.cycle()
Typeahead.inkey() (see examples below)
- Housekeeping function to be called during the same loop as
Typeahead.updateCursor() Typeahead.inkey() (see examples below)
- If you supplied a parent frame for your Typeahead object and Typeahead.updateCursor()
are cycling it / updating it at the same time that the user
is giving input, you may want to call this from within your - If you supplied a parent frame for your Typeahead object and
input loop just to keep the real cursor positioned at the same are cycling it / updating it at the same time that the user
location as Typeahead's fake one is giving input, you may want to call this from within your
input loop just to keep the real cursor positioned at the same
Typeahead.close(cleanUp) location as Typeahead's fake one
- Closes your Typeahead Typeahead.close(cleanUp)
- If 'cleanUp' is true, steps will be taken to tidy up the
user's terminal (probably only necessary if you didn't supply - Closes your Typeahead
a parent frame.) - If 'cleanUp' is true, steps will be taken to tidy up the
user's terminal (probably only necessary if you didn't supply
Examples: a parent frame.)
load('typeahead.js'); Examples:
// This will be our datasource load('typeahead.js');
var suggester = function(str) { // This will be our datasource
var suggestions = []; var suggester = function (str) {
var words = [ var suggestions = [];
"donuts",
"coffee", var words = [
"bacon", 'donuts',
"waffles", 'coffee',
"toast", 'bacon',
"peanut butter", 'waffles',
"buttered toast", 'toast',
"buttered waffles", 'peanut butter',
"toasted donuts" 'buttered toast',
]; 'buttered waffles',
'toasted donuts'
str = str.toUpperCase(); ];
suggestions = words.filter(
function(word) { str = str.toUpperCase();
word = word.toUpperCase(); suggestions = words.filter(
if(word.search(str) > - 1) function (word) {
return true; word = word.toUpperCase();
if(str.search(word) > - 1) if (word.search(str) > -1) return true;
return true; if (str.search(word) > -1) return true;
return false; return false;
} }
); );
return suggestions; return suggestions;
} }
// Typeahead.getstr() blocking input example (easy) // Typeahead.getstr() blocking input example (easy)
console.clear(LIGHTGRAY); console.clear(LIGHTGRAY);
var typeahead = new Typeahead( var typeahead = new Typeahead(
{ 'prompt' : "Type something: ", { 'prompt' : 'Type something: ',
'datasources' : [suggester] 'datasources' : [suggester]
} }
); );
var str = typeahead.getstr(); var str = typeahead.getstr();
console.putmsg(str); console.putmsg(str);
console.pause(); console.pause();
// Typeahead.inkey(), Typeahead.cycle(), Typeahead.updateCursor() // Typeahead.inkey(), Typeahead.cycle(), Typeahead.updateCursor()
// and Typeahead.close() non-blocking input example // and Typeahead.close() non-blocking input example
console.clear(LIGHTGRAY); console.clear(LIGHTGRAY);
var frame = new Frame( var frame = new Frame(
1, 1,
1, 1,
console.screen_columns, console.screen_columns,
console.screen_rows, console.screen_rows,
LIGHTGRAY LIGHTGRAY
); );
frame.open(); frame.open();
var typeahead = new Typeahead( var typeahead = new Typeahead(
{ 'prompt' : "Type something: ", { 'prompt' : 'Type something: ',
'len' : 60, 'len' : 60,
'datasources' : [suggester], 'datasources' : [suggester],
'frame' : frame 'frame' : frame
} }
); );
var str = undefined; var str = undefined;
while(typeof str != "string") { while (typeof str !== 'string') {
var key = console.inkey(K_NONE, 5); var key = console.inkey(K_NONE, 5);
str = typeahead.inkey(key); str = typeahead.inkey(key);
if(!str) { if (!str) {
// Input wasn't handled by Typeahead // Input wasn't handled by Typeahead
// Do something else with it, if you want // Do something else with it, if you want
} }
typeahead.cycle(); typeahead.cycle();
if(frame.cycle()) if (frame.cycle()) typeahead.updateCursor();
typeahead.updateCursor(); }
}
typeahead.close();
typeahead.close(); frame.close();
frame.close();
console.clear(LIGHTGRAY);
console.clear(LIGHTGRAY); console.putmsg(str);
console.putmsg(str); console.pause();
console.pause();
*/ */
load('sbbsdefs.js'); load('sbbsdefs.js');
load('frame.js'); load('frame.js');
load('tree.js'); load('tree.js');
var Typeahead = function(options) { var Typeahead = function (options) {
var properties = { var properties = {
'x' : 0, 'x' : 0,
'y' : 0, 'y' : 0,
'len' : console.screen_columns, 'len' : console.screen_columns,
'prompt' : "", 'height' : 0,
'fg' : LIGHTGRAY, 'prompt' : '',
'bg' : BG_BLUE, 'fg' : LIGHTGRAY,
'sfg' : LIGHTGRAY, 'bg' : BG_BLUE,
'sbg' : BG_BLUE, 'sfg' : LIGHTGRAY,
'hsfg' : WHITE, 'sbg' : BG_BLUE,
'hsbg' : BG_CYAN, 'hsfg' : WHITE,
'cursor' : ascii(219), 'hsbg' : BG_CYAN,
'position' : 0, 'cursor' : ascii(219),
'text' : "", 'position' : 0,
'datasources' : [], 'text' : '',
'delay' : 1, 'datasources' : [],
'minLength' : 1, 'delay' : 1,
'lastKey' : system.timer, 'minLength' : 1,
'suggested' : false, 'lastKey' : system.timer,
'attr' : console.attributes 'suggested' : false,
}; 'attr' : console.attributes
};
var display = {
'parentFrame' : undefined, var display = {
'frame' : undefined, 'parentFrame' : undefined,
'inputFrame' : undefined, 'frame' : undefined,
'cursor' : undefined, 'inputFrame' : undefined,
'treeFrame' : undefined, 'cursor' : undefined,
'tree' : undefined 'treeFrame' : undefined,
}; 'tree' : undefined
};
var initSettings = function() {
function initSettings() {
for(var p in properties) {
if(p == "datasources") for (var p in properties) {
continue; if (p === 'datasources') continue;
if(typeof options[p] != typeof properties[p]) if (typeof options[p] !== typeof properties[p]) continue;
continue; properties[p] = options[p];
properties[p] = options[p]; }
}
if (properties.x === 0 || properties.y === 0) {
if(properties.x == 0 || properties.y == 0) { var xy = console.getxy();
var xy = console.getxy(); properties.x = xy.x;
properties.x = xy.x; properties.y = xy.y;
properties.y = xy.y; }
}
if (properties.len + properties.prompt.length > console.screen_columns) {
if(properties.len + properties.prompt.length > console.screen_columns) properties.len = console.screen_columns - properties.prompt.length;
properties.len = console.screen_columns - properties.prompt.length; }
if(properties.text != "") if (properties.height === 0 ||
properties.position = properties.text.length + 1; properties.height > console.screen_rows - properties.y
) {
if(typeof options.datasources != "undefined" && Array.isArray(options.datasources)) { properties.height = console.screen_rows - properties.y;
properties.datasources = options.datasources.filter( }
function(d) {
return(typeof d == "function"); if (properties.text !== '') {
} properties.position = properties.text.length + 1;
); }
}
if (typeof options.datasources !== 'undefined' &&
} Array.isArray(options.datasources)
) {
var initDisplay = function() { properties.datasources = options.datasources.filter(
function (d) {
if(typeof options.frame != "undefined") return (typeof d === 'function');
display.parentFrame = options.frame; }
);
display.frame = new Frame( }
properties.x,
properties.y, }
properties.prompt.length + properties.len,
1, function initDisplay() {
LIGHTGRAY,
display.parentFrame if (typeof options.frame !== 'undefined') {
); display.parentFrame = options.frame;
display.frame.checkbounds = false; }
display.frame.putmsg(properties.prompt);
display.frame = new Frame(
display.inputFrame = new Frame( properties.x,
display.frame.x + properties.prompt.length, properties.y,
display.frame.y, properties.prompt.length + properties.len,
properties.len, 1,
1, LIGHTGRAY,
properties.bg|properties.fg, display.parentFrame
display.frame );
); display.frame.checkbounds = false;
display.inputFrame.putmsg(properties.text); display.frame.putmsg(properties.prompt);
display.cursor = new Frame( display.inputFrame = new Frame(
display.inputFrame.x + properties.text.length, display.frame.x + properties.prompt.length,
display.inputFrame.y, display.frame.y,
1, properties.len,
1, 1,
properties.bg|properties.fg, properties.bg|properties.fg,
display.inputFrame display.frame
); );
display.cursor.putmsg(properties.cursor); display.inputFrame.putmsg(properties.text);
if(properties.datasources.length > 0) { display.cursor = new Frame(
display.treeFrame = new Frame( display.inputFrame.x + properties.text.length,
display.inputFrame.x, display.inputFrame.y,
display.inputFrame.y + 1, 1,
display.inputFrame.width, 1,
console.screen_rows - display.inputFrame.y, properties.bg|properties.fg,
properties.fg, display.inputFrame
display.frame );
); display.cursor.putmsg(properties.cursor);
display.treeFrame.transparent = true;
} if (properties.datasources.length > 0) {
display.treeFrame = new Frame(
display.frame.open(); display.inputFrame.x,
display.inputFrame.y + 1,
} display.inputFrame.width,
properties.height,
var init = function() { properties.fg,
initSettings(); display.frame
initDisplay(); );
} display.treeFrame.transparent = true;
}
var suggest = function() {
display.frame.open();
var suggestions = [];
properties.datasources.forEach( }
function(datasource) {
suggestions = suggestions.concat(datasource(properties.text)); function init() {
} initSettings();
); initDisplay();
}
if(typeof display.tree != "undefined") {
display.tree.close(); function suggest() {
display.treeFrame.invalidate();
} var suggestions = [];
properties.datasources.forEach(
if(suggestions.length < 1) { function (datasource) {
display.tree = undefined; suggestions = suggestions.concat(datasource(properties.text));
return; }
} );
display.tree = new Tree(display.treeFrame); if (typeof display.tree != 'undefined') {
display.tree.colors.fg = properties.sfg; display.tree.close();
display.tree.colors.bg = properties.sbg; display.treeFrame.invalidate();
display.tree.colors.lfg = properties.hsfg; }
display.tree.colors.lbg = properties.hsbg;
if (suggestions.length < 1) {
display.tree.addItem(""); display.tree = undefined;
suggestions.forEach( return;
function(suggestion) { }
if(typeof suggestion == "object" && typeof suggestion.text == "string") {
var item = display.tree.addItem(suggestion.text); display.tree = new Tree(display.treeFrame);
item.suggestion = suggestion; display.tree.colors.fg = properties.sfg;
} else if(typeof suggestion == "string") { display.tree.colors.bg = properties.sbg;
display.tree.addItem(suggestion); display.tree.colors.lfg = properties.hsfg;
} display.tree.colors.lbg = properties.hsbg;
}
); display.tree.addItem('');
suggestions.forEach(
display.tree.open(); function (suggestion) {
if (typeof suggestion === 'object' &&
properties.suggested = true; typeof suggestion.text === 'string'
) {
} var item = display.tree.addItem(suggestion.text);
item.suggestion = suggestion;
this.inkey = function(key) { } else if (typeof suggestion === 'string') {
if(typeof key == "undefined" || key == "") display.tree.addItem(suggestion);
return; }
var ret = true; }
var change = false; );
switch(key) {
case '\x0c': /* CTRL-L */ display.tree.open();
case '\x00': /* CTRL-@ (NULL) */
case '\x03': /* CTRL-C */ properties.suggested = true;
case '\x04': /* CTRL-D */
case '\x0b': /* CTRL-K */ }
case '\x0e': /* CTRL-N */
case '\x0f': /* CTRL-O */ this.inkey = function (key) {
case '\x09': // TAB if (typeof key === 'undefined' || key === '') return;
case '\x10': /* CTRL-P */ var ret = true;
case '\x11': /* CTRL-Q */ var change = false;
case '\x12': /* CTRL-R */ switch (key) {
case '\x13': /* CTRL-S */ case '\x0c': /* CTRL-L */
case '\x14': /* CTRL-T */ case '\x00': /* CTRL-@ (NULL) */
case '\x15': /* CTRL-U */ case '\x03': /* CTRL-C */
case '\x16': /* CTRL-V */ case '\x04': /* CTRL-D */
case '\x17': /* CTRL-W */ case '\x0b': /* CTRL-K */
case '\x18': /* CTRL-X */ case '\x0e': /* CTRL-N */
case '\x19': /* CTRL-Y */ case '\x0f': /* CTRL-O */
case '\x1a': /* CTRL-Z */ case '\x09': // TAB
case '\x1c': /* CTRL-\ */ case '\x10': /* CTRL-P */
case '\x1f': /* CTRL-_ */ case '\x11': /* CTRL-Q */
ret = false; case '\x12': /* CTRL-R */
break; case '\x13': /* CTRL-S */
case KEY_UP: case '\x14': /* CTRL-T */
case KEY_DOWN: case '\x15': /* CTRL-U */
if(typeof display.tree != "undefined") case '\x16': /* CTRL-V */
display.tree.getcmd(key); case '\x17': /* CTRL-W */
break; case '\x18': /* CTRL-X */
case KEY_HOME: case '\x19': /* CTRL-Y */
properties.position = 0; case '\x1a': /* CTRL-Z */
break; case '\x1c': /* CTRL-\ */
case KEY_END: case '\x1f': /* CTRL-_ */
properties.position = display.inputFrame.x + properties.text.length; ret = false;
break; break;
case KEY_LEFT: case KEY_UP:
properties.position = (properties.position == 0) ? 0 : properties.position - 1; case KEY_DOWN:
break; if (typeof display.tree !== 'undefined') {
case KEY_RIGHT: display.tree.getcmd(key);
properties.position = (properties.position >= properties.text.length) ? properties.text.length : properties.position + 1; }
break; break;
case '\b': case KEY_HOME:
if(properties.position == 0) properties.position = 0;
break; break;
properties.text = properties.text.split(""); case KEY_END:
properties.text.splice((properties.position - 1), 1); properties.position = display.inputFrame.x + properties.text.length;
properties.text = properties.text.join(""); break;
properties.position--; case KEY_LEFT:
change = true; properties.position = (properties.position === 0) ? 0 : properties.position - 1;
break; break;
case '\x7f': case KEY_RIGHT:
if(properties.position >= properties.text.length) properties.position = (properties.position >= properties.text.length) ? properties.text.length : properties.position + 1;
break; break;
properties.text = properties.text.split(""); case '\b':
properties.text.splice((properties.position), 1); if (properties.position === 0) break;
properties.text = properties.text.join(""); properties.text = properties.text.split('');
change = true; properties.text.splice((properties.position - 1), 1);
break; properties.text = properties.text.join('');
case '\r': properties.position--;
case '\n': change = true;
if(typeof display.tree != "undefined" && display.tree.index > 0) { break;
if(typeof display.tree.currentItem.suggestion == "undefined") case '\x7f':
ret = display.tree.currentItem.text; if (properties.position >= properties.text.length) break;
else properties.text = properties.text.split('');
ret = display.tree.currentItem.suggestion; properties.text.splice((properties.position), 1);
} else { properties.text = properties.text.join('');
ret = properties.text; change = true;
} break;
break; case '\r':
default: case '\n':
if(properties.text.length == properties.len) if (typeof display.tree !== 'undefined'
break; && display.tree.index > 0
key = strip_ctrl(key); ) {
if(properties.position != properties.text.length) { if (typeof display.tree.currentItem.suggestion === 'undefined') {
properties.text = properties.text.split(""); ret = display.tree.currentItem.text;
properties.text.splice(properties.position, 0, key); } else {
properties.text = properties.text.join(""); ret = display.tree.currentItem.suggestion;
} else { }
properties.text += key; } else {
} ret = properties.text;
properties.position++; }
if(typeof display.tree != "undefined") break;
display.tree.getcmd(KEY_HOME); default:
change = true; if (properties.text.length === properties.len) break;
break; key = strip_ctrl(key);
} if (properties.position !== properties.text.length) {
if(change) { properties.text = properties.text.split('');
display.inputFrame.clear(); properties.text.splice(properties.position, 0, key);
display.inputFrame.putmsg(properties.text); properties.text = properties.text.join('');
properties.lastKey = system.timer; } else {
properties.suggested = false; properties.text += key;
} }
return ret; properties.position++;
} if (typeof display.tree !== 'undefined') {
display.tree.getcmd(KEY_HOME);
this.getstr = function() { }
var ret; change = true;
while(typeof ret != "string" && typeof ret != "object") { break;
ret = this.inkey(console.inkey(K_NONE, 5)); }
this.cycle(); if (change) {
} display.inputFrame.clear();
this.close(true); display.inputFrame.putmsg(properties.text);
return ret; properties.lastKey = system.timer;
} properties.suggested = false;
}
this.cycle = function() { return ret;
if(properties.text == "" && typeof display.tree != "undefined") { }
display.tree.close();
display.tree = undefined; this.getstr = function () {
display.treeFrame.invalidate(); var ret;
} else if( while (typeof ret !== 'string' && typeof ret !== 'object') {
properties.text.length >= properties.minLength && ret = this.inkey(console.inkey(K_NONE, 5));
properties.datasources.length > 0 && this.cycle();
system.timer - properties.lastKey > properties.delay && }
!properties.suggested this.close(true);
) { return ret;
suggest(); }
}
display.cursor.moveTo(display.inputFrame.x + properties.position, display.inputFrame.y); this.cycle = function () {
display.cursor[time() % 2 == 0 ? "top" : "bottom"](); if (properties.text === '' && typeof display.tree !== 'undefined') {
if(typeof display.parentFrame == "undefined" && display.frame.cycle()) display.tree.close();
this.updateCursor(); display.tree = undefined;
} display.treeFrame.invalidate();
} else if (
this.updateCursor = function() { properties.text.length >= properties.minLength &&
console.gotoxy(display.inputFrame.x + properties.position, display.inputFrame.y); properties.datasources.length > 0 &&
} system.timer - properties.lastKey > properties.delay &&
!properties.suggested
this.close = function(cleanup) { ) {
if(typeof display.tree != "undefined") suggest();
display.tree.close(); }
display.frame.close(); display.cursor.moveTo(display.inputFrame.x + properties.position, display.inputFrame.y);
if(typeof cleanup == "boolean" && cleanup) { display.cursor[time() % 2 === 0 ? 'top' : 'bottom']();
console.attributes = properties.attr; if (typeof display.parentFrame === 'undefined'
if(typeof display.tree != "undefined") { && display.frame.cycle()
for(var i = 0; i < display.tree.items.length; i++) { ) {
console.line_counter = 0; this.updateCursor();
console.crlf(); }
console.clearline(); }
}
} this.updateCursor = function () {
console.gotoxy(1, display.frame.y + 1); console.gotoxy(display.inputFrame.x + properties.position, display.inputFrame.y);
} }
display.frame.delete();
} this.close = function (cleanup) {
if (typeof display.tree !== 'undefined') display.tree.close();
init(); display.frame.close();
if (typeof cleanup === 'boolean' && cleanup) {
console.attributes = properties.attr;
if (typeof display.tree !== 'undefined') {
for (var i = 0; i < display.tree.items.length; i++) {
console.line_counter = 0;
console.crlf();
console.clearline();
}
}
console.gotoxy(1, display.frame.y + 1);
}
display.frame.delete();
}
init();
} }
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment