import {Constants} from "../constants"; import {isCtrl, isFirefox} from "../util/compatibility"; import { blurEvent, copyEvent, cutEvent, dblclickEvent, dropEvent, focusEvent, hotkeyEvent, scrollCenter, selectEvent, } from "../util/editorCommonEvent"; import {paste} from "../util/fixBrowserBehavior"; import {hasClosestByAttribute, hasClosestByClassName} from "../util/hasClosest"; import { getEditorRange, setRangeByWbr, setSelectionFocus, } from "../util/selection"; import {clickToc} from "../util/toc"; import {expandMarker} from "./expandMarker"; import {highlightToolbarIR} from "./highlightToolbarIR"; import {input} from "./input"; import {processAfterRender, processHint} from "./process"; class IR { public range: Range; public element: HTMLPreElement; public processTimeoutId: number; public hlToolbarTimeoutId: number; public composingLock: boolean = false; public preventInput: boolean; constructor(vditor: IVditor) { const divElement = document.createElement("div"); divElement.className = "vditor-ir"; divElement.innerHTML = `
`; this.element = divElement.firstElementChild as HTMLPreElement; this.bindEvent(vditor); focusEvent(vditor, this.element); dblclickEvent(vditor, this.element); blurEvent(vditor, this.element); hotkeyEvent(vditor, this.element); selectEvent(vditor, this.element); dropEvent(vditor, this.element); copyEvent(vditor, this.element, this.copy); cutEvent(vditor, this.element, this.copy); } private copy(event: ClipboardEvent, vditor: IVditor) { const range = getSelection().getRangeAt(0); if (range.toString() === "") { return; } event.stopPropagation(); event.preventDefault(); const tempElement = document.createElement("div"); tempElement.appendChild(range.cloneContents()); event.clipboardData.setData("text/plain", vditor.lute.VditorIRDOM2Md(tempElement.innerHTML).trim()); event.clipboardData.setData("text/html", ""); } private bindEvent(vditor: IVditor) { this.element.addEventListener("paste", (event: ClipboardEvent & { target: HTMLElement }) => { paste(vditor, event, { pasteCode: (code: string) => { document.execCommand("insertHTML", false, code); }, }); }); this.element.addEventListener("compositionstart", (event: InputEvent) => { this.composingLock = true; }); this.element.addEventListener("compositionend", (event: InputEvent) => { if (!isFirefox()) { input(vditor, getSelection().getRangeAt(0).cloneRange()); } this.composingLock = false; }); this.element.addEventListener("input", (event: InputEvent) => { if (event.inputType === "deleteByDrag" || event.inputType === "insertFromDrop") { // https://github.com/Vanessa219/vditor/issues/801 编辑器内容拖拽问题 return; } if (this.preventInput) { this.preventInput = false; return; } if (this.composingLock || event.data === "‘" || event.data === "“" || event.data === "《") { return; } input(vditor, getSelection().getRangeAt(0).cloneRange(), false, event); }); this.element.addEventListener("click", (event: MouseEvent & { target: HTMLInputElement }) => { if (event.target.tagName === "INPUT") { if (event.target.checked) { event.target.setAttribute("checked", "checked"); } else { event.target.removeAttribute("checked"); } this.preventInput = true; processAfterRender(vditor); return; } const range = getEditorRange(vditor); // 点击后光标落于预览区 let previewElement = hasClosestByClassName(event.target, "vditor-ir__preview"); if (!previewElement) { previewElement = hasClosestByClassName( range.startContainer, "vditor-ir__preview"); } if (previewElement) { if (previewElement.previousElementSibling.firstElementChild) { range.selectNodeContents(previewElement.previousElementSibling.firstElementChild); } else { // 行内数学公式 range.selectNodeContents(previewElement.previousElementSibling); } range.collapse(true); setSelectionFocus(range); scrollCenter(vditor); } // 点击图片光标选中图片地址 if (event.target.tagName === "IMG") { const linkElement = event.target.parentElement.querySelector${Constants.ZWSP}