@lexical/code
Version:
This package contains the functionality for the code blocks and code highlighting for Lexical.
10 lines (8 loc) • 16 kB
JavaScript
/**
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
;var e=require("@lexical/utils"),t=require("lexical");function n(e,...t){const n=new URL("https://lexical.dev/docs/error"),r=new URLSearchParams;r.append("code",e);for(const e of t)r.append("v",e);throw n.search=r.toString(),Error(`Minified Lexical error #${e}; visit ${n.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`)}require("prismjs"),require("prismjs/components/prism-clike"),require("prismjs/components/prism-javascript"),require("prismjs/components/prism-markup"),require("prismjs/components/prism-markdown"),require("prismjs/components/prism-c"),require("prismjs/components/prism-css"),require("prismjs/components/prism-objectivec"),require("prismjs/components/prism-sql"),require("prismjs/components/prism-powershell"),require("prismjs/components/prism-python"),require("prismjs/components/prism-rust"),require("prismjs/components/prism-swift"),require("prismjs/components/prism-typescript"),require("prismjs/components/prism-java"),require("prismjs/components/prism-cpp");const r=globalThis.Prism||window.Prism,o=e=>{try{return!!e&&r.languages.hasOwnProperty(e)}catch(e){return!1}};function i(t,n){for(const r of t.childNodes){if(e.isHTMLElement(r)&&r.tagName===n)return!0;i(r,n)}return!1}const s="data-language",a="data-highlight-language";class l extends t.ElementNode{static getType(){return"code"}static clone(e){return new l(e.__language,e.__key)}constructor(e,t){super(t),this.__language=e||void 0,this.__isSyntaxHighlightSupported=o(e)}createDOM(t){const n=document.createElement("code");e.addClassNamesToElement(n,t.theme.code),n.setAttribute("spellcheck","false");const r=this.getLanguage();return r&&(n.setAttribute(s,r),this.getIsSyntaxHighlightSupported()&&n.setAttribute(a,r)),n}updateDOM(e,t,n){const r=this.__language,o=e.__language;return r?r!==o&&(t.setAttribute(s,r),this.__isSyntaxHighlightSupported&&t.setAttribute(a,r)):o&&(t.removeAttribute(s),e.__isSyntaxHighlightSupported&&t.removeAttribute(a)),!1}exportDOM(t){const n=document.createElement("pre");e.addClassNamesToElement(n,t._config.theme.code),n.setAttribute("spellcheck","false");const r=this.getLanguage();return r&&(n.setAttribute(s,r),this.getIsSyntaxHighlightSupported()&&n.setAttribute(a,r)),{element:n}}static importDOM(){return{code:e=>null!=e.textContent&&(/\r?\n/.test(e.textContent)||i(e,"BR"))?{conversion:c,priority:1}:null,div:()=>({conversion:d,priority:1}),pre:()=>({conversion:c,priority:0}),table:e=>h(e)?{conversion:p,priority:3}:null,td:e=>{const t=e,n=t.closest("table");return t.classList.contains("js-file-line")||n&&h(n)?{conversion:f,priority:3}:null},tr:e=>{const t=e.closest("table");return t&&h(t)?{conversion:f,priority:3}:null}}}static importJSON(e){return g().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setLanguage(e.language)}exportJSON(){return{...super.exportJSON(),language:this.getLanguage()}}insertNewAfter(e,n=!0){const r=this.getChildren(),o=r.length;if(o>=2&&"\n"===r[o-1].getTextContent()&&"\n"===r[o-2].getTextContent()&&e.isCollapsed()&&e.anchor.key===this.__key&&e.anchor.offset===o){r[o-1].remove(),r[o-2].remove();const e=t.$createParagraphNode();return this.insertAfter(e,n),e}const{anchor:i,focus:s}=e,a=(i.isBefore(s)?i:s).getNode();if(t.$isTextNode(a)){let e=y(a);const n=[];for(;;)if(t.$isTabNode(e))n.push(t.$createTabNode()),e=e.getNextSibling();else{if(!$(e))break;{let t=0;const r=e.getTextContent(),o=e.getTextContentSize();for(;t<o&&" "===r[t];)t++;if(0!==t&&n.push(S(" ".repeat(t))),t!==o)break;e=e.getNextSibling()}}const r=a.splitText(i.offset)[0],o=0===i.offset?0:1,s=r.getIndexWithinParent()+o,l=a.getParentOrThrow(),g=[t.$createLineBreakNode(),...n];l.splice(s,0,g);const u=n[n.length-1];u?u.select():0===i.offset?r.selectPrevious():r.getNextSibling().selectNext(0,0)}if(u(a)){const{offset:n}=e.anchor;a.splice(n,0,[t.$createLineBreakNode()]),a.select(n+1,n+1)}return null}canIndent(){return!1}collapseAtStart(){const e=t.$createParagraphNode();return this.getChildren().forEach((t=>e.append(t))),this.replace(e),!0}setLanguage(e){const t=this.getWritable();return t.__language=e||void 0,t.__isSyntaxHighlightSupported=o(e),t}getLanguage(){return this.getLatest().__language}getIsSyntaxHighlightSupported(){return this.getLatest().__isSyntaxHighlightSupported}}function g(e){return t.$applyNodeReplacement(new l(e))}function u(e){return e instanceof l}function c(e){return{node:g(e.getAttribute(s))}}function d(e){const t=e,n=N(t);return n||function(e){let t=e.parentElement;for(;null!==t;){if(N(t))return!0;t=t.parentElement}return!1}(t)?{node:n?g():null}:{node:null}}function p(){return{node:g()}}function f(){return{node:null}}function N(e){return null!==e.style.fontFamily.match("monospace")}function h(e){return e.classList.contains("js-file-line-container")}const m="javascript",T={c:"C",clike:"C-like",cpp:"C++",css:"CSS",html:"HTML",java:"Java",js:"JavaScript",markdown:"Markdown",objc:"Objective-C",plain:"Plain Text",powershell:"PowerShell",py:"Python",rust:"Rust",sql:"SQL",swift:"Swift",typescript:"TypeScript",xml:"XML"},_={cpp:"cpp",java:"java",javascript:"js",md:"markdown",plaintext:"plain",python:"py",text:"plain",ts:"typescript"};function C(e){return _[e]||e}class O extends t.TextNode{constructor(e="",t,n){super(e,n),this.__highlightType=t}static getType(){return"code-highlight"}static clone(e){return new O(e.__text,e.__highlightType||void 0,e.__key)}getHighlightType(){return this.getLatest().__highlightType}setHighlightType(e){const t=this.getWritable();return t.__highlightType=e||void 0,t}canHaveFormat(){return!1}createDOM(t){const n=super.createDOM(t),r=x(t.theme,this.__highlightType);return e.addClassNamesToElement(n,r),n}updateDOM(t,n,r){const o=super.updateDOM(t,n,r),i=x(r.theme,t.__highlightType),s=x(r.theme,this.__highlightType);return i!==s&&(i&&e.removeClassNamesFromElement(n,i),s&&e.addClassNamesToElement(n,s)),o}static importJSON(e){return S().updateFromJSON(e)}updateFromJSON(e){return super.updateFromJSON(e).setHighlightType(e.highlightType)}exportJSON(){return{...super.exportJSON(),highlightType:this.getHighlightType()}}setFormat(e){return this}isParentRequired(){return!0}createParentElementNode(){return g()}}function x(e,t){return t&&e&&e.codeHighlight&&e.codeHighlight[t]}function S(e="",n){return t.$applyNodeReplacement(new O(e,n))}function $(e){return e instanceof O}function M(n,r){let o=n;for(let i=t.$getSiblingCaret(n,r);i&&($(i.origin)||t.$isTabNode(i.origin));i=e.$getAdjacentCaret(i))o=i.origin;return o}function y(e){return M(e,"previous")}function L(e){return M(e,"next")}const A={defaultLanguage:m,tokenize(e,t){return r.tokenize(e,r.languages[t||""]||r.languages[this.defaultLanguage])}};function b(e,r){let o=null,i=null,s=e,a=r,l=e.getTextContent();for(;;){if(0===a){if(s=s.getPreviousSibling(),null===s)break;if($(s)||t.$isTabNode(s)||t.$isLineBreakNode(s)||n(167),t.$isLineBreakNode(s)){o={node:s,offset:1};break}a=Math.max(0,s.getTextContentSize()-1),l=s.getTextContent()}else a--;const e=l[a];$(s)&&" "!==e&&(i={node:s,offset:a})}if(null!==i)return i;let g=null;if(r<e.getTextContentSize())$(e)&&(g=e.getTextContent()[r]);else{const t=e.getNextSibling();$(t)&&(g=t.getTextContent()[0])}if(null!==g&&" "!==g)return o;{const n=function(e,n){let r=e,o=n,i=e.getTextContent(),s=e.getTextContentSize();for(;;){if(!$(r)||o===s){if(r=r.getNextSibling(),null===r||t.$isLineBreakNode(r))return null;$(r)&&(o=0,i=r.getTextContent(),s=r.getTextContentSize())}if($(r)){if(" "!==i[o])return{node:r,offset:o};o++}}}(e,r);return null!==n?n:o}}function E(e){const r=L(e);return t.$isLineBreakNode(r)&&n(168),r}function D(e,n,r){const o=e.getParent();u(o)?k(o,n,r):$(e)&&e.replace(t.$createTextNode(e.__text))}function v(e,n){const r=n.getElementByKey(e.getKey());if(null===r)return;const o=e.getChildren(),i=o.length;if(i===r.__cachedChildrenLength)return;r.__cachedChildrenLength=i;let s="1",a=1;for(let e=0;e<i;e++)t.$isLineBreakNode(o[e])&&(s+="\n"+ ++a);r.setAttribute("data-gutter",s)}const R=new Set;function k(e,n,r){const o=e.getKey();R.has(o)||(R.add(o),void 0===e.getLanguage()&&e.setLanguage(r.defaultLanguage),n.update((()=>{!function(e,n){const r=t.$getNodeByKey(e);if(!u(r)||!r.isAttached())return;const o=t.$getSelection();if(!t.$isRangeSelection(o))return void n();const i=o.anchor,s=i.offset,a="element"===i.type&&t.$isLineBreakNode(r.getChildAtIndex(i.offset-1));let l=0;if(!a){const e=i.getNode();l=s+e.getPreviousSiblings().reduce(((e,t)=>e+t.getTextContentSize()),0)}if(!n())return;if(a)return void i.getNode().select(s,s);r.getChildren().some((e=>{const n=t.$isTextNode(e);if(n||t.$isLineBreakNode(e)){const t=e.getTextContentSize();if(n&&t>=l)return e.select(l,l),!0;l-=t}return!1}))}(o,(()=>{const n=t.$getNodeByKey(o);if(!u(n)||!n.isAttached())return!1;const i=n.getTextContent(),s=P(r.tokenize(i,n.getLanguage()||r.defaultLanguage)),a=function(e,t){let n=0;for(;n<e.length&&B(e[n],t[n]);)n++;const r=e.length,o=t.length,i=Math.min(r,o)-n;let s=0;for(;s<i;)if(s++,!B(e[r-s],t[o-s])){s--;break}const a=n,l=r-s,g=t.slice(n,o-s);return{from:a,nodesForReplacement:g,to:l}}(n.getChildren(),s),{from:l,to:g,nodesForReplacement:c}=a;return!(l===g&&!c.length)&&(e.splice(l,g-l,c),!0)}))}),{onUpdate:()=>{R.delete(o)},skipTransforms:!0}))}function P(e,n){const r=[];for(const o of e)if("string"==typeof o){const e=o.split(/(\n|\t)/),i=e.length;for(let o=0;o<i;o++){const i=e[o];"\n"===i||"\r\n"===i?r.push(t.$createLineBreakNode()):"\t"===i?r.push(t.$createTabNode()):i.length>0&&r.push(S(i,n))}}else{const{content:e}=o;"string"==typeof e?r.push(...P([e],o.type)):Array.isArray(e)&&r.push(...P(e,o.type))}return r}function B(e,n){return $(e)&&$(n)&&e.__text===n.__text&&e.__highlightType===n.__highlightType||t.$isTabNode(e)&&t.$isTabNode(n)||t.$isLineBreakNode(e)&&t.$isLineBreakNode(n)}function I(e){if(!t.$isRangeSelection(e))return!1;const n=e.anchor.getNode(),r=e.focus.getNode();if(n.is(r)&&u(n))return!0;const o=n.getParent();return u(o)&&o.is(r.getParent())}function j(e){const r=e.getNodes(),o=[[]];if(1===r.length&&u(r[0]))return o;let i=o[0];for(let e=0;e<r.length;e++){const s=r[e];$(s)||t.$isTabNode(s)||t.$isLineBreakNode(s)||n(169),t.$isLineBreakNode(s)?0!==e&&i.length>0&&(i=[],o.push(i)):i.push(s)}return o}function w(e){const r=t.$getSelection();if(!t.$isRangeSelection(r)||!I(r))return!1;const o=j(r),i=o.length;if(o.length>1){for(let n=0;n<i;n++){const r=o[n];if(r.length>0){let o=r[0];0===n&&(o=y(o)),null!==o&&(e===t.INDENT_CONTENT_COMMAND?o.insertBefore(t.$createTabNode()):t.$isTabNode(o)&&o.remove())}}return!0}const s=r.getNodes()[0];if(u(s)||$(s)||t.$isTabNode(s)||t.$isLineBreakNode(s)||n(171),u(s))return e===t.INDENT_CONTENT_COMMAND&&r.insertNodes([t.$createTabNode()]),!0;const a=y(s);return e===t.INDENT_CONTENT_COMMAND?t.$isLineBreakNode(a)?a.insertAfter(t.$createTabNode()):a.insertBefore(t.$createTabNode()):t.$isTabNode(a)&&a.remove(),!0}function H(e,n){const r=t.$getSelection();if(!t.$isRangeSelection(r))return!1;const{anchor:o,focus:i}=r,s=o.offset,a=i.offset,l=o.getNode(),g=i.getNode(),u=e===t.KEY_ARROW_UP_COMMAND;if(!I(r)||!$(l)&&!t.$isTabNode(l)||!$(g)&&!t.$isTabNode(g))return!1;if(!n.altKey){if(r.isCollapsed()){const e=l.getParentOrThrow();if(u&&0===s&&null===l.getPreviousSibling()){if(null===e.getPreviousSibling())return e.selectPrevious(),n.preventDefault(),!0}else if(!u&&s===l.getTextContentSize()&&null===l.getNextSibling()){if(null===e.getNextSibling())return e.selectNext(),n.preventDefault(),!0}}return!1}let c,d;if(l.isBefore(g)?(c=y(l),d=L(g)):(c=y(g),d=L(l)),null==c||null==d)return!1;const p=c.getNodesBetween(d);for(let e=0;e<p.length;e++){const n=p[e];if(!$(n)&&!t.$isTabNode(n)&&!t.$isLineBreakNode(n))return!1}n.preventDefault(),n.stopPropagation();const f=u?c.getPreviousSibling():d.getNextSibling();if(!t.$isLineBreakNode(f))return!0;const N=u?f.getPreviousSibling():f.getNextSibling();if(null==N)return!0;const h=$(N)||t.$isTabNode(N)||t.$isLineBreakNode(N)?u?y(N):L(N):null;let m=null!=h?h:N;return f.remove(),p.forEach((e=>e.remove())),e===t.KEY_ARROW_UP_COMMAND?(p.forEach((e=>m.insertBefore(e))),m.insertBefore(f)):(m.insertAfter(f),m=f,p.forEach((e=>{m.insertAfter(e),m=e}))),r.setTextNodeRange(l,s,g,a),!0}function q(e,n){const r=t.$getSelection();if(!t.$isRangeSelection(r))return!1;const{anchor:o,focus:i}=r,s=o.getNode(),a=i.getNode(),l=e===t.MOVE_TO_START;if(!I(r)||!$(s)&&!t.$isTabNode(s)||!$(a)&&!t.$isTabNode(a))return!1;if(l){const e=b(a,i.offset);if(null!==e){const{node:n,offset:o}=e;t.$isLineBreakNode(n)?n.selectNext(0,0):r.setTextNodeRange(n,o,n,o)}else a.getParentOrThrow().selectStart()}else{E(a).select()}return n.preventDefault(),n.stopPropagation(),!0}const W=y,F=L,K=E,z=b;exports.$createCodeHighlightNode=S,exports.$createCodeNode=g,exports.$getEndOfCodeInLine=E,exports.$getFirstCodeNodeOfLine=y,exports.$getLastCodeNodeOfLine=L,exports.$getStartOfCodeInLine=b,exports.$isCodeHighlightNode=$,exports.$isCodeNode=u,exports.CODE_LANGUAGE_FRIENDLY_NAME_MAP=T,exports.CODE_LANGUAGE_MAP=_,exports.CodeHighlightNode=O,exports.CodeNode=l,exports.DEFAULT_CODE_LANGUAGE=m,exports.PrismTokenizer=A,exports.getCodeLanguages=()=>Object.keys(r.languages).filter((e=>"function"!=typeof r.languages[e])).sort(),exports.getDefaultCodeLanguage=()=>m,exports.getEndOfCodeInLine=K,exports.getFirstCodeNodeOfLine=W,exports.getLanguageFriendlyName=function(e){const t=C(e);return T[t]||t},exports.getLastCodeNodeOfLine=F,exports.getStartOfCodeInLine=z,exports.normalizeCodeLang=C,exports.registerCodeHighlighting=function(r,o){if(!r.hasNodes([l,O]))throw new Error("CodeHighlightPlugin: CodeNode or CodeHighlightNode not registered on editor");return null==o&&(o=A),e.mergeRegister(r.registerMutationListener(l,(e=>{r.update((()=>{for(const[n,o]of e)if("destroyed"!==o){const e=t.$getNodeByKey(n);null!==e&&v(e,r)}}))}),{skipInitialization:!1}),r.registerNodeTransform(l,(e=>k(e,r,o))),r.registerNodeTransform(t.TextNode,(e=>D(e,r,o))),r.registerNodeTransform(O,(e=>D(e,r,o))),r.registerCommand(t.KEY_TAB_COMMAND,(e=>{const o=function(e){const r=t.$getSelection();if(!t.$isRangeSelection(r)||!I(r))return null;const o=e?t.OUTDENT_CONTENT_COMMAND:t.INDENT_CONTENT_COMMAND,i=e?t.OUTDENT_CONTENT_COMMAND:t.INSERT_TAB_COMMAND;if(j(r).length>1)return o;const s=r.getNodes()[0];if(u(s)||$(s)||t.$isTabNode(s)||t.$isLineBreakNode(s)||n(170),u(s))return o;const a=y(s),l=L(s),g=r.anchor,c=r.focus;let d,p;return c.isBefore(g)?(d=c,p=g):(d=g,p=c),null!==a&&null!==l&&d.key===a.getKey()&&0===d.offset&&p.key===l.getKey()&&p.offset===l.getTextContentSize()?o:i}(e.shiftKey);return null!==o&&(e.preventDefault(),r.dispatchCommand(o,void 0),!0)}),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.INSERT_TAB_COMMAND,(()=>!!I(t.$getSelection())&&(t.$insertNodes([t.$createTabNode()]),!0)),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.INDENT_CONTENT_COMMAND,(e=>w(t.INDENT_CONTENT_COMMAND)),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.OUTDENT_CONTENT_COMMAND,(e=>w(t.OUTDENT_CONTENT_COMMAND)),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.KEY_ARROW_UP_COMMAND,(e=>{const n=t.$getSelection();if(!t.$isRangeSelection(n))return!1;const{anchor:r}=n,o=r.getNode();return!!I(n)&&(n.isCollapsed()&&0===r.offset&&null===o.getPreviousSibling()&&u(o.getParentOrThrow())?(e.preventDefault(),!0):H(t.KEY_ARROW_UP_COMMAND,e))}),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.KEY_ARROW_DOWN_COMMAND,(e=>{const n=t.$getSelection();if(!t.$isRangeSelection(n))return!1;const{anchor:r}=n,o=r.getNode();return!!I(n)&&(n.isCollapsed()&&r.offset===o.getTextContentSize()&&null===o.getNextSibling()&&u(o.getParentOrThrow())?(e.preventDefault(),!0):H(t.KEY_ARROW_DOWN_COMMAND,e))}),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.MOVE_TO_START,(e=>q(t.MOVE_TO_START,e)),t.COMMAND_PRIORITY_LOW),r.registerCommand(t.MOVE_TO_END,(e=>q(t.MOVE_TO_END,e)),t.COMMAND_PRIORITY_LOW))};