diff --git a/.eslintrc.js b/.eslintrc.js index 679cc7de97e12be33892ba31f9d467713611e95e..cbc56192d3b0f620e5522a1cda2330465a62e8a6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -31,6 +31,10 @@ eslint.rules['react/prop-types'] = [ 'onMouseDown', 'onMouseEnter', 'theme', + 'node', + 'view', + 'getPos', + 'readOnly', ], }, ]; diff --git a/editors/demo/src/Editoria/config/config.js b/editors/demo/src/Editoria/config/config.js index 3a8e29965a5aebaa601be2f6808f328594646ccc..b2ae40a224965a69bb44f8ba462fcaa4c71a53ed 100644 --- a/editors/demo/src/Editoria/config/config.js +++ b/editors/demo/src/Editoria/config/config.js @@ -43,6 +43,7 @@ import { CustomTagInlineToolGroupService, CustomTagBlockToolGroupService, CustomTagService, + BlockDropDownToolGroupService, } from 'wax-prosemirror-services'; import { EditoriaSchema } from 'wax-prosemirror-core'; @@ -77,6 +78,7 @@ export default { templateArea: 'mainMenuToolBar', toolGroups: [ 'Base', + 'BlockDropDown', { name: 'Annotations', more: [ @@ -141,6 +143,7 @@ export default { }, }, PmPlugins: [columnResizing(), tableEditing(), invisibles([hardBreak()])], + ImageService: { showAlt: true }, CustomTagService: { tags: [ { label: 'custom-tag-label-1', tagType: 'inline' }, @@ -152,6 +155,7 @@ export default { }, services: [ + new BlockDropDownToolGroupService(), new CustomTagService(), new DisplayBlockLevelService(), new DisplayToolGroupService(), diff --git a/editors/demo/src/Editoria/theme/theme.js b/editors/demo/src/Editoria/theme/theme.js index 011ea8916f75580b4474d3ab63d6d5c8e10fdaa0..3ba885af8cfc67d047f854242531bae6885f266d 100644 --- a/editors/demo/src/Editoria/theme/theme.js +++ b/editors/demo/src/Editoria/theme/theme.js @@ -1,4 +1,3 @@ -/* eslint-disable import/extensions */ import 'typeface-fira-sans-condensed'; import 'fontsource-merriweather'; import 'typeface-vollkorn'; diff --git a/editors/demo/src/Editors.js b/editors/demo/src/Editors.js index 9e14f6ac6c5dfb292ff737394c05d66b8ce35c76..0ffa6e0962d7df6fc6678274d594c45776e4043d 100644 --- a/editors/demo/src/Editors.js +++ b/editors/demo/src/Editors.js @@ -73,7 +73,7 @@ const Editors = () => { case 'oen': return <OEN />; default: - return <HHMI />; + return <Editoria />; } }; diff --git a/editors/demo/src/HHMI/config/config.js b/editors/demo/src/HHMI/config/config.js index e32464eb2f5cff425edb5790c60a10b9d0665b0c..70ca2465e00b04e3ad4758887c2dfbe0bc3f99ac 100644 --- a/editors/demo/src/HHMI/config/config.js +++ b/editors/demo/src/HHMI/config/config.js @@ -16,10 +16,6 @@ import { MathService, FullScreenService, FullScreenToolGroupService, - SpecialCharactersService, - SpecialCharactersToolGroupService, - EditorInfoToolGroupServices, - BottomInfoService, MultipleChoiceQuestionService, FillTheGapQuestionService, QuestionsDropDownToolGroupService, @@ -69,7 +65,6 @@ export default { RulesService: [emDash, ellipsis], PmPlugins: [columnResizing(), tableEditing(), invisibles([hardBreak()])], - services: [ new MatchingService(), new FillTheGapQuestionService(), @@ -92,9 +87,5 @@ export default { new MathService(), new FullScreenService(), new FullScreenToolGroupService(), - new SpecialCharactersService(), - new SpecialCharactersToolGroupService(), - new EditorInfoToolGroupServices(), - new BottomInfoService(), ], }; diff --git a/editors/demo/src/HHMI/theme/theme.js b/editors/demo/src/HHMI/theme/theme.js index 011ea8916f75580b4474d3ab63d6d5c8e10fdaa0..3ba885af8cfc67d047f854242531bae6885f266d 100644 --- a/editors/demo/src/HHMI/theme/theme.js +++ b/editors/demo/src/HHMI/theme/theme.js @@ -1,4 +1,3 @@ -/* eslint-disable import/extensions */ import 'typeface-fira-sans-condensed'; import 'fontsource-merriweather'; import 'typeface-vollkorn'; diff --git a/editors/demo/src/NCBI/theme/theme.js b/editors/demo/src/NCBI/theme/theme.js index 011ea8916f75580b4474d3ab63d6d5c8e10fdaa0..3ba885af8cfc67d047f854242531bae6885f266d 100644 --- a/editors/demo/src/NCBI/theme/theme.js +++ b/editors/demo/src/NCBI/theme/theme.js @@ -1,4 +1,3 @@ -/* eslint-disable import/extensions */ import 'typeface-fira-sans-condensed'; import 'fontsource-merriweather'; import 'typeface-vollkorn'; diff --git a/editors/demo/src/OEN/theme/theme.js b/editors/demo/src/OEN/theme/theme.js index 011ea8916f75580b4474d3ab63d6d5c8e10fdaa0..3ba885af8cfc67d047f854242531bae6885f266d 100644 --- a/editors/demo/src/OEN/theme/theme.js +++ b/editors/demo/src/OEN/theme/theme.js @@ -1,4 +1,3 @@ -/* eslint-disable import/extensions */ import 'typeface-fira-sans-condensed'; import 'fontsource-merriweather'; import 'typeface-vollkorn'; diff --git a/wax-prosemirror-core/index.js b/wax-prosemirror-core/index.js index 1b73762dac31294e51a1f11c7e4ee5bb457ee86c..dff5e11ffd24a867a9308de89568e6ab06b0ae59 100644 --- a/wax-prosemirror-core/index.js +++ b/wax-prosemirror-core/index.js @@ -31,7 +31,7 @@ export { default as ShortCutsService } from './src/config/defaultServices/ShortC export { default as QuestionsNodeView } from './src/utilities/lib/helpers/QuestionsNodeView'; export { default as trackedTransaction } from './src/utilities/track-changes/trackedTransaction'; -/* Components */ +/* Components TODO Remove from Core */ export { default as LeftMenuTitle } from './src/components/LeftMenuTitle'; export { default as LeftSideButton } from './src/components/LeftSideButton'; diff --git a/wax-prosemirror-core/src/Wax.js b/wax-prosemirror-core/src/Wax.js index 13c2da41586f73bbd5fc5ad4dc34a06525ee166d..a4cc8235eb9f4b5624e6953492f36bdfde20f7ac 100644 --- a/wax-prosemirror-core/src/Wax.js +++ b/wax-prosemirror-core/src/Wax.js @@ -48,18 +48,11 @@ const Wax = forwardRef((props, ref) => { } = props; if (!application) return null; - const WaxOnchange = onChange || (v => true); const finalOnChange = content => { + if (!onChange) return; const { schema } = application.schema; - helpers.alterNotesSchema(schema); - if (targetFormat === 'JSON') { - WaxOnchange(content); - } else { - const serialize = serializer(schema); - WaxOnchange(serialize(content)); - } - helpers.revertNotesSchema(schema); + helpers.saveContent(content, onChange, schema, serializer, targetFormat); }; const Layout = application.container.get('Layout'); @@ -74,7 +67,7 @@ const Wax = forwardRef((props, ref) => { customValues={customValues} debug={debug} fileUpload={fileUpload} - onChange={finalOnChange || (v => true)} + onChange={finalOnChange || (() => true)} placeholder={placeholder} readonly={readonly} ref={ref} diff --git a/wax-prosemirror-core/src/WaxView.js b/wax-prosemirror-core/src/WaxView.js index 327f206cc9a8115303663ad271bce7ef892ac342..0ac0dd1a0f0207668390cdd9fdaf5b61b2f045ce 100644 --- a/wax-prosemirror-core/src/WaxView.js +++ b/wax-prosemirror-core/src/WaxView.js @@ -1,4 +1,3 @@ -/* eslint-disable import/no-extraneous-dependencies */ /* eslint-disable react/prop-types */ import React, { useRef, @@ -104,9 +103,9 @@ const WaxView = forwardRef((props, ref) => { if (debug) applyDevTools(view); setTimeout(() => { if (autoFocus && view) { - view.focus(); view.state.tr.insertText('', 0); - view.dispatch(view.state.tr); + view.dispatch(view.state.tr.scrollIntoView()); + view.focus(); } }, 500); @@ -156,7 +155,6 @@ const WaxView = forwardRef((props, ref) => { const docContent = targetFormat === 'JSON' ? state.doc.toJSON() : state.doc.content; - if (!previousDoc.eq(view.state.doc) || tr.getMeta('forceUpdate')) props.onChange(docContent); }; diff --git a/wax-prosemirror-core/src/components/ToolGroups.js b/wax-prosemirror-core/src/components/ToolGroups.js index d35ae6f220d128ee119490c0c00520bab4587576..e097668166458487a93e130a805d2ee9c92d4863 100644 --- a/wax-prosemirror-core/src/components/ToolGroups.js +++ b/wax-prosemirror-core/src/components/ToolGroups.js @@ -1,5 +1,4 @@ /* eslint no-underscore-dangle: 0 */ -/* eslint react/prop-types: 0 */ import React from 'react'; import { v4 as uuidv4 } from 'uuid'; import ToolGroupComponent from './ToolGroupComponent'; @@ -7,7 +6,6 @@ import ToolGroupComponent from './ToolGroupComponent'; const ToolGroups = ({ toolGroups, view }) => { return toolGroups.map(toolGroup => { if (toolGroup._toolGroups.length > 0) { - // eslint-disable-next-line react/jsx-filename-extension return <ToolGroups toolGroups={toolGroup._toolGroups} view={view} />; } return ( diff --git a/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuService.js b/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuService.js index c2fc849c658f38797eeb347c23dc5758b1bf8a1b..a311fd8dd2d193e9734b292015a3071b4bbd406a 100644 --- a/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuService.js +++ b/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuService.js @@ -44,8 +44,9 @@ class MenuService extends Service { } tools.push(tl); } catch (error) { + const service = tool.name ? tool.name : tool; throw Error( - `Could not load Service ${tool.name}. Please configure service through config`, + `Could not load Service ${service}. Please configure service through config`, ); } }); diff --git a/wax-prosemirror-core/src/config/defaultServices/PortalService/AbstractNodeView.js b/wax-prosemirror-core/src/config/defaultServices/PortalService/AbstractNodeView.js index c8ee404c64c2f6d76f9ced16b47c355d7a6bdba0..92fd9234cce332a17c8ce8acabd27359a2c5ff6e 100644 --- a/wax-prosemirror-core/src/config/defaultServices/PortalService/AbstractNodeView.js +++ b/wax-prosemirror-core/src/config/defaultServices/PortalService/AbstractNodeView.js @@ -1,4 +1,3 @@ -/* eslint-disable class-methods-use-this */ import { v4 as uuidv4 } from 'uuid'; export default class AbstractNodeView { @@ -40,6 +39,7 @@ export default class AbstractNodeView { return innerView && innerView.dom.contains(event.target); } + // eslint-disable-next-line class-methods-use-this ignoreMutation() { return true; } diff --git a/wax-prosemirror-core/src/config/defaultServices/SchemaService/Mark.js b/wax-prosemirror-core/src/config/defaultServices/SchemaService/Mark.js index b1dc8d2681b9d6fcd51694d29668e3844abe5243..4c7c4bfe4859d4fa98b237a1ea70f2d7ee1ba281 100644 --- a/wax-prosemirror-core/src/config/defaultServices/SchemaService/Mark.js +++ b/wax-prosemirror-core/src/config/defaultServices/SchemaService/Mark.js @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import { isPlainObject } from 'lodash'; import Middleware from '../../../utilities/lib/Middleware'; import ParseRule from './ParseRule'; diff --git a/wax-prosemirror-core/src/config/defaultServices/SchemaService/ParseRule.js b/wax-prosemirror-core/src/config/defaultServices/SchemaService/ParseRule.js index 199059881dfdce96f2e17f8b86995db7da40f3b9..1972224cbc75a9eba8e8b1e2b8febbfff25a90fa 100644 --- a/wax-prosemirror-core/src/config/defaultServices/SchemaService/ParseRule.js +++ b/wax-prosemirror-core/src/config/defaultServices/SchemaService/ParseRule.js @@ -6,6 +6,7 @@ export default class ParseRule { style = null; exporter = null; defaultMiddleware = (hook, next) => { + // eslint-disable-next-line no-param-reassign hook = {}; next(); }; diff --git a/wax-prosemirror-core/src/helpers/helpers.js b/wax-prosemirror-core/src/helpers/helpers.js index 0041106f99c5be244e4df1397e46fddb0802c80a..e3d40fb3da72da57fa9736bd0df1c822785a628a 100644 --- a/wax-prosemirror-core/src/helpers/helpers.js +++ b/wax-prosemirror-core/src/helpers/helpers.js @@ -45,8 +45,18 @@ const getDocContent = (schema, serializer, targetFormat, context) => { return content; }; +const saveContent = (content, onChange, schema, serializer, targetFormat) => { + alterNotesSchema(schema); + if (targetFormat === 'JSON') { + onChange(content); + } else { + const serialize = serializer(schema); + onChange(serialize(content)); + } + revertNotesSchema(schema); +}; + export default { - alterNotesSchema, getDocContent, - revertNotesSchema, + saveContent, }; diff --git a/wax-prosemirror-core/src/utilities/lib/ToolGroup.js b/wax-prosemirror-core/src/utilities/lib/ToolGroup.js index 6c2c3b0de574d1e62642bc6a1b8e410a185a40b9..0e50d3fb417e4364ed5a50a8fb0b6e4bf3062da9 100644 --- a/wax-prosemirror-core/src/utilities/lib/ToolGroup.js +++ b/wax-prosemirror-core/src/utilities/lib/ToolGroup.js @@ -5,7 +5,6 @@ import { v4 as uuidv4 } from 'uuid'; import { isEmpty } from 'lodash'; import ToolGroups from '../../components/ToolGroups'; import ToolGroupComponent from '../../components/ToolGroupComponent'; -import 'reflect-metadata'; @injectable() class ToolGroup { diff --git a/wax-prosemirror-core/src/utilities/lib/Tools.js b/wax-prosemirror-core/src/utilities/lib/Tools.js index 6e6eb09c0d7fa5300aa2d0c52b162348863ce238..0d3490a3b6c2879a6c8bd76c93b0596ff9b68fa4 100644 --- a/wax-prosemirror-core/src/utilities/lib/Tools.js +++ b/wax-prosemirror-core/src/utilities/lib/Tools.js @@ -1,4 +1,4 @@ -/* eslint-disable */ +/* eslint-disable no-underscore-dangle */ import React from 'react'; import { v4 as uuidv4 } from 'uuid'; import { isEmpty } from 'lodash'; @@ -55,7 +55,7 @@ class Tools { if (isEmpty(view)) return null; return this._isDisplayed ? ( - <Button key={uuidv4()} item={this.toJSON()} view={view} /> + <Button item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/package.json b/wax-prosemirror-services/package.json index 184735047d22c6dd5c7152696ff220d0f0e73805..1346dbf7676d730c1295939e81603ee2fd731982 100644 --- a/wax-prosemirror-services/package.json +++ b/wax-prosemirror-services/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "highlight.js": "^10.1.1", + "use-dynamic-refs": "^1.0.0", "inversify": "^5.0.1", "inversify-inject-decorators": "^3.1.0", "lodash": "^4.17.4", diff --git a/wax-prosemirror-services/src/BaseService/RedoService/Redo.js b/wax-prosemirror-services/src/BaseService/RedoService/Redo.js index 2dede3a710cb9243fed69dfd48360a0ce26a5bbf..2c5b311394f849b16bc23d611434d36e641037b7 100644 --- a/wax-prosemirror-services/src/BaseService/RedoService/Redo.js +++ b/wax-prosemirror-services/src/BaseService/RedoService/Redo.js @@ -27,8 +27,7 @@ export default class Redo extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <UndoRedoButton item={this.toJSON()} key="Redo" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/BaseService/RedoService/RedoService.js b/wax-prosemirror-services/src/BaseService/RedoService/RedoService.js index 78049a7e71dc7085d84ba634f1a25c13600ad6ae..3e63728b39cda08be758af53181be2cabc7d3b16 100644 --- a/wax-prosemirror-services/src/BaseService/RedoService/RedoService.js +++ b/wax-prosemirror-services/src/BaseService/RedoService/RedoService.js @@ -2,8 +2,6 @@ import { Service } from 'wax-prosemirror-core'; import Redo from './Redo'; class RedoService extends Service { - // boot() {} - register() { this.container.bind('Redo').to(Redo); } diff --git a/wax-prosemirror-services/src/BaseService/SaveService/Save.js b/wax-prosemirror-services/src/BaseService/SaveService/Save.js index b1a678ad8b3fc3e5aaee1bd348001d83558a4d02..aad2e9ab121d74c3c25c9af27bded8895f6e0169 100644 --- a/wax-prosemirror-services/src/BaseService/SaveService/Save.js +++ b/wax-prosemirror-services/src/BaseService/SaveService/Save.js @@ -14,8 +14,7 @@ export default class Save extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <SaveButton item={this.toJSON()} key="Save" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/BaseService/UndoService/Undo.js b/wax-prosemirror-services/src/BaseService/UndoService/Undo.js index cbb275cc91df5d6064d78ee5331bb51222ebbb07..4d2207ff7c49b8a7470ce6731bf1dfe927d496bf 100644 --- a/wax-prosemirror-services/src/BaseService/UndoService/Undo.js +++ b/wax-prosemirror-services/src/BaseService/UndoService/Undo.js @@ -27,8 +27,7 @@ export default class Undo extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <UndoRedoButton item={this.toJSON()} key="Undo" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoTool.js b/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoTool.js index d091d542589c975b1e16c690e4fd870ef760644c..d990da40f0bab7a810ef0c6a4d8aefe1f644d776 100644 --- a/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoTool.js +++ b/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoTool.js @@ -21,8 +21,7 @@ class CounterInfoTool extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <EditorInfoTool item={this.toJSON()} key="CounterInfo" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoTool.js b/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoTool.js index ded4eb777302582b9373c4ceeaadd09a0d5a4722..124d38f44c8bfbcc11d845e0023220d1b1eb7006 100644 --- a/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoTool.js +++ b/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoTool.js @@ -21,8 +21,7 @@ class ShortCutsInfoTool extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <EditorShortCutsTool item={this.toJSON()} key="ShortCutsInfo" diff --git a/wax-prosemirror-services/src/CodeBlockService/plugins/highlightPlugin.js b/wax-prosemirror-services/src/CodeBlockService/plugins/highlightPlugin.js index 760487247bed3bec19af9d6c24f208b1b300e6ac..8d53e48c623a4b417ae3f7e00da52a5f188a351b 100644 --- a/wax-prosemirror-services/src/CodeBlockService/plugins/highlightPlugin.js +++ b/wax-prosemirror-services/src/CodeBlockService/plugins/highlightPlugin.js @@ -29,7 +29,7 @@ const highlightPlugin = (nodeTypes = ['code_block']) => { } = state; let codeBlock = false; - doc.nodesBetween($from.pos, $to.pos, (node, from) => { + doc.nodesBetween($from.pos, $to.pos, node => { if (node.type.name === 'code_block') { codeBlock = true; } diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js index 77b49c8dd23a1584b81ebcb5a1a2abc75973b140..2a5ccec585acb0bd6d497d0947bab56902dbe504 100644 --- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js +++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentBubbleComponent.js @@ -3,12 +3,7 @@ import React, { useLayoutEffect, useContext } from 'react'; import { WaxContext, Commands, DocumentHelpers } from 'wax-prosemirror-core'; import CommentBubble from './CommentBubble'; -const CommentBubbleComponent = ({ - setPosition, - position, - showComment, - group, -}) => { +const CommentBubbleComponent = ({ setPosition, position, group }) => { const { activeView, activeViewId } = useContext(WaxContext); const { state, dispatch } = activeView; @@ -38,7 +33,7 @@ const CommentBubbleComponent = ({ state.doc.nodesBetween( state.selection.$from.pos, state.selection.$to.pos, - (node, from) => { + node => { if ( node.type.name === 'math_display' || node.type.name === 'math_inline' || diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentItemList.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentItemList.js index d1dc93628cb9f499ed278bcea60f8d3f6e5228a0..484c904365e14508935d46c68369991a43866b4b 100644 --- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentItemList.js +++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentItemList.js @@ -2,8 +2,6 @@ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; import styled from 'styled-components'; import { clone, uniqueId } from 'lodash'; - -// import { th } from '../_helpers' import CommentItem from './CommentItem'; const Wrapper = styled.div` diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js index 1af91233bdaa2589c269e941bbedba97f2094217..1cfc2520d7a4a12e69bba83c6bb32b40f0e462c7 100644 --- a/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js +++ b/wax-prosemirror-services/src/CommentsService/components/ui/comments/CommentReply.js @@ -1,7 +1,6 @@ import React, { useState, useRef, useEffect } from 'react'; import PropTypes from 'prop-types'; import styled, { css } from 'styled-components'; - import { grid, th } from '@pubsweet/ui-toolkit'; const Wrapper = styled.div` diff --git a/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/TrackChangesBox.js b/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/TrackChangesBox.js index 9fa68dc6dbd69d77691cd9b6a5897b8230408a85..87c6cc0f733608b60e628dfd78d664b0837919f4 100644 --- a/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/TrackChangesBox.js +++ b/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/TrackChangesBox.js @@ -84,7 +84,6 @@ const Icons = styled.div` `; const IconButton = props => { - // eslint-disable-next-line react/prop-types const { name, onClick } = props; const handleClick = e => { e.stopPropagation(); diff --git a/wax-prosemirror-services/src/CustomTagService/components/CustomTagInlineComponent.js b/wax-prosemirror-services/src/CustomTagService/components/CustomTagInlineComponent.js index e39cdd872cb7d1498dfe4a4721cc7bc8ae4b7848..ee3e58e15ecaa3246f0cb39b4398356145e31435 100644 --- a/wax-prosemirror-services/src/CustomTagService/components/CustomTagInlineComponent.js +++ b/wax-prosemirror-services/src/CustomTagService/components/CustomTagInlineComponent.js @@ -9,7 +9,7 @@ const StyledButton = styled(MenuButton)` } `; -const CustomTagInlineComponent = ({ view: { state }, item }) => { +const CustomTagInlineComponent = ({ item }) => { const { icon, title } = item; const localInline = JSON.parse(localStorage.getItem('isInline')); const [isOpen, setIsOpen] = useState( diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/Author.js b/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/Author.js index 7351a46f148ef495fa79c89d6465fefc4df4b030..6f7e948c1be1172281f2a9695e3d0b0a7edb7e0b 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/Author.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/Author.js @@ -36,8 +36,7 @@ class Author extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/EpigraphPoetry.js b/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/EpigraphPoetry.js index 5250b1d1967117387fd608b40171b88c39870ea4..8e40cdc2fa034e842ffde30bf64eb4c44ce162e5 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/EpigraphPoetry.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/EpigraphPoetry.js @@ -40,8 +40,7 @@ class EpigraphPoetry extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/EpigraphProse.js b/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/EpigraphProse.js index d99932e6627d6513049d592c9370866ee238905c..04882489bfa5d6da795deccd791d8f5933263b06 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/EpigraphProse.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/EpigraphProse.js @@ -40,8 +40,7 @@ export default class EpigraphProse extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="epigraphProse" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js index 63634f18a3dc2fbecbea2bfd4749b7fdf41d26ae..36b8127b0ceb3449c681d91ecb0fbfac46e1f0ee 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading2.js @@ -56,8 +56,7 @@ export default class Heading2 extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="Heading2" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js index 189a6a0b42916f56b48dba3bbe747be73c4a3eca..0d190638a6225ed9986c7b84302801e7da3c7156 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading3.js @@ -56,8 +56,7 @@ export default class Heading3 extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="Heading3" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js index 7c9e753cac6e89d3078c50d3e3115e86818cb12c..49b47c67b95f9fdd2a5fd9456188894e27021a09 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading4.js @@ -25,7 +25,7 @@ export default class Heading4 extends Tools { if (activeViewId !== 'main') return false; const { from, to } = state.selection; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.name === 'heading4') { isActive = true; } @@ -56,8 +56,7 @@ export default class Heading4 extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="Heading4" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading5.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading5.js index 1e9f6b57a00f05612834c4978f3db24f3c1d4e39..873389940ff6a5613c2b8da115681bc022e3e0b0 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading5.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading5.js @@ -25,7 +25,7 @@ export default class Heading2 extends Tools { if (activeViewId !== 'main') return false; const { from, to } = state.selection; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.name === 'heading5') { isActive = true; } @@ -56,8 +56,7 @@ export default class Heading2 extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="Heading5" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading6.js b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading6.js index 51167521f7d2e3b409a9ab7aca2e599c93cdadd7..96cb862611ae1e12e7460dd0ba9d9124f390636f 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading6.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/HeadingService/Heading6.js @@ -24,7 +24,7 @@ export default class Heading2 extends Tools { if (activeViewId !== 'main') return false; const { from, to } = state.selection; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.name === 'heading6') { isActive = true; } @@ -46,8 +46,7 @@ export default class Heading2 extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="Heading5" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/SubTitle.js b/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/SubTitle.js index 408de02dbf4f23d92206d20b14827f0014c9e3bc..6758aba274d9839d395e3fb4eb9bdf56db3d7c55 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/SubTitle.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/SubTitle.js @@ -36,8 +36,7 @@ export default class SubTitle extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/Title.js b/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/Title.js index e2477c1dff6d0826dc99232d593a5a7a06a7303e..1b95b3348b7917080f9884e17781b6471da81210 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/Title.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/Title.js @@ -64,9 +64,8 @@ export default class Title extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( - <TitleButton key="Title" item={this.toJSON()} view={view} /> + return this.isDisplayed() ? ( + <TitleButton item={this.toJSON()} key="Title" view={view} /> ) : null; } } diff --git a/wax-prosemirror-services/src/DisplayBlockLevel/index.js b/wax-prosemirror-services/src/DisplayBlockLevel/index.js index 847094daf61e09914336ed0e5b4bf9886107c5c7..cf9bff85eb561b2ac0c54a4814784bede96c25d5 100644 --- a/wax-prosemirror-services/src/DisplayBlockLevel/index.js +++ b/wax-prosemirror-services/src/DisplayBlockLevel/index.js @@ -1,9 +1,9 @@ -import AuthorService from "./AuthorService/AuthorService"; -import EpigraphPoetryService from "./EpigraphPoetryService/EpigraphPoetryService"; -import EpigraphProseService from "./EpigraphProseService/EpigraphProseService"; -import HeadingService from "./HeadingService/HeadingService"; -import SubTitleService from "./SubTitleService/SubTitleService"; -import TitleService from "./TitleService/TitleService"; +import AuthorService from './AuthorService/AuthorService'; +import EpigraphPoetryService from './EpigraphPoetryService/EpigraphPoetryService'; +import EpigraphProseService from './EpigraphProseService/EpigraphProseService'; +import HeadingService from './HeadingService/HeadingService'; +import SubTitleService from './SubTitleService/SubTitleService'; +import TitleService from './TitleService/TitleService'; export default [ new AuthorService(), @@ -11,5 +11,5 @@ export default [ new EpigraphPoetryService(), new HeadingService(), new SubTitleService(), - new TitleService() + new TitleService(), ]; diff --git a/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggesting.js b/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggesting.js index 57892b7ba99df1097fa33549407cf4f5d7c62473..a3903308810cc5c8a63bdd29b2416b4cdd6f8629 100644 --- a/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggesting.js +++ b/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggesting.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ import React from 'react'; import { injectable } from 'inversify'; import { isEmpty } from 'lodash'; @@ -13,21 +12,20 @@ export default class EditingSuggesting extends Tools { name = 'EditingSuggesting'; get run() { - return state => { + return () => { return true; }; } get enable() { - return state => { + return () => { return true; }; } renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <EditingSuggestingDropDown enabled={this.config.enabled} item={this.toJSON()} diff --git a/wax-prosemirror-services/src/EnterService/plugins/GetContentOnEnterPlugin.js b/wax-prosemirror-services/src/EnterService/plugins/GetContentOnEnterPlugin.js index 102844cdbf4fe63bdc94155ff79118c13b3b5a4a..1573bde85c9e9177910b2afc9318b6fe9439b463 100644 --- a/wax-prosemirror-services/src/EnterService/plugins/GetContentOnEnterPlugin.js +++ b/wax-prosemirror-services/src/EnterService/plugins/GetContentOnEnterPlugin.js @@ -1,5 +1,4 @@ import { EditorState, Plugin, PluginKey } from 'prosemirror-state'; -// eslint-disable-next-line import/no-extraneous-dependencies import { DOMSerializer, DOMParser } from 'prosemirror-model'; const getContentOnEnterPlugin = new PluginKey('getContentOnEnterPlugin'); @@ -28,8 +27,8 @@ export default props => { return new Plugin({ key: getContentOnEnterPlugin, state: { - init: (_, state) => {}, - apply(tr, prev, _, newState) {}, + init: () => {}, + apply() {}, }, props: { handleKeyDown(view, event) { diff --git a/wax-prosemirror-services/src/EssayService/EssayQuestion.js b/wax-prosemirror-services/src/EssayService/EssayQuestion.js index 9abd0d8a9b3365eb2f7e3cc4f52f9a811eace479..88b4717da05acfa251f7ad1c27ffcafee3328172 100644 --- a/wax-prosemirror-services/src/EssayService/EssayQuestion.js +++ b/wax-prosemirror-services/src/EssayService/EssayQuestion.js @@ -11,7 +11,7 @@ import ToolBarBtn from './components/ToolBarBtn'; const checkifEmpty = view => { const { state } = view; const { from, to } = state.selection; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.textContent !== ' ') Commands.simulateKey(view, 13, 'Enter'); }); if (state.selection.constructor.name === 'GapCursor') { @@ -105,7 +105,14 @@ class EssayQuestion extends Tools { } get active() { - return state => {}; + return state => { + if ( + Commands.isParentOfType(state, state.config.schema.nodes.essay_question) + ) { + return true; + } + return false; + }; } select = (state, activeView) => { @@ -115,7 +122,7 @@ class EssayQuestion extends Tools { const { disallowedTools } = activeView.props; if (from === null || disallowedTools.includes('Essay')) status = false; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.groups.includes('questions')) { status = false; } @@ -123,14 +130,9 @@ class EssayQuestion extends Tools { return status; }; - get enable() { - return state => {}; - } - renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ToolBarBtn item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/EssayService/components/ContainerEditor.js b/wax-prosemirror-services/src/EssayService/components/ContainerEditor.js index 273c908444c79500c2b04e9dd587c24d861d1222..c1cf6b5c59f6b17253c64f825065a7090fa36dec 100644 --- a/wax-prosemirror-services/src/EssayService/components/ContainerEditor.js +++ b/wax-prosemirror-services/src/EssayService/components/ContainerEditor.js @@ -16,7 +16,7 @@ const EditorWrapper = styled.div` } `; -const ContainerEditor = ({ node, view, getPos, isEditable, autoFocus }) => { +const ContainerEditor = ({ node, view, getPos }) => { const editorRef = useRef(); const context = useContext(WaxContext); diff --git a/wax-prosemirror-services/src/EssayService/components/EditorComponent.js b/wax-prosemirror-services/src/EssayService/components/EditorComponent.js index e89bc34433f988847bcf92365f760698df456c7f..02a97a20723c50bf6475affb760ff63bb388b53b 100644 --- a/wax-prosemirror-services/src/EssayService/components/EditorComponent.js +++ b/wax-prosemirror-services/src/EssayService/components/EditorComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -74,7 +72,6 @@ const EditorComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, diff --git a/wax-prosemirror-services/src/EssayService/components/EssayAnswerComponent.js b/wax-prosemirror-services/src/EssayService/components/EssayAnswerComponent.js index 7779917927e4251278eb8cfb1622ce196e33f9f0..8940b0e522fe256dd30e49eb9ee5e58f22ed835b 100644 --- a/wax-prosemirror-services/src/EssayService/components/EssayAnswerComponent.js +++ b/wax-prosemirror-services/src/EssayService/components/EssayAnswerComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -56,9 +54,10 @@ const EssayAnswerComponent = ({ node, view, getPos }) => { } = context; let essayAnswerView; const questionId = node.attrs.id; - const isEditable = main.props.editable(editable => { - return editable; - }); + + const customProps = main.props.customValues; + + const { testMode } = customProps; let finalPlugins = []; @@ -105,7 +104,6 @@ const EssayAnswerComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, @@ -123,7 +121,7 @@ const EssayAnswerComponent = ({ node, view, getPos }) => { mount: editorRef.current, }, { - editable: () => !isEditable, + editable: () => testMode, state: EditorState.create({ doc: node, plugins: finalPlugins, @@ -193,7 +191,7 @@ const EssayAnswerComponent = ({ node, view, getPos }) => { }; return ( - <EditorWrapper editable={!isEditable}> + <EditorWrapper editable={testMode}> <div ref={editorRef} /> </EditorWrapper> ); diff --git a/wax-prosemirror-services/src/EssayService/components/EssayQuestionComponent.js b/wax-prosemirror-services/src/EssayService/components/EssayQuestionComponent.js index c4c47c48ccd7a99c84336d5efe3fd39d0f65ed47..ce4b2c268ab044e3787c31cbc766c972e7c1c00d 100644 --- a/wax-prosemirror-services/src/EssayService/components/EssayQuestionComponent.js +++ b/wax-prosemirror-services/src/EssayService/components/EssayQuestionComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -104,7 +102,6 @@ const EssayQuestionComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/CreateGapService/CreateGap.js b/wax-prosemirror-services/src/FillTheGapQuestionService/CreateGapService/CreateGap.js index dbe6cfa2b33fe87f5e137b728453dc649095068c..0b6a2370ed272e7bb03c13ab500dd2951cc5a6a1 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/CreateGapService/CreateGap.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/CreateGapService/CreateGap.js @@ -37,14 +37,6 @@ class CreateGap extends Tools { return false; }; - - get active() { - return state => {}; - } - - get enable() { - return state => {}; - } } export default CreateGap; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js index 23e37bbb02a8e38b3e1a5e83caffcacaf245aa20..ed20f863d7fe2b862b2828765bd76564b5a328a1 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapContainerNodeView.js @@ -27,7 +27,7 @@ export default class FillTheGapContainerNodeView extends QuestionsNodeView { } stopEvent(event) { - if (event.target.type === 'text') { + if (event.target.type === 'textarea') { return true; } diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapQuestion.js b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapQuestion.js index 414916a523f5de5f14921f768b886bd10398f9e4..e5ea91345d50124778a066d216a2ed1e5f429f66 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapQuestion.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/FillTheGapQuestion.js @@ -1,7 +1,7 @@ import { injectable } from 'inversify'; import { findWrapping } from 'prosemirror-transform'; import { v4 as uuidv4 } from 'uuid'; -import { Tools } from 'wax-prosemirror-core'; +import { Commands, Tools } from 'wax-prosemirror-core'; import helpers from '../MultipleChoiceQuestionService/helpers/helpers'; @injectable() @@ -31,7 +31,17 @@ class FillTheGapQuestion extends Tools { } get active() { - return state => {}; + return state => { + if ( + Commands.isParentOfType( + state, + state.config.schema.nodes.fill_the_gap_container, + ) + ) { + return true; + } + return false; + }; } select = (state, activeViewId, activeView) => { @@ -47,10 +57,6 @@ class FillTheGapQuestion extends Tools { }); return status; }; - - get enable() { - return state => {}; - } } export default FillTheGapQuestion; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js index cd423adee99f8b2bf02379edbe19f688d7df1bb8..3e62759ffbf5973756795cc31b680339f9cf1101 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/ContainerEditor.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/EditorComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/EditorComponent.js index 40f5efe55df87bbea5f3b682afb842ba15167fbe..f7b5e645bcc2c25a90101034265a99bc06cdc80f 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/EditorComponent.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/EditorComponent.js @@ -1,6 +1,3 @@ -/* eslint-disable react/prop-types */ -/* stylelint-disable declaration-no-important */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js deleted file mode 100644 index fd7cf39bc2bfff29e5a78202235c7364543a71a7..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FeedbackComponent.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint-disable react/prop-types */ - -import React, { useContext, useRef, useState } from 'react'; -import styled from 'styled-components'; -import { DocumentHelpers, WaxContext } from 'wax-prosemirror-core'; - -const FeedBack = styled.div` - color: black; - margin-top: 10px; - padding: 10px; -`; - -const FeedBackLabel = styled.span` - font-weight: 700; -`; - -const FeedBackInput = styled.input` - border: none; - border-bottom: 1px solid black; - display: flex; - width: 100%; - - &:focus { - outline: none; - } - - ::placeholder { - color: rgb(170, 170, 170); - font-style: italic; - } -`; - -export default ({ node, view, getPos, readOnly }) => { - const context = useContext(WaxContext); - const { - pmViews: { main }, - } = context; - const [feedBack, setFeedBack] = useState(node.attrs.feedback); - const feedBackRef = useRef(null); - - const feedBackInput = () => { - setFeedBack(feedBackRef.current.value); - const allNodes = getNodes(main); - allNodes.forEach(singleNode => { - if (singleNode.node.attrs.id === node.attrs.id) { - main.dispatch( - main.state.tr.setNodeMarkup(getPos(), undefined, { - ...singleNode.node.attrs, - feedback: feedBackRef.current.value, - }), - ); - } - }); - return false; - }; - - return ( - <FeedBack> - <FeedBackLabel>Feedback</FeedBackLabel> - <FeedBackInput - autoFocus="autoFocus" - disabled={readOnly} - onChange={feedBackInput} - placeholder="Insert feedback" - ref={feedBackRef} - type="text" - value={feedBack} - /> - </FeedBack> - ); -}; - -const getNodes = view => { - const allNodes = DocumentHelpers.findBlockNodes(view.state.doc); - const fillTheGapNodes = []; - allNodes.forEach(node => { - if (node.node.type.name === 'fill_the_gap_container') - fillTheGapNodes.push(node); - }); - return fillTheGapNodes; -}; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js index 4f1822150e4a546b7e403aaedd98031f67174c6f..e51d291f9d735aa737615b11ad1b4956e5e3b27a 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/FillTheGapContainerComponent.js @@ -1,9 +1,8 @@ -/* eslint-disable react/prop-types */ import React, { useContext } from 'react'; import { WaxContext, ComponentPlugin } from 'wax-prosemirror-core'; import styled from 'styled-components'; import ContainerEditor from './ContainerEditor'; -import FeedbackComponent from './FeedbackComponent'; +import FeedbackComponent from '../../MultipleChoiceQuestionService/components/FeedbackComponent'; const FillTheGapContainer = styled.div` border: 3px solid #f5f5f7; @@ -41,19 +40,22 @@ export default ({ node, view, getPos }) => { }); const readOnly = !isEditable; + const { feedback } = node.attrs; return ( <FillTheGapWrapper> <div> - <span> Fill The Gap</span> - <FillTheGapContainerTool> - <FillTheGapTool /> - </FillTheGapContainerTool> + {/* <span> Fill The Gap</span> */} + {!testMode && !readOnly && ( + <FillTheGapContainerTool> + <FillTheGapTool /> + </FillTheGapContainerTool> + )} </div> <FillTheGapContainer className="fill-the-gap"> <ContainerEditor getPos={getPos} node={node} view={view} /> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/GapComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/GapComponent.js index efc17d00e85d22f08872143943820c9a7851260f..0f5e0f3039f51aeb09b8c3f038f4a9fb84068de5 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/GapComponent.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/GapComponent.js @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React from 'react'; import EditorComponent from './EditorComponent'; diff --git a/wax-prosemirror-services/src/FillTheGapQuestionService/components/InputComponent.js b/wax-prosemirror-services/src/FillTheGapQuestionService/components/InputComponent.js index 969603c88654cbff79f64ff37c5b5cd523844147..5ae80bcd524e0e333b795b82107f3ee45cc4c3c1 100644 --- a/wax-prosemirror-services/src/FillTheGapQuestionService/components/InputComponent.js +++ b/wax-prosemirror-services/src/FillTheGapQuestionService/components/InputComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useState, useEffect } from 'react'; import styled from 'styled-components'; import { TextSelection } from 'prosemirror-state'; @@ -17,7 +15,7 @@ const AnswerInput = styled.input` } `; -export default ({ node, view, getPos }) => { +export default () => { const context = useContext(WaxContext); const { pmViews: { main }, diff --git a/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplace.js b/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplace.js index 4c75a2a4d3044a25ece4ba2b14baba7a97553802..9d01aebc12d9fa01b2e0b3d194afb5654487ba35 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplace.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplace.js @@ -11,14 +11,8 @@ export default class FindAndReplace extends Tools { icon = 'findAndReplace'; name = 'find'; - get run() { - return (state, dispatch) => {}; - } - - select = (state, activeViewId) => {}; - get enable() { - return state => { + return () => { return true; }; } @@ -26,8 +20,8 @@ export default class FindAndReplace extends Tools { renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( - <FindAndReplaceTool key={uuidv4()} item={this.toJSON()} view={view} /> + return this.isDisplayed() ? ( + <FindAndReplaceTool item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } } diff --git a/wax-prosemirror-services/src/FindAndReplaceService/components/ExpandedFindAndReplaceComponent.js b/wax-prosemirror-services/src/FindAndReplaceService/components/ExpandedFindAndReplaceComponent.js index 91c2bf505dcbcdfcb2ea8d745f7789565c4573fb..9d6d5932166aa880d54a534803adc8f128028477 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/components/ExpandedFindAndReplaceComponent.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/components/ExpandedFindAndReplaceComponent.js @@ -158,7 +158,7 @@ const ExpandedFindAndReplaceComponent = ({ const allStates = []; - each(pmViews, (singleView, viewId) => { + each(pmViews, singleView => { allStates.push(singleView.state); }); diff --git a/wax-prosemirror-services/src/FindAndReplaceService/components/FindAndReplaceTool.js b/wax-prosemirror-services/src/FindAndReplaceService/components/FindAndReplaceTool.js index 529da8f188712f4c5652dcf19fd9cc887347d922..194ea9d6272ae6dd6dd9970d13ae35f45240c606 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/components/FindAndReplaceTool.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/components/FindAndReplaceTool.js @@ -25,7 +25,7 @@ const DropWrapper = styled.div` top: 32px; `; -const FindAndReplaceTool = ({ view = {}, item }) => { +const FindAndReplaceTool = ({ item }) => { const { pmViews: { main }, } = useContext(WaxContext); diff --git a/wax-prosemirror-services/src/FindAndReplaceService/components/FindComponent.js b/wax-prosemirror-services/src/FindAndReplaceService/components/FindComponent.js index 5b8eadad1ed8267b6b71daf37fc421d09c359c33..6bb6347a1affe67224f057c77104bf638540b09e 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/components/FindComponent.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/components/FindComponent.js @@ -190,7 +190,7 @@ const FindComponent = ({ setCounterSearches(counter); if (searchRef.current === document.activeElement) { - eachRight(pmViews, (singleView, viewId) => { + eachRight(pmViews, singleView => { singleView.dispatch(singleView.state.tr); }); } @@ -198,7 +198,7 @@ const FindComponent = ({ const closeFind = () => { findAndReplacePlugin.props.setSearchText(''); - each(pmViews, (singleView, viewId) => { + each(pmViews, singleView => { singleView.dispatch(singleView.state.tr); }); close(); diff --git a/wax-prosemirror-services/src/FindAndReplaceService/components/helpers.js b/wax-prosemirror-services/src/FindAndReplaceService/components/helpers.js index 8608573616c8382183a1550f6a58fbf212c07ed6..27da634d57ff5a02ab8926b1ac557dae42e7850f 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/components/helpers.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/components/helpers.js @@ -4,7 +4,7 @@ import { TextSelection } from 'prosemirror-state'; const getMatchesByView = (views, searchValue, matchCase) => { let allResults = 0; - each(views, (singleView, viewId) => { + each(views, singleView => { const results = DocumentHelpers.findMatches( singleView.state.doc, searchValue, diff --git a/wax-prosemirror-services/src/FindAndReplaceService/plugins/FindAndReplacePlugin.js b/wax-prosemirror-services/src/FindAndReplaceService/plugins/FindAndReplacePlugin.js index 662a33f0fa47d1208044e5c7ac7643b39bd84f12..96924cca117a8d2047602a3298e44ab1e33b2a5f 100644 --- a/wax-prosemirror-services/src/FindAndReplaceService/plugins/FindAndReplacePlugin.js +++ b/wax-prosemirror-services/src/FindAndReplaceService/plugins/FindAndReplacePlugin.js @@ -7,11 +7,11 @@ const findAndReplacePlugin = new PluginKey('findAndReplacePlugin'); let searchText = ''; let matchCase = false; -export default props => { +export default () => { return new Plugin({ key: findAndReplacePlugin, state: { - init: (_, state) => { + init: () => { return DecorationSet.empty; }, apply(tr, prev, _, newState) { @@ -26,7 +26,7 @@ export default props => { ); } if (allMatches.length > 0) { - decorations = allMatches.map((result, index) => { + decorations = allMatches.map(result => { return Decoration.inline(result.from, result.to, { class: 'search-result', }); @@ -52,9 +52,9 @@ export default props => { matchCase = searchCase; }, }, - view(editorState) { + view() { return { - update: (view, previousState) => {}, + update: () => {}, }; }, }); diff --git a/wax-prosemirror-services/src/FullScreenService/FullScreenTool.js b/wax-prosemirror-services/src/FullScreenService/FullScreenTool.js index a722c60db6337ef6fb75eececb30545593d778c9..6613c1e7362be5a98701b9cf13d6610a395d9b5f 100644 --- a/wax-prosemirror-services/src/FullScreenService/FullScreenTool.js +++ b/wax-prosemirror-services/src/FullScreenService/FullScreenTool.js @@ -14,20 +14,19 @@ export default class FullScreenTool extends Tools { return () => true; } - select = (state, activeViewId) => { + select = () => { return true; }; get enable() { - return state => { + return () => { return true; }; } renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <FullScreenButton item={this.toJSON()} key="FullScreen" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/HighlightService/TextHighlightTool.js b/wax-prosemirror-services/src/HighlightService/TextHighlightTool.js index 1953e140b7668265cb0c20e41db1f39b61d6c3e5..4b04f99ae2de7827f99a1d66ef55042c3ddeec29 100644 --- a/wax-prosemirror-services/src/HighlightService/TextHighlightTool.js +++ b/wax-prosemirror-services/src/HighlightService/TextHighlightTool.js @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import React from 'react'; import { injectable } from 'inversify'; import { isEmpty } from 'lodash'; @@ -12,7 +11,7 @@ class TextHighlightTool extends Tools { icon = 'highlight'; name = 'TextHighlightTool'; - select = (state, activeViewId, activeView) => { + select = () => { // return !activeView.state.selection.empty; return window.getSelection().toString().trim().length !== 0; }; @@ -52,7 +51,7 @@ class TextHighlightTool extends Tools { renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <TextHighlightingTool item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/ImageService/AltComponent.js b/wax-prosemirror-services/src/ImageService/AltComponent.js index 1dc2aebf532f9ea0be16c2a23a0706465d4303f1..9786988c1a4a4a9e1016da4e7f989299abe598a1 100644 --- a/wax-prosemirror-services/src/ImageService/AltComponent.js +++ b/wax-prosemirror-services/src/ImageService/AltComponent.js @@ -1,13 +1,31 @@ -/* eslint-disable react/prop-types */ import React, { useContext, useLayoutEffect, useRef, useState } from 'react'; import styled from 'styled-components'; import { WaxContext } from 'wax-prosemirror-core'; +const StyledInputAlt = styled.input` + background: #e2ebff; + border: none; + box-sizing: border-box; + width: 240px; + min-height: 20px; + padding: 4px; + + &:focus { + outline: none; + } + + &::placeholder { + color: black; + font-weight: bold; + } +`; + export default ({ setPosition, position }) => { const altRef = useRef(null); const [altText, setAltText] = useState(''); const context = useContext(WaxContext); const { + app, activeView, pmViews: { main }, } = context; @@ -18,34 +36,19 @@ export default ({ setPosition, position }) => { const readOnly = !isEditable; - const StyledInputAlt = styled.input` - background: #e2ebff; - border: none; - box-sizing: border-box; - width: 240px; - min-height: 20px; - padding: 4px; - - &:focus { - outline: none; - } - - &::placeholder { - color: black; - font-weight: bold; - } - `; - useLayoutEffect(() => { - const WaxSurface = activeView.dom.getBoundingClientRect(); + const WaxSurface = main.dom.getBoundingClientRect(); const { selection } = activeView.state; if (!selection || !selection.node || !selection.node.attrs.id) return; const imageId = selection.node.attrs.id; const image = document.querySelector(`[data-id='${imageId}']`); + const figCaption = document.getElementsByTagName('figcaption')[0]; + if (!image) return; const imagePosition = image.getBoundingClientRect(); + const figCaptionPosition = figCaption.getBoundingClientRect().height - 5; const left = imagePosition.left - WaxSurface.left; - const top = imagePosition.bottom - WaxSurface.top - 22; + const top = imagePosition.bottom - WaxSurface.top - figCaptionPosition; setPosition({ ...position, left, top }); }, [position.left, position.top]); @@ -60,23 +63,24 @@ export default ({ setPosition, position }) => { ); }; - if (!readOnly) { - return ( - <StyledInputAlt - autoFocus="autoFocus" - key="alt" - onChange={altTextOnChange} - placeholder="Alt Text" - ref={altRef} - type="text" - value={ - activeView.state.selection && - activeView.state.selection.node && - activeView.state.selection.node.attrs.alt !== '' - ? activeView.state.selection.node.attrs.alt - : altText - } - /> - ); - } + const imageConfig = app.config.get('config.ImageService'); + const showAlt = imageConfig && imageConfig.showAlt; + + return !readOnly && showAlt ? ( + <StyledInputAlt + autoFocus="autoFocus" + key="alt" + onChange={altTextOnChange} + placeholder="Alt Text" + ref={altRef} + type="text" + value={ + activeView.state.selection && + activeView.state.selection.node && + activeView.state.selection.node.attrs.alt !== '' + ? activeView.state.selection.node.attrs.alt + : altText + } + /> + ) : null; }; diff --git a/wax-prosemirror-services/src/ImageService/Image.js b/wax-prosemirror-services/src/ImageService/Image.js index 0fac58ed91181518c6b584bbe4c24e055b7f3055..789f921fb2ea738978081f88e8b6d0b43f51e4be 100644 --- a/wax-prosemirror-services/src/ImageService/Image.js +++ b/wax-prosemirror-services/src/ImageService/Image.js @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import React, { useContext } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { isEmpty } from 'lodash'; @@ -42,7 +41,7 @@ export default class Image extends Tools { this.pmplugins.get('imagePlaceHolder'), context, ); - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ImageUpload fileUpload={upload} item={this.toJSON()} diff --git a/wax-prosemirror-services/src/ImageService/schema/imageNode.js b/wax-prosemirror-services/src/ImageService/schema/imageNode.js index 2dba4d90dce02cbe39d4fde2bef69254aaa6c8a1..f009e4f13b98457c1f92935b4814a50aee5e504a 100644 --- a/wax-prosemirror-services/src/ImageService/schema/imageNode.js +++ b/wax-prosemirror-services/src/ImageService/schema/imageNode.js @@ -1,5 +1,4 @@ // import { SchemaHelpers } from 'wax-prosemirror-core'; -import { isEmpty } from 'lodash'; const imageNode = { attrs: { diff --git a/wax-prosemirror-services/src/InlineAnnotations/index.js b/wax-prosemirror-services/src/InlineAnnotations/index.js index 59e5880c48848bd81cee5fe3f21b7e7d738ce41e..c9d9565c5337e5cde668c4b2b3b959ccd4f771d9 100644 --- a/wax-prosemirror-services/src/InlineAnnotations/index.js +++ b/wax-prosemirror-services/src/InlineAnnotations/index.js @@ -1,11 +1,11 @@ -import CodeService from "./CodeService/CodeService"; -import StrongService from "./StrongService/StrongService"; -import EmphasisService from "./EmphasisService/EmphasisService"; -import SubscriptService from "./SubscriptService/SubscriptService"; -import SuperscriptService from "./SuperscriptService/SuperscriptService"; -import StrikeThroughService from "./StrikeThroughService/StrikeThroughService"; -import UnderlineService from "./UnderlineService/UnderlineService"; -import SmallCapsService from "./SmallCapsService/SmallCapsService"; +import CodeService from './CodeService/CodeService'; +import StrongService from './StrongService/StrongService'; +import EmphasisService from './EmphasisService/EmphasisService'; +import SubscriptService from './SubscriptService/SubscriptService'; +import SuperscriptService from './SuperscriptService/SuperscriptService'; +import StrikeThroughService from './StrikeThroughService/StrikeThroughService'; +import UnderlineService from './UnderlineService/UnderlineService'; +import SmallCapsService from './SmallCapsService/SmallCapsService'; export default [ new CodeService(), @@ -15,5 +15,5 @@ export default [ new SuperscriptService(), new StrikeThroughService(), new UnderlineService(), - new SmallCapsService() + new SmallCapsService(), ]; diff --git a/wax-prosemirror-services/src/LinkService/components/LinkComponent.js b/wax-prosemirror-services/src/LinkService/components/LinkComponent.js index d1c126957698d08e4a1df182867aa52cddbe5288..0efda11294af82505a487859682005f20cc7b8f2 100644 --- a/wax-prosemirror-services/src/LinkService/components/LinkComponent.js +++ b/wax-prosemirror-services/src/LinkService/components/LinkComponent.js @@ -60,7 +60,7 @@ const StyledButtonCancel = styled.button` `; -const LinkComponent = ({ mark, setPosition, position }) => { +const LinkComponent = ({ mark }) => { const href = mark ? mark.attrs.href : null; const linkMark = mark || null; const { activeView } = useContext(WaxContext); diff --git a/wax-prosemirror-services/src/ListsService/BulletListService/schema/bulletListNode.js b/wax-prosemirror-services/src/ListsService/BulletListService/schema/bulletListNode.js index 13b437a268763a549580595ba7217e386b5e9708..15a9f0bd38e6ab097cd4f12ad518369df9bb32b6 100644 --- a/wax-prosemirror-services/src/ListsService/BulletListService/schema/bulletListNode.js +++ b/wax-prosemirror-services/src/ListsService/BulletListService/schema/bulletListNode.js @@ -22,6 +22,7 @@ const bulletListNode = { if (hook.node.attrs.track && hook.node.attrs.track.length) { attrs['data-track'] = JSON.stringify(hook.node.attrs.track); } + // eslint-disable-next-line no-param-reassign hook.value = ['ul', attrs, 0]; next(); }, diff --git a/wax-prosemirror-services/src/ListsService/ListItemService/schema/listItemNode.js b/wax-prosemirror-services/src/ListsService/ListItemService/schema/listItemNode.js index fefea9264c154fb58b1ab8cef1d2a19e2ec913b4..b8f382fa283bec26f0e288264cad5ea90b9400e8 100644 --- a/wax-prosemirror-services/src/ListsService/ListItemService/schema/listItemNode.js +++ b/wax-prosemirror-services/src/ListsService/ListItemService/schema/listItemNode.js @@ -1,4 +1,3 @@ -/* eslint-disable camelcase */ import { SchemaHelpers } from 'wax-prosemirror-core'; const listItemNode = { @@ -22,6 +21,7 @@ const listItemNode = { if (hook.node.attrs.track && hook.node.attrs.track.length) { attrs['data-track'] = JSON.stringify(hook.node.attrs.track); } + // eslint-disable-next-line no-param-reassign hook.value = ['li', attrs, 0]; next(); }, diff --git a/wax-prosemirror-services/src/MatchingService/MatchingContainerNodeView.js b/wax-prosemirror-services/src/MatchingService/MatchingContainerNodeView.js index 1eb1037359be1e64c88bbacb89e8a6f8e99f40ed..05bb83d977280dbb7eb8b4f027a7694f3ab6ded1 100644 --- a/wax-prosemirror-services/src/MatchingService/MatchingContainerNodeView.js +++ b/wax-prosemirror-services/src/MatchingService/MatchingContainerNodeView.js @@ -22,8 +22,15 @@ export default class MatchingContainerNodeView extends QuestionsNodeView { return 'matching_container'; } + update(node) { + if (node.type.name === 'paragraph') { + if (!node.sameMarkup(this.node)) return false; + } + return super.update(node); + } + stopEvent(event) { - if (event.target.type === 'text') { + if (event.target.type === 'textarea') { return true; } const innerView = this.context.pmViews[this.node.attrs.id]; diff --git a/wax-prosemirror-services/src/MatchingService/MatchingQuestion.js b/wax-prosemirror-services/src/MatchingService/MatchingQuestion.js index 1e31ab9907400bb844b8f3dd0bd6420f509d4158..2fb469e76cede7ff2931763691f4be1cd8997b8c 100644 --- a/wax-prosemirror-services/src/MatchingService/MatchingQuestion.js +++ b/wax-prosemirror-services/src/MatchingService/MatchingQuestion.js @@ -3,7 +3,7 @@ import { Fragment } from 'prosemirror-model'; import { findWrapping } from 'prosemirror-transform'; import { TextSelection } from 'prosemirror-state'; import { v4 as uuidv4 } from 'uuid'; -import { Tools } from 'wax-prosemirror-core'; +import { Tools, Commands } from 'wax-prosemirror-core'; import helpers from '../MultipleChoiceQuestionService/helpers/helpers'; @injectable() @@ -48,6 +48,20 @@ class MatchingQuestion extends Tools { }; } + get active() { + return state => { + if ( + Commands.isParentOfType( + state, + state.config.schema.nodes.matching_container, + ) + ) { + return true; + } + return false; + }; + } + select = (state, activeViewId, activeView) => { const { disallowedTools } = activeView.props; let status = true; @@ -61,13 +75,5 @@ class MatchingQuestion extends Tools { }); return status; }; - - get active() { - return state => {}; - } - - get enable() { - return state => {}; - } } export default MatchingQuestion; diff --git a/wax-prosemirror-services/src/MatchingService/components/ContainerEditor.js b/wax-prosemirror-services/src/MatchingService/components/ContainerEditor.js index 3d9c42641b542ed499d1168243c947d02719c386..f1f51e1780f298cdf0dffc5ce2cdfc2c75a73d05 100644 --- a/wax-prosemirror-services/src/MatchingService/components/ContainerEditor.js +++ b/wax-prosemirror-services/src/MatchingService/components/ContainerEditor.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -28,7 +26,7 @@ const EditorWrapper = styled.div` } `; -const ContainerEditor = ({ node, view, getPos, isEditable, autoFocus }) => { +const ContainerEditor = ({ node, view, getPos }) => { const editorRef = useRef(); const context = useContext(WaxContext); diff --git a/wax-prosemirror-services/src/MatchingService/components/EditorComponent.js b/wax-prosemirror-services/src/MatchingService/components/EditorComponent.js index c66af0e13360d20bb17dfcc7546391ed8086a037..6f2b08ca8d782e3b5292006b6b129d3cb72f35b2 100644 --- a/wax-prosemirror-services/src/MatchingService/components/EditorComponent.js +++ b/wax-prosemirror-services/src/MatchingService/components/EditorComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -89,7 +87,6 @@ const EditorComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, diff --git a/wax-prosemirror-services/src/MatchingService/components/FeedbackComponent.js b/wax-prosemirror-services/src/MatchingService/components/FeedbackComponent.js deleted file mode 100644 index 0d9bbec922a7b8142729f8c5ab7385c66d4e927c..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/MatchingService/components/FeedbackComponent.js +++ /dev/null @@ -1,80 +0,0 @@ -/* eslint-disable react/prop-types */ - -import React, { useContext, useRef, useState } from 'react'; -import styled from 'styled-components'; -import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; - -const FeedBack = styled.div` - color: black; - margin-top: 10px; -`; - -const FeedBackLabel = styled.span` - font-weight: 700; -`; - -const FeedBackInput = styled.input` - border: none; - border-bottom: 1px solid black; - display: flex; - width: 100%; - - &:focus { - outline: none; - } - - ::placeholder { - color: rgb(170, 170, 170); - font-style: italic; - } -`; - -export default ({ node, view, getPos, readOnly }) => { - const context = useContext(WaxContext); - const { - pmViews: { main }, - } = context; - const [feedBack, setFeedBack] = useState(node.attrs.feedback); - const feedBackRef = useRef(null); - - const feedBackInput = () => { - setFeedBack(feedBackRef.current.value); - const allNodes = getNodes(main); - allNodes.forEach(singleNode => { - if (singleNode.node.attrs.id === node.attrs.id) { - main.dispatch( - main.state.tr.setNodeMarkup(getPos(), undefined, { - ...singleNode.node.attrs, - feedback: feedBack, - }), - ); - } - }); - return false; - }; - - return ( - <FeedBack> - <FeedBackLabel>Feedback</FeedBackLabel> - <FeedBackInput - autoFocus="autoFocus" - disabled={readOnly} - onChange={feedBackInput} - placeholder="Insert feedback" - ref={feedBackRef} - type="text" - value={feedBack} - /> - </FeedBack> - ); -}; - -const getNodes = view => { - const allNodes = DocumentHelpers.findBlockNodes(view.state.doc); - const fillTheGapNodes = []; - allNodes.forEach(node => { - if (node.node.type.name === 'matching_container') - fillTheGapNodes.push(node); - }); - return fillTheGapNodes; -}; diff --git a/wax-prosemirror-services/src/MatchingService/components/MatchingContainerComponent.js b/wax-prosemirror-services/src/MatchingService/components/MatchingContainerComponent.js index d8560e271279fe31e3399b99e0a80641da5693da..8fe2c2ceef28d8d111d55845437931064a3600a4 100644 --- a/wax-prosemirror-services/src/MatchingService/components/MatchingContainerComponent.js +++ b/wax-prosemirror-services/src/MatchingService/components/MatchingContainerComponent.js @@ -1,10 +1,10 @@ /* eslint-disable react/destructuring-assignment */ -/* eslint-disable react/prop-types */ import React, { useContext, useEffect, useRef, useState } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { WaxContext, DocumentHelpers, Icon } from 'wax-prosemirror-core'; +import useDynamicRefs from 'use-dynamic-refs'; import styled from 'styled-components'; -import FeedbackComponent from './FeedbackComponent'; +import FeedbackComponent from '../../MultipleChoiceQuestionService/components/FeedbackComponent'; import ContainerEditor from './ContainerEditor'; const MatchingWrapper = styled.div` @@ -125,6 +125,7 @@ export default ({ node, view, getPos }) => { const [addingOption, setAddingOption] = useState(false); const addOptionRef = useRef(null); const addOptionBtnRef = useRef(null); + const [getRef, setRef] = useDynamicRefs(); const customProps = main.props.customValues; @@ -214,11 +215,37 @@ export default ({ node, view, getPos }) => { }); }; + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + options.forEach(option => { + if (document.activeElement === getRef(option.value).current) { + getRef(option.value).current.click(); + } + }); + } + }; + + options.forEach(option => { + if (getRef(option.value).current) + getRef(option.value).current.addEventListener('keydown', listener); + }); + + return () => { + options.forEach(option => { + if (getRef(option.value).current) + getRef(option.value).current.removeEventListener('keydown', listener); + }); + }; + }, [options]); + const { testMode } = customProps; + const { feedback } = node.attrs; return ( <MatchingWrapper> - <span>Matching</span> + {/* <span>Matching</span> */} <MatchingContainer className="matching"> <QuestionWrapper> <ContainerEditor getPos={getPos} node={node} view={view} /> @@ -230,7 +257,7 @@ export default ({ node, view, getPos }) => { {options.length > 0 && ( <ul> <li>Options: </li> - {options.map((option, index) => { + {options.map(option => { return ( <li key={option.value}> <span> @@ -238,6 +265,7 @@ export default ({ node, view, getPos }) => { {!readOnly && ( <ActionButton onClick={() => removeOption(option.value)} + ref={setRef(option.value)} type="button" > <StyledIconAction name="deleteOutlined" /> @@ -268,7 +296,7 @@ export default ({ node, view, getPos }) => { )} </CreateOptions> )} - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} diff --git a/wax-prosemirror-services/src/MatchingService/components/MatchingOptionComponent.js b/wax-prosemirror-services/src/MatchingService/components/MatchingOptionComponent.js index 1281931b692f5853019e3809dacbd42aa43e999f..ea42dc3a5f38f069af116a627e922ec98b6409a0 100644 --- a/wax-prosemirror-services/src/MatchingService/components/MatchingOptionComponent.js +++ b/wax-prosemirror-services/src/MatchingService/components/MatchingOptionComponent.js @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React, { useContext } from 'react'; import { v4 as uuidv4 } from 'uuid'; import { TextSelection } from 'prosemirror-state'; diff --git a/wax-prosemirror-services/src/MathService/BlockInputRule.js b/wax-prosemirror-services/src/MathService/BlockInputRule.js index 2ca7c909456b83f802b77a2a8d2f9a8958436b13..3c4f1d79c7c6501020c0e47d3c71800a8b652086 100644 --- a/wax-prosemirror-services/src/MathService/BlockInputRule.js +++ b/wax-prosemirror-services/src/MathService/BlockInputRule.js @@ -1,11 +1,10 @@ -/* eslint-disable */ import { InputRule } from 'prosemirror-inputrules'; import { NodeSelection } from 'prosemirror-state'; const blockInputRule = (pattern, nodeType, getAttrs) => { return new InputRule(pattern, (state, match, start, end) => { - let $start = state.doc.resolve(start); - let attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; + const $start = state.doc.resolve(start); + const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs; if ( !$start @@ -14,7 +13,7 @@ const blockInputRule = (pattern, nodeType, getAttrs) => { ) return null; - let tr = state.tr + const tr = state.tr .delete(start, end) .setBlockType(start, start, nodeType, attrs); return tr.setSelection( diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceNodeView.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceNodeView.js index 78a157c9c8e2d10c4f229f9d7f020c7e2484347d..99176684f90b789a134e0cda1444595bcf996adf 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceNodeView.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceNodeView.js @@ -23,7 +23,7 @@ export default class MultipleChoiceNodeView extends QuestionsNodeView { } stopEvent(event) { - if (event.target.type === 'text') { + if (event.target.type === 'textarea') { return true; } const innerView = this.context.pmViews[this.node.attrs.id]; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestion.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestion.js index c5dcabbb11629f41c174e5ad55964a54afcd9c65..e7a6b47518f54780afd8663d4d18a0b5974a77b3 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestion.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceQuestion.js @@ -51,7 +51,7 @@ class MultipleChoiceQuestion extends Tools { if (from === null) return false; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.groups.includes('questions')) { status = false; } @@ -59,14 +59,9 @@ class MultipleChoiceQuestion extends Tools { return status; }; - get enable() { - return state => {}; - } - renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ToolBarBtn item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestion.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestion.js index 078aa4d7e4884b32ff7920f6dc5ecf475b90fc46..0861b08bd6061989e6193fa71e4992c6b2b92c3c 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestion.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/MultipleChoiceSingleCorrectQuestion.js @@ -51,7 +51,7 @@ class MultipleChoiceSingleCorrectQuestion extends Tools { if (from === null) return false; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.groups.includes('questions')) { status = false; } @@ -59,14 +59,9 @@ class MultipleChoiceSingleCorrectQuestion extends Tools { return status; }; - get enable() { - return state => {}; - } - renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ToolBarBtn item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/components/AnswerComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/components/AnswerComponent.js index e7cd0222219c88534fc0ea64ed950fc25106de21..1210e87c4b439fac88f218e75534666e896c7c56 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/components/AnswerComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/components/AnswerComponent.js @@ -1,5 +1,4 @@ -/* eslint-disable react/prop-types */ -import React, { useContext } from 'react'; +import React, { useContext, useEffect, useRef } from 'react'; import styled from 'styled-components'; import { TextSelection, NodeSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers, Icon } from 'wax-prosemirror-core'; @@ -84,13 +83,45 @@ export default ({ node, view, getPos }) => { pmViews: { main }, } = context; - // eslint-disable-next-line react/destructuring-assignment const customProps = main.props.customValues; const isEditable = main.props.editable(editable => { return editable; }); + const addOptionBtnRef = useRef(null); + const removeOptionBtnRef = useRef(null); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (addOptionBtnRef.current) addOptionBtnRef.current.click(); + } + }; + if (addOptionBtnRef.current) + addOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (addOptionBtnRef.current) + addOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (removeOptionBtnRef.current) removeOptionBtnRef.current.click(); + } + }; + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + const removeOption = () => { const answersCount = findAnswerCount(); if (answersCount.count >= 1) { @@ -162,7 +193,7 @@ export default ({ node, view, getPos }) => { }); let count = -1; - parentContainer.descendants((element, position) => { + parentContainer.descendants(element => { if (element.type.name === 'multiple_choice_single_correct') { count += 1; } @@ -173,6 +204,7 @@ export default ({ node, view, getPos }) => { const readOnly = !isEditable; const { testMode } = customProps; + const { feedback } = node.attrs; return ( <Wrapper> @@ -185,7 +217,7 @@ export default ({ node, view, getPos }) => { <QuestionData> <EditorComponent getPos={getPos} node={node} view={view} /> </QuestionData> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} @@ -197,12 +229,20 @@ export default ({ node, view, getPos }) => { </QuestionControlsWrapper> <IconsWrapper> {!readOnly && ( - <ActionButton onClick={() => addOption(node.attrs.id)} type="button"> + <ActionButton + onClick={() => addOption(node.attrs.id)} + ref={addOptionBtnRef} + type="button" + > <StyledIconAction name="plusSquare" /> </ActionButton> )} {!readOnly && ( - <ActionButton onClick={removeOption} type="button"> + <ActionButton + onClick={removeOption} + ref={removeOptionBtnRef} + type="button" + > <StyledIconAction name="deleteOutlined" /> </ActionButton> )} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestion.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestion.js index b7fd6b8f2a4902918a51424a0be5e7dfc49674a6..d2dc43cfbc53bfcae8d1c230815c9e3a716d289b 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestion.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/TrueFalseQuestion.js @@ -48,7 +48,7 @@ class TrueFalseQuestion extends Tools { if (from === null) return false; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.groups.includes('questions')) { status = false; } @@ -56,14 +56,9 @@ class TrueFalseQuestion extends Tools { return status; }; - get enable() { - return state => {}; - } - renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ToolBarBtn item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/AnswerComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/AnswerComponent.js index 7929580ff2e6a19695f49d32c036e4525b3c38eb..c96a6251f7560067298c4f390545f72ba4c6cc71 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/AnswerComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/AnswerComponent.js @@ -1,5 +1,4 @@ -/* eslint-disable react/prop-types */ -import React, { useContext } from 'react'; +import React, { useContext, useEffect, useRef } from 'react'; import styled from 'styled-components'; import { TextSelection, NodeSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers, Icon } from 'wax-prosemirror-core'; @@ -90,6 +89,39 @@ export default ({ node, view, getPos }) => { return editable; }); + const addOptionBtnRef = useRef(null); + const removeOptionBtnRef = useRef(null); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (addOptionBtnRef.current) addOptionBtnRef.current.click(); + } + }; + if (addOptionBtnRef.current) + addOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (addOptionBtnRef.current) + addOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (removeOptionBtnRef.current) removeOptionBtnRef.current.click(); + } + }; + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + const removeOption = () => { const answersCount = findAnswerCount(); if (answersCount.count >= 1) { @@ -161,7 +193,7 @@ export default ({ node, view, getPos }) => { }); let count = -1; - parentContainer.descendants((element, position) => { + parentContainer.descendants(element => { if (element.type.name === 'true_false') { count += 1; } @@ -172,6 +204,7 @@ export default ({ node, view, getPos }) => { const readOnly = !isEditable; const { testMode } = customProps; + const { feedback } = node.attrs; return ( <Wrapper> @@ -184,7 +217,7 @@ export default ({ node, view, getPos }) => { <QuestionData> <EditorComponent getPos={getPos} node={node} view={view} /> </QuestionData> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} @@ -196,12 +229,20 @@ export default ({ node, view, getPos }) => { </QuestionControlsWrapper> <IconsWrapper> {!readOnly && ( - <ActionButton onClick={() => addOption(node.attrs.id)} type="button"> + <ActionButton + onClick={() => addOption(node.attrs.id)} + ref={addOptionBtnRef} + type="button" + > <StyledIconAction name="plusSquare" /> </ActionButton> )} {!readOnly && ( - <ActionButton onClick={removeOption} type="button"> + <ActionButton + onClick={removeOption} + ref={removeOptionBtnRef} + type="button" + > <StyledIconAction name="deleteOutlined" /> </ActionButton> )} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/SwitchComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/SwitchComponent.js index 9b0dd0edc964ac252235a35881b8bb80c64f2290..5fdd636b329035a9e165d420d90fd2cf23c5101e 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/SwitchComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseQuestionService/components/SwitchComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useState, useContext, useEffect } from 'react'; import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; import TrueFalseSwitch from './TrueFalseSwitch'; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestion.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestion.js index ee320f1eb54f0db8c293117943ddf3d4e82175a5..ce39f1988a081d0aea143e10a8fc947b22c50963 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestion.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/TrueFalseSingleCorrectQuestion.js @@ -51,7 +51,7 @@ class TrueFalseSingleCorrectQuestion extends Tools { if (from === null) return false; - state.doc.nodesBetween(from, to, (node, pos) => { + state.doc.nodesBetween(from, to, node => { if (node.type.groups.includes('questions')) { status = false; } @@ -59,14 +59,9 @@ class TrueFalseSingleCorrectQuestion extends Tools { return status; }; - get enable() { - return state => {}; - } - renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <ToolBarBtn item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/components/AnswerComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/components/AnswerComponent.js index 6ece29738b8d5a41c40b0fa8d2efbb50215fab20..707d0eaf585ca185c4e1ab91cf5e1e88366f7915 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/components/AnswerComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/components/AnswerComponent.js @@ -1,5 +1,4 @@ -/* eslint-disable react/prop-types */ -import React, { useContext } from 'react'; +import React, { useContext, useEffect, useRef } from 'react'; import styled from 'styled-components'; import { TextSelection, NodeSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers, Icon } from 'wax-prosemirror-core'; @@ -90,6 +89,39 @@ export default ({ node, view, getPos }) => { return editable; }); + const addOptionBtnRef = useRef(null); + const removeOptionBtnRef = useRef(null); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (addOptionBtnRef.current) addOptionBtnRef.current.click(); + } + }; + if (addOptionBtnRef.current) + addOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (addOptionBtnRef.current) + addOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (removeOptionBtnRef.current) removeOptionBtnRef.current.click(); + } + }; + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + const removeOption = () => { const answersCount = findAnswerCount(); if (answersCount.count >= 1) { @@ -172,6 +204,7 @@ export default ({ node, view, getPos }) => { const readOnly = !isEditable; const { testMode } = customProps; + const { feedback } = node.attrs; return ( <Wrapper> @@ -184,7 +217,7 @@ export default ({ node, view, getPos }) => { <QuestionData> <EditorComponent getPos={getPos} node={node} view={view} /> </QuestionData> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} @@ -196,12 +229,20 @@ export default ({ node, view, getPos }) => { </QuestionControlsWrapper> <IconsWrapper> {!readOnly && ( - <ActionButton onClick={() => addOption(node.attrs.id)} type="button"> + <ActionButton + onClick={() => addOption(node.attrs.id)} + ref={addOptionBtnRef} + type="button" + > <StyledIconAction name="plusSquare" /> </ActionButton> )} {!readOnly && ( - <ActionButton onClick={removeOption} type="button"> + <ActionButton + onClick={removeOption} + ref={removeOptionBtnRef} + type="button" + > <StyledIconAction name="deleteOutlined" /> </ActionButton> )} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/AnswerComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/AnswerComponent.js index db77cb66ab31161d829979219a83a92b443d6fce..bd696b59e21cc48e6ed37e435b9efb76d4c3d17e 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/AnswerComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/AnswerComponent.js @@ -1,5 +1,4 @@ -/* eslint-disable react/prop-types */ -import React, { useContext } from 'react'; +import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { TextSelection, NodeSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers, Icon } from 'wax-prosemirror-core'; @@ -89,11 +88,43 @@ export default ({ node, view, getPos }) => { const isEditable = main.props.editable(editable => { return editable; }); + const addOptionBtnRef = useRef(null); + const removeOptionBtnRef = useRef(null); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (addOptionBtnRef.current) addOptionBtnRef.current.click(); + } + }; + if (addOptionBtnRef.current) + addOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (addOptionBtnRef.current) + addOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); + + useEffect(() => { + const listener = event => { + if (event.code === 'Enter') { + event.preventDefault(); + if (removeOptionBtnRef.current) removeOptionBtnRef.current.click(); + } + }; + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.addEventListener('keydown', listener); + return () => { + if (removeOptionBtnRef.current) + removeOptionBtnRef.current.removeEventListener('keydown', listener); + }; + }, []); const removeOption = () => { const answersCount = findAnswerCount(); if (answersCount.count >= 1) { - main.state.doc.nodesBetween(getPos(), getPos() + 1, (sinlgeNode, pos) => { + main.state.doc.nodesBetween(getPos(), getPos() + 1, sinlgeNode => { if (sinlgeNode.attrs.id === node.attrs.id) { main.dispatch( main.state.tr.deleteRange(getPos(), getPos() + sinlgeNode.nodeSize), @@ -160,7 +191,7 @@ export default ({ node, view, getPos }) => { }); let count = -1; - parentContainer.descendants((element, position) => { + parentContainer.descendants(element => { if (element.type.name === 'multiple_choice') { count += 1; } @@ -171,6 +202,7 @@ export default ({ node, view, getPos }) => { const readOnly = !isEditable; const { testMode } = customProps; + const { feedback } = node.attrs; return ( <Wrapper> @@ -183,7 +215,7 @@ export default ({ node, view, getPos }) => { <QuestionData> <EditorComponent getPos={getPos} node={node} view={view} /> </QuestionData> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} @@ -195,12 +227,20 @@ export default ({ node, view, getPos }) => { </QuestionControlsWrapper> <IconsWrapper> {!readOnly && ( - <ActionButton onClick={() => addOption(node.attrs.id)} type="button"> + <ActionButton + onClick={() => addOption(node.attrs.id)} + ref={addOptionBtnRef} + type="button" + > <StyledIconAction name="plusSquare" /> </ActionButton> )} {!readOnly && ( - <ActionButton onClick={removeOption} type="button"> + <ActionButton + onClick={removeOption} + ref={removeOptionBtnRef} + type="button" + > <StyledIconAction name="deleteOutlined" /> </ActionButton> )} diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/EditorComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/EditorComponent.js index a8aecaa678fcde9743de7775bd4c8eda2359fdd6..59f95977f4001754d838af4479cd3948dd57d0ac 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/EditorComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/EditorComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -86,7 +84,6 @@ const EditorComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/FeedbackComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/FeedbackComponent.js index 6a289b04554e9296bfa600b0f702baca01a0a4e9..ade5c99e78e6d798eb9038de820a360f59f7c097 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/FeedbackComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/FeedbackComponent.js @@ -1,7 +1,6 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useState } from 'react'; import styled from 'styled-components'; +import { TextSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; const FeedBack = styled.div` @@ -13,10 +12,27 @@ const FeedBackLabel = styled.span` font-weight: 700; `; -const FeedBackInput = styled.input` +const FeedBackInput = styled.textarea` border: none; display: flex; + font-family: Fira Sans Condensed; width: 100%; + resize: vertical; + white-space: pre-wrap; + overflow-wrap: break-word; + + background-attachment: local; + background-image: linear-gradient(to right, white 10px, transparent 10px), + linear-gradient(to left, white 10px, transparent 10px), + repeating-linear-gradient( + white, + white 30px, + #ccc 30px, + #ccc 31px, + white 31px + ); + line-height: 31px; + padding: 8px 10px; &:focus { outline: none; @@ -28,7 +44,7 @@ const FeedBackInput = styled.input` } `; -export default ({ node, view, getPos, readOnly }) => { +export default ({ node, getPos, readOnly }) => { const context = useContext(WaxContext); const { pmViews: { main }, @@ -50,18 +66,43 @@ export default ({ node, view, getPos, readOnly }) => { ); } }); + setNullSelection(); + setHeight(); return false; }; + const setHeight = () => { + const textarea = feedBackRef.current; + if (!textarea) return; + const heightLimit = 200; + textarea.style.height = ''; + textarea.style.height = `${Math.min(textarea.scrollHeight, heightLimit)}px`; + }; + + const setNullSelection = () => { + main.dispatch( + main.state.tr.setSelection(TextSelection.create(main.state.tr.doc, null)), + ); + }; + + const onFocus = () => { + setTimeout(() => { + setNullSelection(); + }, 50); + }; + return ( <FeedBack> <FeedBackLabel>Feedback</FeedBackLabel> <FeedBackInput autoFocus="autoFocus" onChange={feedBackInput} + onFocus={onFocus} placeholder="Insert feedback" readOnly={readOnly} ref={feedBackRef} + rows="1" + style={{ height: setHeight() }} type="text" value={feedBack} /> @@ -77,7 +118,10 @@ const getNodes = view => { node.node.type.name === 'multiple_choice' || node.node.type.name === 'multiple_choice_single_correct' || node.node.type.name === 'true_false' || - node.node.type.name === 'true_false_single_correct' + node.node.type.name === 'true_false_single_correct' || + node.node.type.name === 'matching_container' || + node.node.type.name === 'fill_the_gap_container' || + node.node.type.name === 'multiple_drop_down_container' ) { multipleChoiceNodes.push(node); } diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionComponent.js index 0cb0e8b3fd5ce38b63da210ea55563e056a8d31c..90c2772b1721a19247b2e98e4b7ee9c099ed1c0a 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionComponent.js @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React from 'react'; import QuestionEditorComponent from './QuestionEditorComponent'; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionEditorComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionEditorComponent.js index abbe5724afa7f185037be528417fecb51c368a03..bd653c9b74ade6fbef96b0e0123c896d6cee71a7 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionEditorComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/QuestionEditorComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; @@ -8,7 +6,7 @@ import { StepMap } from 'prosemirror-transform'; import { keymap } from 'prosemirror-keymap'; import { baseKeymap, chainCommands } from 'prosemirror-commands'; import { undo, redo } from 'prosemirror-history'; -import { WaxContext } from 'wax-prosemirror-core'; +import { WaxContext, ComponentPlugin } from 'wax-prosemirror-core'; import { splitListItem, liftListItem, @@ -56,6 +54,9 @@ const EditorWrapper = styled.div` } } `; + +let WaxOverlays = () => true; + const QuestionEditorComponent = ({ node, view, getPos }) => { const editorRef = useRef(); @@ -120,7 +121,6 @@ const QuestionEditorComponent = ({ node, view, getPos }) => { const plugins = [keymap(createKeyBindings()), ...app.getPlugins()]; - // eslint-disable-next-line no-shadow const createPlaceholder = placeholder => { return Placeholder({ content: placeholder, @@ -133,6 +133,7 @@ const QuestionEditorComponent = ({ node, view, getPos }) => { ]); useEffect(() => { + WaxOverlays = ComponentPlugin('waxOverlays'); questionView = new EditorView( { mount: editorRef.current, @@ -209,6 +210,7 @@ const QuestionEditorComponent = ({ node, view, getPos }) => { return ( <EditorWrapper> <div ref={editorRef} /> + <WaxOverlays activeViewId={questionId} /> </EditorWrapper> ); }; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/SwitchComponent.js b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/SwitchComponent.js index f93f57e83090308138916a5700373bbf4b656d68..cdf6481287a05ca6c69f508a1a919b8be9a42333 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/SwitchComponent.js +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/components/SwitchComponent.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useState, useContext, useEffect } from 'react'; import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; import YesNoSwitch from './YesNoSwitch'; @@ -9,7 +7,6 @@ const CustomSwitch = ({ node, getPos }) => { const [checked, setChecked] = useState(false); const [checkedAnswerMode, setCheckedAnswerMode] = useState(false); const { - pmViews, pmViews: { main }, } = context; diff --git a/wax-prosemirror-services/src/MultipleChoiceQuestionService/multipleQuestionStyles.css b/wax-prosemirror-services/src/MultipleChoiceQuestionService/multipleQuestionStyles.css index 7982754a5140574dae07e471d0c5b0bfe3149996..f35d630133fada470ad4809d2d207459caf3ac0c 100644 --- a/wax-prosemirror-services/src/MultipleChoiceQuestionService/multipleQuestionStyles.css +++ b/wax-prosemirror-services/src/MultipleChoiceQuestionService/multipleQuestionStyles.css @@ -29,7 +29,7 @@ } -.multiple-choice:before { +/* .multiple-choice:before { content: 'Multiple Choice' ; } @@ -43,7 +43,7 @@ .true-false-single-correct:before { content: 'True False Single Correct'; -} +} */ .rc-switch { position: relative; diff --git a/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownContainerNodeView.js b/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownContainerNodeView.js index fe43906a40ab6a4841cbc03c275aa607e8d873ad..5db50ef91e627ed3f8fb3bf09f88f6f12deb1bfb 100644 --- a/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownContainerNodeView.js +++ b/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownContainerNodeView.js @@ -23,7 +23,7 @@ export default class MultipleDropDownContainerNodeView extends QuestionsNodeView } stopEvent(event) { - if (event.target.type === 'text') { + if (event.target.type === 'textarea') { return true; } const innerView = this.context.pmViews[this.node.attrs.id]; diff --git a/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownQuestion.js b/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownQuestion.js index c1b56c46c442c1f85de1e9c7d2d352e2369b5f3e..caf9d6b45a5905f837330bc08e6522c85020dbb0 100644 --- a/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownQuestion.js +++ b/wax-prosemirror-services/src/MultipleDropDownService/MultipleDropDownQuestion.js @@ -1,7 +1,7 @@ import { injectable } from 'inversify'; import { findWrapping } from 'prosemirror-transform'; import { v4 as uuidv4 } from 'uuid'; -import { Tools } from 'wax-prosemirror-core'; +import { Tools, Commands } from 'wax-prosemirror-core'; import helpers from '../MultipleChoiceQuestionService/helpers/helpers'; @injectable() @@ -35,7 +35,17 @@ class MultipleDropDownQuestion extends Tools { } get active() { - return state => {}; + return state => { + if ( + Commands.isParentOfType( + state, + state.config.schema.nodes.multiple_drop_down_container, + ) + ) { + return true; + } + return false; + }; } select = (state, activeViewId, activeView) => { diff --git a/wax-prosemirror-services/src/MultipleDropDownService/components/ContainerEditor.js b/wax-prosemirror-services/src/MultipleDropDownService/components/ContainerEditor.js index 86ef1684ceff8c17296a61fa5f6efd2d76e34102..71632a7df8370379ef6656d2c1c1e218bff3fba9 100644 --- a/wax-prosemirror-services/src/MultipleDropDownService/components/ContainerEditor.js +++ b/wax-prosemirror-services/src/MultipleDropDownService/components/ContainerEditor.js @@ -1,5 +1,3 @@ -/* eslint-disable react/prop-types */ - import React, { useContext, useRef, useEffect } from 'react'; import styled from 'styled-components'; import { EditorView } from 'prosemirror-view'; diff --git a/wax-prosemirror-services/src/MultipleDropDownService/components/FeedbackComponent.js b/wax-prosemirror-services/src/MultipleDropDownService/components/FeedbackComponent.js deleted file mode 100644 index 92c510744d181fdaa5d546096e16d2f684a1478f..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/MultipleDropDownService/components/FeedbackComponent.js +++ /dev/null @@ -1,81 +0,0 @@ -/* eslint-disable react/prop-types */ - -import React, { useContext, useRef, useState } from 'react'; -import styled from 'styled-components'; -import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; - -const FeedBack = styled.div` - color: black; - margin-top: 10px; - padding: 10px; -`; - -const FeedBackLabel = styled.span` - font-weight: 700; -`; - -const FeedBackInput = styled.input` - border: none; - border-bottom: 1px solid black; - display: flex; - width: 100%; - - &:focus { - outline: none; - } - - ::placeholder { - color: rgb(170, 170, 170); - font-style: italic; - } -`; - -export default ({ node, view, getPos, readOnly }) => { - const context = useContext(WaxContext); - const { - pmViews: { main }, - } = context; - const [feedBack, setFeedBack] = useState(node.attrs.feedback); - const feedBackRef = useRef(null); - - const feedBackInput = () => { - setFeedBack(feedBackRef.current.value); - const allNodes = getNodes(main); - allNodes.forEach(singleNode => { - if (singleNode.node.attrs.id === node.attrs.id) { - main.dispatch( - main.state.tr.setNodeMarkup(getPos(), undefined, { - ...singleNode.node.attrs, - feedback: feedBackRef.current.value, - }), - ); - } - }); - return false; - }; - - return ( - <FeedBack> - <FeedBackLabel>Feedback</FeedBackLabel> - <FeedBackInput - autoFocus="autoFocus" - disabled={readOnly} - onChange={feedBackInput} - placeholder="Insert feedback" - ref={feedBackRef} - type="text" - value={feedBack} - /> - </FeedBack> - ); -}; - -const getNodes = view => { - const allNodes = DocumentHelpers.findBlockNodes(view.state.doc); - const fillTheGapNodes = []; - allNodes.forEach(node => { - if (node.node.type.name === 'multiple_drop_down_container') - fillTheGapNodes.push(node); - }); - return fillTheGapNodes; -}; diff --git a/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownComponent.js b/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownComponent.js index 7d8f557de9032b1ec10533b39fb865e584b49aac..bf35fc9a43605d52b0d538349732d54ba08ace4b 100644 --- a/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownComponent.js +++ b/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownComponent.js @@ -1,4 +1,3 @@ -/* eslint-disable react/prop-types */ import React, { useContext, useEffect, useState } from 'react'; import { WaxContext, Icon } from 'wax-prosemirror-core'; import styled, { css } from 'styled-components'; @@ -41,7 +40,7 @@ const CorrectAnswer = styled.span``; const Answer = styled.span``; -export default ({ node, view, getPos }) => { +export default ({ node, getPos }) => { const context = useContext(WaxContext); const { pmViews: { main }, diff --git a/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownContainerComponent.js b/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownContainerComponent.js index 182c356d02bc2e3606b09d26574f1c32e776139a..174dd6cdd01c7e1b614910bd187e9fe8280cbd96 100644 --- a/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownContainerComponent.js +++ b/wax-prosemirror-services/src/MultipleDropDownService/components/MultipleDropDownContainerComponent.js @@ -1,9 +1,8 @@ -/* eslint-disable react/prop-types */ import React, { useContext } from 'react'; import { WaxContext, ComponentPlugin } from 'wax-prosemirror-core'; import styled from 'styled-components'; import ContainerEditor from './ContainerEditor'; -import FeedbackComponent from './FeedbackComponent'; +import FeedbackComponent from '../../MultipleChoiceQuestionService/components/FeedbackComponent'; const MultipleDropDownpWrapper = styled.div` margin: 0px 38px 15px 38px; @@ -41,18 +40,21 @@ export default ({ node, view, getPos }) => { const readOnly = !isEditable; const { testMode } = customProps; + const { feedback } = node.attrs; return ( <MultipleDropDownpWrapper> <div> - <span>Multiple Drop Down</span> - <MultipleDropDownContainerTool> - <MultipleDropDown /> - </MultipleDropDownContainerTool> + {/* <span>Multiple Drop Down</span> */} + {!testMode && !readOnly && ( + <MultipleDropDownContainerTool> + <MultipleDropDown /> + </MultipleDropDownContainerTool> + )} </div> <MultipleDropDownpContainer className="multiple-drop-down"> <ContainerEditor getPos={getPos} node={node} view={view} /> - {!testMode && ( + {!testMode && !(readOnly && feedback === '') && ( <FeedbackComponent getPos={getPos} node={node} diff --git a/wax-prosemirror-services/src/OENContainersService/PopulateHeadingsComponent.js b/wax-prosemirror-services/src/OENContainersService/PopulateHeadingsComponent.js index c3320f7ab6caa4aa162777064ea9a147acbca00b..b8c4b26505def180cc15baf841af693184f9d6a9 100644 --- a/wax-prosemirror-services/src/OENContainersService/PopulateHeadingsComponent.js +++ b/wax-prosemirror-services/src/OENContainersService/PopulateHeadingsComponent.js @@ -81,7 +81,7 @@ export default ({ setPosition, position }) => { const allSectionNodes = []; const sectionHeadings = {}; - doc.descendants((editorNode, index) => { + doc.descendants(editorNode => { if (editorNode.type.name === 'oen_section') { allSectionNodes.push(editorNode); } diff --git a/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersTool.js b/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersTool.js index 559ba2d52faec1ddc0ad50e9c9556c35a4d8629d..c56accbc192cf2058c00454e02ea0b67cc1a218b 100644 --- a/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersTool.js +++ b/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersTool.js @@ -12,7 +12,7 @@ export default class SpecialCharacters extends Tools { name = 'specialCharacters'; get enable() { - return state => { + return () => { return true; }; } @@ -20,7 +20,7 @@ export default class SpecialCharacters extends Tools { renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <SpecialCharactersTool item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/SpecialCharactersService/components/SpecialCharactersTool.js b/wax-prosemirror-services/src/SpecialCharactersService/components/SpecialCharactersTool.js index fb9f15f176c38dce1ea5fc1fb43a55a36cf9825d..0389b28a1441d35ed6a76d9bb60b4a2969403b36 100644 --- a/wax-prosemirror-services/src/SpecialCharactersService/components/SpecialCharactersTool.js +++ b/wax-prosemirror-services/src/SpecialCharactersService/components/SpecialCharactersTool.js @@ -21,7 +21,7 @@ const DropWrapper = styled.div` top: 32px; `; -const SpecialCharactersTool = ({ view = {}, item }) => { +const SpecialCharactersTool = ({ item }) => { const { pmViews: { main }, } = useContext(WaxContext); diff --git a/wax-prosemirror-services/src/TablesService/EditTableService/TableDropDownOptions.js b/wax-prosemirror-services/src/TablesService/EditTableService/TableDropDownOptions.js index eb7de94ed06613ad2c12d55b3dc31da8e3f0eed8..5b89a5335ce32b234ac949ae0efc5ecee7922294 100644 --- a/wax-prosemirror-services/src/TablesService/EditTableService/TableDropDownOptions.js +++ b/wax-prosemirror-services/src/TablesService/EditTableService/TableDropDownOptions.js @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import React from 'react'; import { v4 as uuidv4 } from 'uuid'; import { injectable } from 'inversify'; @@ -30,7 +29,7 @@ export default class TableDropDownOptions extends Tools { renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <TableDropDown item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TablesService/InsertTableService/Table.js b/wax-prosemirror-services/src/TablesService/InsertTableService/Table.js index 1c66b83f5ea40c87a0506c97d243638705eb53e1..0da67a526420dca15a4889455c4e6be59667a6f4 100644 --- a/wax-prosemirror-services/src/TablesService/InsertTableService/Table.js +++ b/wax-prosemirror-services/src/TablesService/InsertTableService/Table.js @@ -35,9 +35,7 @@ export default class Table extends Tools { renderTool(view) { if (isEmpty(view)) return null; - - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <CreateTable item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TablesService/components/CreateTable.js b/wax-prosemirror-services/src/TablesService/components/CreateTable.js index 4826da9ae9eb968c44b8916621b3161075554b5f..e3fccffe04cfa49282df34eca1a2c7030a974784 100644 --- a/wax-prosemirror-services/src/TablesService/components/CreateTable.js +++ b/wax-prosemirror-services/src/TablesService/components/CreateTable.js @@ -21,7 +21,7 @@ const DropWrapper = styled.div` position: absolute; `; -const CreateTable = ({ view = {}, item }) => { +const CreateTable = ({ item }) => { const { pmViews: { main }, activeView, diff --git a/wax-prosemirror-services/src/TablesService/components/InsertTableTool.js b/wax-prosemirror-services/src/TablesService/components/InsertTableTool.js index 9e85eaaf9ead36e93d2d91e4011da48f7bd12b27..52197e38e617d77224304ad4d4b199043841ad10 100644 --- a/wax-prosemirror-services/src/TablesService/components/InsertTableTool.js +++ b/wax-prosemirror-services/src/TablesService/components/InsertTableTool.js @@ -4,15 +4,7 @@ * TO DO -- Implement a gdocs-style CSS only solution to dramatically cut back on renders */ -/* eslint-disable react/jsx-handler-names */ -/* eslint-disable react/destructuring-assignment */ -/* eslint-disable react/no-find-dom-node */ -/* eslint-disable no-underscore-dangle */ -/* eslint-disable no-plusplus */ -/* eslint-disable prefer-template */ -/* eslint-disable prefer-destructuring */ -/* eslint-disable max-classes-per-file */ -/* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable*/ import React, { useEffect, useState } from 'react'; import PropTypes from 'prop-types'; diff --git a/wax-prosemirror-services/src/TextBlockLevel/BlockQuoteService/BlockQuote.js b/wax-prosemirror-services/src/TextBlockLevel/BlockQuoteService/BlockQuote.js index f8744d10f35a53ac39f08798030e8f3e587f31cd..7312a0358401c2c08b4a181dfad0f7353aea7b8f 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/BlockQuoteService/BlockQuote.js +++ b/wax-prosemirror-services/src/TextBlockLevel/BlockQuoteService/BlockQuote.js @@ -44,8 +44,7 @@ class BlockQuote extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/ExtractPoetry.js b/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/ExtractPoetry.js index 59b37c8e8934581e578844a713667f4249079fe5..8442508266700dfe68caef83c259809f588c71df 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/ExtractPoetry.js +++ b/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/ExtractPoetry.js @@ -40,8 +40,7 @@ class ExtractPoetry extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/ExtractProse.js b/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/ExtractProse.js index ef2186bc7b42555b411b35a495dab3533354dc0c..6fd34b2df6628b75e0f38075497acd499c1cb9ab 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/ExtractProse.js +++ b/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/ExtractProse.js @@ -40,8 +40,7 @@ class ExtractProse extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/ParagraphContinued.js b/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/ParagraphContinued.js index 928fc7c907c50ea749e12bf93bceeee79022ba48..088a9bb5bc027ed2bd7443f0c6d14b3c5f27c4de 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/ParagraphContinued.js +++ b/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/ParagraphContinued.js @@ -40,8 +40,7 @@ class ParagraphContinued extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/ParagraphService/Paragraph.js b/wax-prosemirror-services/src/TextBlockLevel/ParagraphService/Paragraph.js index 45f652282bf953a1039fb14b62911d9327723da7..c5284251d923b70b99c7d2c097116ad9c8753cc2 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/ParagraphService/Paragraph.js +++ b/wax-prosemirror-services/src/TextBlockLevel/ParagraphService/Paragraph.js @@ -36,8 +36,7 @@ export default class Paragraph extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/SourceNote.js b/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/SourceNote.js index d261b4c27545d091e4df5576277ad64330d9af47..ea4e6871830eeaaaaf1890329203570d88a8ee73 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/SourceNote.js +++ b/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/SourceNote.js @@ -36,8 +36,7 @@ class SourceNote extends Tools { renderTool(view) { if (isEmpty(view)) return null; - // eslint-disable-next-line no-underscore-dangle - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <LeftSideButton item={this.toJSON()} key="BlockQuote" view={view} /> ) : null; } diff --git a/wax-prosemirror-services/src/TextBlockLevel/index.js b/wax-prosemirror-services/src/TextBlockLevel/index.js index 7506441049eced9f65d37eb4a3e2a2b6fe2875be..011f2941e73d71fdd81052100325f08af5762e97 100644 --- a/wax-prosemirror-services/src/TextBlockLevel/index.js +++ b/wax-prosemirror-services/src/TextBlockLevel/index.js @@ -1,9 +1,9 @@ -import ExtractPoetryService from "./ExtractPoetryService/ExtractPoetryService"; -import ExtractProseService from "./ExtractProseService/ExtractProseService"; -import ParagraphContinuedService from "./ParagraphContinuedService/ParagraphContinuedService"; -import ParagraphService from "./ParagraphService/ParagraphService"; -import SourceNoteService from "./SourceNoteService/SourceNoteService"; -import BlockQuoteService from "./BlockQuoteService/BlockQuoteService"; +import ExtractPoetryService from './ExtractPoetryService/ExtractPoetryService'; +import ExtractProseService from './ExtractProseService/ExtractProseService'; +import ParagraphContinuedService from './ParagraphContinuedService/ParagraphContinuedService'; +import ParagraphService from './ParagraphService/ParagraphService'; +import SourceNoteService from './SourceNoteService/SourceNoteService'; +import BlockQuoteService from './BlockQuoteService/BlockQuoteService'; export default [ new ExtractPoetryService(), @@ -11,5 +11,5 @@ export default [ new ParagraphContinuedService(), new ParagraphService(), new SourceNoteService(), - new BlockQuoteService() + new BlockQuoteService(), ]; diff --git a/wax-prosemirror-services/src/TrackChangeService/EnableTrackChangeService/EnableTrackChange.js b/wax-prosemirror-services/src/TrackChangeService/EnableTrackChangeService/EnableTrackChange.js index f428cade637362eeab1ee8630f1b2ffae05addc0..03a7af0d8d981f39b2198e4cd0a199edb24b6024 100644 --- a/wax-prosemirror-services/src/TrackChangeService/EnableTrackChangeService/EnableTrackChange.js +++ b/wax-prosemirror-services/src/TrackChangeService/EnableTrackChangeService/EnableTrackChange.js @@ -1,4 +1,3 @@ -/* eslint-disable no-unused-vars */ import React from 'react'; import { injectable } from 'inversify'; import { isEmpty } from 'lodash'; @@ -13,21 +12,21 @@ export default class EnableTrackChange extends Tools { name = 'EnableTrackChange'; get run() { - return state => { + return () => { this.config.enabled = !this.config.enabled; return true; }; } get enable() { - return state => { + return () => { return true; }; } renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( + return this.isDisplayed() ? ( <TrackChangeEnable enabled={this.config.enabled} item={this.toJSON()} diff --git a/wax-prosemirror-services/src/TrackOptionsService/TrackOptionsTool.js b/wax-prosemirror-services/src/TrackOptionsService/TrackOptionsTool.js index 338a2855867f472f7db1688fbb672ff12a4fef33..24078a5a01f2fda7ca5a2b601fdc767f8ee48e64 100644 --- a/wax-prosemirror-services/src/TrackOptionsService/TrackOptionsTool.js +++ b/wax-prosemirror-services/src/TrackOptionsService/TrackOptionsTool.js @@ -12,7 +12,7 @@ export default class SpecialCharacters extends Tools { name = 'trackchangeoptions'; get enable() { - return state => { + return () => { return true; }; } @@ -20,8 +20,8 @@ export default class SpecialCharacters extends Tools { renderTool(view) { if (isEmpty(view)) return null; - return this._isDisplayed ? ( - <TrackChangeOptionsTool key={uuidv4()} item={this.toJSON()} view={view} /> + return this.isDisplayed() ? ( + <TrackChangeOptionsTool item={this.toJSON()} key={uuidv4()} view={view} /> ) : null; } } diff --git a/wax-prosemirror-services/src/TrackOptionsService/components/TrackChangeOptionsComponent.js b/wax-prosemirror-services/src/TrackOptionsService/components/TrackChangeOptionsComponent.js index 9c4f9b31d0a8b7cba6d42d8e0957b3206adda0cb..733454d01417bb9fc9f77f8ab0c8487e3c5516fd 100644 --- a/wax-prosemirror-services/src/TrackOptionsService/components/TrackChangeOptionsComponent.js +++ b/wax-prosemirror-services/src/TrackOptionsService/components/TrackChangeOptionsComponent.js @@ -1,6 +1,5 @@ /* eslint-disable react/prop-types */ -/* eslint-disable array-callback-return */ -import React, { useContext, useState } from 'react'; +import React, { useContext } from 'react'; import styled from 'styled-components'; import { grid } from '@pubsweet/ui-toolkit'; import { each } from 'lodash'; @@ -160,31 +159,31 @@ const getTrackBlockNodes = main => { return trackBlockNodes; }; -const getComments = main => { - const comments = []; - const commentsNodes = DocumentHelpers.findChildrenByMark( - main.state.doc, - main.state.schema.marks.comment, - true, - ); - commentsNodes.map(node => { - if (node.node.marks.length > 0) { - node.node.marks.filter(mark => { - if (mark.type.name === 'comment') { - comments.push(mark); - } - }); - } - }); - return [...new Set(comments.map(item => item.attrs.id))]; -}; +// const getComments = main => { +// const comments = []; +// const commentsNodes = DocumentHelpers.findChildrenByMark( +// main.state.doc, +// main.state.schema.marks.comment, +// true, +// ); +// commentsNodes.map(node => { +// if (node.node.marks.length > 0) { +// node.node.marks.filter(mark => { +// if (mark.type.name === 'comment') { +// comments.push(mark); +// } +// }); +// } +// }); +// return [...new Set(comments.map(item => item.attrs.id))]; +// }; const TrackChangeOptionsComponent = ({ groups, setShowHidden, showHiddenValue, }) => { - const [isShownTrack, setIsShownTrack] = useState(false); + // const [isShownTrack, setIsShownTrack] = useState(false); const menuItems = groups[0].items; const { app, pmViews, activeView, activeViewId } = useContext(WaxContext); const { state } = activeView; @@ -192,12 +191,12 @@ const TrackChangeOptionsComponent = ({ const hideShowPlugin = app.PmPlugins.get('hideShowPlugin'); const inlineTracks = getInlineTracks(pmViews.main).length; const blockTracks = getTrackBlockNodes(pmViews.main).length; - const comments = getComments(pmViews.main).length; + // const comments = getComments(pmViews.main).length; const renderTools = () => { const tools = []; tools.push( - menuItems.map((menuItem, index) => { + menuItems.map(menuItem => { const isActive = !!( menuItem.active(state, activeViewId) && menuItem.select(state, activeViewId) @@ -220,7 +219,7 @@ const TrackChangeOptionsComponent = ({ if (menuItem.name === 'ShowHideTrackChange') { setShowHidden(!showHiddenValue); hideShowPlugin.props.setHideShow(showHiddenValue); - each(pmViews, (singleView, viewId) => { + each(pmViews, singleView => { singleView.dispatch(singleView.state.tr); }); return false; diff --git a/wax-prosemirror-services/src/TransformService/TransformTool.js b/wax-prosemirror-services/src/TransformService/TransformTool.js index 31803c65b59015716a6541b9e1bd367392defa20..0bb9fc00de70aa0046a98e4c6d3984d27fc53428 100644 --- a/wax-prosemirror-services/src/TransformService/TransformTool.js +++ b/wax-prosemirror-services/src/TransformService/TransformTool.js @@ -128,53 +128,53 @@ class TransformTool extends Tools { dispatch(tr); break; } - case 'titleCase': - state.doc.nodesBetween($from.pos, $to.pos, (node, position) => { - if (node.marks.length > 0) { - node.marks.forEach(item => { - marksAdd.push({ - name: item.type.name, - type: item.type, - pos: DocumentHelpers.findMark(state, item.type, true), - attrs: item.attrs, - }); - }); - } - - if (node.type.name !== 'code_block') { - if (!node.isTextblock || $from.pos === $to.pos) return; - const startPosition = Math.max(position + 1, $from.pos); - const endPosition = Math.min( - position + node.nodeSize, - selection.to, - ); - const substringFrom = Math.max(0, $from.pos - position - 1); - const substringTo = Math.max(0, selection.to - position - 1); - - const updatedText = node.textBetween(substringFrom, substringTo); - - if (updatedText.length > 0) { - const textNode = state.schema.text(updatedText.toTitleCase()); - tr.replaceWith(startPosition, endPosition, textNode); - } - } - }); - - marksAdd.forEach(item => { - if (item.name !== 'transform') { - item.pos.forEach(markPos => { - tr.addMark( - markPos.from, - markPos.to, - item.type.create(item.attrs), - ); - }); - } - }); - - dispatch(tr); - - break; + // case 'titleCase': + // state.doc.nodesBetween($from.pos, $to.pos, (node, position) => { + // if (node.marks.length > 0) { + // node.marks.forEach(item => { + // marksAdd.push({ + // name: item.type.name, + // type: item.type, + // pos: DocumentHelpers.findMark(state, item.type, true), + // attrs: item.attrs, + // }); + // }); + // } + + // if (node.type.name !== 'code_block') { + // if (!node.isTextblock || $from.pos === $to.pos) return; + // const startPosition = Math.max(position + 1, $from.pos); + // const endPosition = Math.min( + // position + node.nodeSize, + // selection.to, + // ); + // const substringFrom = Math.max(0, $from.pos - position - 1); + // const substringTo = Math.max(0, selection.to - position - 1); + + // const updatedText = node.textBetween(substringFrom, substringTo); + + // if (updatedText.length > 0) { + // const textNode = state.schema.text(updatedText.toTitleCase()); + // tr.replaceWith(startPosition, endPosition, textNode); + // } + // } + // }); + + // marksAdd.forEach(item => { + // if (item.name !== 'transform') { + // item.pos.forEach(markPos => { + // tr.addMark( + // markPos.from, + // markPos.to, + // item.type.create(item.attrs), + // ); + // }); + // } + // }); + + // dispatch(tr); + + // break; default: break; } diff --git a/wax-prosemirror-services/src/TransformService/components/TransformCaseComponent.js b/wax-prosemirror-services/src/TransformService/components/TransformCaseComponent.js index 32af9f3f314dee18b4f6a35d2207b2fbe014ba1c..99c17c00d4dd7e5cd402b985e484dba313cb2366 100644 --- a/wax-prosemirror-services/src/TransformService/components/TransformCaseComponent.js +++ b/wax-prosemirror-services/src/TransformService/components/TransformCaseComponent.js @@ -59,7 +59,7 @@ const TransformCaseComponent = ({ view: { state }, item }) => { { id: 1, name: 'Upper Case', iconName: 'transformCase' }, { id: 2, name: 'Lower Case', iconName: 'lowerCaseTransform' }, { id: 3, name: 'Sentence Case', iconName: 'transformCase' }, - { id: 4, name: 'Title Case', iconName: 'transformCase' }, + // { id: 4, name: 'Title Case', iconName: 'transformCase' }, ]; const onClickTransform = (e, id) => { @@ -73,9 +73,9 @@ const TransformCaseComponent = ({ view: { state }, item }) => { case 3: item.run(activeView.state, activeView.dispatch, 'sentenceCase'); break; - case 4: - item.run(activeView.state, activeView.dispatch, 'titleCase'); - break; + // case 4: + // item.run(activeView.state, activeView.dispatch, 'titleCase'); + // break; default: break; } diff --git a/wax-prosemirror-services/src/TransformService/titleCase.js b/wax-prosemirror-services/src/TransformService/titleCase.js index e75546c1a6b1c394304dc7c00f69c7a721079ad1..102a61ccfa567b8ef02fb6505c77e526d9fb9077 100644 --- a/wax-prosemirror-services/src/TransformService/titleCase.js +++ b/wax-prosemirror-services/src/TransformService/titleCase.js @@ -1,30 +1,30 @@ // eslint-disable-next-line no-extend-native -export default String.prototype.toTitleCase = function () { - const smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i; - const alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/; - const wordSeparators = /([ :–—-])/; - return this.split(wordSeparators) - .map(function (current, index, array) { - if ( - current.search(smallWords) > -1 && - index !== 0 && - index !== array.length - 1 && - array[index - 3] !== ':' && - array[index + 1] !== ':' && - (array[index + 1] !== '-' || - (array[index - 1] === '-' && array[index + 1] === '-')) - ) { - return current.toLowerCase(); - } - if (current.substr(1).search(/[A-Z]|\../) > -1) { - return current; - } - if (array[index + 1] === ':' && array[index + 2] !== '') { - return current; - } - return current.replace(alphanumericPattern, function (match) { - return match.toUpperCase(); - }); - }) - .join(''); -}; +// export default String.prototype.toTitleCase = function () { +// const smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i; +// const alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/; +// const wordSeparators = /([ :–—-])/; +// return this.split(wordSeparators) +// .map(function (current, index, array) { +// if ( +// current.search(smallWords) > -1 && +// index !== 0 && +// index !== array.length - 1 && +// array[index - 3] !== ':' && +// array[index + 1] !== ':' && +// (array[index + 1] !== '-' || +// (array[index - 1] === '-' && array[index + 1] === '-')) +// ) { +// return current.toLowerCase(); +// } +// if (current.substr(1).search(/[A-Z]|\../) > -1) { +// return current; +// } +// if (array[index + 1] === ':' && array[index + 2] !== '') { +// return current; +// } +// return current.replace(alphanumericPattern, function (match) { +// return match.toUpperCase(); +// }); +// }) +// .join(''); +// }; diff --git a/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDown.js b/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDown.js index 33cc9b5bb3a0d8955da22bd2be64d8a1cbe37703..87b7825fb0bbc1747397766c0d9f3aa9801f4934 100644 --- a/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDown.js +++ b/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDown.js @@ -1,14 +1,9 @@ -import React, { useContext } from 'react'; +import React, { useMemo } from 'react'; import { injectable, inject } from 'inversify'; import { isEmpty } from 'lodash'; import { v4 as uuidv4 } from 'uuid'; -import styled from 'styled-components'; -import { - WaxContext, - ToolGroup, - ReactDropDownStyles, -} from 'wax-prosemirror-core'; -import Dropdown from 'react-dropdown'; +import { ToolGroup } from 'wax-prosemirror-core'; +import BlockDropDownComponent from './BlockDropDownComponent'; @injectable() class BlockDropDown extends ToolGroup { @@ -48,83 +43,20 @@ class BlockDropDown extends ToolGroup { blockQuote, ]; } - renderTools(view) { - if (isEmpty(view) || window.innerWidth > 600) return null; - - const { activeViewId } = useContext(WaxContext); - - const Wrapper = styled.span` - ${ReactDropDownStyles}; - `; - const DropdownStyled = styled(Dropdown)` - display: inline-flex; - cursor: not-allowed; - opacity: ${props => (props.select ? 1 : 0.4)}; - pointer-events: ${props => (props.select ? 'default' : 'none')}; - .Dropdown-control { - border: none; - } - .Dropdown-arrow { - right: 25px; - top: 10px; - } - .Dropdown-menu { - width: 120%; - display: flex; - flex-direction: column; - align-items: flex-start; - .Dropdown-option { - width: 100%; - } - } - `; - - const { dispatch, state } = view; - const dropDownOptions = [ - { label: 'Title', value: '0', item: this._tools[0] }, - { label: 'author', value: '1', item: this._tools[1] }, - { label: 'Subtitle', value: '2', item: this._tools[2] }, - { label: 'Epigraph Prose', value: '3', item: this._tools[3] }, - { label: 'Epigraph Poetry', value: '4', item: this._tools[4] }, - { label: 'Heading 1', value: '5', item: this._tools[5] }, - { label: 'Heading 2', value: '6', item: this._tools[6] }, - { label: 'Heading 3', value: '7', item: this._tools[7] }, - { label: 'Paragraph', value: '8', item: this._tools[8] }, - { label: 'Paragraph Continued', value: '9', item: this._tools[9] }, - { label: 'Extract Prose', value: '10', item: this._tools[10] }, - { label: 'Extract Poetry', value: '11', item: this._tools[11] }, - { label: 'Source Note', value: '12', item: this._tools[12] }, - { label: 'Block Quote', value: '13', item: this._tools[13] }, - ]; - - const isDisabled = - dropDownOptions[0].item.enable && - dropDownOptions[0].item.enable(state) && - dropDownOptions[0].item.select && - dropDownOptions[0].item.select(state, activeViewId); - - let found = ''; - dropDownOptions.forEach((item, i) => { - if (item.item.active(state, activeViewId) === true) { - found = item.item.label; - } - }); - - return ( - <Wrapper key={uuidv4()}> - <DropdownStyled - value={found} + renderTools(view) { + if (isEmpty(view)) return null; + const MultipleDropDown = useMemo( + () => ( + <BlockDropDownComponent key={uuidv4()} - options={dropDownOptions} - onChange={option => { - this._tools[option.value].run(state, dispatch); - }} - placeholder="Block Level" - select={isDisabled} + tools={this._tools} + view={view} /> - </Wrapper> + ), + [], ); + return MultipleDropDown; } } diff --git a/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDownComponent.js b/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDownComponent.js new file mode 100644 index 0000000000000000000000000000000000000000..b8928070250b1ff03ef88cf6c2e0739835b195a5 --- /dev/null +++ b/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDownComponent.js @@ -0,0 +1,98 @@ +/* eslint-disable no-underscore-dangle */ +import React, { useContext, useMemo, useState, useEffect } from 'react'; +import styled from 'styled-components'; +import { WaxContext, ReactDropDownStyles } from 'wax-prosemirror-core'; +import Dropdown from 'react-dropdown'; +import { v4 as uuidv4 } from 'uuid'; + +const Wrapper = styled.div` + ${ReactDropDownStyles}; +`; +const DropdownStyled = styled(Dropdown)` + display: inline-flex; + cursor: not-allowed; + opacity: ${props => (props.select ? 1 : 0.4)}; + pointer-events: ${props => (props.select ? 'default' : 'none')}; + .Dropdown-control { + border: none; + padding: 12px 122px 8px 10px; + &:hover { + box-shadow: none; + } + } + + .Dropdown-arrow { + top: 17px; + } + + .Dropdown-menu { + width: 100.4%; + display: flex; + flex-direction: column; + align-items: flex-start; + .Dropdown-option { + width: 100%; + } + } +`; + +// eslint-disable-next-line react/prop-types +const BlockDropDownComponent = ({ view, tools }) => { + const context = useContext(WaxContext); + const { + activeViewId, + pmViews: { main }, + } = context; + const [label, setLabel] = useState(null); + const { dispatch, state } = view; + + const dropDownOptions = [ + { label: 'Title', value: '0', item: tools[0] }, + { label: 'author', value: '1', item: tools[1] }, + { label: 'Subtitle', value: '2', item: tools[2] }, + { label: 'Epigraph Prose', value: '3', item: tools[3] }, + { label: 'Epigraph Poetry', value: '4', item: tools[4] }, + { label: 'Heading 1', value: '5', item: tools[5] }, + { label: 'Heading 2', value: '6', item: tools[6] }, + { label: 'Heading 3', value: '7', item: tools[7] }, + { label: 'Paragraph', value: '8', item: tools[8] }, + { label: 'Paragraph Continued', value: '9', item: tools[9] }, + { label: 'Extract Prose', value: '10', item: tools[10] }, + { label: 'Extract Poetry', value: '11', item: tools[11] }, + { label: 'Source Note', value: '12', item: tools[12] }, + { label: 'Block Quote', value: '13', item: tools[13] }, + ]; + + useEffect(() => { + setLabel('Block Level'); + dropDownOptions.forEach(option => { + if (option.item.active(main.state, activeViewId)) { + setTimeout(() => { + setLabel(option.item.label); + }); + } + }); + }, [main.state.selection.$from.parent.type.name]); + + const MultipleDropDown = useMemo( + () => ( + <Wrapper key={uuidv4()}> + <DropdownStyled + key={uuidv4()} + onChange={option => { + tools[option.value].run(state, dispatch); + }} + options={dropDownOptions} + placeholder="Block Level" + select + value={label} + /> + </Wrapper> + ), + [label], + ); + + return MultipleDropDown; +}; + +export default BlockDropDownComponent; diff --git a/wax-prosemirror-services/src/WaxToolGroups/OENLeftToolGroupService/OENTools.js b/wax-prosemirror-services/src/WaxToolGroups/OENLeftToolGroupService/OENTools.js index fe5c02cf398632bff928b87e95d2f396f60e6144..5a30dc70c090592663cc9c67947802e1ed8f9bf2 100644 --- a/wax-prosemirror-services/src/WaxToolGroups/OENLeftToolGroupService/OENTools.js +++ b/wax-prosemirror-services/src/WaxToolGroups/OENLeftToolGroupService/OENTools.js @@ -1,4 +1,3 @@ -/* eslint-disable no-underscore-dangle */ import React, { useMemo } from 'react'; import { injectable, inject } from 'inversify'; import { isEmpty } from 'lodash'; @@ -49,6 +48,7 @@ class OENTools extends ToolGroup { disabled: false, component: ( <BlockLevelTools + // eslint-disable-next-line no-underscore-dangle groups={this._toolGroups[0].groups.map(group => ({ groupName: group.title === 'Custom Block' || group.title === 'OEN Containers' diff --git a/wax-prosemirror-services/src/WaxToolGroups/QuestionsDropDownToolGroupService/DropDownComponent.js b/wax-prosemirror-services/src/WaxToolGroups/QuestionsDropDownToolGroupService/DropDownComponent.js index cdd315aa7257c119d650be1084fee0186b5dd0d9..fe05823b367c367a80085f576c5d8d5537263f0c 100644 --- a/wax-prosemirror-services/src/WaxToolGroups/QuestionsDropDownToolGroupService/DropDownComponent.js +++ b/wax-prosemirror-services/src/WaxToolGroups/QuestionsDropDownToolGroupService/DropDownComponent.js @@ -94,8 +94,8 @@ const DropDownComponent = ({ view, tools }) => { ]; useEffect(() => { - setLabel('Question Types'); - dropDownOptions.forEach((option, i) => { + setLabel('Question Type'); + dropDownOptions.forEach(option => { if (option.item.active(main.state)) { setTimeout(() => { setLabel(option.label); @@ -118,7 +118,7 @@ const DropDownComponent = ({ view, tools }) => { key={uuidv4()} onChange={option => onChange(option)} options={dropDownOptions} - placeholder="Question Types" + placeholder="Question Type" select={isDisabled} value={label} /> diff --git a/yarn.lock b/yarn.lock index e4b8b17e1f3820ed95a2c0d6fb705e567d31f164..2c6e901745e58be728c358a5abe2c03ef998dd19 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,7 +1267,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99" integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw== @@ -4951,7 +4951,7 @@ cssstyle@^1.0.0, cssstyle@^1.1.1: dependencies: cssom "0.3.x" -csstype@^2.2.0, csstype@^2.5.2, csstype@^2.6.7: +csstype@^2.2.0, csstype@^2.5.2: version "2.6.11" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.11.tgz#452f4d024149ecf260a852b025e36562a253ffc5" integrity sha512-l8YyEC9NBkSm783PFTvh0FmJy7s5pFKrDp49ZL7zBGX3fWkO+N4EEyan1qqp8cwPLDcD0OSdyY6hAMoxp34JFw== @@ -5341,14 +5341,6 @@ dom-converter@^0.2: dependencies: utila "~0.4" -dom-helpers@^5.0.1: - version "5.1.4" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b" - integrity sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^2.6.7" - dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -12492,16 +12484,6 @@ react-scripts@3.4: optionalDependencies: fsevents "2.1.2" -react-transition-group@^4.3.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" - integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react@^16.13.1: version "16.13.1" resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" @@ -14869,6 +14851,11 @@ use-deep-compare-effect@^1.3.1: "@types/use-deep-compare-effect" "^1.2.0" dequal "^2.0.2" +use-dynamic-refs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/use-dynamic-refs/-/use-dynamic-refs-1.0.0.tgz#934b9448d59773ef299f65f36ffc87c343e40353" + integrity sha512-1Ky+Jaj6MIpTRz6NTaCLVm/iDXfRNwUMH9X7BkLtgSL2RCXHQhK2p9SVhut8jZPDfxLDtOIYNM3txsiLXd4yVQ== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f"