From dbd8892d802a8125186b61accf9c15b74816cf74 Mon Sep 17 00:00:00 2001 From: chris <kokosias@yahoo.gr> Date: Thu, 3 Mar 2022 16:12:15 +0200 Subject: [PATCH] new nodeView files --- .../FillTheGapContainerNodeView.js | 3 + .../components/ContainerEditor.js | 12 --- .../components/FeedbackComponent.js | 75 +++++++++++++++++++ .../FillTheGapContainerComponent.js | 14 +++- .../MultipleChoiceContainerNodeView.js | 55 ++++++++++++++ .../MultipleChoiceQuestionService.js | 7 ++ ...pleChoiceSingleCorrectContainerNodeView.js | 55 ++++++++++++++ ...tipleChoiceSingleCorrectQuestionService.js | 11 ++- .../TrueFalseContainerNodeView.js | 55 ++++++++++++++ .../TrueFalseQuestionService.js | 7 ++ ...TrueFalseSingleCorrectContainerNodeView.js | 55 ++++++++++++++ .../TrueFalseSingleCorrectQuestionService.js | 13 +++- 12 files changed, 342 insertions(+), 20 deletions(-) create mode 100644 wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js create mode 100644 wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js index dec3f753b..8fee80cf8 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js @@ -50,6 +50,9 @@ export default class FillTheGapContainerNodeView extends AbstractNodeView { } stopEvent(event) { + if (event.target.type === 'text') { + return true; + } return ( this.context.view[this.node.attrs.id] !== undefined && event.target !== undefined && diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js index 29cbe00d8..b25b24aa2 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js @@ -13,18 +13,6 @@ import { WaxContext } from 'wax-prosemirror-core'; const EditorWrapper = styled.span` > .ProseMirror { - // background: #a6a6a6 !important; - // border: 1px solid #a6a6a6; - // border-radius: 4px; - // box-shadow: none; - // color: #fff !important; - // display: inline; - // min-width: 50px; - // padding: 0px 2px 0px 2px !important; - // white-space: break-spaces; - // width: auto; - // word-wrap: break-word; - &:focus { outline: none; } diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js new file mode 100644 index 000000000..1c34fe93f --- /dev/null +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js @@ -0,0 +1,75 @@ +/* eslint-disable react/destructuring-assignment */ +/* eslint-disable react/prop-types */ + +import React, { useContext, useRef, useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { TextSelection } from 'prosemirror-state'; +import { WaxContext } from 'wax-prosemirror-core'; +import { DocumentHelpers } from 'wax-prosemirror-utilities'; + +const FeedBack = styled.div` + color: black; + margin-top: 10px; +`; + +const FeedBackLabel = styled.span` + font-weight: 700; +`; + +const FeedBackInput = styled.input` + // border: none; + display: flex; + width: 100%; +`; + +export default ({ node, view, getPos }) => { + const context = useContext(WaxContext); + const [feedBack, setFeedBack] = useState(' '); + const [typing, setTyping] = useState(false); + const feedBackRef = useRef(null); + + useEffect(() => {}, []); + + const handleKeyDown = e => { + setTyping(true); + if (e.key === 'Backspace') { + context.view.main.dispatch( + context.view.main.state.tr.setSelection( + TextSelection.create(context.view.main.state.tr.doc, null), + ), + ); + } + }; + + const feedBackInput = () => { + setFeedBack(feedBackRef.current.value); + }; + + const saveFeedBack = () => { + return false; + }; + + const onFocus = () => { + context.view.main.dispatch( + context.view.main.state.tr.setSelection( + TextSelection.create(context.view.main.state.tr.doc, null), + ), + ); + }; + + return ( + <FeedBack> + <FeedBackLabel>Feedback</FeedBackLabel> + <FeedBackInput + onBlur={saveFeedBack} + onChange={feedBackInput} + onFocus={onFocus} + onKeyDown={handleKeyDown} + placeholder="Insert feedback" + ref={feedBackRef} + type="text" + value={feedBack} + /> + </FeedBack> + ); +}; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js index a776e8370..742e1fe26 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js @@ -1,12 +1,20 @@ /* eslint-disable react/prop-types */ import React from 'react'; +import styled from 'styled-components'; import ContainerEditor from './ContainerEditor'; +import FeedbackComponent from './FeedbackComponent'; + +const FillTheGapContainer = styled.div` + margin-bottom: 15px; + margin-top: 10px; +`; export default ({ node, view, getPos }) => { return ( - <> + <FillTheGapContainer> + <span>Fill The Gap</span> <ContainerEditor getPos={getPos} node={node} view={view} /> - <div>feedback</div> - </> + <FeedbackComponent getPos={getPos} node={node} view={view} /> + </FillTheGapContainer> ); }; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js new file mode 100644 index 000000000..c00da4041 --- /dev/null +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceContainerNodeView.js @@ -0,0 +1,55 @@ +import AbstractNodeView from '../PortalService/AbstractNodeView'; + +export default class MultipleChoiceContainerNodeView extends AbstractNodeView { + constructor( + node, + view, + getPos, + decorations, + createPortal, + Component, + context, + ) { + super(node, view, getPos, decorations, createPortal, Component, context); + + this.node = node; + this.outerView = view; + this.getPos = getPos; + this.context = context; + } + + static name() { + return 'multiple_choice_container'; + } + + update(node) { + this.node = node; + if (this.context.view[node.attrs.id]) { + const { state } = this.context.view[node.attrs.id]; + const start = node.content.findDiffStart(state.doc.content); + if (start != null) { + let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); + const overlap = start - Math.min(endA, endB); + if (overlap > 0) { + endA += overlap; + endB += overlap; + } + this.context.view[node.attrs.id].dispatch( + state.tr + .replace(start, endB, node.slice(start, endA)) + .setMeta('fromOutside', true), + ); + } + } + + return true; + } + + stopEvent(event) { + if (event.target.type === 'text') { + return true; + } + const innerView = this.context.view[this.node.attrs.id]; + return innerView && innerView.dom.contains(event.target); + } +} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js index 5227d4446..c2a28b8c6 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestionService.js @@ -5,6 +5,7 @@ import multipleChoiceContainerNode from './schema/multipleChoiceContainerNode'; import questionNode from './schema/questionNode'; import AnswerComponent from './components/AnswerComponent'; import QuestionComponent from './components/QuestionComponent'; +import MultipleChoiceContainerNodeView from './MultipleChoiceContainerNodeView'; import MultipleChoiceNodeView from './MultipleChoiceNodeView'; import QuestionNodeView from './QuestionNodeView'; import MultipleChoiceSingleCorrectQuestionService from './MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService'; @@ -30,6 +31,12 @@ class MultipleChoiceQuestionService extends Service { question_node_multiple: questionNode, }); + // addPortal({ + // nodeView: MultipleChoiceContainerNodeView, + // component: QuestionComponent, + // context: this.app, + // }); + addPortal({ nodeView: QuestionNodeView, component: QuestionComponent, diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js new file mode 100644 index 000000000..1e0db8862 --- /dev/null +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectContainerNodeView.js @@ -0,0 +1,55 @@ +import AbstractNodeView from '../../PortalService/AbstractNodeView'; + +export default class MultipleChoiceSingleCorrectContainerNodeView extends AbstractNodeView { + constructor( + node, + view, + getPos, + decorations, + createPortal, + Component, + context, + ) { + super(node, view, getPos, decorations, createPortal, Component, context); + + this.node = node; + this.outerView = view; + this.getPos = getPos; + this.context = context; + } + + static name() { + return 'multiple_choice_container'; + } + + update(node) { + this.node = node; + if (this.context.view[node.attrs.id]) { + const { state } = this.context.view[node.attrs.id]; + const start = node.content.findDiffStart(state.doc.content); + if (start != null) { + let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); + const overlap = start - Math.min(endA, endB); + if (overlap > 0) { + endA += overlap; + endB += overlap; + } + this.context.view[node.attrs.id].dispatch( + state.tr + .replace(start, endB, node.slice(start, endA)) + .setMeta('fromOutside', true), + ); + } + } + + return true; + } + + stopEvent(event) { + if (event.target.type === 'text') { + return true; + } + const innerView = this.context.view[this.node.attrs.id]; + return innerView && innerView.dom.contains(event.target); + } +} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js index 48e7ac31b..9f1901ab6 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestionService.js @@ -4,6 +4,7 @@ import multipleChoiceSingleCorrectNode from './schema/multipleChoiceSingleCorrec import multipleChoiceSingleCorrectContainerNode from './schema/multipleChoiceSingleCorrectContainerNode'; import questionSingleNode from './schema/questionSingleNode'; import AnswerComponent from './components/AnswerComponent'; +import MultipleChoiceSingleCorrectContainerNodeView from './MultipleChoiceSingleCorrectContainerNodeView'; import MultipleChoiceSingleCorrectNodeView from './MultipleChoiceSingleCorrectNodeView'; import QuestionMultipleSingleNodeView from './QuestionMultipleSingleNodeView'; import QuestionComponent from '../components/QuestionComponent'; @@ -17,17 +18,23 @@ class MultipleChoiceSingleCorrectQuestionService extends Service { const addPortal = this.container.get('AddPortal'); createNode({ - multiple_choice_single_correct: multipleChoiceSingleCorrectNode, + multiple_choice_single_correct_container: multipleChoiceSingleCorrectContainerNode, }); createNode({ - multiple_choice_single_correct_container: multipleChoiceSingleCorrectContainerNode, + multiple_choice_single_correct: multipleChoiceSingleCorrectNode, }); createNode({ question_node_multiple_single: questionSingleNode, }); + // addPortal({ + // nodeView: MultipleChoiceSingleCorrectContainerNodeView, + // component: QuestionComponent, + // context: this.app, + // }); + addPortal({ nodeView: QuestionMultipleSingleNodeView, component: QuestionComponent, diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js new file mode 100644 index 000000000..f5f145d38 --- /dev/null +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseContainerNodeView.js @@ -0,0 +1,55 @@ +import AbstractNodeView from '../../PortalService/AbstractNodeView'; + +export default class TrueFalseContainerNodeView extends AbstractNodeView { + constructor( + node, + view, + getPos, + decorations, + createPortal, + Component, + context, + ) { + super(node, view, getPos, decorations, createPortal, Component, context); + + this.node = node; + this.outerView = view; + this.getPos = getPos; + this.context = context; + } + + static name() { + return 'true_false_container'; + } + + update(node) { + this.node = node; + if (this.context.view[node.attrs.id]) { + const { state } = this.context.view[node.attrs.id]; + const start = node.content.findDiffStart(state.doc.content); + if (start != null) { + let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); + const overlap = start - Math.min(endA, endB); + if (overlap > 0) { + endA += overlap; + endB += overlap; + } + this.context.view[node.attrs.id].dispatch( + state.tr + .replace(start, endB, node.slice(start, endA)) + .setMeta('fromOutside', true), + ); + } + } + + return true; + } + + stopEvent(event) { + if (event.target.type === 'text') { + return true; + } + const innerView = this.context.view[this.node.attrs.id]; + return innerView && innerView.dom.contains(event.target); + } +} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js index 1ee73119c..91aa037e7 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestionService.js @@ -4,6 +4,7 @@ import trueFalseNode from './schema/trueFalseNode'; import questionTrueFalseNode from './schema/questionTrueFalseNode'; import trueFalseContainerNode from './schema/trueFalseContainerNode'; import AnswerComponent from './components/AnswerComponent'; +import TrueFalseContainerNodeView from './TrueFalseContainerNodeView'; import TrueFalseNodeView from './TrueFalseNodeView'; import QuestionTrueFalseNodeView from './QuestionTrueFalseNodeView'; import QuestionComponent from '../components/QuestionComponent'; @@ -26,6 +27,12 @@ class TrueFalseQuestionService extends Service { question_node_true_false: questionTrueFalseNode, }); + // addPortal({ + // nodeView: TrueFalseContainerNodeView, + // component: QuestionComponent, + // context: this.app, + // }); + addPortal({ nodeView: QuestionTrueFalseNodeView, component: QuestionComponent, diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js new file mode 100644 index 000000000..d8a8ed1c1 --- /dev/null +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectContainerNodeView.js @@ -0,0 +1,55 @@ +import AbstractNodeView from '../../PortalService/AbstractNodeView'; + +export default class TrueFalseSingleCorrectContainerNodeView extends AbstractNodeView { + constructor( + node, + view, + getPos, + decorations, + createPortal, + Component, + context, + ) { + super(node, view, getPos, decorations, createPortal, Component, context); + + this.node = node; + this.outerView = view; + this.getPos = getPos; + this.context = context; + } + + static name() { + return 'true_false_single_correct_container'; + } + + update(node) { + this.node = node; + if (this.context.view[node.attrs.id]) { + const { state } = this.context.view[node.attrs.id]; + const start = node.content.findDiffStart(state.doc.content); + if (start != null) { + let { a: endA, b: endB } = node.content.findDiffEnd(state.doc.content); + const overlap = start - Math.min(endA, endB); + if (overlap > 0) { + endA += overlap; + endB += overlap; + } + this.context.view[node.attrs.id].dispatch( + state.tr + .replace(start, endB, node.slice(start, endA)) + .setMeta('fromOutside', true), + ); + } + } + + return true; + } + + stopEvent(event) { + if (event.target.type === 'text') { + return true; + } + const innerView = this.context.view[this.node.attrs.id]; + return innerView && innerView.dom.contains(event.target); + } +} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js index 27d171056..4f38a73f3 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestionService.js @@ -4,6 +4,7 @@ import trueFalseSingleCorrectNode from './schema/trueFalseSingleCorrectNode'; import trueFalseSingleCorrectContainerNode from './schema/trueFalseSingleCorrectContainerNode'; import questionTrueFalseSingleNode from './schema/questionTrueFalseSingleNode'; import AnswerComponent from './components/AnswerComponent'; +import TrueFalseSingleCorrectContainerNodeView from './TrueFalseSingleCorrectContainerNodeView'; import TrueFalseSingleCorrectNodeView from './TrueFalseSingleCorrectNodeView'; import QuestionTrueFalseSingleNodeView from './QuestionTrueFalseSingleNodeView'; import QuestionComponent from '../components/QuestionComponent'; @@ -17,17 +18,23 @@ class TrueFalseSingleCorrectQuestionService extends Service { const addPortal = this.container.get('AddPortal'); createNode({ - true_false_single_correct: trueFalseSingleCorrectNode, + true_false_single_correct_container: trueFalseSingleCorrectContainerNode, }); createNode({ - true_false_single_correct_container: trueFalseSingleCorrectContainerNode, + question_node_true_false_single: questionTrueFalseSingleNode, }); createNode({ - question_node_true_false_single: questionTrueFalseSingleNode, + true_false_single_correct: trueFalseSingleCorrectNode, }); + // addPortal({ + // nodeView: TrueFalseSingleCorrectContainerNodeView, + // component: QuestionComponent, + // context: this.app, + // }); + addPortal({ nodeView: QuestionTrueFalseSingleNodeView, component: QuestionComponent, -- GitLab