import { THEME, h } from "./dom"; /** * Generate a build for the output component * @param target The parent element in which it is mounted * @returns DOM reference to the console box and output container */ export default function outputBuild(target: HTMLElement) { const consoleBox = h("span"); const outputBox = h("div", { class: THEME.OUTPUT, children: [consoleBox] }); target.appendChild(outputBox); return { outputBox, consoleBox }; } /** * Generate a build for the input component * @param target The parent element in which it is mounted * @returns DOM reference to the input element */ export function inputBuild(target: HTMLElement) { const inputBox = h("textarea", { props: { // 明确声明为普通文本输入,降低移动端将其识别为登录表单的概率。 spellcheck: false, autocorrect: "off", autocapitalize: "off", autocomplete: "off", name: "xterminal_input", inputmode: "text", enterkeyhint: "enter", rows: 1, wrap: "off" } }); // 部分密码管理器会读取 data-* 做识别,显式标记为非登录用途。 inputBox.setAttribute("data-form-type", "other"); inputBox.setAttribute("data-lpignore", "true"); inputBox.setAttribute("data-1p-ignore", "true"); inputBox.setAttribute("data-bwignore", "true"); inputBox.setAttribute("aria-autocomplete", "none"); inputBox.setAttribute("autocapitalize", "off"); inputBox.setAttribute("autocorrect", "off"); // 某些浏览器在首帧点击文本输入框时会误触发凭据弹窗; // 先只读,获得焦点后立刻解除,可显著降低“刷新后点一下就弹登录”的概率。 inputBox.readOnly = true; inputBox.addEventListener( "focus", () => { inputBox.readOnly = false; }, { once: true } ); const stdin = h("div", { class: THEME.INPUT, children: [inputBox] }); target.appendChild(stdin); return inputBox; }