From e2f94b393fd9adaf591ae473890fe00689ca4851 Mon Sep 17 00:00:00 2001 From: Shane Friedman Date: Fri, 6 Sep 2024 16:57:04 -0400 Subject: [PATCH] Don't drop ref when merging html attrs in output spec --- docs/assets/{index-3279a106.js => index-f325ec79.js} | 2 +- docs/index.html | 2 +- src/components/OutputSpec.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename docs/assets/{index-3279a106.js => index-f325ec79.js} (99%) diff --git a/docs/assets/index-3279a106.js b/docs/assets/index-f325ec79.js similarity index 99% rename from docs/assets/index-3279a106.js rename to docs/assets/index-f325ec79.js index c4ec839..1a0e892 100644 --- a/docs/assets/index-3279a106.js +++ b/docs/assets/index-f325ec79.js @@ -50,4 +50,4 @@ Error generating stack: `+o.message+` Copyright (c) 2018 Jed Watson. Licensed under the MIT License (MIT), see http://jedwatson.github.io/classnames -*/(function(t){(function(){var e={}.hasOwnProperty;function n(){for(var r=[],i=0;i{var n;return((n=e[1])==null?void 0:n.toUpperCase())??""})}function YC(t){const e=new CSSStyleSheet;e.insertRule(`* { ${t} }`);const r=e.cssRules[0].style,i={};for(let o=0;o0&&(e.step=r);break}case"disabled":{e.disabled=r!=null;break}case"rows":{const i=parseInt(r,10);Number.isNaN(i)||(e.rows=r);break}default:{e[n]=r;break}}return e}const df=C.forwardRef(function({outputSpec:e,children:n,...r},i){if(typeof e=="string")return z(Ju,{children:e});if(!Array.isArray(e))throw new Error("@nytimes/react-prosemirror only supports strings and arrays in toDOM");const s=e[0].replace(" ",":"),l=e[1];let a={ref:i,...r},u=1;l&&typeof l=="object"&&l.nodeType==null&&!Array.isArray(l)&&(u=2,a=s0(l0(l),r));const c=[];for(let f=u;fu)throw new RangeError("Content hole must be the only child of its parent node");return C.createElement(s,a,n)}c.push(z(df,{ref:void 0,outputSpec:d,children:n}))}return C.createElement(s,a,...c)}),a0=C.forwardRef(function({mark:e,children:n},r){var a,u;const i=C.useContext(st),o=[],s=C.useRef(null);C.useImperativeHandle(r,()=>s.current,[]);const l=(u=(a=e.type.spec).toDOM)==null?void 0:u.call(a,e,!0);if(!l)throw new Error(`Mark spec for ${e.type.name} is missing toDOM`);return C.useLayoutEffect(()=>{if(!s.current)return;const c=o[0],f=new bC(void 0,o,e,s.current,(c==null?void 0:c.dom.parentElement)??s.current);i.push(f);for(const d of o)d.parent=f}),z(df,{ref:s,outputSpec:l,children:z(st.Provider,{value:o,children:n})})});function GC({widget:t,pos:e}){const n=C.useContext(st),r=C.useRef(null),i=C.useRef(e);return i.current=e,qy(o=>{if(!r.current)return;const s=t.type.toDOM;let l=typeof s=="function"?s(o,()=>i.current):s;if(!t.type.spec.raw){if(l.nodeType!=1){const a=document.createElement("span");a.appendChild(l),l=a}l.contentEditable="false",l.classList.add("ProseMirror-widget")}r.current.firstElementChild!==l&&r.current.replaceChildren(l)}),C.useLayoutEffect(()=>{if(!r.current)return;const o=new uf(void 0,t,r.current);n.push(o)}),z("span",{ref:r})}function u0({outerDeco:t,pos:e,node:n,innerDeco:r,...i}){var D,R;const o=C.useRef(null),s=C.useRef(null),l=C.useRef(null),a=C.useRef(n),u=C.useRef(t),c=C.useRef(r),f=C.useRef(e);f.current=e;const d=C.useRef(null),p=C.useRef(null),h=vl(),{nodeViews:m}=C.useContext(jy),{view:S}=C.useContext(vo);let g=null;const y=m[n.type.name],k=S==null?void 0:S.someProp("nodeViews",E=>E==null?void 0:E[n.type.name]);C.useLayoutEffect(()=>{if(!p.current||!d.current)return;const{dom:E}=p.current;return s.current=d.current,d.current.appendChild(E),()=>{var P,ne;(ne=(P=p.current)==null?void 0:P.destroy)==null||ne.call(P)}},[]),C.useLayoutEffect(()=>{if(!k||!p.current)return;const{destroy:E,update:P}=p.current;if(((P==null?void 0:P.call(p.current,n,t,r))??!0)||(E==null||E.call(p.current),!d.current))return;a.current=n,u.current=t,c.current=r,p.current=k(a.current,S,()=>f.current,u.current,c.current);const{dom:Rt}=p.current;s.current=d.current,d.current.appendChild(Rt)},[k,S,r,n,t]);const w=r0(n,o,s,r,t,void 0,l);if(y)g=z(y,{...i,ref:s,nodeProps:{node:n,pos:e,decorations:t,innerDecorations:r,isSelected:(h==null?void 0:h.selection)instanceof b&&h.selection.node===n},children:z(bi,{pos:e,node:n,innerDecorations:r})});else if(k){p.current||(p.current=k(a.current,S,()=>f.current,u.current,c.current));const{contentDOM:E}=p.current;l.current=E??null,g=C.createElement(n.isInline?"span":"div",{ref:d,contentEditable:!!E,suppressContentEditableWarning:!0},E&&Hr.createPortal(z(bi,{pos:e,node:n,innerDecorations:r}),E))}else{const E=(R=(D=n.type.spec).toDOM)==null?void 0:R.call(D,n);E&&(g=z(df,{...i,ref:s,outputSpec:E,children:z(bi,{pos:e,node:n,innerDecorations:r})}))}if(!g)throw new Error(`Node spec for ${n.type.name} is missing toDOM`);const M=C.cloneElement(t.reduce(hf,g),t.some(E=>E.type.attrs.nodeName)?{ref:o}:void 0),O=n.marks.reduce((E,P)=>z(a0,{mark:P,children:E}),M);return z(st.Provider,{value:w,children:C.cloneElement(O,n.marks.length||t.some(E=>E.type.attrs.nodeName)?{ref:o}:void 0)})}function XC(){const t=C.useContext(st),e=C.useRef(null),[n,r]=C.useState(!1);return C.useLayoutEffect(()=>{var s;const i=t[t.length-1];if((Ce.safari||Ce.chrome)&&((s=i==null?void 0:i.dom)==null?void 0:s.contentEditable)=="false"){r(!0);return}if(!e.current)return;const o=new ff(void 0,[],e.current,null);t.push(o)}),n?z("img",{ref:e,className:"ProseMirror-separator"}):null}class ZC extends C.Component{constructor(){super(...arguments),this.viewDescRef=null}updateEffect(){const{decorations:e,siblingDescriptors:n,node:r}=this.props,i=Hr.findDOMNode(this);if(!i)return;let o=i;for(;o.firstChild;)o=o.firstChild;!this.viewDescRef||this.viewDescRef instanceof zC?this.viewDescRef=new IC(void 0,[],r,e,U.empty,i,o):(this.viewDescRef.parent=void 0,this.viewDescRef.children=[],this.viewDescRef.node=r,this.viewDescRef.outerDeco=e,this.viewDescRef.innerDeco=U.empty,this.viewDescRef.dom=i,this.viewDescRef.dom.pmViewDesc=this.viewDescRef,this.viewDescRef.nodeDOM=o),n.push(this.viewDescRef)}componentDidMount(){this.updateEffect()}componentDidUpdate(){this.updateEffect()}render(){const{node:e,decorations:n}=this.props;return n.reduce(hf,e.text)}}function eN(){const t=C.useContext(st),e=C.useRef(null);return C.useLayoutEffect(()=>{if(!e.current)return;const n=new ff(void 0,[],e.current,null);t.push(n)}),z("br",{ref:e,className:"ProseMirror-trailingBreak"})}function tN({widget:t,pos:e}){const n=C.useContext(st),r=C.useRef(null);C.useLayoutEffect(()=>{if(!r.current)return;const o=new uf(void 0,t,r.current);n.push(o)});const{Component:i}=t.type;return i&&z(i,{ref:r,widget:t,pos:e,contentEditable:!1})}function hf(t,e){const{nodeName:n,...r}=e.type.attrs,i=l0(r);return n||typeof t=="string"?C.createElement(n??"span",i,t):C.cloneElement(t,s0(t.props,i))}function $u({innerPos:t,childViews:e}){const{view:n}=C.useContext(vo),r=vl(),i=i0(),o=e.reduce((s,l)=>{var c;const a=s[s.length-1];if(!a)return[[l]];const u=a[a.length-1];return u?!l.marks.length&&!u.marks.length||l.marks.length&&u.marks.length&&((c=l.marks[0])!=null&&c.eq(u.marks[0]))?[...s.slice(0,s.length-1),[...a.slice(0,a.length),l]]:[...s,[l]]:[...s.slice(0,s.length),[l]]},[]);return z(Ju,{children:o.map(s=>{const l=s[0];if(!l)return null;const a=l.marks[0];return a?z(a0,{mark:a,children:z($u,{innerPos:t,childViews:s.map(u=>({...u,marks:u.marks.slice(1)}))},zi(r==null?void 0:r.doc,t,l,i==null?void 0:i.posToKey))},zi(r==null?void 0:r.doc,t,l,i==null?void 0:i.posToKey)):s.map(u=>{const c=t+u.offset,f=u.type==="widget"?z(tN,{widget:u.widget,pos:c}):u.type==="native-widget"?z(GC,{widget:u.widget,pos:c}):u.node.isText?z(st.Consumer,{children:d=>z(ZC,{view:n,node:u.node,pos:c,siblingDescriptors:d,decorations:u.outerDeco})}):z(u0,{node:u.node,pos:c,outerDeco:u.outerDeco,innerDeco:u.innerDeco});return C.cloneElement(f,{key:zi(r==null?void 0:r.doc,t,u,i==null?void 0:i.posToKey)})})})})}function zi(t,e,n,r){const i=e+n.offset,o=r==null?void 0:r.get(i);if(n.type==="widget"||n.type==="native-widget")return n.widget.type.spec.key?n.widget.type.spec.key:(console.warn(`Widget at position ${i} doesn't have a key specified. This has negative performance implications.`),`${o}-${n.index}`);if(o)return o;if(!t)return i;const s=t.resolve(i).start()-1,l=r==null?void 0:r.get(s);return l?`${l}-${n.offset}`:i}function nN(t){const e=t[t.length-1];if((e==null?void 0:e.type)!=="widget"&&(e==null?void 0:e.type)!=="native-widget"||e.widget.type.side>=0)return;let n=null;for(let i=t.length-2;i>=0;i--){const o=t[i];if((o==null?void 0:o.type)==="node"){n=o;break}}if(!n||!n.node.isInline)return;const r=n.marks;e.marks=e.marks.reduce((i,o)=>o.addToSet(i),r)}function rN(t){const e=t[t.length-1];if((e==null?void 0:e.type)!=="node"||!e.node.isInline)return;const n=e.marks;for(let r=t.length-2;r>=0;r--){const i=t[r];if((i==null?void 0:i.type)!=="widget"&&(i==null?void 0:i.type)!=="native-widget"||i.widget.type.side<0)break;i.marks=i.marks.reduce((o,s)=>s.addToSet(o),n)}}function iN(t,e,n,r){return t.length?t.every(i=>i.type!=="node"||i.node.isInline)?[z($u,{childViews:t,innerPos:e},zi(n,e,t[0],r))]:t.map(i=>{if(i.type==="node"){const o=e+i.offset,s=(r==null?void 0:r.get(o))??o;return z(u0,{outerDeco:i.outerDeco,node:i.node,innerDeco:i.innerDeco,pos:o},s)}else return z($u,{childViews:[i],innerPos:e},zi(n,e,i,r))}):[]}function bi({pos:t,node:e,innerDecorations:n}){const r=vl(),i=i0();if(!e)return null;const o=t+1,s=[];JC(e,n,(u,c,f,d)=>{const p=u.type.spec.marks??[];c?s.push({type:"native-widget",widget:u,marks:p,offset:f,index:d}):s.push({type:"widget",widget:u,marks:p,offset:f,index:d}),nN(s)},(u,c,f,d)=>{s.push({type:"node",node:u,marks:u.marks,innerDeco:f,outerDeco:c,offset:d}),rN(s)});const l=iN(s,o,r==null?void 0:r.doc,i==null?void 0:i.posToKey),a=s[s.length-1];return(!a||a.type!=="node"||a.node.isInline&&!a.node.isText||/\n$/.test(a.node.text))&&l.push(z(XC,{},"trailing-hack-img"),z(eN,{},"trailing-hack-br")),z(Ju,{children:l})}const oN=C.forwardRef(function({className:e,node:n,innerDeco:r,outerDeco:i,as:o,viewDesc:s},l){const a=C.useRef(null);C.useImperativeHandle(l,()=>a.current,[]);const u=r0(n,a,a,r,i,s),c={ref:a,className:e,suppressContentEditableWarning:!0},f=o?C.cloneElement(o,c,z(st.Provider,{value:u,children:z(bi,{pos:-1,node:n,innerDecorations:r})})):C.createElement("div",c,z(st.Provider,{value:u,children:z(bi,{pos:-1,node:n,innerDecorations:r})}));if(!n)return f;const d=i.filter(h=>!h.inline);return d.length?d.reduce(hf,f):f}),c0=C.createContext(null);function sN({as:t},e){const n=C.useRef(null),{setMount:r,...i}=C.useContext(c0);return C.useImperativeHandle(e,()=>n.current,[]),z(st.Provider,{value:[],children:z(oN,{ref:o=>{n.current=o,r(o)},...i,as:t})})}const lN=C.forwardRef(sN);function aN({className:t,children:e,nodeViews:n={},customNodeViews:r,...i}){var c;const[o,s]=C.useState(null),l=WC(o,{...i,nodeViews:r});UC(l.view);const a=l.view?iC(l.view,l.cursorWrapper):U.empty,u=l.view?eC(l.view):[];return z(jC,{children:z(vo.Provider,{value:l,children:z(jy.Provider,{value:{nodeViews:n},children:z(c0.Provider,{value:{className:t,setMount:s,node:(c=l.view)==null?void 0:c.state.doc,innerDeco:a,outerDeco:u,viewDesc:l.docViewDescRef.current},children:e})})})})}const _=new yp({nodes:{doc:{content:"block+"},paragraph:{group:"block",content:"inline*",toDOM(){return["p",0]}},...Sw({cellContent:"inline*",cellAttributes:{},tableGroup:"block"}),footnote:{group:"inline",content:"text*",inline:!0,atom:!0,attrs:{number:{default:0}}},list:{group:"block",content:"list_item+",toDOM(){return["ul",0]}},list_item:{content:"paragraph+",toDOM(){return["li",0]}},image:{group:"block",toDOM(){return["div",["img",{src:"https://smoores.gitlab.io/storyteller/img/Storyteller_Logo.png",height:150,width:150}]]}},text:{group:"inline"}},marks:{em:{toDOM(){return["em",0]}},strong:{toDOM(){return["strong",0]}}}}),uN=on.create({schema:_,doc:_.nodes.doc.create({},[_.nodes.paragraph.create({},[_.text("This ",[_.marks.em.create()]),_.text("is",[_.marks.em.create(),_.marks.strong.create()]),_.text(" the first paragraph")]),_.nodes.paragraph.create({},[_.text("This is the second paragraph"),_.nodes.footnote.create({number:1},_.text("Footnote"))]),_.nodes.paragraph.create(),_.nodes.image.create(),_.nodes.image.create(),_.nodes.paragraph.create({},_.text("This is the third paragraph 🫵")),_.nodes.table.create({},[_.nodes.table_row.create({},[_.nodes.table_header.create({},_.text("h1")),_.nodes.table_header.create({},_.text("h2"))]),_.nodes.table_row.create({},[_.nodes.table_cell.create({},_.text("c1")),_.nodes.table_cell.create({},_.text("c2"))])])]),plugins:[hC(),_S({rules:[WS(/^\s*([-+*])\s$/,_.nodes.list)]}),Bw(),Yw()]}),cN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("p",{ref:i,...r,children:e})}),fN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("ul",{ref:i,...r,children:e})}),dN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("li",{ref:i,...r,children:e})}),hN=C.forwardRef(function({nodeProps:e,...n},r){return z("span",{ref:r,...n,suppressContentEditableWarning:!0,contentEditable:"false",children:z("button",{children:e.node.attrs.number})})}),pN=C.forwardRef(function({widget:e,pos:n,...r},i){return z("span",{...r,ref:i,style:{display:"block",backgroundColor:"blue",width:"4px",height:"4px",position:"absolute",transform:"translateX(-2px)"},children:"Widget"})}),mN=new Tt({view(t){const e=t.coordsAtPos(t.state.selection.from),n=document.createElement("div");return n.style.width="4px",n.style.height="4px",n.style.position="absolute",n.style.top=`${e.top-2}px`,n.style.left=`${e.left-2}px`,n.style.backgroundColor="blue",document.body.appendChild(n),{update(r){const i=r.coordsAtPos(r.state.selection.from);n.style.top=`${i.top-2}px`,n.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(n)}}}});new Tt({props:{decorations(t){return U.create(t.doc,[Qy(t.selection.from,pN,{side:0,key:"widget-plugin-widget"})])}},view(t){const e=t.coordsAtPos(t.state.selection.from),n=document.createElement("div");return n.style.width="4px",n.style.height="4px",n.style.position="absolute",n.style.top=`${e.top-2}px`,n.style.left=`${e.left-2}px`,n.style.backgroundColor="blue",document.body.appendChild(n),{update(r){const i=r.coordsAtPos(r.state.selection.from);n.style.top=`${i.top-2}px`,n.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(n)}}}});const gN=[JS({...Q1,"Mod-i":If(_.marks.em),"Mod-b":If(_.marks.strong)}),mN,bS()],yN={paragraph:()=>{const t=document.createElement("p");return{dom:t,contentDOM:t}}};function kN(){const[t,e]=C.useState(uN),[n,r]=C.useState(!0);return kf("main",{children:[z("h1",{children:"React ProseMirror Demo"}),kf("button",{onClick:()=>{n?r(i=>!i):window.location.reload()},children:["Switch to"," ",n?"ProseMirror node views":"React node views (requires reload)"]}),z(aN,{className:"ProseMirror",state:t,dispatchTransaction:function(i){e(o=>o.apply(i))},plugins:gN,nodeViews:n?{paragraph:cN,list:fN,list_item:dN,footnote:hN}:void 0,customNodeViews:n?void 0:yN,children:z(lN,{as:z("article",{})})},`${n}`)]})}const SN=Uy(document.getElementById("root"));SN.render(z(kN,{})); +*/(function(t){(function(){var e={}.hasOwnProperty;function n(){for(var r=[],i=0;i{var n;return((n=e[1])==null?void 0:n.toUpperCase())??""})}function YC(t){const e=new CSSStyleSheet;e.insertRule(`* { ${t} }`);const r=e.cssRules[0].style,i={};for(let o=0;o0&&(e.step=r);break}case"disabled":{e.disabled=r!=null;break}case"rows":{const i=parseInt(r,10);Number.isNaN(i)||(e.rows=r);break}default:{e[n]=r;break}}return e}const df=C.forwardRef(function({outputSpec:e,children:n,...r},i){if(typeof e=="string")return z(Ju,{children:e});if(!Array.isArray(e))throw new Error("@nytimes/react-prosemirror only supports strings and arrays in toDOM");const s=e[0].replace(" ",":"),l=e[1];let a={ref:i,...r},u=1;l&&typeof l=="object"&&l.nodeType==null&&!Array.isArray(l)&&(u=2,a=s0(l0(l),a));const c=[];for(let f=u;fu)throw new RangeError("Content hole must be the only child of its parent node");return C.createElement(s,a,n)}c.push(z(df,{ref:void 0,outputSpec:d,children:n}))}return C.createElement(s,a,...c)}),a0=C.forwardRef(function({mark:e,children:n},r){var a,u;const i=C.useContext(st),o=[],s=C.useRef(null);C.useImperativeHandle(r,()=>s.current,[]);const l=(u=(a=e.type.spec).toDOM)==null?void 0:u.call(a,e,!0);if(!l)throw new Error(`Mark spec for ${e.type.name} is missing toDOM`);return C.useLayoutEffect(()=>{if(!s.current)return;const c=o[0],f=new bC(void 0,o,e,s.current,(c==null?void 0:c.dom.parentElement)??s.current);i.push(f);for(const d of o)d.parent=f}),z(df,{ref:s,outputSpec:l,children:z(st.Provider,{value:o,children:n})})});function GC({widget:t,pos:e}){const n=C.useContext(st),r=C.useRef(null),i=C.useRef(e);return i.current=e,qy(o=>{if(!r.current)return;const s=t.type.toDOM;let l=typeof s=="function"?s(o,()=>i.current):s;if(!t.type.spec.raw){if(l.nodeType!=1){const a=document.createElement("span");a.appendChild(l),l=a}l.contentEditable="false",l.classList.add("ProseMirror-widget")}r.current.firstElementChild!==l&&r.current.replaceChildren(l)}),C.useLayoutEffect(()=>{if(!r.current)return;const o=new uf(void 0,t,r.current);n.push(o)}),z("span",{ref:r})}function u0({outerDeco:t,pos:e,node:n,innerDeco:r,...i}){var D,R;const o=C.useRef(null),s=C.useRef(null),l=C.useRef(null),a=C.useRef(n),u=C.useRef(t),c=C.useRef(r),f=C.useRef(e);f.current=e;const d=C.useRef(null),p=C.useRef(null),h=vl(),{nodeViews:m}=C.useContext(jy),{view:S}=C.useContext(vo);let g=null;const y=m[n.type.name],k=S==null?void 0:S.someProp("nodeViews",E=>E==null?void 0:E[n.type.name]);C.useLayoutEffect(()=>{if(!p.current||!d.current)return;const{dom:E}=p.current;return s.current=d.current,d.current.appendChild(E),()=>{var P,ne;(ne=(P=p.current)==null?void 0:P.destroy)==null||ne.call(P)}},[]),C.useLayoutEffect(()=>{if(!k||!p.current)return;const{destroy:E,update:P}=p.current;if(((P==null?void 0:P.call(p.current,n,t,r))??!0)||(E==null||E.call(p.current),!d.current))return;a.current=n,u.current=t,c.current=r,p.current=k(a.current,S,()=>f.current,u.current,c.current);const{dom:Rt}=p.current;s.current=d.current,d.current.appendChild(Rt)},[k,S,r,n,t]);const w=r0(n,o,s,r,t,void 0,l);if(y)g=z(y,{...i,ref:s,nodeProps:{node:n,pos:e,decorations:t,innerDecorations:r,isSelected:(h==null?void 0:h.selection)instanceof b&&h.selection.node===n},children:z(bi,{pos:e,node:n,innerDecorations:r})});else if(k){p.current||(p.current=k(a.current,S,()=>f.current,u.current,c.current));const{contentDOM:E}=p.current;l.current=E??null,g=C.createElement(n.isInline?"span":"div",{ref:d,contentEditable:!!E,suppressContentEditableWarning:!0},E&&Hr.createPortal(z(bi,{pos:e,node:n,innerDecorations:r}),E))}else{const E=(R=(D=n.type.spec).toDOM)==null?void 0:R.call(D,n);E&&(g=z(df,{...i,ref:s,outputSpec:E,children:z(bi,{pos:e,node:n,innerDecorations:r})}))}if(!g)throw new Error(`Node spec for ${n.type.name} is missing toDOM`);const M=C.cloneElement(t.reduce(hf,g),t.some(E=>E.type.attrs.nodeName)?{ref:o}:void 0),O=n.marks.reduce((E,P)=>z(a0,{mark:P,children:E}),M);return z(st.Provider,{value:w,children:C.cloneElement(O,n.marks.length||t.some(E=>E.type.attrs.nodeName)?{ref:o}:void 0)})}function XC(){const t=C.useContext(st),e=C.useRef(null),[n,r]=C.useState(!1);return C.useLayoutEffect(()=>{var s;const i=t[t.length-1];if((Ce.safari||Ce.chrome)&&((s=i==null?void 0:i.dom)==null?void 0:s.contentEditable)=="false"){r(!0);return}if(!e.current)return;const o=new ff(void 0,[],e.current,null);t.push(o)}),n?z("img",{ref:e,className:"ProseMirror-separator"}):null}class ZC extends C.Component{constructor(){super(...arguments),this.viewDescRef=null}updateEffect(){const{decorations:e,siblingDescriptors:n,node:r}=this.props,i=Hr.findDOMNode(this);if(!i)return;let o=i;for(;o.firstChild;)o=o.firstChild;!this.viewDescRef||this.viewDescRef instanceof zC?this.viewDescRef=new IC(void 0,[],r,e,U.empty,i,o):(this.viewDescRef.parent=void 0,this.viewDescRef.children=[],this.viewDescRef.node=r,this.viewDescRef.outerDeco=e,this.viewDescRef.innerDeco=U.empty,this.viewDescRef.dom=i,this.viewDescRef.dom.pmViewDesc=this.viewDescRef,this.viewDescRef.nodeDOM=o),n.push(this.viewDescRef)}componentDidMount(){this.updateEffect()}componentDidUpdate(){this.updateEffect()}render(){const{node:e,decorations:n}=this.props;return n.reduce(hf,e.text)}}function eN(){const t=C.useContext(st),e=C.useRef(null);return C.useLayoutEffect(()=>{if(!e.current)return;const n=new ff(void 0,[],e.current,null);t.push(n)}),z("br",{ref:e,className:"ProseMirror-trailingBreak"})}function tN({widget:t,pos:e}){const n=C.useContext(st),r=C.useRef(null);C.useLayoutEffect(()=>{if(!r.current)return;const o=new uf(void 0,t,r.current);n.push(o)});const{Component:i}=t.type;return i&&z(i,{ref:r,widget:t,pos:e,contentEditable:!1})}function hf(t,e){const{nodeName:n,...r}=e.type.attrs,i=l0(r);return n||typeof t=="string"?C.createElement(n??"span",i,t):C.cloneElement(t,s0(t.props,i))}function $u({innerPos:t,childViews:e}){const{view:n}=C.useContext(vo),r=vl(),i=i0(),o=e.reduce((s,l)=>{var c;const a=s[s.length-1];if(!a)return[[l]];const u=a[a.length-1];return u?!l.marks.length&&!u.marks.length||l.marks.length&&u.marks.length&&((c=l.marks[0])!=null&&c.eq(u.marks[0]))?[...s.slice(0,s.length-1),[...a.slice(0,a.length),l]]:[...s,[l]]:[...s.slice(0,s.length),[l]]},[]);return z(Ju,{children:o.map(s=>{const l=s[0];if(!l)return null;const a=l.marks[0];return a?z(a0,{mark:a,children:z($u,{innerPos:t,childViews:s.map(u=>({...u,marks:u.marks.slice(1)}))},zi(r==null?void 0:r.doc,t,l,i==null?void 0:i.posToKey))},zi(r==null?void 0:r.doc,t,l,i==null?void 0:i.posToKey)):s.map(u=>{const c=t+u.offset,f=u.type==="widget"?z(tN,{widget:u.widget,pos:c}):u.type==="native-widget"?z(GC,{widget:u.widget,pos:c}):u.node.isText?z(st.Consumer,{children:d=>z(ZC,{view:n,node:u.node,pos:c,siblingDescriptors:d,decorations:u.outerDeco})}):z(u0,{node:u.node,pos:c,outerDeco:u.outerDeco,innerDeco:u.innerDeco});return C.cloneElement(f,{key:zi(r==null?void 0:r.doc,t,u,i==null?void 0:i.posToKey)})})})})}function zi(t,e,n,r){const i=e+n.offset,o=r==null?void 0:r.get(i);if(n.type==="widget"||n.type==="native-widget")return n.widget.type.spec.key?n.widget.type.spec.key:(console.warn(`Widget at position ${i} doesn't have a key specified. This has negative performance implications.`),`${o}-${n.index}`);if(o)return o;if(!t)return i;const s=t.resolve(i).start()-1,l=r==null?void 0:r.get(s);return l?`${l}-${n.offset}`:i}function nN(t){const e=t[t.length-1];if((e==null?void 0:e.type)!=="widget"&&(e==null?void 0:e.type)!=="native-widget"||e.widget.type.side>=0)return;let n=null;for(let i=t.length-2;i>=0;i--){const o=t[i];if((o==null?void 0:o.type)==="node"){n=o;break}}if(!n||!n.node.isInline)return;const r=n.marks;e.marks=e.marks.reduce((i,o)=>o.addToSet(i),r)}function rN(t){const e=t[t.length-1];if((e==null?void 0:e.type)!=="node"||!e.node.isInline)return;const n=e.marks;for(let r=t.length-2;r>=0;r--){const i=t[r];if((i==null?void 0:i.type)!=="widget"&&(i==null?void 0:i.type)!=="native-widget"||i.widget.type.side<0)break;i.marks=i.marks.reduce((o,s)=>s.addToSet(o),n)}}function iN(t,e,n,r){return t.length?t.every(i=>i.type!=="node"||i.node.isInline)?[z($u,{childViews:t,innerPos:e},zi(n,e,t[0],r))]:t.map(i=>{if(i.type==="node"){const o=e+i.offset,s=(r==null?void 0:r.get(o))??o;return z(u0,{outerDeco:i.outerDeco,node:i.node,innerDeco:i.innerDeco,pos:o},s)}else return z($u,{childViews:[i],innerPos:e},zi(n,e,i,r))}):[]}function bi({pos:t,node:e,innerDecorations:n}){const r=vl(),i=i0();if(!e)return null;const o=t+1,s=[];JC(e,n,(u,c,f,d)=>{const p=u.type.spec.marks??[];c?s.push({type:"native-widget",widget:u,marks:p,offset:f,index:d}):s.push({type:"widget",widget:u,marks:p,offset:f,index:d}),nN(s)},(u,c,f,d)=>{s.push({type:"node",node:u,marks:u.marks,innerDeco:f,outerDeco:c,offset:d}),rN(s)});const l=iN(s,o,r==null?void 0:r.doc,i==null?void 0:i.posToKey),a=s[s.length-1];return(!a||a.type!=="node"||a.node.isInline&&!a.node.isText||/\n$/.test(a.node.text))&&l.push(z(XC,{},"trailing-hack-img"),z(eN,{},"trailing-hack-br")),z(Ju,{children:l})}const oN=C.forwardRef(function({className:e,node:n,innerDeco:r,outerDeco:i,as:o,viewDesc:s},l){const a=C.useRef(null);C.useImperativeHandle(l,()=>a.current,[]);const u=r0(n,a,a,r,i,s),c={ref:a,className:e,suppressContentEditableWarning:!0},f=o?C.cloneElement(o,c,z(st.Provider,{value:u,children:z(bi,{pos:-1,node:n,innerDecorations:r})})):C.createElement("div",c,z(st.Provider,{value:u,children:z(bi,{pos:-1,node:n,innerDecorations:r})}));if(!n)return f;const d=i.filter(h=>!h.inline);return d.length?d.reduce(hf,f):f}),c0=C.createContext(null);function sN({as:t},e){const n=C.useRef(null),{setMount:r,...i}=C.useContext(c0);return C.useImperativeHandle(e,()=>n.current,[]),z(st.Provider,{value:[],children:z(oN,{ref:o=>{n.current=o,r(o)},...i,as:t})})}const lN=C.forwardRef(sN);function aN({className:t,children:e,nodeViews:n={},customNodeViews:r,...i}){var c;const[o,s]=C.useState(null),l=WC(o,{...i,nodeViews:r});UC(l.view);const a=l.view?iC(l.view,l.cursorWrapper):U.empty,u=l.view?eC(l.view):[];return z(jC,{children:z(vo.Provider,{value:l,children:z(jy.Provider,{value:{nodeViews:n},children:z(c0.Provider,{value:{className:t,setMount:s,node:(c=l.view)==null?void 0:c.state.doc,innerDeco:a,outerDeco:u,viewDesc:l.docViewDescRef.current},children:e})})})})}const _=new yp({nodes:{doc:{content:"block+"},paragraph:{group:"block",content:"inline*",toDOM(){return["p",0]}},...Sw({cellContent:"inline*",cellAttributes:{},tableGroup:"block"}),footnote:{group:"inline",content:"text*",inline:!0,atom:!0,attrs:{number:{default:0}}},list:{group:"block",content:"list_item+",toDOM(){return["ul",0]}},list_item:{content:"paragraph+",toDOM(){return["li",0]}},image:{group:"block",toDOM(){return["div",["img",{src:"https://smoores.gitlab.io/storyteller/img/Storyteller_Logo.png",height:150,width:150}]]}},text:{group:"inline"}},marks:{em:{toDOM(){return["em",0]}},strong:{toDOM(){return["strong",0]}}}}),uN=on.create({schema:_,doc:_.nodes.doc.create({},[_.nodes.paragraph.create({},[_.text("This ",[_.marks.em.create()]),_.text("is",[_.marks.em.create(),_.marks.strong.create()]),_.text(" the first paragraph")]),_.nodes.paragraph.create({},[_.text("This is the second paragraph"),_.nodes.footnote.create({number:1},_.text("Footnote"))]),_.nodes.paragraph.create(),_.nodes.image.create(),_.nodes.image.create(),_.nodes.paragraph.create({},_.text("This is the third paragraph 🫵")),_.nodes.table.create({},[_.nodes.table_row.create({},[_.nodes.table_header.create({},_.text("h1")),_.nodes.table_header.create({},_.text("h2"))]),_.nodes.table_row.create({},[_.nodes.table_cell.create({},_.text("c1")),_.nodes.table_cell.create({},_.text("c2"))])])]),plugins:[hC(),_S({rules:[WS(/^\s*([-+*])\s$/,_.nodes.list)]}),Bw(),Yw()]}),cN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("p",{ref:i,...r,children:e})}),fN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("ul",{ref:i,...r,children:e})}),dN=C.forwardRef(function({children:e,nodeProps:n,...r},i){return z("li",{ref:i,...r,children:e})}),hN=C.forwardRef(function({nodeProps:e,...n},r){return z("span",{ref:r,...n,suppressContentEditableWarning:!0,contentEditable:"false",children:z("button",{children:e.node.attrs.number})})}),pN=C.forwardRef(function({widget:e,pos:n,...r},i){return z("span",{...r,ref:i,style:{display:"block",backgroundColor:"blue",width:"4px",height:"4px",position:"absolute",transform:"translateX(-2px)"},children:"Widget"})}),mN=new Tt({view(t){const e=t.coordsAtPos(t.state.selection.from),n=document.createElement("div");return n.style.width="4px",n.style.height="4px",n.style.position="absolute",n.style.top=`${e.top-2}px`,n.style.left=`${e.left-2}px`,n.style.backgroundColor="blue",document.body.appendChild(n),{update(r){const i=r.coordsAtPos(r.state.selection.from);n.style.top=`${i.top-2}px`,n.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(n)}}}});new Tt({props:{decorations(t){return U.create(t.doc,[Qy(t.selection.from,pN,{side:0,key:"widget-plugin-widget"})])}},view(t){const e=t.coordsAtPos(t.state.selection.from),n=document.createElement("div");return n.style.width="4px",n.style.height="4px",n.style.position="absolute",n.style.top=`${e.top-2}px`,n.style.left=`${e.left-2}px`,n.style.backgroundColor="blue",document.body.appendChild(n),{update(r){const i=r.coordsAtPos(r.state.selection.from);n.style.top=`${i.top-2}px`,n.style.left=`${i.left-2}px`},destroy(){document.body.removeChild(n)}}}});const gN=[JS({...Q1,"Mod-i":If(_.marks.em),"Mod-b":If(_.marks.strong)}),mN,bS()],yN={paragraph:()=>{const t=document.createElement("p");return{dom:t,contentDOM:t}}};function kN(){const[t,e]=C.useState(uN),[n,r]=C.useState(!0);return kf("main",{children:[z("h1",{children:"React ProseMirror Demo"}),kf("button",{onClick:()=>{n?r(i=>!i):window.location.reload()},children:["Switch to"," ",n?"ProseMirror node views":"React node views (requires reload)"]}),z(aN,{className:"ProseMirror",state:t,dispatchTransaction:function(i){e(o=>o.apply(i))},plugins:gN,nodeViews:n?{paragraph:cN,list:fN,list_item:dN,footnote:hN}:void 0,customNodeViews:n?void 0:yN,children:z(lN,{as:z("article",{})})},`${n}`)]})}const SN=Uy(document.getElementById("root"));SN.render(z(kN,{})); diff --git a/docs/index.html b/docs/index.html index a53b465..47cdc2b 100644 --- a/docs/index.html +++ b/docs/index.html @@ -5,7 +5,7 @@ React-ProseMirror Demo - + diff --git a/src/components/OutputSpec.tsx b/src/components/OutputSpec.tsx index a899927..4d8c536 100644 --- a/src/components/OutputSpec.tsx +++ b/src/components/OutputSpec.tsx @@ -38,7 +38,7 @@ const ForwardedOutputSpec = forwardRef(function OutputSpec( !Array.isArray(attrs) ) { start = 2; - props = mergeReactProps(htmlAttrsToReactProps(attrs), propOverrides); + props = mergeReactProps(htmlAttrsToReactProps(attrs), props); } const content: ReactNode[] = [];