Fix the terminal to stop glitching out and not displaying unless window is resized.
This commit is contained in:
parent
6fb44f7d7b
commit
a2b451b990
11 changed files with 478 additions and 603 deletions
|
@ -9,6 +9,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
|
||||||
* `[pre.7]` — Fixes bug with injected JS that was causing `<!DOCTYPE html>` to be ignored in templates.
|
* `[pre.7]` — Fixes bug with injected JS that was causing `<!DOCTYPE html>` to be ignored in templates.
|
||||||
* `[pre.7]` — Fixes exception thrown when trying to delete a node due to a misnamed model.
|
* `[pre.7]` — Fixes exception thrown when trying to delete a node due to a misnamed model.
|
||||||
* `[pre.7]` — Fixes username vanishing on failed login attempts.
|
* `[pre.7]` — Fixes username vanishing on failed login attempts.
|
||||||
|
* `[pre.7]` — Terminal is now fixed to actually output all lines, rather than leaving one hanging in neverland until the browser is resized.
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* Login attempts and pasword reset requests are now protected by invisible ReCaptcha. This feature can be disabled with a `.env` variable.
|
* Login attempts and pasword reset requests are now protected by invisible ReCaptcha. This feature can be disabled with a `.env` variable.
|
||||||
|
@ -24,6 +25,7 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
|
||||||
* Routes are now handled in the `routes/` folder, and use a significantly cleaner syntax. Controller names and methods have been updated as well to be clearer as well as avoid conflicts with PHP reserved keywords.
|
* Routes are now handled in the `routes/` folder, and use a significantly cleaner syntax. Controller names and methods have been updated as well to be clearer as well as avoid conflicts with PHP reserved keywords.
|
||||||
* API has been completely overhauled to use new permissions system. **Any old API keys will immediately become invalid and fail to operate properly anymore. You will need to generate new keys.**
|
* API has been completely overhauled to use new permissions system. **Any old API keys will immediately become invalid and fail to operate properly anymore. You will need to generate new keys.**
|
||||||
* Cleaned up dynamic database connection setting to use a single function call from the host model.
|
* Cleaned up dynamic database connection setting to use a single function call from the host model.
|
||||||
|
* `[pre.7]` — Corrected a config option for spigot servers to set a boolean value as boolean, and not as a string.
|
||||||
|
|
||||||
## v0.6.0-pre.7 (Courageous Carniadactylus)
|
## v0.6.0-pre.7 (Courageous Carniadactylus)
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -17,32 +17,22 @@
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
|
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count || 10;
|
||||||
|
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq || 200;
|
||||||
|
var CONSOLE_OUTPUT_LIMIT = Pterodactyl.config.console_limit || 2000;
|
||||||
|
var InitialLogSent = false;
|
||||||
|
|
||||||
var Console = (function () {
|
(function initConsole() {
|
||||||
var CONSOLE_PUSH_COUNT = Pterodactyl.config.console_count;
|
window.TerminalQueue = [];
|
||||||
var CONSOLE_PUSH_FREQ = Pterodactyl.config.console_freq;
|
window.Terminal = $('#terminal').terminal(function (command, term) {
|
||||||
|
|
||||||
var terminalQueue;
|
|
||||||
var terminal;
|
|
||||||
var recievedInitialLog = false;
|
|
||||||
|
|
||||||
var cpuChart;
|
|
||||||
var cpuData;
|
|
||||||
var memoryChart;
|
|
||||||
var memoryData;
|
|
||||||
var timeLabels;
|
|
||||||
|
|
||||||
var $terminalNotify;
|
|
||||||
|
|
||||||
function initConsole() {
|
|
||||||
terminalQueue = [];
|
|
||||||
terminal = $('#terminal').terminal(function (command, term) {
|
|
||||||
Socket.emit('send command', command);
|
Socket.emit('send command', command);
|
||||||
}, {
|
}, {
|
||||||
greetings: '',
|
greetings: '',
|
||||||
name: Pterodactyl.server.uuid,
|
name: Pterodactyl.server.uuid,
|
||||||
height: 450,
|
height: 450,
|
||||||
exit: false,
|
exit: false,
|
||||||
|
echoCommand: false,
|
||||||
|
outputLimit: CONSOLE_OUTPUT_LIMIT,
|
||||||
prompt: Pterodactyl.server.username + ':~$ ',
|
prompt: Pterodactyl.server.username + ':~$ ',
|
||||||
scrollOnEcho: false,
|
scrollOnEcho: false,
|
||||||
scrollBottomOffset: 5,
|
scrollBottomOffset: 5,
|
||||||
|
@ -51,27 +41,131 @@ var Console = (function () {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$terminalNotify = $('#terminalNotify');
|
window.TerminalNotifyElement = $('#terminalNotify');
|
||||||
$terminalNotify.on('click', function () {
|
TerminalNotifyElement.on('click', function () {
|
||||||
terminal.scroll_to_bottom();
|
Terminal.scroll_to_bottom();
|
||||||
$terminalNotify.addClass('hidden');
|
TerminalNotifyElement.addClass('hidden');
|
||||||
})
|
})
|
||||||
|
|
||||||
terminal.on('scroll', function () {
|
Terminal.on('scroll', function () {
|
||||||
if (terminal.is_bottom()) {
|
if (Terminal.is_bottom()) {
|
||||||
$terminalNotify.addClass('hidden');
|
TerminalNotifyElement.addClass('hidden');
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// Socket.on('initial status', function (data) {
|
||||||
|
// Terminal.clear();
|
||||||
|
// if (data.status === 1 || data.status === 2) {
|
||||||
|
// Socket.emit('send server log');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function pushOutputQueue() {
|
||||||
|
if (TerminalQueue.length > CONSOLE_PUSH_COUNT) {
|
||||||
|
// console throttled warning show
|
||||||
}
|
}
|
||||||
|
|
||||||
function initGraphs() {
|
if (TerminalQueue.length > 0) {
|
||||||
|
for (var i = 0; i < CONSOLE_PUSH_COUNT && TerminalQueue.length > 0; i++) {
|
||||||
|
Terminal.echo(TerminalQueue[0], { flush: false });
|
||||||
|
TerminalQueue.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush after looping through all.
|
||||||
|
Terminal.flush();
|
||||||
|
|
||||||
|
// Show Warning
|
||||||
|
if (! Terminal.is_bottom()) {
|
||||||
|
TerminalNotifyElement.removeClass('hidden');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function setupSocketListeners() {
|
||||||
|
// Update Listings on Initial Status
|
||||||
|
Socket.on('initial status', function (data) {
|
||||||
|
console.log('initial status 2');
|
||||||
|
if (! InitialLogSent) {
|
||||||
|
updateServerPowerControls(data.status);
|
||||||
|
|
||||||
|
if (data.status === 1 || data.status === 2) {
|
||||||
|
Socket.emit('send server log');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update Listings on Status
|
||||||
|
Socket.on('status', function (data) {
|
||||||
|
updateServerPowerControls(data.status);
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('server log', function (data) {
|
||||||
|
if (! InitialLogSent) {
|
||||||
|
Terminal.clear();
|
||||||
|
TerminalQueue.push(data);
|
||||||
|
InitialLogSent = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('console', function (data) {
|
||||||
|
TerminalQueue.push(data.line);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
function updateServerPowerControls (data) {
|
||||||
|
// Server is On or Starting
|
||||||
|
if(data == 1 || data == 2) {
|
||||||
|
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
||||||
|
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
if (data == 0) {
|
||||||
|
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
||||||
|
}
|
||||||
|
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(data !== 0) {
|
||||||
|
$('[data-attr="power"][data-action="kill"]').removeClass('disabled');
|
||||||
|
} else {
|
||||||
|
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(document).ready(function () {
|
||||||
|
$('[data-attr="power"]').click(function (event) {
|
||||||
|
if (! $(this).hasClass('disabled')) {
|
||||||
|
Socket.emit('set status', $(this).data('action'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Socket.on('proc', function (proc) {
|
||||||
|
if (CPUData.length > 10) {
|
||||||
|
CPUData.shift();
|
||||||
|
MemoryData.shift();
|
||||||
|
TimeLabels.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
||||||
|
CPUData.push(cpuUse);
|
||||||
|
MemoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
||||||
|
|
||||||
|
TimeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
||||||
|
|
||||||
|
CPUChart.update();
|
||||||
|
MemoryChart.update();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
var ctc = $('#chart_cpu');
|
var ctc = $('#chart_cpu');
|
||||||
timeLabels = [];
|
var TimeLabels = [];
|
||||||
cpuData = [];
|
var CPUData = [];
|
||||||
cpuChart = new Chart(ctc, {
|
var CPUChart = new Chart(ctc, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: timeLabels,
|
labels: TimeLabels,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Percent Use",
|
label: "Percent Use",
|
||||||
|
@ -92,7 +186,7 @@ var Console = (function () {
|
||||||
pointHoverBorderWidth: 2,
|
pointHoverBorderWidth: 2,
|
||||||
pointRadius: 1,
|
pointRadius: 1,
|
||||||
pointHitRadius: 10,
|
pointHitRadius: 10,
|
||||||
data: cpuData,
|
data: CPUData,
|
||||||
spanGaps: false,
|
spanGaps: false,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -112,11 +206,11 @@ var Console = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
var ctm = $('#chart_memory');
|
var ctm = $('#chart_memory');
|
||||||
memoryData = [];
|
MemoryData = [];
|
||||||
memoryChart = new Chart(ctm, {
|
MemoryChart = new Chart(ctm, {
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: timeLabels,
|
labels: TimeLabels,
|
||||||
datasets: [
|
datasets: [
|
||||||
{
|
{
|
||||||
label: "Memory Use",
|
label: "Memory Use",
|
||||||
|
@ -137,7 +231,7 @@ var Console = (function () {
|
||||||
pointHoverBorderWidth: 2,
|
pointHoverBorderWidth: 2,
|
||||||
pointRadius: 1,
|
pointRadius: 1,
|
||||||
pointHitRadius: 10,
|
pointHitRadius: 10,
|
||||||
data: memoryData,
|
data: MemoryData,
|
||||||
spanGaps: false,
|
spanGaps: false,
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -155,122 +249,4 @@ var Console = (function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function addSocketListeners() {
|
|
||||||
// Update Listings on Initial Status
|
|
||||||
Socket.on('initial status', function (data) {
|
|
||||||
if (! recievedInitialLog) {
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
|
|
||||||
if (data.status === 1 || data.status === 2) {
|
|
||||||
Socket.emit('send server log');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update Listings on Status
|
|
||||||
Socket.on('status', function (data) {
|
|
||||||
updateServerPowerControls(data.status);
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('server log', function (data) {
|
|
||||||
if (! recievedInitialLog) {
|
|
||||||
terminal.clear();
|
|
||||||
terminalQueue.push(data);
|
|
||||||
recievedInitialLog = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('console', function (data) {
|
|
||||||
terminalQueue.push(data.line);
|
|
||||||
});
|
|
||||||
|
|
||||||
Socket.on('proc', function (proc) {
|
|
||||||
if (cpuData.length > 10) {
|
|
||||||
cpuData.shift();
|
|
||||||
memoryData.shift();
|
|
||||||
timeLabels.shift();
|
|
||||||
}
|
|
||||||
|
|
||||||
var cpuUse = (Pterodactyl.server.cpu > 0) ? parseFloat(((proc.data.cpu.total / Pterodactyl.server.cpu) * 100).toFixed(3).toString()) : proc.data.cpu.total;
|
|
||||||
cpuData.push(cpuUse);
|
|
||||||
memoryData.push(parseInt(proc.data.memory.total / (1024 * 1024)));
|
|
||||||
|
|
||||||
var m = new Date();
|
|
||||||
timeLabels.push($.format.date(new Date(), 'HH:mm:ss'));
|
|
||||||
|
|
||||||
cpuChart.update();
|
|
||||||
memoryChart.update();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function pushOutputQueue() {
|
|
||||||
if (terminalQueue.length > CONSOLE_PUSH_COUNT) {
|
|
||||||
// console throttled warning show
|
|
||||||
}
|
|
||||||
|
|
||||||
if (terminalQueue.length > 0) {
|
|
||||||
for (var i = 0; i < CONSOLE_PUSH_COUNT && terminalQueue.length > 0; i++) {
|
|
||||||
terminal.echo(terminalQueue[0], {flush: false});
|
|
||||||
terminalQueue.shift();
|
|
||||||
}
|
|
||||||
terminal.flush()
|
|
||||||
|
|
||||||
// Show
|
|
||||||
if (!terminal.is_bottom()) {
|
|
||||||
$terminalNotify.removeClass('hidden');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.setTimeout(pushOutputQueue, CONSOLE_PUSH_FREQ);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateServerPowerControls (data) {
|
|
||||||
// Server is On or Starting
|
|
||||||
if(data == 1 || data == 2) {
|
|
||||||
$('[data-attr="power"][data-action="start"]').addClass('disabled');
|
|
||||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').removeClass('disabled');
|
|
||||||
} else {
|
|
||||||
if (data == 0) {
|
|
||||||
$('[data-attr="power"][data-action="start"]').removeClass('disabled');
|
|
||||||
}
|
|
||||||
$('[data-attr="power"][data-action="stop"], [data-attr="power"][data-action="restart"]').addClass('disabled');
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data !== 0) {
|
|
||||||
$('[data-attr="power"][data-action="kill"]').removeClass('disabled');
|
|
||||||
} else {
|
|
||||||
$('[data-attr="power"][data-action="kill"]').addClass('disabled');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
init: function () {
|
|
||||||
|
|
||||||
initConsole();
|
|
||||||
pushOutputQueue();
|
|
||||||
initGraphs();
|
|
||||||
addSocketListeners();
|
|
||||||
|
|
||||||
$('[data-attr="power"]').click(function (event) {
|
|
||||||
if (! $(this).hasClass('disabled')) {
|
|
||||||
Socket.emit('set status', $(this).data('action'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getTerminal: function () {
|
|
||||||
return terminal
|
|
||||||
},
|
|
||||||
|
|
||||||
getTerminalQueue: function () {
|
|
||||||
return terminalQueue
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
Console.init();
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -50,11 +50,13 @@ var Server = (function () {
|
||||||
|
|
||||||
var notifySocketError = false;
|
var notifySocketError = false;
|
||||||
|
|
||||||
|
console.log('Starting connection');
|
||||||
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
|
window.Socket = io(Pterodactyl.node.scheme + '://' + Pterodactyl.node.fqdn + ':' + Pterodactyl.node.daemonListen + '/ws/' + Pterodactyl.server.uuid, {
|
||||||
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
'query': 'token=' + Pterodactyl.server.daemonSecret,
|
||||||
});
|
});
|
||||||
|
|
||||||
Socket.io.on('connect_error', function (err) {
|
Socket.io.on('connect_error', function (err) {
|
||||||
|
console.log('connect_error');
|
||||||
if(typeof notifySocketError !== 'object') {
|
if(typeof notifySocketError !== 'object') {
|
||||||
notifySocketError = $.notify({
|
notifySocketError = $.notify({
|
||||||
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
message: 'There was an error attempting to establish a WebSocket connection to the Daemon. This panel will not work as expected.<br /><br />' + err,
|
||||||
|
@ -67,6 +69,7 @@ var Server = (function () {
|
||||||
|
|
||||||
// Connected to Socket Successfully
|
// Connected to Socket Successfully
|
||||||
Socket.on('connect', function () {
|
Socket.on('connect', function () {
|
||||||
|
console.log('connect');
|
||||||
if (notifySocketError !== false) {
|
if (notifySocketError !== false) {
|
||||||
notifySocketError.close();
|
notifySocketError.close();
|
||||||
notifySocketError = false;
|
notifySocketError = false;
|
||||||
|
@ -74,6 +77,7 @@ var Server = (function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
Socket.on('initial status', function (data) {
|
Socket.on('initial status', function (data) {
|
||||||
|
console.log('initial status');
|
||||||
setStatusIcon(data.status);
|
setStatusIcon(data.status);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
39
public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js
vendored
Normal file
39
public/themes/pterodactyl/vendor/terminal/jquery.terminal.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
121
public/themes/pterodactyl/vendor/terminal/keyboard.polyfill.js
vendored
Normal file
121
public/themes/pterodactyl/vendor/terminal/keyboard.polyfill.js
vendored
Normal file
|
@ -0,0 +1,121 @@
|
||||||
|
/* global define, KeyboardEvent, module */
|
||||||
|
// https://github.com/cvan/keyboardevent-key-polyfill/blob/master/LICENSE.md
|
||||||
|
(function () {
|
||||||
|
|
||||||
|
var keyboardeventKeyPolyfill = {
|
||||||
|
polyfill: polyfill,
|
||||||
|
keys: {
|
||||||
|
3: 'Cancel',
|
||||||
|
6: 'Help',
|
||||||
|
8: 'Backspace',
|
||||||
|
9: 'Tab',
|
||||||
|
12: 'Clear',
|
||||||
|
13: 'Enter',
|
||||||
|
16: 'Shift',
|
||||||
|
17: 'Control',
|
||||||
|
18: 'Alt',
|
||||||
|
19: 'Pause',
|
||||||
|
20: 'CapsLock',
|
||||||
|
27: 'Escape',
|
||||||
|
28: 'Convert',
|
||||||
|
29: 'NonConvert',
|
||||||
|
30: 'Accept',
|
||||||
|
31: 'ModeChange',
|
||||||
|
32: ' ',
|
||||||
|
33: 'PageUp',
|
||||||
|
34: 'PageDown',
|
||||||
|
35: 'End',
|
||||||
|
36: 'Home',
|
||||||
|
37: 'ArrowLeft',
|
||||||
|
38: 'ArrowUp',
|
||||||
|
39: 'ArrowRight',
|
||||||
|
40: 'ArrowDown',
|
||||||
|
41: 'Select',
|
||||||
|
42: 'Print',
|
||||||
|
43: 'Execute',
|
||||||
|
44: 'PrintScreen',
|
||||||
|
45: 'Insert',
|
||||||
|
46: 'Delete',
|
||||||
|
48: ['0', ')'],
|
||||||
|
49: ['1', '!'],
|
||||||
|
50: ['2', '@'],
|
||||||
|
51: ['3', '#'],
|
||||||
|
52: ['4', '$'],
|
||||||
|
53: ['5', '%'],
|
||||||
|
54: ['6', '^'],
|
||||||
|
55: ['7', '&'],
|
||||||
|
56: ['8', '*'],
|
||||||
|
57: ['9', '('],
|
||||||
|
91: 'OS',
|
||||||
|
93: 'ContextMenu',
|
||||||
|
144: 'NumLock',
|
||||||
|
145: 'ScrollLock',
|
||||||
|
181: 'VolumeMute',
|
||||||
|
182: 'VolumeDown',
|
||||||
|
183: 'VolumeUp',
|
||||||
|
186: [';', ':'],
|
||||||
|
187: ['=', '+'],
|
||||||
|
188: [',', '<'],
|
||||||
|
189: ['-', '_'],
|
||||||
|
190: ['.', '>'],
|
||||||
|
191: ['/', '?'],
|
||||||
|
192: ['`', '~'],
|
||||||
|
219: ['[', '{'],
|
||||||
|
220: ['\\', '|'],
|
||||||
|
221: [']', '}'],
|
||||||
|
222: ["'", '"'],
|
||||||
|
224: 'Meta',
|
||||||
|
225: 'AltGraph',
|
||||||
|
246: 'Attn',
|
||||||
|
247: 'CrSel',
|
||||||
|
248: 'ExSel',
|
||||||
|
249: 'EraseEof',
|
||||||
|
250: 'Play',
|
||||||
|
251: 'ZoomOut'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function keys (F1-24).
|
||||||
|
var i;
|
||||||
|
for (i = 1; i < 25; i++) {
|
||||||
|
keyboardeventKeyPolyfill.keys[111 + i] = 'F' + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printable ASCII characters.
|
||||||
|
var letter = '';
|
||||||
|
for (i = 65; i < 91; i++) {
|
||||||
|
letter = String.fromCharCode(i);
|
||||||
|
keyboardeventKeyPolyfill.keys[i] = [letter.toLowerCase(), letter.toUpperCase()];
|
||||||
|
}
|
||||||
|
|
||||||
|
function polyfill () {
|
||||||
|
if (!('KeyboardEvent' in window) ||
|
||||||
|
'key' in KeyboardEvent.prototype) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Polyfill `key` on `KeyboardEvent`.
|
||||||
|
var proto = {
|
||||||
|
get: function (x) {
|
||||||
|
var key = keyboardeventKeyPolyfill.keys[this.which || this.keyCode];
|
||||||
|
|
||||||
|
if (Array.isArray(key)) {
|
||||||
|
key = key[+this.shiftKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.defineProperty(KeyboardEvent.prototype, 'key', proto);
|
||||||
|
return proto;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define('keyboardevent-key-polyfill', keyboardeventKeyPolyfill);
|
||||||
|
} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
|
||||||
|
module.exports = keyboardeventKeyPolyfill;
|
||||||
|
} else if (window) {
|
||||||
|
window.keyboardeventKeyPolyfill = keyboardeventKeyPolyfill;
|
||||||
|
}
|
||||||
|
|
||||||
|
})();
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
* This is example of how to create custom formatter for jQuery Terminal
|
* This is example of how to create custom formatter for jQuery Terminal
|
||||||
*
|
*
|
||||||
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl>
|
* Copyright (c) 2014-2016 Jakub Jankiewicz <http://jcubic.pl/me>
|
||||||
* Released under the MIT license
|
* Released under the MIT license
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@ -21,10 +21,10 @@
|
||||||
// :: Replace overtyping (from man) formatting with terminal formatting
|
// :: Replace overtyping (from man) formatting with terminal formatting
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
$.terminal.overtyping = function(string) {
|
$.terminal.overtyping = function(string) {
|
||||||
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full, g) {
|
return string.replace(/((?:_\x08.|.\x08_)+)/g, function(full) {
|
||||||
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
|
var striped = full.replace(/_x08|\x08_|_\u0008|\u0008_/g, '');
|
||||||
return '[[u;;]' + striped + ']';
|
return '[[u;;]' + striped + ']';
|
||||||
}).replace(/((?:.\x08.)+)/g, function(full, g) {
|
}).replace(/((?:.\x08.)+)/g, function(full) {
|
||||||
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
|
return '[[b;#fff;]' + full.replace(/(.)(?:\x08|\u0008)\1/g,
|
||||||
function(full, g) {
|
function(full, g) {
|
||||||
return g;
|
return g;
|
||||||
|
@ -153,18 +153,8 @@
|
||||||
var _8bit_background = false;
|
var _8bit_background = false;
|
||||||
var process_8bit = false;
|
var process_8bit = false;
|
||||||
var palette = $.terminal.ansi_colors.palette;
|
var palette = $.terminal.ansi_colors.palette;
|
||||||
for(var i in controls) {
|
function set_styles(num) {
|
||||||
if (controls.hasOwnProperty(i)) {
|
switch (num) {
|
||||||
num = parseInt(controls[i], 10);
|
|
||||||
if (process_8bit && (_8bit_background || _8bit_color)) {
|
|
||||||
if (_8bit_color && palette[num]) {
|
|
||||||
output_color = palette[num];
|
|
||||||
}
|
|
||||||
if (_8bit_background && palette[num]) {
|
|
||||||
output_background = palette[num];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(num) {
|
|
||||||
case 1:
|
case 1:
|
||||||
styles.push('b');
|
styles.push('b');
|
||||||
bold = true;
|
bold = true;
|
||||||
|
@ -193,7 +183,7 @@
|
||||||
reverse = true;
|
reverse = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (controls.indexOf('5') == -1) {
|
if (controls.indexOf('5') === -1) {
|
||||||
if (color_list[num]) {
|
if (color_list[num]) {
|
||||||
output_color = color_list[num];
|
output_color = color_list[num];
|
||||||
}
|
}
|
||||||
|
@ -203,6 +193,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (var i in controls) {
|
||||||
|
if (controls.hasOwnProperty(i)) {
|
||||||
|
num = parseInt(controls[i], 10);
|
||||||
|
if (process_8bit && (_8bit_background || _8bit_color)) {
|
||||||
|
if (_8bit_color && palette[num]) {
|
||||||
|
output_color = palette[num];
|
||||||
|
}
|
||||||
|
if (_8bit_background && palette[num]) {
|
||||||
|
output_background = palette[num];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set_styles(num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
|
@ -225,14 +228,14 @@
|
||||||
}
|
}
|
||||||
if (_8bit_color) {
|
if (_8bit_color) {
|
||||||
color = output_color;
|
color = output_color;
|
||||||
} else if (output_color == 'inherit') {
|
} else if (output_color === 'inherit') {
|
||||||
color = output_color;
|
color = output_color;
|
||||||
} else {
|
} else {
|
||||||
color = colors[output_color];
|
color = colors[output_color];
|
||||||
}
|
}
|
||||||
if (_8bit_background) {
|
if (_8bit_background) {
|
||||||
background = output_background;
|
background = output_background;
|
||||||
} else if (output_background == 'transparent') {
|
} else if (output_background === 'transparent') {
|
||||||
background = output_background;
|
background = output_background;
|
||||||
} else {
|
} else {
|
||||||
background = backgrounds[output_background];
|
background = backgrounds[output_background];
|
||||||
|
@ -245,20 +248,20 @@
|
||||||
return group.replace(/m\x1B\[/g, ';');
|
return group.replace(/m\x1B\[/g, ';');
|
||||||
});*/
|
});*/
|
||||||
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
|
var splitted = input.split(/(\x1B\[[0-9;]*[A-Za-z])/g);
|
||||||
if (splitted.length == 1) {
|
if (splitted.length === 1) {
|
||||||
return input;
|
return input;
|
||||||
}
|
}
|
||||||
var output = [];
|
var output = [];
|
||||||
//skip closing at the begining
|
//skip closing at the begining
|
||||||
if (splitted.length > 3) {
|
if (splitted.length > 3) {
|
||||||
var str = splitted.slice(0,3).join('');
|
var str = splitted.slice(0, 3).join('');
|
||||||
if (str.match(/^\[0*m$/)) {
|
if (str.match(/^\[0*m$/)) {
|
||||||
splitted = splitted.slice(3);
|
splitted = splitted.slice(3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var next, prev_color, prev_background, code, match;
|
var prev_color, prev_background, code, match;
|
||||||
var inside = false;
|
var inside = false;
|
||||||
for (var i=0; i<splitted.length; ++i) {
|
for (var i = 0; i < splitted.length; ++i) {
|
||||||
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
|
match = splitted[i].match(/^\x1B\[([0-9;]*)([A-Za-z])$/);
|
||||||
if (match) {
|
if (match) {
|
||||||
switch (match[2]) {
|
switch (match[2]) {
|
||||||
|
@ -285,8 +288,7 @@
|
||||||
prev_background = code[2];
|
prev_background = code[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if (+match[1] !== 0) {
|
||||||
if (+match[1] !== 0) {
|
|
||||||
inside = true;
|
inside = true;
|
||||||
code[1] = code[1] || prev_color;
|
code[1] = code[1] || prev_color;
|
||||||
code[2] = code[2] || prev_background;
|
code[2] = code[2] || prev_background;
|
||||||
|
@ -299,7 +301,6 @@
|
||||||
prev_background = code[2];
|
prev_background = code[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -222,6 +222,9 @@
|
||||||
<div class="control-sidebar-bg"></div>
|
<div class="control-sidebar-bg"></div>
|
||||||
</div>
|
</div>
|
||||||
@section('footer-scripts')
|
@section('footer-scripts')
|
||||||
|
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
|
||||||
|
<script>keyboardeventKeyPolyfill.polyfill();</script>
|
||||||
|
|
||||||
{!! Theme::js('js/laroute.js') !!}
|
{!! Theme::js('js/laroute.js') !!}
|
||||||
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||||
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
||||||
|
|
|
@ -262,6 +262,9 @@
|
||||||
<div class="control-sidebar-bg"></div>
|
<div class="control-sidebar-bg"></div>
|
||||||
</div>
|
</div>
|
||||||
@section('footer-scripts')
|
@section('footer-scripts')
|
||||||
|
{!! Theme::js('vendor/terminal/keyboard.polyfill.js') !!}
|
||||||
|
<script>keyboardeventKeyPolyfill.polyfill();</script>
|
||||||
|
|
||||||
{!! Theme::js('js/laroute.js') !!}
|
{!! Theme::js('js/laroute.js') !!}
|
||||||
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
{!! Theme::js('vendor/jquery/jquery.min.js') !!}
|
||||||
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
{!! Theme::js('vendor/sweetalert/sweetalert.min.js') !!}
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
@parent
|
@parent
|
||||||
{!! Theme::js('js/frontend/server.socket.js') !!}
|
{!! Theme::js('js/frontend/server.socket.js') !!}
|
||||||
{!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!}
|
{!! Theme::js('vendor/mousewheel/jquery.mousewheel-min.js') !!}
|
||||||
{!! Theme::js('vendor/terminal/jquery.terminal-0.11.23.min.js') !!}
|
{!! Theme::js('vendor/terminal/jquery.terminal.min.js') !!}
|
||||||
{!! Theme::js('vendor/terminal/unix_formatting.js') !!}
|
{!! Theme::js('vendor/terminal/unix_formatting.js') !!}
|
||||||
{!! Theme::js('js/frontend/console.js') !!}
|
{!! Theme::js('js/frontend/console.js') !!}
|
||||||
{!! Theme::js('vendor/chartjs/chart.min.js') !!}
|
{!! Theme::js('vendor/chartjs/chart.min.js') !!}
|
||||||
|
|
Loading…
Add table
Reference in a new issue