UNPKG

@lexical/devtools-core

Version:

This package contains tools necessary to debug and develop Lexical.

11 lines (9 loc) • 10.1 kB
/** * 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{$generateHtmlFromNodes as e}from"@lexical/html";import{$isLinkNode as t}from"@lexical/link";import{$isMarkNode as n}from"@lexical/mark";import{$isTableSelection as o}from"@lexical/table";import{$getSelection as r,$getRoot as i,$isRangeSelection as l,$getSlotNameWithinHost as s,$getSlotHost as c,$isNodeSelection as a,$getSlotNames as u,$getSlot as f,$isElementNode as d,$isDecoratorNode as h,$isTextNode as m,$isParagraphNode as g,COMMAND_PRIORITY_CRITICAL as p}from"lexical";import{forwardRef as y,useState as $,useRef as b,useCallback as x,useEffect as C}from"react";import{jsxs as N,jsx as S}from"react/jsx-runtime";const T=Object.freeze({"\t":"\\t","\n":"\\n"}),k=new RegExp(Object.keys(T).join("|"),"g"),j=Object.freeze({ancestorHasNextSibling:"|",ancestorIsLastChild:" ",hasNextSibling:"\u251c",isLastChild:"\u2514",selectedChar:"^",selectedLine:">"}),v=[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"],L=[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"],w=[e=>e.isDirectionless()&&"Directionless",e=>e.isUnmergeable()&&"Unmergeable"],B=[e=>e.isToken()&&"Token",e=>e.isSegmented()&&"Segmented"];function F(u,f,p,y,$=!1){const b=u.getEditorState(),x=u._config,C=u._compositionKey,N=u._editable;if(p){let t="";return b.read(()=>{t=function(e){const t=document.createElement("div");return t.innerHTML=e.trim(),A(t,0).innerHTML}(e(u))},{editor:u}),t}let S=" root\n";const T=b.read(()=>{const e=r();return E(i(),(o,r,i)=>{const s=`(${o.getKey()})`,c=o.getType()||"",u=o.isSelected(),f=void 0!==i?`[slot: ${i}] `:"",p=function(e,t){if(void 0===t)return"";if(d(e)&&e.isShadowRoot())return" [shadow-root]";if(h(e)&&!e.isInline())return" [atomic decorator]";return""}(o,i);S+=`${u?j.selectedLine:" "} ${r.join(" ")} ${s} ${f}${c}${p} ${function(e,o,r=!1){const i=o?o(e,r):void 0;if(void 0!==i&&i.length>0)return i;if(m(e)){const t=e.getTextContent(),n=0===t.length?"(empty)":`"${_(t,r)}"`,o=function(e){return[I(e),D(e),H(e),R(e)].filter(Boolean).join(", ")}(e);return[n,0!==o.length?`{ ${o} }`:null].filter(Boolean).join(" ").trim()}if(t(e)){const t=e.getURL(),n=0===t.length?"(empty)":`"${_(t,r)}"`,o=function(e){return[K(e),O(e),P(e),R(e)].filter(Boolean).join(", ")}(e);return[n,0!==o.length?`{ ${o} }`:null].filter(Boolean).join(" ").trim()}if(n(e))return`ids: [ ${e.getIDs().join(", ")} ]`;if(g(e)){const t=function(e){let t=L.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""}(o,y,$)}\n`,S+=function({indent:e,isSelected:t,node:n,nodeKeyDisplay:o,selection:r,typeDisplay:i}){if(!m(n)||!l(r)||!t||d(n))return"";const s=r.anchor,c=r.focus;if(""===n.getTextContent()||s.getNode()===r.focus.getNode()&&s.offset===c.offset)return"";const[u,f]=function(e,t){const n=t.getStartEndPoints();if(a(t)||null===n)return[-1,-1];const[o,r]=n,i=e.getTextContent(),l=i.length;let s=-1,c=-1;if("text"===o.type&&"text"===r.type){const t=o.getNode(),n=r.getNode();t===n&&e===t&&o.offset!==r.offset?[s,c]=o.offset<r.offset?[o.offset,r.offset]:[r.offset,o.offset]:[s,c]=e===t?t.isBefore(n)?[o.offset,l]:[0,o.offset]:e===n?n.isBefore(t)?[r.offset,l]:[0,r.offset]:[0,l]}const u=(i.slice(0,s).match(k)||[]).length,f=(i.slice(s,c).match(k)||[]).length;return[s+u,c+u+f]}(n,r);if(u===f)return"";const h=e[e.length-1]===j.hasNextSibling?j.ancestorHasNextSibling:j.ancestorIsLastChild,g=[...e.slice(0,e.length-1),h],p=Array(u+1).fill(" "),y=Array(f-u).fill(j.selectedChar),$=i.length+2,b=Array(o.length+$).fill(" ");return[j.selectedLine,g.join(" "),[...b,...p,...y].join("")].join(" ")+"\n"}({indent:r,isSelected:u,node:o,nodeKeyDisplay:s,selection:e,typeDisplay:c})}),null===e?": null":l(e)?function(e){let t="";const n=I(e),o=function(e){let t=e;for(;null!==t;){const e=s(t);if(null!==e){const n=c(t);if(null!==n)return{host:n,name:e}}t=t.getParent()??c(t)}return null}(e.anchor.getNode()),r=null!==o?` (in slot "${o.name}" of ${o.host.getType()} { key: ${o.host.getKey()} })`:"";t+=`: range${r} ${""!==n?`{ ${n} }`:""} ${""!==e.style?`{ style: ${e.style} } `:""}`;const i=e.anchor,l=e.focus,a=i.offset,u=l.offset;return t+=`\n \u251c anchor { key: ${i.key}, offset: ${null===a?"null":a}, type: ${i.type} }`,t+=`\n \u2514 focus { key: ${l.key}, offset: ${null===u?"null":u}, type: ${l.type} }`,t}(e):o(e)?function(e){return`: table\n \u2514 { table: ${e.tableKey}, anchorCell: ${e.anchor.key}, focusCell: ${e.focus.key} }`}(e):function(e){if(!a(e))return"";return`: node\n \u2514 [${Array.from(e._nodes).join(", ")}]`}(e)},{editor:u});if(S+="\n selection"+T,S+="\n\n commands:",f.length)for(const{index:e,type:t,payload:n}of f)S+=`\n \u2514 ${e}. { type: ${t}, payload: ${n instanceof Event?n.constructor.name:n} }`;else S+="\n \u2514 None dispatched.";const{version:v}=u.constructor;return S+=`\n\n editor${v?` (v${v})`:""}:`,S+=`\n \u2514 namespace ${x.namespace}`,null!==C&&(S+=`\n \u2514 compositionKey ${C}`),S+=`\n \u2514 editable ${String(N)}`,S}function E(e,t,n=[]){const o=[];for(const t of u(e)){const n=f(e,t);null!==n&&o.push([t,n])}const r=d(e)?e.getChildren():[],i=o.length+r.length;let l=0;for(const[e,r]of o){const o=l===i-1;t(r,n.concat(o?j.isLastChild:j.hasNextSibling),e),(d(r)||h(r))&&E(r,t,n.concat(o?j.ancestorIsLastChild:j.ancestorHasNextSibling)),l++}for(const e of r){const o=l===i-1;t(e,n.concat(o?j.isLastChild:j.hasNextSibling)),(d(e)||h(e))&&E(e,t,n.concat(o?j.ancestorIsLastChild:j.ancestorHasNextSibling)),l++}}function _(e,t=!1){const n=Object.entries(T).reduce((e,[t,n])=>e.replace(new RegExp(t,"g"),String(n)),e);return t?n.replace(/[^\s]/g,"*"):n}function D(e){let t=w.map(t=>t(e)).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="detail: "+t),t}function H(e){let t=B.map(t=>t(e)).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="mode: "+t),t}function I(e){let t=v.map(t=>t(e)).filter(Boolean).join(", ").toLocaleLowerCase();return""!==t&&(t="format: "+t),t}function K(e){let t=e.getTarget();return null!=t&&(t="target: "+t),t}function O(e){let t=e.getRel();return null!=t&&(t="rel: "+t),t}function P(e){let t=e.getTitle();return null!=t&&(t="title: "+t),t}function R(e){if(!e.__state)return!1;const t=[];for(const[n,o]of e.__state.knownState.entries()){if(n.isEqual(o,n.defaultValue))continue;const e=JSON.stringify(n.unparse(o));t.push(`[${n.key}: ${e}]`)}let n=t.join(",");return""!==n&&(n="state: "+n),n}function A(e,t){const n=new Array(1+t++).join(" "),o=new Array(t-1).join(" ");let r;for(let i=0;i<e.children.length;i++)r=document.createTextNode("\n"+n),e.insertBefore(r,e.children[i]),A(e.children[i],t),e.lastElementChild===e.children[i]&&(r=document.createTextNode("\n"+o),e.appendChild(r));return e}const U=/*#__PURE__*/y(function({treeTypeButtonClassName:e,timeTravelButtonClassName:t,timeTravelPanelSliderClassName:n,timeTravelPanelButtonClassName:o,viewClassName:r,timeTravelPanelClassName:i,editorState:l,setEditorState:s,setEditorReadOnly:c,generateContent:a,commandsLog:u=[]},f){const[d,h]=$([]),[m,g]=$(""),[p,y]=$(!1),[T,k]=$(!1),j=b(0),v=b(null),[L,w]=$(!1),[B,F]=$(!1),[E,_]=$(!1),D=b(null),H=b([]),I=b(0),K=x(e=>{const t=++I.current;a(e).then(e=>{t===I.current&&g(e)}).catch(e=>{t===I.current&&g(`Error rendering tree: ${e.message}\n\nStack:\n${e.stack}`)})},[a]);C(()=>{if(!E&&l._nodeMap.size>1e3&&(F(!0),!E))return;if(D.current!==l||H.current!==u){const e=D.current!==l;D.current=l,H.current=u,K(T),!p&&e&&h(e=>[...e,[Date.now(),l]])}},[l,K,T,E,p,u]);const O=d.length;C(()=>{if(L){let e;const t=()=>{const n=j.current;if(n===O-1)return void w(!1);const o=d[n][0],r=d[n+1][0];e=setTimeout(()=>{j.current++;const e=j.current,n=v.current;null!==n&&(n.value=String(e)),s(d[e][1]),t()},r-o)};return t(),()=>{clearTimeout(e)}}},[d,L,O,s]); return N("div",{className:r,children:[!E&&B?/*#__PURE__*/N("div",{style:{padding:20},children:[/*#__PURE__*/S("span",{style:{marginRight:20},children:"Detected large EditorState, this can impact debugging performance."}),/*#__PURE__*/S("button",{onClick:()=>{_(!0)},style:{background:"transparent",border:"1px solid white",color:"white",cursor:"pointer",padding:5},children:"Show full tree"})]}):null,E?null:/*#__PURE__*/S("button",{onClick:()=>(K(!T),void k(!T)),className:e,type:"button",children:T?"Tree":"Export DOM"}),!p&&(E||!B)&&O>2&&/*#__PURE__*/S("button",{onClick:()=>{c(!0),j.current=O-1,y(!0)},className:t,type:"button",children:"Time Travel"}),(E||!B)&&/*#__PURE__*/S("pre",{ref:f,children:m}),p&&(E||!B)&&/*#__PURE__*/N("div",{className:i,children:[/*#__PURE__*/S("button",{className:o,onClick:()=>{j.current===O-1&&(j.current=1),w(!L)},type:"button",children:L?"Pause":"Play"}),/*#__PURE__*/S("input",{className:n,ref:v,onChange:e=>{const t=Number(e.target.value),n=d[t];n&&(j.current=t,s(n[1]))},type:"range",min:"1",max:O-1}),/*#__PURE__*/S("button",{className:o,onClick:()=>{c(!1);const e=d.length-1,t=d[e];s(t[1]);const n=v.current;null!==n&&(n.value=String(e)),y(!1),w(!1)},type:"button",children:"Exit"})]})]})});function M(e,t){const n=[];let o=0;for(const r of e._commands.keys())n.push(e.registerCommand(r,e=>{o+=1;const n={index:o,payload:e,type:r.type?r.type:"UNKNOWN"};return t(e=>[...e.slice(-9),n]),!1},p));return()=>n.forEach(e=>e())}function z(e){const[t,n]=$([]);return C(()=>M(e,n),[e]),t}export{U as TreeView,F as generateContent,M as registerLexicalCommandLogger,z as useLexicalCommandsLog};