UNPKG

prism-react-editor

Version:

Lightweight, extensible code editor component for React apps

164 lines (163 loc) 5.82 kB
import { n as numLines, d as doc, a as addListener, s as selectionChange } from "./core-Dm5I6BkG.js"; let prevSelection; const regexEscape = (str) => str.replace(/[$+?|.^*()[\]{}\\]/g, "\\$&"); const getLineBefore = (text, position) => text.slice(getLineStart(text, position), position); const getLines = (text, start, end = start) => [ text.slice(start = getLineStart(text, start), end = getLineEnd(text, end)).split("\n"), start, end ]; const getClosestToken = (editor, selector, marginLeft = 0, marginRight = marginLeft, position = editor.getSelection()[0]) => { const value = editor.value; const line = editor.lines[numLines(value, 0, position)]; const walker = doc.createTreeWalker(line, 5); let node = walker.lastChild(); let offset = getLineEnd(value, position) + 1 - position - node.length; while (-offset <= marginRight && (node = walker.previousNode())) { if (node.lastChild) continue; offset -= node.length || 0; if (offset <= marginLeft) { for (; node != line; node = node.parentNode) { if (node.matches?.(selector)) return node; } } } }; const getLanguage = (editor, position) => getClosestToken(editor, "[class*=language-]", 0, 0, position)?.className.match( /language-(\S*)/ )[1] || editor.props.language; const insertText = (editor, text, start, end, newCursorStart, newCursorEnd) => { if (!editor.props.readOnly) { prevSelection = editor.getSelection(); end ??= start; let textarea = editor.textarea; let value = editor.value; let avoidBug = isChrome && !value[end ?? prevSelection[1]] && /\n$/.test(text) && /^$|\n$/.test(value); editor.focused || textarea.focus(); if (start != null) textarea.setSelectionRange(start, end); if (newCursorStart != null) { addListener( textarea, "input", () => { textarea.setSelectionRange( newCursorStart, newCursorEnd ?? newCursorStart, prevSelection[2] ); }, { once: true, capture: true } ); } isWebKit || textarea.dispatchEvent(new InputEvent("beforeinput", { data: text })); if (isChrome || isWebKit) { if (avoidBug) { textarea.selectionEnd--; text = text.slice(0, -1); } if (isWebKit) text += "\n"; doc.execCommand( text ? "insertHTML" : "delete", false, text.replace(/&/g, "&amp;").replace(/</g, "&lt;") ); if (avoidBug) textarea.selectionStart++; } else doc.execCommand(text ? "insertText" : "delete", false, text); prevSelection = 0; } }; const getModifierCode = (e) => e.altKey + e.ctrlKey * 2 + e.metaKey * 4 + e.shiftKey * 8; const userAgent = doc ? navigator.userAgent : ""; const isMac = doc ? /Mac|iPhone|iPod|iPad/i.test(navigator.platform) : false; const isChrome = /Chrome\//.test(userAgent); const isWebKit = !isChrome && /AppleWebKit\//.test(userAgent); const setSelection = (editor, start, end = start, direction) => { let focused = editor.focused; let textarea = editor.textarea; let relatedTarget; if (!focused) { addListener( textarea, "focus", (e) => { relatedTarget = e.relatedTarget; }, { once: true } ); textarea.focus(); } textarea.setSelectionRange(start, end, direction); selectionChange(!(!focused && (relatedTarget ? relatedTarget.focus() : textarea.blur()))); }; const addOverlay = (editor, overlay) => { editor.lines?.[0].append(overlay); }; const voidlessLangs = new Set("xml,rss,atom,jsx,tsx,xquery,xeora,xeoracube,actionscript".split(",")); const voidTags = /^(?:area|base|w?br|col|embed|hr|img|input|link|meta|source|track)$/i; const scrollToEl = (editor, el, paddingTop = 0) => { const style = editor.container.style; style.scrollPaddingBlock = `calc(var(--_sp) + ${paddingTop}px) calc(var(--_sp) + ${isChrome && !el.textContent ? el.offsetHeight : 0}px)`; el.scrollIntoView({ block: "nearest" }); style.scrollPaddingBlock = ""; }; const getLineStart = (text, position) => position ? text.lastIndexOf("\n", position - 1) + 1 : 0; const getLineEnd = (text, position) => (position = text.indexOf("\n", position)) + 1 ? position : text.length; const templateEl = /* @__PURE__ */ doc?.createElement("div"); const createTemplate = (html, node) => { if (templateEl) { templateEl.innerHTML = html; node = templateEl.firstChild; } return () => node?.cloneNode(true); }; const getPosition = (editor, el) => { const rect1 = el.getBoundingClientRect(); const rect2 = editor.lines[0].getBoundingClientRect(); return { top: rect1.y - rect2.y, bottom: rect2.bottom - rect1.bottom, left: rect1.x - rect2.x, right: rect2.right - rect1.right, height: rect1.height }; }; const addListener2 = (element, type, listener, options) => { addListener(element, type, listener, options); return () => element.removeEventListener(type, listener, options); }; const addTextareaListener = (editor, type, listener, options) => { return addListener2(editor.textarea, type, listener, options); }; const updateNode = (node, text) => { if (node.data != text) node.data = text; }; const testBracket = (str, brackets, l) => { return brackets.indexOf(str[0]) + 1 || l && brackets.indexOf(str[l]) + 1; }; export { addTextareaListener as a, addListener2 as b, getLanguage as c, insertText as d, getLines as e, getLineEnd as f, getModifierCode as g, getLineBefore as h, isMac as i, getLineStart as j, createTemplate as k, getPosition as l, scrollToEl as m, getClosestToken as n, voidTags as o, prevSelection as p, addOverlay as q, regexEscape as r, setSelection as s, testBracket as t, updateNode as u, voidlessLangs as v, isWebKit as w, isChrome as x }; //# sourceMappingURL=local-Cq-4Fajb.js.map