From 5a3087f5a525d25c84b2f855bf903d4486841a99 Mon Sep 17 00:00:00 2001 From: chris <kokosias@yahoo.gr> Date: Tue, 27 Apr 2021 10:50:57 +0300 Subject: [PATCH] sync history inside nodeView --- .../MultipleChoiceNodeView.js | 54 +--------------- .../components/TestComponent.js | 62 ++++++++++++++++++- 2 files changed, 64 insertions(+), 52 deletions(-) diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/MultipleChoiceNodeView.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/MultipleChoiceNodeView.js index 5df7616c0..2eb969fb6 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/MultipleChoiceNodeView.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/MultipleChoiceNodeView.js @@ -14,68 +14,20 @@ export default class MultipleChoiceNodeView extends AbstractNodeView { context, ) { super(node, view, getPos, decorations, createPortal, Component, context); - console.log('ccc', context); this.node = node; this.outerView = view; this.getPos = getPos; this.context = context; - - this.innerView = new EditorView( - { - mount: this.dom.appendChild(document.createElement('div')), - }, - { - state: EditorState.create({ - doc: node, - }), - dispatchTransaction: this.dispatchInner.bind(this), - - handleDOMEvents: { - mousedown: () => { - // Kludge to prevent issues due to the fact that the whole - // footnote is node-selected (and thus DOM-selected) when - // the parent editor is focused. - if (this.outerView.hasFocus()) this.innerView.focus(); - }, - }, - - attributes: { - spellcheck: 'false', - }, - }, - ); } static name() { return 'multiple_choice'; } - dispatchInner(tr) { - this.context.updateView( - { - ['mytest']: this.innerView, - }, - 'mytest', - ); - let { state, transactions } = this.innerView.state.applyTransaction(tr); - this.innerView.updateState(state); - - if (!tr.getMeta('fromOutside')) { - let outerTr = this.outerView.state.tr, - offsetMap = StepMap.offset(this.getPos() + 1); - for (let i = 0; i < transactions.length; i++) { - let steps = transactions[i].steps; - for (let j = 0; j < steps.length; j++) - outerTr.step(steps[j].map(offsetMap)); - } - if (outerTr.docChanged) this.outerView.dispatch(outerTr); - } - } - update(node) { if (!node.sameMarkup(this.node)) return false; this.node = node; - if (this.innerView) { - let state = this.innerView.state; + if (this.context.view[node.attrs.id]) { + let state = this.context.view[node.attrs.id].state; let start = node.content.findDiffStart(state.doc.content); if (start != null) { let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); @@ -84,7 +36,7 @@ export default class MultipleChoiceNodeView extends AbstractNodeView { endA += overlap; endB += overlap; } - this.innerView.dispatch( + this.context.view[node.attrs.id].dispatch( state.tr .replace(start, endB, node.slice(start, endA)) .setMeta('fromOutside', true), diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/TestComponent.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/TestComponent.js index 83a8dcb5b..ff7951be9 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/TestComponent.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/TestComponent.js @@ -1,10 +1,69 @@ /* eslint-disable react-hooks/exhaustive-deps */ -import React, { useState } from 'react'; +import React, { useContext, useRef, useState, useEffect } from 'react'; +import { EditorView } from 'prosemirror-view'; +import { EditorState, TextSelection } from 'prosemirror-state'; +import { StepMap } from 'prosemirror-transform'; +import { WaxContext } from 'wax-prosemirror-core'; import styled from 'styled-components'; export default ({ node, view, getPos }) => { const [showExplanation, setShowExplanation] = useState(false); + const context = useContext(WaxContext); + const editorRef = useRef(); + let questionView; + const questionId = node.attrs.id; + + useEffect(() => { + questionView = new EditorView( + { mount: editorRef.current }, + { + state: EditorState.create({ + doc: node, + }), + // This is the magic part + dispatchTransaction, + handleDOMEvents: { + mousedown: () => { + context.updateView({}, questionId); + // Kludge to prevent issues due to the fact that the whole + // footnote is node-selected (and thus DOM-selected) when + // the parent editor is focused. + if (questionView.hasFocus()) questionView.focus(); + }, + }, + + attributes: { + spellcheck: 'false', + }, + }, + ); + + //Set Each note into Wax's Context + context.updateView( + { + [questionId]: questionView, + }, + questionId, + ); + }, []); + + const dispatchTransaction = tr => { + let { state, transactions } = questionView.state.applyTransaction(tr); + questionView.updateState(state); + context.updateView({}, questionId); + + if (!tr.getMeta('fromOutside')) { + let outerTr = view.state.tr, + offsetMap = StepMap.offset(getPos() + 1); + for (let i = 0; i < transactions.length; i++) { + let steps = transactions[i].steps; + for (let j = 0; j < steps.length; j++) + outerTr.step(steps[j].map(offsetMap)); + } + if (outerTr.docChanged) view.dispatch(outerTr); + } + }; const clickMe = () => { setShowExplanation(true); @@ -13,6 +72,7 @@ export default ({ node, view, getPos }) => { return ( <> + <div ref={editorRef} /> <button onClick={clickMe}>Show Explanation</button> {showExplanation && ( <input type="text" placeholder="type your explanation"></input> -- GitLab