@lexical/devtools-core
Version:
This package contains tools necessary to debug and develop Lexical.
10 lines (8 loc) • 9.32 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/html"),t=require("@lexical/link"),n=require("@lexical/mark"),r=require("@lexical/table"),o=require("lexical"),s=require("react"),i=require("react/jsx-runtime");const l=Object.freeze({"\t":"\\t","\n":"\\n"}),a=new RegExp(Object.keys(l).join("|"),"g"),c=Object.freeze({ancestorHasNextSibling:"|",ancestorIsLastChild:" ",hasNextSibling:"├",isLastChild:"└",selectedChar:"^",selectedLine:">"}),u=[e=>e.hasFormat("bold")&&"Bold",e=>e.hasFormat("code")&&"Code",e=>e.hasFormat("italic")&&"Italic",e=>e.hasFormat("strikethrough")&&"Strikethrough",e=>e.hasFormat("subscript")&&"Subscript",e=>e.hasFormat("superscript")&&"Superscript",e=>e.hasFormat("underline")&&"Underline",e=>e.hasFormat("highlight")&&"Highlight"],f=[e=>e.hasTextFormat("bold")&&"Bold",e=>e.hasTextFormat("code")&&"Code",e=>e.hasTextFormat("italic")&&"Italic",e=>e.hasTextFormat("strikethrough")&&"Strikethrough",e=>e.hasTextFormat("subscript")&&"Subscript",e=>e.hasTextFormat("superscript")&&"Superscript",e=>e.hasTextFormat("underline")&&"Underline",e=>e.hasTextFormat("highlight")&&"Highlight"],d=[e=>e.isDirectionless()&&"Directionless",e=>e.isUnmergeable()&&"Unmergeable"],h=[e=>e.isToken()&&"Token",e=>e.isSegmented()&&"Segmented"];function g(e,t,n=[]){const r=e.getChildren(),s=r.length;r.forEach(((e,r)=>{t(e,n.concat(r===s-1?c.isLastChild:c.hasNextSibling)),o.$isElementNode(e)&&g(e,t,n.concat(r===s-1?c.ancestorIsLastChild:c.ancestorHasNextSibling))}))}function m(e,t=!1){const n=Object.entries(l).reduce(((e,[t,n])=>e.replace(new RegExp(t,"g"),String(n))),e);return t?n.replace(/[^\s]/g,"*"):n}function p(e){let t=d.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="detail: "+t),t}function y(e){let t=h.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="mode: "+t),t}function x(e){let t=u.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="format: "+t),t}function $(e){let t=e.getTarget();return null!=t&&(t="target: "+t),t}function S(e){let t=e.getRel();return null!=t&&(t="rel: "+t),t}function C(e){let t=e.getTitle();return null!=t&&(t="title: "+t),t}function N(e){if(!e.__state)return!1;const t=[];for(const[n,r]of e.__state.knownState.entries()){if(n.isEqual(r,n.defaultValue))continue;const e=JSON.stringify(n.unparse(r));t.push(`[${n.key}: ${e}]`)}let n=t.join(",");return""!==n&&(n="state: "+n),n}function b(e,t){const n=new Array(1+t++).join(" "),r=new Array(t-1).join(" ");let o;for(let s=0;s<e.children.length;s++)o=document.createTextNode("\n"+n),e.insertBefore(o,e.children[s]),b(e.children[s],t),e.lastElementChild===e.children[s]&&(o=document.createTextNode("\n"+r),e.appendChild(o));return e}const T=s.forwardRef((function({treeTypeButtonClassName:e,timeTravelButtonClassName:t,timeTravelPanelSliderClassName:n,timeTravelPanelButtonClassName:r,viewClassName:o,timeTravelPanelClassName:l,editorState:a,setEditorState:c,setEditorReadOnly:u,generateContent:f,commandsLog:d=[]},h){const[g,m]=s.useState([]),[p,y]=s.useState(""),[x,$]=s.useState(!1),[S,C]=s.useState(!1),N=s.useRef(0),b=s.useRef(null),[T,j]=s.useState(!1),[k,L]=s.useState(!1),[v,E]=s.useState(!1),R=s.useRef(),w=s.useRef([]),F=s.useRef(0),B=s.useCallback((e=>{const t=++F.current;f(e).then((e=>{t===F.current&&y(e)})).catch((e=>{t===F.current&&y(`Error rendering tree: ${e.message}\n\nStack:\n${e.stack}`)}))}),[f]);s.useEffect((()=>{if(!v&&a._nodeMap.size>1e3&&(L(!0),!v))return;if(R.current!==a||w.current!==d){const e=R.current!==a;R.current=a,w.current=d,B(S),!x&&e&&m((e=>[...e,[Date.now(),a]]))}}),[a,B,S,v,x,d]);const _=g.length;s.useEffect((()=>{if(T){let e;const t=()=>{const n=N.current;if(n===_-1)return void j(!1);const r=g[n][0],o=g[n+1][0];e=setTimeout((()=>{N.current++;const e=N.current,n=b.current;null!==n&&(n.value=String(e)),c(g[e][1]),t()}),o-r)};return t(),()=>{clearTimeout(e)}}}),[g,T,_,c]);return i.jsxs("div",{className:o,children:[!v&&k?i.jsxs("div",{style:{padding:20},children:[i.jsx("span",{style:{marginRight:20},children:"Detected large EditorState, this can impact debugging performance."}),i.jsx("button",{onClick:()=>{E(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5},children:"Show full tree"})]}):null,v?null:i.jsx("button",{onClick:()=>(B(!S),void C(!S)),className:e,type:"button",children:S?"Tree":"Export DOM"}),!x&&(v||!k)&&_>2&&i.jsx("button",{onClick:()=>{u(!0),N.current=_-1,$(!0)},className:t,type:"button",children:"Time Travel"}),(v||!k)&&i.jsx("pre",{ref:h,children:p}),x&&(v||!k)&&i.jsxs("div",{className:l,children:[i.jsx("button",{className:r,onClick:()=>{N.current===_-1&&(N.current=1),j(!T)},type:"button",children:T?"Pause":"Play"}),i.jsx("input",{className:n,ref:b,onChange:e=>{const t=Number(e.target.value),n=g[t];n&&(N.current=t,c(n[1]))},type:"range",min:"1",max:_-1}),i.jsx("button",{className:r,onClick:()=>{u(!1);const e=g.length-1,t=g[e];c(t[1]);const n=b.current;null!==n&&(n.value=String(e)),$(!1),j(!1)},type:"button",children:"Exit"})]})]})}));function j(e,t){const n=new Set;let r=0;for(const[s]of e._commands)n.add(e.registerCommand(s,(e=>(t((t=>{r+=1;const n=[...t];return n.push({index:r,payload:e,type:s.type?s.type:"UNKNOWN"}),n.length>10&&n.shift(),n})),!1)),o.COMMAND_PRIORITY_CRITICAL));return()=>n.forEach((e=>e()))}exports.TreeView=T,exports.generateContent=function(s,i,l,u,d=!1){const h=s.getEditorState(),T=s._config,j=s._compositionKey,k=s._editable;if(l){let t="";return h.read((()=>{t=function(e){const t=document.createElement("div");return t.innerHTML=e.trim(),b(t,0).innerHTML}(e.$generateHtmlFromNodes(s))})),t}let L=" root\n";const v=h.read((()=>{const e=o.$getSelection();return g(o.$getRoot(),((r,s)=>{const i=`(${r.getKey()})`,l=r.getType()||"",h=r.isSelected();L+=`${h?c.selectedLine:" "} ${s.join(" ")} ${i} ${l} ${function(e,r,s=!1){const i=r?r(e,s):void 0;if(void 0!==i&&i.length>0)return i;if(o.$isTextNode(e)){const t=e.getTextContent(),n=0===t.length?"(empty)":`"${m(t,s)}"`,r=function(e){return[x(e),p(e),y(e),N(e)].filter(Boolean).join(", ")}(e);return[n,0!==r.length?`{ ${r} }`:null].filter(Boolean).join(" ").trim()}if(t.$isLinkNode(e)){const t=e.getURL(),n=0===t.length?"(empty)":`"${m(t,s)}"`,r=function(e){return[$(e),S(e),C(e),N(e)].filter(Boolean).join(", ")}(e);return[n,0!==r.length?`{ ${r} }`:null].filter(Boolean).join(" ").trim()}if(n.$isMarkNode(e))return`ids: [ ${e.getIDs().join(", ")} ]`;if(o.$isParagraphNode(e)){const t=function(e){let t=f.map((t=>t(e))).filter(Boolean).join(", ").toLocaleLowerCase();""!==t&&(t="format: "+t);return t}(e);let n=""!==t?`{ ${t} }`:"";return n+=e.__style?`(${e.__style})`:"",n}return""}(r,u,d)}\n`,L+=function({indent:e,isSelected:t,node:n,nodeKeyDisplay:r,selection:s,typeDisplay:i}){if(!o.$isTextNode(n)||!o.$isRangeSelection(s)||!t||o.$isElementNode(n))return"";const l=s.anchor,u=s.focus;if(""===n.getTextContent()||l.getNode()===s.focus.getNode()&&l.offset===u.offset)return"";const[f,d]=function(e,t){const n=t.getStartEndPoints();if(o.$isNodeSelection(t)||null===n)return[-1,-1];const[r,s]=n,i=e.getTextContent(),l=i.length;let c=-1,u=-1;if("text"===r.type&&"text"===s.type){const t=r.getNode(),n=s.getNode();t===n&&e===t&&r.offset!==s.offset?[c,u]=r.offset<s.offset?[r.offset,s.offset]:[s.offset,r.offset]:[c,u]=e===t?t.isBefore(n)?[r.offset,l]:[0,r.offset]:e===n?n.isBefore(t)?[s.offset,l]:[0,s.offset]:[0,l]}const f=(i.slice(0,c).match(a)||[]).length,d=(i.slice(c,u).match(a)||[]).length;return[c+f,u+f+d]}(n,s);if(f===d)return"";const h=e[e.length-1]===c.hasNextSibling?c.ancestorHasNextSibling:c.ancestorIsLastChild,g=[...e.slice(0,e.length-1),h],m=Array(f+1).fill(" "),p=Array(d-f).fill(c.selectedChar),y=i.length+2,x=Array(r.length+y).fill(" ");return[c.selectedLine,g.join(" "),[...x,...m,...p].join("")].join(" ")+"\n"}({indent:s,isSelected:h,node:r,nodeKeyDisplay:i,selection:e,typeDisplay:l})})),null===e?": null":o.$isRangeSelection(e)?function(e){let t="";const n=x(e);t+=`: range ${""!==n?`{ ${n} }`:""} ${""!==e.style?`{ style: ${e.style} } `:""}`;const r=e.anchor,o=e.focus,s=r.offset,i=o.offset;return t+=`\n ├ anchor { key: ${r.key}, offset: ${null===s?"null":s}, type: ${r.type} }`,t+=`\n └ focus { key: ${o.key}, offset: ${null===i?"null":i}, type: ${o.type} }`,t}(e):r.$isTableSelection(e)?function(e){return`: table\n └ { table: ${e.tableKey}, anchorCell: ${e.anchor.key}, focusCell: ${e.focus.key} }`}(e):function(e){if(!o.$isNodeSelection(e))return"";return`: node\n └ [${Array.from(e._nodes).join(", ")}]`}(e)}));if(L+="\n selection"+v,L+="\n\n commands:",i.length)for(const{index:e,type:t,payload:n}of i)L+=`\n └ ${e}. { type: ${t}, payload: ${n instanceof Event?n.constructor.name:n} }`;else L+="\n └ None dispatched.";const{version:E}=s.constructor;return L+=`\n\n editor${E?` (v${E})`:""}:`,L+=`\n └ namespace ${T.namespace}`,null!==j&&(L+=`\n └ compositionKey ${j}`),L+=`\n └ editable ${String(k)}`,L},exports.registerLexicalCommandLogger=j,exports.useLexicalCommandsLog=function(e){const[t,n]=s.useState([]);return s.useEffect((()=>j(e,n)),[e]),s.useMemo((()=>t),[t])};