diff --git a/wax-prosemirror-components/src/components/rightArea/RightArea.js b/wax-prosemirror-components/src/components/rightArea/RightArea.js index 54fa39a30ff94f8419059f6034f6c0f0d93cbecd..d6e890e42584a7379ea8a207542a1a4f4248eba3 100644 --- a/wax-prosemirror-components/src/components/rightArea/RightArea.js +++ b/wax-prosemirror-components/src/components/rightArea/RightArea.js @@ -25,10 +25,21 @@ export default ({ area }) => { let annotationTop = 0; let boxHeight = 0; let top = 0; + let WaxSurface = {}; const allCommentsTop = []; + let panelWrapper = {}; + let panelWrapperHeight = {}; + if (main) { + WaxSurface = main.dom.getBoundingClientRect(); + + if (area === 'main') { + } else { + panelWrapper = document.getElementsByClassName('panelWrapper'); + panelWrapperHeight = panelWrapper[0].getBoundingClientRect().height; + } + } each(marksNodes[area], (markNode, pos) => { - const WaxSurface = main.dom.getBoundingClientRect(); const id = markNode instanceof Mark ? markNode.attrs.id : markNode.node.attrs.id; @@ -44,9 +55,6 @@ export default ({ area }) => { annotationTop = markNodeEl.getBoundingClientRect().top - WaxSurface.top; } else { - const panelWrapper = document.getElementsByClassName('panelWrapper'); - const panelWrapperHeight = panelWrapper[0].getBoundingClientRect() - .height; markNodeEl = document .querySelector('#notes-container') .querySelector(`[data-id="${id}"]`); diff --git a/wax-prosemirror-core/src/Wax.js b/wax-prosemirror-core/src/Wax.js index a562140c2732086d8d02394a7e1e94906f8057e8..0cc74c051c84a69802f4f3b5c909ff95f0c3273c 100644 --- a/wax-prosemirror-core/src/Wax.js +++ b/wax-prosemirror-core/src/Wax.js @@ -3,18 +3,17 @@ import React, { useEffect, useState } from 'react'; import debounce from 'lodash/debounce'; import styled from 'styled-components'; +import { DOMSerializer, DOMParser } from 'prosemirror-model'; + import WaxProvider from './WaxContext'; import Application from './Application'; -import WaxDOMSerializer from './WaxDOMSerializer'; -import WaxDOMParser from './WaxDOMParser'; - import WaxView from './WaxView'; import defaultPlugins from './plugins/defaultPlugins'; import Placeholder from './plugins/placeholder'; const parser = schema => { - const WaxParser = WaxDOMParser.fromSchema(schema); + const WaxParser = DOMParser.fromSchema(schema); return content => { const container = document.createElement('article'); @@ -24,7 +23,7 @@ const parser = schema => { }; const serializer = schema => { - const WaxSerializer = WaxDOMSerializer.fromSchema(schema); + const WaxSerializer = DOMSerializer.fromSchema(schema); return content => { const container = document.createElement('article'); container.appendChild(WaxSerializer.serializeFragment(content)); @@ -91,12 +90,30 @@ const Wax = props => { }; const parse = parser(schema); - const serialize = serializer(schema); WaxOptions.doc = parse(editorContent); const finalOnChange = debounce( value => { + /*HACK alter toDOM of footnote, because of how PM treats inline nodes + with content */ + if (schema.nodes.footnote) { + const old = schema.nodes.footnote.spec.toDOM; + schema.nodes.footnote.spec.toDOM = function (node) { + old.apply(this, arguments); + return ['footnote', node.attrs, 0]; + }; + } + + const serialize = serializer(schema); WaxOnchange(serialize(value)); + + if (schema.nodes.footnote) { + const old = schema.nodes.footnote.spec.toDOM; + schema.nodes.footnote.spec.toDOM = function (node) { + old.apply(this, arguments); + return ['footnote', node.attrs]; + }; + } }, 1000, { maxWait: 5000 }, diff --git a/wax-prosemirror-core/src/WaxContext.js b/wax-prosemirror-core/src/WaxContext.js index 6d5c226bcd902c42381577d2b31906ed6393c054..b5a934509a6907f93bfc39f2795fd1002a4e588c 100644 --- a/wax-prosemirror-core/src/WaxContext.js +++ b/wax-prosemirror-core/src/WaxContext.js @@ -1,3 +1,5 @@ +/* eslint react/prop-types: 0 */ +/* eslint react/destructuring-assignment: 0 */ import React, { useContext, useState } from 'react'; export const WaxContext = React.createContext({ @@ -7,6 +9,7 @@ export const WaxContext = React.createContext({ app: null, updateView: null, updateActiveView: null, + removeView: null, }); export default props => { @@ -15,13 +18,18 @@ export default props => { view: props.view || {}, activeView: props.activeView || {}, activeViewId: props.activeViewId || {}, + removeView: view => { + const newContext = { ...context, view }; + + setContext({ ...newContext }); + }, updateView: (newView, activeViewId) => { const view = Object.assign(context.view, newView); const activeView = view[activeViewId || context.activeViewId]; setContext({ ...context, view, - activeView: activeView, + activeView, activeViewId: activeViewId || context.activeViewId, }); }, diff --git a/wax-prosemirror-core/src/WaxDOMParser.js b/wax-prosemirror-core/src/WaxDOMParser.js deleted file mode 100644 index d398104ab8e8a02ec94019ea7d7d15fc746fb294..0000000000000000000000000000000000000000 --- a/wax-prosemirror-core/src/WaxDOMParser.js +++ /dev/null @@ -1,5 +0,0 @@ -import { DOMParser } from "prosemirror-model"; - -class WaxDOMParser extends DOMParser {} - -export default WaxDOMParser; diff --git a/wax-prosemirror-core/src/WaxDOMSerializer.js b/wax-prosemirror-core/src/WaxDOMSerializer.js deleted file mode 100644 index d47e7ebd675f6959007068c1ca6d47102389c244..0000000000000000000000000000000000000000 --- a/wax-prosemirror-core/src/WaxDOMSerializer.js +++ /dev/null @@ -1,5 +0,0 @@ -import { DOMSerializer } from "prosemirror-model"; - -class WaxDOMSerializer extends DOMSerializer {} - -export default WaxDOMSerializer; diff --git a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js index 56c21d63b135536f11fd551a34886113ec169208..361b9ce6dcdb080e346671f44366b652789cdc5d 100644 --- a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js +++ b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js @@ -213,8 +213,8 @@ const CommentsContainer = styled.div` } `; -let surfaceHeight = 500; -let notesHeight = 50; +let surfaceHeight = 700; +let notesHeight = 150; const onResizeEnd = arr => { surfaceHeight = arr[0].size; @@ -280,7 +280,7 @@ const EditoriaLayout = ({ editor }) => { <PanelGroup direction="column" panelWidths={[ - { size: surfaceHeight, resize: 'stretch' }, + { size: surfaceHeight, resize: 'dynamic' }, { size: notesHeight, resize: 'stretch' }, ]} onResizeEnd={onResizeEnd} diff --git a/wax-prosemirror-schema/src/nodes/footNoteNode.js b/wax-prosemirror-schema/src/nodes/footNoteNode.js index f1a97afd24d119771461e380e62d25c238eef635..582da4bc05536573939652e17f37ee7be631c360 100644 --- a/wax-prosemirror-schema/src/nodes/footNoteNode.js +++ b/wax-prosemirror-schema/src/nodes/footNoteNode.js @@ -1,14 +1,13 @@ -// TODO Write the node in WaxSchema const footnote = { group: 'inline', - content: 'block*', + content: 'inline*', inline: true, atom: true, attrs: { id: { default: '' }, }, toDOM: node => { - return ['footnote', node.attrs, 0]; + return ['footnote', node.attrs]; }, parseDOM: [ { diff --git a/wax-prosemirror-services/src/NoteService/Editor.js b/wax-prosemirror-services/src/NoteService/Editor.js index 980f3d086d8ee7f16027eef5103e626feb30c901..ae90d0fae42f3e4cee21c16d254a229600418ee7 100644 --- a/wax-prosemirror-services/src/NoteService/Editor.js +++ b/wax-prosemirror-services/src/NoteService/Editor.js @@ -1,5 +1,5 @@ /* eslint react/prop-types: 0 */ -import React, { useEffect, useRef, useContext, useState } from 'react'; +import React, { useEffect, useRef, useContext, useMemo } from 'react'; import { filter } from 'lodash'; import { EditorView } from 'prosemirror-view'; import { EditorState, TextSelection } from 'prosemirror-state'; @@ -139,6 +139,9 @@ export default ({ node, view }) => { ); } } - - return <NoteEditorContainer ref={editorRef} />; + const MemorizedComponent = useMemo( + () => <NoteEditorContainer ref={editorRef} />, + [], + ); + return <>{MemorizedComponent}</>; }; diff --git a/wax-prosemirror-services/src/NoteService/Note.js b/wax-prosemirror-services/src/NoteService/Note.js index 80dc15f5d6aea9887622f4a274b816976bf829b7..dea7314ffcee8d24481c74135790aadf9e084617 100644 --- a/wax-prosemirror-services/src/NoteService/Note.js +++ b/wax-prosemirror-services/src/NoteService/Note.js @@ -13,8 +13,8 @@ class Note extends Tools { get run() { return (state, dispatch) => { - let { empty, $from, $to } = state.selection, - content = Fragment.empty; + const { empty, $from, $to } = state.selection; + let content = Fragment.empty; if (!empty && $from.sameParent($to) && $from.parent.inlineContent) content = $from.parent.content.cut( $from.parentOffset, @@ -22,7 +22,7 @@ class Note extends Tools { ); const footnote = state.config.schema.nodes.footnote.create( { id: uuidv4() }, - Fragment.empty, + content, ); dispatch(state.tr.replaceSelectionWith(footnote)); }; diff --git a/wax-prosemirror-services/src/NoteService/NoteComponent.js b/wax-prosemirror-services/src/NoteService/NoteComponent.js index e378c0536a23f9c382e7b47e657ead80e50591e6..1e4b0d03648c1b5884e5a7f464168c508f64b1dc 100644 --- a/wax-prosemirror-services/src/NoteService/NoteComponent.js +++ b/wax-prosemirror-services/src/NoteService/NoteComponent.js @@ -7,12 +7,29 @@ import NoteEditor from './NoteEditor'; export default () => { const { + view, view: { main }, } = useContext(WaxContext); const [notes, setNotes] = useState([]); + + const cleanUpNoteViews = () => { + if (view) { + const currentNotes = DocumentHelpers.findChildrenByType( + main.state.doc, + main.state.schema.nodes.footnote, + true, + ); + if (notes.length > currentNotes.length) { + // TODO remove from context views that no loger exist + // console.log('to do cleanup'); + } + } + }; + useDeepCompareEffect(() => { setNotes(updateNotes(main)); + cleanUpNoteViews(); }, [updateNotes(main)]); const noteComponent = useMemo(