import type { Editable } from "./editable"; import { bridgeCommand } from "./lib"; import { onInput, onKey, onKeyUp } from "./inputHandlers"; import { onFocus, onBlur } from "./focusHandlers"; import { updateButtonState } from "./toolbar"; function onPaste(evt: ClipboardEvent): void { bridgeCommand("paste"); evt.preventDefault(); } function onCutOrCopy(): void { bridgeCommand("cutOrCopy"); } export class EditingArea extends HTMLDivElement { editable: Editable; baseStyle: HTMLStyleElement; constructor() { super(); this.attachShadow({ mode: "open" }); this.className = "field"; const rootStyle = document.createElement("link"); rootStyle.setAttribute("rel", "stylesheet"); rootStyle.setAttribute("href", "./_anki/css/editable.css"); this.shadowRoot!.appendChild(rootStyle); this.baseStyle = document.createElement("style"); this.baseStyle.setAttribute("rel", "stylesheet"); this.shadowRoot!.appendChild(this.baseStyle); this.editable = document.createElement("anki-editable") as Editable; this.shadowRoot!.appendChild(this.editable); } get ord(): number { return Number(this.getAttribute("ord")); } set fieldHTML(content: string) { this.editable.fieldHTML = content; } get fieldHTML(): string { return this.editable.fieldHTML; } connectedCallback(): void { this.addEventListener("keydown", onKey); this.addEventListener("keyup", onKeyUp); this.addEventListener("input", onInput); this.addEventListener("focus", onFocus); this.addEventListener("blur", onBlur); this.addEventListener("paste", onPaste); this.addEventListener("copy", onCutOrCopy); this.addEventListener("oncut", onCutOrCopy); this.addEventListener("mouseup", updateButtonState); const baseStyleSheet = this.baseStyle.sheet as CSSStyleSheet; baseStyleSheet.insertRule("anki-editable {}", 0); } disconnectedCallback(): void { this.removeEventListener("keydown", onKey); this.removeEventListener("keyup", onKeyUp); this.removeEventListener("input", onInput); this.removeEventListener("focus", onFocus); this.removeEventListener("blur", onBlur); this.removeEventListener("paste", onPaste); this.removeEventListener("copy", onCutOrCopy); this.removeEventListener("oncut", onCutOrCopy); this.removeEventListener("mouseup", updateButtonState); } initialize(color: string, content: string): void { this.setBaseColor(color); this.editable.fieldHTML = content; } setBaseColor(color: string): void { const styleSheet = this.baseStyle.sheet as CSSStyleSheet; const firstRule = styleSheet.cssRules[0] as CSSStyleRule; firstRule.style.color = color; } setBaseStyling(fontFamily: string, fontSize: string, direction: string): void { const styleSheet = this.baseStyle.sheet as CSSStyleSheet; const firstRule = styleSheet.cssRules[0] as CSSStyleRule; firstRule.style.fontFamily = fontFamily; firstRule.style.fontSize = fontSize; firstRule.style.direction = direction; } isRightToLeft(): boolean { const styleSheet = this.baseStyle.sheet as CSSStyleSheet; const firstRule = styleSheet.cssRules[0] as CSSStyleRule; return firstRule.style.direction === "rtl"; } getSelection(): Selection { return this.shadowRoot!.getSelection()!; } focusEditable(): void { this.editable.focus(); } blurEditable(): void { this.editable.blur(); } }