UNPKG

md-editor-rt

Version:

Markdown editor for react, developed in jsx and typescript, dark theme、beautify content by prettier、render articles directly、paste or clip the picture and upload it...

2 lines (1 loc) 8.35 kB
"use strict";const y=require("react/jsx-runtime"),d=require("react"),q=require("./config.cjs"),A=require("./event-bus.cjs"),_=require("./index2.cjs"),W=require("@vavt/util"),J=`.${q.prefix}-preview > [data-line]`,P=(t,e)=>+getComputedStyle(t).getPropertyValue(e).replace("px",""),K=(t,e)=>{const L=W.debounce(()=>{t.removeEventListener("scroll",r),t.addEventListener("scroll",r),e.removeEventListener("scroll",r),e.addEventListener("scroll",r)},50),r=$=>{const C=t.clientHeight,H=e.clientHeight,g=t.scrollHeight,i=e.scrollHeight,v=(g-C)/(i-H);$.target===t?(e.removeEventListener("scroll",r),e.scrollTo({top:t.scrollTop/v}),L()):(t.removeEventListener("scroll",r),t.scrollTo({top:e.scrollTop*v}),L())};return[()=>{L().finally(()=>{t.dispatchEvent(new Event("scroll"))})},()=>{t.removeEventListener("scroll",r),e.removeEventListener("scroll",r)}]},Q=(t,e,L)=>{const{view:r}=L,$=W.createSmoothScroll(),C=c=>r.lineBlockAt(r.state.doc.line(c+1).from).top,H=c=>r.lineBlockAt(r.state.doc.line(c+1).from).bottom;let g=[],i=[],v=[];const w=()=>{g=[],i=Array.from(e.querySelectorAll(J)),v=i.map(a=>Number(a.dataset.line));const c=[...v],{lines:p}=r.state.doc;let E=c.shift()||0,s=c.shift()||p;for(let a=0;a<p;a++)a===s&&(E=a,s=c.shift()||p),g.push({start:E,end:s-1})},O=(c,p)=>{let E=1;for(let s=i.length-1;s-1>=0;s--){const a=i[s],f=i[s-1];if(a.offsetTop+a.offsetHeight>p&&f.offsetTop<p){E=Number(f.dataset.line);break}}for(let s=g.length-1;s>=0;s--){const a=H(g[s].end),f=C(g[s].start);if(a>c&&f<=c){E=E<g[s].start?E:g[s].start;break}}return E};let S=0,D=0;const B=()=>{if(D!==0)return!1;S++;const{scrollDOM:c,contentHeight:p}=r;let E=P(e,"padding-block-start");const s=r.lineBlockAtHeight(c.scrollTop),{number:a}=r.state.doc.lineAt(s.from),f=g[a-1];if(!f)return!1;let k=1;const M=e.querySelector(`[data-line="${f.start}"]`)||e.firstElementChild?.firstElementChild,l=e.querySelector(`[data-line="${f.end+1}"]`)||e.lastElementChild?.lastElementChild,h=c.scrollHeight-c.clientHeight,N=e.scrollHeight-e.clientHeight;let b=C(f.start),m=H(f.end),x=M.offsetTop,T=l.offsetTop-x;b===0&&(x=0,M===l?(E=0,m=p-c.offsetHeight,T=N):T=l.offsetTop),k=(c.scrollTop-b)/(m-b);const u=l==e.lastElementChild?.lastElementChild?l.offsetTop+l.clientHeight:l.offsetTop;if(m>=h||u>N){const o=O(h,N);b=C(o),k=(c.scrollTop-b)/(h-b);const I=e.querySelector(`[data-line="${o}"]`);b>0&&I&&(x=I.offsetTop),T=N-x+P(e,"padding-block-start")}const n=x-E+T*k;$(e,n,()=>{S--})},j=()=>{if(S!==0)return;D++;const{scrollDOM:c}=r,p=e.scrollTop,E=e.scrollHeight,s=c.scrollHeight-c.clientHeight,a=e.scrollHeight-e.clientHeight;let f=e.firstElementChild?.firstElementChild,k=e.firstElementChild?.lastElementChild;if(v.length>0){let u=Math.ceil(v[v.length-1]*(p/E)),n=v.findLastIndex(o=>o<=u);n=n===-1?0:n,u=v[n];for(let o=n;o>=0&&o<v.length;)if(i[o].offsetTop>p){if(o-1>=0){o--;continue}u=-1,n=o;break}else{if(o+1<v.length&&i[o+1].offsetTop<p){o++;continue}u=v[o],n=o;break}switch(n){case-1:{f=e.firstElementChild?.firstElementChild,k=i[n];break}case v.length-1:{f=i[n],k=e.firstElementChild?.lastElementChild;break}default:f=i[n],k=i[n+1===i.length?n:n+1]}}let M=f===e.firstElementChild?.firstElementChild?0:f.offsetTop-P(f,"margin-block-start"),l=k.offsetTop,h=0;const{start:N,end:b}=g[Number(f.dataset.line||0)];let m=C(N);const x=C(b+1===r.state.doc.lines?b:b+1);let T=0;if(x>s||k.offsetTop+k.offsetHeight>a){const u=O(s,a),n=e.querySelector(`[data-line="${u}"]`);M=n?n.offsetTop-P(n,"margin-block-start"):M,m=C(u),h=(p-M)/(a-M),T=s-m}else f===e.firstElementChild?.firstElementChild?(f===k&&(l=k.offsetTop+k.offsetHeight+ +getComputedStyle(k).marginBlockEnd.replace("px","")),T=x,h=Math.max(p/l,0)):(h=Math.max((p-M)/(l-M),0),T=x-m);$(t,m+T*h,()=>{D--})},R=c=>{const{scrollDOM:p,contentHeight:E}=r,s=p.clientHeight;if(E<=s||e.firstElementChild.clientHeight<=e.clientHeight||r.state.doc.lines<=g[g.length-1]?.end)return!1;c.target===t?B():j()};return[()=>{w(),t.addEventListener("scroll",R),e.addEventListener("scroll",R),t.dispatchEvent(new Event("scroll"))},()=>{t.removeEventListener("scroll",R),e.removeEventListener("scroll",R)}]},F=d.createContext({scrollElementRef:void 0,rootNodeRef:void 0}),U=({tocItem:t,mdHeadingId:e,onActive:L,onClick:r,scrollElementOffsetTop:$=0})=>{const{scrollElementRef:C,rootNodeRef:H}=d.useContext(F),g=d.useRef(null);return d.useEffect(()=>{t.active&&L(t,g.current)},[L,t,t.active]),y.jsxs("div",{ref:g,className:_.classnames([`${q.prefix}-catalog-link`,t.active&&`${q.prefix}-catalog-active`]),onClick:i=>{if(i.stopPropagation(),r?.(i,t),i.defaultPrevented)return;const v=e({text:t.text,level:t.level,index:t.index,currentToken:t.currentToken,nextToken:t.nextToken}),w=H?.current.getElementById(v),O=C?.current;if(w&&O){let S=w.offsetParent,D=w.offsetTop;if(O.contains(S))for(;S&&O!=S;)D+=S?.offsetTop,S=S?.offsetParent;const B=w.previousElementSibling;let j=0;B||(j=P(w,"margin-block-start")),O?.scrollTo({top:D-$-j,behavior:"smooth"})}},children:[y.jsx("span",{title:t.text,children:t.text}),t.children&&t.children.length>0&&y.jsx("div",{className:`${q.prefix}-catalog-wrapper`,children:t.children.map(i=>y.jsx(U,{mdHeadingId:e,tocItem:i,onActive:L,onClick:r,scrollElementOffsetTop:$},`${t.text}-link-${i.level}-${i.text}`))})]})},X=d.memo(U),Y=t=>{const{editorId:e,mdHeadingId:L=q.defaultProps.mdHeadingId,theme:r="light",offsetTop:$=20,syncWith:C="preview",catalogMaxDepth:H}=t,g=d.useMemo(()=>`#${e}-preview-wrapper`,[e]),[i,v]=d.useState([]),[w,O]=d.useState(),S=d.useRef(null),D=d.useRef(null),B=d.useRef(void 0),j=d.useRef(null),[R,c]=d.useState(),[p,E]=d.useState({}),s=d.useMemo(()=>{const l=[];return i.forEach((h,N)=>{if(H&&h.level>H)return;const{text:b,level:m,line:x}=h,T={level:m,text:b,line:x,index:N+1,active:w===h};if(l.length===0)l.push(T);else{let u=l[l.length-1];if(T.level>u.level)for(let n=u.level+1;n<=6;n++){const{children:o}=u;if(!o){u.children=[T];break}if(u=o[o.length-1],T.level<=u.level){o.push(T);break}}else l.push(T)}}),l},[w,i,H]),[a]=d.useState(()=>t.scrollElement||`#${e}-preview-wrapper`),f=d.useCallback(()=>{if(a instanceof HTMLElement)return a;let l=document;return(a===g||t.isScrollElementInShadow)&&(l=S.current?.getRootNode()),l.querySelector(a)},[g,t.isScrollElementInShadow,a]),k=d.useCallback((l,h)=>{E({top:h.offsetTop+P(h,"padding-block-start")+"px"}),t.onActive?.(l,h)},[t]);d.useEffect(()=>{j.current=S.current.getRootNode()},[]),d.useEffect(()=>{let l=[];const h=m=>{if(m.length===0)return O(void 0),v([]),l=m,!1;const{activeHead:x,activeIndex:T}=m.reduce((n,o,I)=>{let G=0;if(C==="preview"){const V=j.current?.getElementById(L({text:o.text,level:o.level,index:I+1,currentToken:o.currentToken,nextToken:o.nextToken}));V instanceof HTMLElement&&(G=_.getRelativeTop(V,D.current))}else if(R){const V=R.lineBlockAt(R.state.doc.line(o.line+1).from).top,z=R.scrollDOM.scrollTop;G=V-z}return G<$&&G>n.minTop?{activeHead:o,activeIndex:I,minTop:G}:n},{activeHead:m[0],activeIndex:0,minTop:Number.MIN_SAFE_INTEGER});let u=x;if(H&&u.level>H){for(let n=T;n>=0;n--){const o=m[n];if(o.level<=H){u=o;break}}if(u.level>H){const n=m.find(o=>o.level<=H);n&&(u=n)}}O(u),v(m),l=m},N=()=>{h(l)},b=m=>{if(B.current?.removeEventListener("scroll",N),C==="editor")B.current=R?.scrollDOM;else{const x=f();D.current=x,B.current=x===document.documentElement?document:x}h(m),B.current?.addEventListener("scroll",N)};return A.bus.on(e,{name:A.CATALOG_CHANGED,callback:b}),A.bus.emit(e,A.PUSH_CATALOG),()=>{A.bus.remove(e,A.CATALOG_CHANGED,b),B.current?.removeEventListener("scroll",N)}},[$,L,f,e,C,R,H]);const M=d.useMemo(()=>({scrollElementRef:D,rootNodeRef:j}),[]);return d.useEffect(()=>{const l=h=>{c(h)};return A.bus.on(e,{name:A.GET_EDITOR_VIEW,callback:l}),A.bus.emit(e,A.SEND_EDITOR_VIEW),()=>{A.bus.remove(e,A.GET_EDITOR_VIEW,l)}},[e]),y.jsx(F.Provider,{value:M,children:y.jsx("div",{className:_.classnames([`${q.prefix}-catalog`,r==="dark"&&`${q.prefix}-catalog-dark`,t.className||""]),style:t.style,ref:S,children:s.length>0&&y.jsxs(y.Fragment,{children:[y.jsx("div",{className:`${q.prefix}-catalog-indicator`,style:p}),y.jsx("div",{className:`${q.prefix}-catalog-container`,children:s.map(l=>y.jsx(X,{mdHeadingId:L,tocItem:l,onActive:k,onClick:t.onClick,scrollElementOffsetTop:t.scrollElementOffsetTop},`link-${l.level}-${l.text}`))})]})})})},Z=d.memo(Y);exports.MdCatalog=Z;exports.scrollAuto=Q;exports.scrollAutoWithScale=K;