pocketpy/web/index.js

167 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const MINIMUM_COLS = 2
const MINIMUM_ROWS = 1
class FitAddon {
constructor() {}
activate(terminal) {
this._terminal = terminal
}
dispose() {}
fit() {
const dims = this.proposeDimensions()
if (!dims || !this._terminal || isNaN(dims.cols) || isNaN(dims.rows)) {
return
}
// TODO: Remove reliance on private API
const core = this._terminal._core
// Force a full render
if (
this._terminal.rows !== dims.rows ||
this._terminal.cols !== dims.cols
) {
core._renderService.clear()
this._terminal.resize(dims.cols, dims.rows)
}
}
proposeDimensions() {
if (!this._terminal) {
return undefined
}
if (!this._terminal.element || !this._terminal.element.parentElement) {
return undefined
}
// TODO: Remove reliance on private API
const core = this._terminal._core
const dims = core._renderService.dimensions
if (dims.actualCellWidth === 0 || dims.actualCellHeight === 0) {
return undefined
}
const scrollbarWidth =
this._terminal.options.scrollback === 0 ? 0 : core.viewport.scrollBarWidth
const parentElementStyle = window.getComputedStyle(
this._terminal.element.parentElement
)
const parentElementHeight = parseInt(
parentElementStyle.getPropertyValue("height")
)
const parentElementWidth = Math.max(
0,
parseInt(parentElementStyle.getPropertyValue("width"))
)
const elementStyle = window.getComputedStyle(this._terminal.element)
const elementPadding = {
top: parseInt(elementStyle.getPropertyValue("padding-top")),
bottom: parseInt(elementStyle.getPropertyValue("padding-bottom")),
right: parseInt(elementStyle.getPropertyValue("padding-right")),
left: parseInt(elementStyle.getPropertyValue("padding-left"))
}
const elementPaddingVer = elementPadding.top + elementPadding.bottom
const elementPaddingHor = elementPadding.right + elementPadding.left
const availableHeight = parentElementHeight - elementPaddingVer
const availableWidth =
parentElementWidth - elementPaddingHor - scrollbarWidth
const geometry = {
cols: Math.max(
MINIMUM_COLS,
Math.floor(availableWidth / dims.actualCellWidth)
),
rows: Math.max(
MINIMUM_ROWS,
Math.floor(availableHeight / dims.actualCellHeight)
)
}
return geometry
}
}
const term = new Terminal(
{
cursorBlink: true,
fontSize: 16,
theme: {
background: '#282C34',
foreground: '#ffffff',
cursor: '#ffffff',
cursorAccent: '#282C34',
selection: '#41454E',
},
}
);
var command = "";
var need_more_lines = false;
var stopped = false;
var repl = 0;
var Module = {
'print': function(text) {
term.write(text + "\r\n");
},
'printErr': function(text) {
term.write(text + "\r\n");
},
'onRuntimeInitialized': function(text) {
var vm = Module.ccall('pkpy_new_vm', 'number', ['boolean'], [true]);
repl = Module.ccall('pkpy_new_repl', 'number', ['number'], [vm]);
term.write(need_more_lines ? "... " : ">>> ");
},
'onAbort': function(text) {
stopped = true;
},
};
function term_init() {
term.open(document.getElementById('terminal'));
const addon = new FitAddon();
term.loadAddon(addon);
addon.fit();
// refit when window is resized
window.addEventListener('resize', () => {
addon.fit();
});
term.onData(e => {
if (stopped) return;
switch (e) {
case '\r': // Enter
term.write("\r\n");
need_more_lines = Module.ccall('pkpy_repl_input', 'bool', ['number', 'string'], [repl, command]);
command = '';
term.write(need_more_lines ? "... " : ">>> ");
break;
case '\u007F': // Backspace (DEL)
// Do not delete the prompt
if (term._core.buffer.x > 4) { // '>>> ' or '... '
var re=/[^\u4E00-\u9FA5]/;
if (re.test(command.charAt(command.length-1))){//判断前一个字符是否为中文
term.write('\b \b');//false
}else{
term.write('\b\b \b');//中文占两个字节ascii字符占一个字节
}
if (command.length > 0) {
command = command.substr(0, command.length - 1);
}
}
break;
default: // Print all other characters for demo
if (e >= String.fromCharCode(0x20) && e <= String.fromCharCode(0x7E) || e >= '\u00a0') {
command += e;
term.write(e);
}
}
});
}