vditor
Version:
♏ 易于使用的 Markdown 编辑器,为适配不同的应用场景而生
87 lines (75 loc) • 3.24 kB
text/typescript
import {getMarkdown} from "../markdown/getMarkdown";
import {isFirefox} from "../util/compatibility";
import {dropEvent, focusEvent, hotkeyEvent} from "../util/editorCommonEvent";
import {paste} from "../util/fixBrowserBehavior";
import {processAfterRender, processPaste} from "./process";
class Editor {
public element: HTMLTextAreaElement;
public composingLock: boolean = false;
public processTimeoutId: number;
constructor(vditor: IVditor) {
this.element = document.createElement("textarea");
this.element.className = "vditor-sv vditor-reset";
this.element.placeholder = vditor.options.placeholder;
this.element.spellcheck = false;
this.bindEvent(vditor);
focusEvent(vditor, this.element);
hotkeyEvent(vditor, this.element);
dropEvent(vditor, this.element, (code: string) => {
processPaste(vditor, code.replace(/</g, "<").replace(/&/g, "&"));
});
}
private bindEvent(vditor: IVditor) {
this.element.addEventListener("blur", () => {
if (vditor.options.blur) {
vditor.options.blur(getMarkdown(vditor));
}
});
this.element.addEventListener("paste", (event: ClipboardEvent & {target: HTMLElement}) => {
paste(vditor, event, {
pasteCode: (code: string) => {
processPaste(vditor, code.replace(/</g, "<").replace(/&/g, "&"));
},
});
});
this.element.addEventListener("scroll", () => {
if (vditor.preview.element.style.display !== "block") {
return;
}
const textScrollTop = this.element.scrollTop;
const textHeight = this.element.clientHeight;
const textScrollHeight = this.element.scrollHeight - parseFloat(this.element.style.paddingBottom || "0");
const preview = vditor.preview.element;
if (textScrollTop / textHeight > 0.5) {
preview.scrollTop = (textScrollTop + textHeight) * preview.scrollHeight / textScrollHeight - textHeight;
} else {
preview.scrollTop = textScrollTop * preview.scrollHeight / textScrollHeight;
}
});
this.element.addEventListener("compositionstart", () => {
this.composingLock = true;
});
this.element.addEventListener("compositionend", () => {
this.composingLock = false;
if (!isFirefox()) {
processAfterRender(vditor);
}
});
this.element.addEventListener("input", () => {
if (!this.composingLock) {
processAfterRender(vditor);
}
});
this.element.addEventListener("select", () => {
const selectedText = this.element.value.substring(this.element.selectionStart, this.element.selectionEnd);
if (selectedText.trim()) {
if (vditor.options.select) {
vditor.options.select(selectedText);
}
} else if (vditor.options.unSelect) {
vditor.options.unSelect();
}
});
}
}
export {Editor};