@dodona/papyros
Version:
Scratchpad for multiple programming languages in the browser.
101 lines • 3.89 kB
JavaScript
import { SWITCH_INPUT_MODE_A_ID, USER_INPUT_WRAPPER_ID } from "./Constants";
import { BackendEventType } from "./BackendEvent";
import { addListener, getElement, t } from "./util/Util";
import { InteractiveInputHandler } from "./input/InteractiveInputHandler";
import { BatchInputHandler } from "./input/BatchInputHandler";
import { BackendManager } from "./BackendManager";
import { Renderable, renderWithOptions } from "./util/Rendering";
export var InputMode;
(function (InputMode) {
InputMode["Interactive"] = "interactive";
InputMode["Batch"] = "batch";
})(InputMode || (InputMode = {}));
export const INPUT_MODES = [InputMode.Batch, InputMode.Interactive];
export class InputManager extends Renderable {
constructor(sendInput, inputMode) {
super();
this.onUserInput = this.onUserInput.bind(this);
this.inputHandlers = this.buildInputHandlerMap();
this.inputMode = inputMode;
this.sendInput = sendInput;
this.waiting = false;
this.prompt = "";
BackendManager.subscribe(BackendEventType.Start, () => this.onRunStart());
BackendManager.subscribe(BackendEventType.End, () => this.onRunEnd());
BackendManager.subscribe(BackendEventType.Input, e => this.onInputRequest(e));
}
buildInputHandlerMap() {
const interactiveInputHandler = new InteractiveInputHandler(this.onUserInput);
const batchInputHandler = new BatchInputHandler(this.onUserInput);
return new Map([
[InputMode.Interactive, interactiveInputHandler],
[InputMode.Batch, batchInputHandler]
]);
}
getInputMode() {
return this.inputMode;
}
setInputMode(inputMode) {
this.inputHandler.toggle(false);
this.inputMode = inputMode;
this.render();
this.inputHandler.toggle(true);
}
getInputHandler(inputMode) {
return this.inputHandlers.get(inputMode);
}
get inputHandler() {
return this.getInputHandler(this.inputMode);
}
isWaiting() {
return this.waiting;
}
_render(options) {
let switchMode = "";
const otherMode = this.inputMode === InputMode.Interactive ?
InputMode.Batch : InputMode.Interactive;
switchMode = `<a id="${SWITCH_INPUT_MODE_A_ID}" data-value="${otherMode}"
class="_tw-flex _tw-flex-row-reverse hover:_tw-cursor-pointer _tw-text-blue-500">
${t(`Papyros.switch_input_mode_to.${otherMode}`)}
</a>`;
renderWithOptions(options, `
<div id="${USER_INPUT_WRAPPER_ID}" class="_tw-my-1">
</div>
${switchMode}`);
addListener(SWITCH_INPUT_MODE_A_ID, im => this.setInputMode(im), "click", "data-value");
this.inputHandler.render({
parentElementId: USER_INPUT_WRAPPER_ID,
darkMode: options.darkMode,
inputStyling: options.inputStyling
});
this.inputHandler.waitWithPrompt(this.waiting, this.prompt);
}
waitWithPrompt(waiting, prompt = "") {
this.waiting = waiting;
this.prompt = prompt;
this.inputHandler.waitWithPrompt(this.waiting, this.prompt);
}
onUserInput(line) {
this.sendInput(line);
this.waitWithPrompt(false);
}
/**
* Asynchronously handle an input request by prompting the user for input
* @param {BackendEvent} e Event containing the input data
*/
onInputRequest(e) {
this.waitWithPrompt(true, e.data);
}
onRunStart() {
// Prevent switching input mode during runs
getElement(SWITCH_INPUT_MODE_A_ID).hidden = true;
this.waitWithPrompt(false);
this.inputHandler.onRunStart();
}
onRunEnd() {
getElement(SWITCH_INPUT_MODE_A_ID).hidden = false;
this.inputHandler.onRunEnd();
this.waitWithPrompt(false);
}
}
//# sourceMappingURL=InputManager.js.map