Docker container behind dos.jerryaldrichiii.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

172 lines
7.0 KiB

/**@license
* __ _____ ________ __
* / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / /
* __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ /
* / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__
* \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/
* \/ /____/
* http://terminal.jcubic.pl
*
* Wrapper for options that will create autocomplete menu for jQuery Terminal
*
* Copyright (c) 2014-2021 Jakub Jankiewicz <https://jcubic.pl/me>
* Released under the MIT license
*
*/
/* global define */
(function(factory) {
var root = typeof window !== 'undefined' ? window : global;
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
// istanbul ignore next
define(['jquery', 'jquery.terminal'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = function(root, jQuery) {
if (jQuery === undefined) {
// require('jQuery') returns a factory that requires window to
// build a jQuery instance, we normalize how we use modules
// that require this pattern but the window provided is a noop
// if it's defined (how jquery works)
if (typeof window !== 'undefined') {
jQuery = require('jquery');
} else {
jQuery = require('jquery')(root);
}
}
if (!jQuery.fn.terminal) {
if (typeof window !== 'undefined') {
require('jquery.terminal');
} else {
require('jquery.terminal')(jQuery);
}
}
factory(jQuery);
return jQuery;
};
} else {
// Browser
// istanbul ignore next
factory(root.jQuery);
}
})(function($) {
var jquery_terminal = $.fn.terminal;
$.fn.terminal = function(interpreter, options) {
function init(node) {
return jquery_terminal.call(node, interpreter, autocomplete_menu(options));
}
if (this.length > 1) {
return this.each(init.bind(null, this));
} else {
return init(this);
}
};
// -----------------------------------------------------------------------------------
// :: cancableble task for usage in comletion menu to ignore previous async completion
// -----------------------------------------------------------------------------------
function Task(fn) {
this._fn = fn;
}
Task.prototype.invoke = function() {
if (!this._cancel) {
this._fn.apply(null, arguments);
}
};
Task.prototype.cancel = function() {
this._cancel = true;
};
// -----------------------------------------------------------------------------------
// :: function return patched terminal settings
// -----------------------------------------------------------------------------------
function autocomplete_menu(options) {
if (options && !options.autocompleteMenu) {
return options;
}
var settings = options || {};
var last_task;
// -------------------------------------------------------------------------------
// :: function that do actuall matching and displaying of completion menu
// -------------------------------------------------------------------------------
function complete_menu(term, e, word, list) {
var matched = [];
var regex = new RegExp('^' + $.terminal.escape_regex(word));
for (var i = list.length; i--;) {
if (regex.test(list[i])) {
matched.unshift(list[i]);
}
}
if (e.which === 9) {
if (term.complete(matched)) {
word = term.before_cursor(true);
regex = new RegExp('^' + $.terminal.escape_regex(word));
}
}
if (word && matched.length) {
ul.hide();
for (i = 0; i < matched.length; ++i) {
var text = matched[i].replace(regex, '');
if (text) {
$('<li>' + text + '</li>').appendTo(ul);
}
}
ul.show();
}
}
var ul;
if (typeof settings.completion !== 'undefined') {
var onInit = settings.onInit || $.noop;
var keydown = settings.keydown || $.noop;
var completion = settings.completion;
delete settings.completion;
settings.onInit = function(term) {
onInit.call(this, term);
// init html menu element
var wrapper = this.cmd().find('.cmd-cursor').
wrap('<span/>').parent().addClass('cursor-wrapper');
ul = $('<ul></ul>').appendTo(wrapper);
ul.on('click', 'li', function() {
term.insert($(this).text());
ul.empty();
});
};
var timer;
settings.keydown = function(e, term) {
// setTimeout because terminal is adding characters in keypress
// we use keydown because we need to prevent default action
// for tab and still execute custom code
clearTimeout(timer);
timer = setTimeout(function() {
ul.empty();
var word = term.before_cursor(true);
if (last_task) {
last_task.cancel(); // ignore previous completion task
}
// we save task in closure for callbacks and promise::then
var task = last_task = new Task(complete_menu);
if (typeof completion === 'function') {
var ret = completion.call(term, word, function(list) {
task.invoke(term, e, word, list);
});
if (ret && typeof ret.then === 'function') {
ret.then(function(completion) {
task.invoke(term, e, word, completion);
});
} else if (ret instanceof Array) {
task.invoke(term, e, word, ret);
}
} else if (completion instanceof Array) {
task.invoke(term, e, word, completion);
}
}, 0);
var ret = keydown.call(this, e, term);
if (typeof ret !== 'undefined') {
return false;
}
if (e.which === 9) {
return false;
}
};
}
return settings;
}
});