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