├── .nvmrc
├── editors
└── demo
│ ├── src
│ ├── NCBI
│ │ ├── theme
│ │ │ ├── elements
│ │ │ │ └── ButtonStyles.js
│ │ │ └── index.js
│ │ ├── config
│ │ │ ├── index.js
│ │ │ └── configMini.js
│ │ └── layout
│ │ │ ├── index.js
│ │ │ ├── EditorElements.js
│ │ │ └── EditorMiniElements.js
│ ├── HHMI
│ │ ├── config
│ │ │ └── index.js
│ │ ├── theme
│ │ │ ├── index.js
│ │ │ └── elements
│ │ │ │ ├── index.js
│ │ │ │ └── ButtonStyles.js
│ │ └── layout
│ │ │ ├── index.js
│ │ │ └── EditorElements.js
│ ├── OEN
│ │ ├── config
│ │ │ ├── index.js
│ │ │ └── defaultSchema.js
│ │ ├── layout
│ │ │ ├── index.js
│ │ │ └── EditorElements.js
│ │ └── theme
│ │ │ ├── index.js
│ │ │ └── elements
│ │ │ ├── index.js
│ │ │ └── ButtonStyles.js
│ ├── Editoria
│ │ ├── theme
│ │ │ ├── index.js
│ │ │ └── elements
│ │ │ │ ├── index.js
│ │ │ │ └── ButtonStyles.js
│ │ ├── config
│ │ │ ├── index.js
│ │ │ └── defaultSchema.js
│ │ └── layout
│ │ │ ├── index.js
│ │ │ └── EditorElements.js
│ └── index.js
│ ├── jsconfig.json
│ ├── public
│ ├── favicon.ico
│ └── manifest.json
│ └── .gitignore
├── wax-prosemirror-services
├── src
│ ├── TrackChangeService
│ │ ├── schema
│ │ │ ├── trackChangesNodes
│ │ │ │ ├── imageTrackNode.js
│ │ │ │ ├── listItemTrackNode.js
│ │ │ │ └── bulletListTrackNode.js
│ │ │ └── trackChangesMarks
│ │ │ │ └── index.js
│ │ ├── TrackOptionsToolGroupService
│ │ │ ├── TrackOptionsToolGroupService.js
│ │ │ └── TrackOptions.js
│ │ ├── TrackingAndEditingToolGroupService
│ │ │ ├── TrackingAndEditingToolGroupService.js
│ │ │ └── TrackingAndEditing.js
│ │ ├── TrackCommentOptionsToolGroupService
│ │ │ └── TrackCommentOptionsToolGroupService.js
│ │ ├── ShowHideTrackChangeService
│ │ │ ├── ShowHideTrackChangeService.js
│ │ │ └── ShowHideTrackChange.js
│ │ ├── AcceptTrackChangeService
│ │ │ └── AcceptTrackChangeService.js
│ │ ├── EnableTrackChangeService
│ │ │ └── EnableTrackChangeService.js
│ │ ├── RejectTrackChangeService
│ │ │ └── RejectTrackChangeService.js
│ │ └── track-changes
│ │ │ └── helpers
│ │ │ └── removeNode.js
│ ├── InlineAnnotations
│ │ ├── StrongService
│ │ │ ├── strong.css
│ │ │ ├── schema
│ │ │ │ └── strongMark.js
│ │ │ ├── StrongService.js
│ │ │ └── Strong.js
│ │ ├── SubscriptService
│ │ │ ├── subscript.css
│ │ │ ├── schema
│ │ │ │ └── subscriptMark.js
│ │ │ ├── SubscriptService.js
│ │ │ └── Subscript.js
│ │ ├── SuperscriptService
│ │ │ ├── superscript.css
│ │ │ ├── schema
│ │ │ │ └── superscriptMark.js
│ │ │ ├── SuperscriptService.js
│ │ │ └── Superscript.js
│ │ ├── CodeService
│ │ │ ├── schema
│ │ │ │ └── codeMark.js
│ │ │ ├── CodeService.js
│ │ │ └── Code.js
│ │ ├── InlineAnnotationsService.js
│ │ ├── EmphasisService
│ │ │ ├── schema
│ │ │ │ └── emphasisMark.js
│ │ │ ├── EmphasisService.js
│ │ │ └── Emphasis.js
│ │ ├── UnderlineService
│ │ │ ├── schema
│ │ │ │ └── underlineMark.js
│ │ │ ├── UnderlineService.js
│ │ │ └── Underline.js
│ │ ├── AnnotationToolGroupService
│ │ │ └── AnnotationToolGroupService.js
│ │ ├── SmallCapsService
│ │ │ ├── SmallCapsService.js
│ │ │ ├── schema
│ │ │ │ └── smallcapsMark.js
│ │ │ └── SmallCaps.js
│ │ ├── StrikeThroughService
│ │ │ ├── StrikeThroughService.js
│ │ │ ├── schema
│ │ │ │ └── strikethroughMark.js
│ │ │ └── StrikeThrough.js
│ │ └── index.js
│ ├── FindAndReplaceService
│ │ ├── findAndReplace.css
│ │ ├── FindAndReplaceToolGroupService
│ │ │ ├── FindAndReplaceToolGroupService.js
│ │ │ └── FindAndReplaceTool.js
│ │ ├── FindAndReplace.js
│ │ └── FindAndReplaceService.js
│ ├── ModalService
│ │ ├── pmPlugins
│ │ │ ├── actions.js
│ │ │ └── ModalPlugin.js
│ │ ├── ModalComponent.js
│ │ └── ModalService.js
│ ├── ListsService
│ │ ├── BlockQuoteService
│ │ │ ├── blockQuote.css
│ │ │ ├── schema
│ │ │ │ └── blockQuoteNode.js
│ │ │ ├── BlockQuoteToolGroupService
│ │ │ │ ├── BlockQuoteToolGroupService.js
│ │ │ │ └── BlockQuoteTool.js
│ │ │ └── BlockQuoteService.js
│ │ ├── ListsService.js
│ │ ├── ListToolGroupService
│ │ │ ├── ListToolGroupService.js
│ │ │ └── Lists.js
│ │ ├── JoinUpService
│ │ │ └── JoinUpService.js
│ │ ├── lists.css
│ │ ├── ListItemService
│ │ │ ├── ListItemService.js
│ │ │ └── schema
│ │ │ │ └── listItemNode.js
│ │ ├── LiftService
│ │ │ ├── Lift.js
│ │ │ └── LiftService.js
│ │ ├── index.js
│ │ ├── BulletListService
│ │ │ ├── schema
│ │ │ │ └── bulletListNode.js
│ │ │ └── BulletListService.js
│ │ └── OrderedListService
│ │ │ └── OrderedListService.js
│ ├── ImageService
│ │ ├── schema
│ │ │ ├── index.js
│ │ │ └── figureCaptionNode.js
│ │ └── ImageToolGroupService
│ │ │ ├── ImageToolGroupService.js
│ │ │ └── Images.js
│ ├── MathService
│ │ ├── schema
│ │ │ ├── mathSelectMark.js
│ │ │ ├── index.js
│ │ │ ├── mathInlineNode.js
│ │ │ └── mathDisplayNode.js
│ │ ├── InlineInputRule.js
│ │ └── BlockInputRule.js
│ ├── BaseService
│ │ ├── BaseService.js
│ │ ├── RedoService
│ │ │ ├── RedoService.js
│ │ │ └── Redo.js
│ │ ├── UndoService
│ │ │ ├── UndoService.js
│ │ │ └── Undo.js
│ │ ├── SaveService
│ │ │ ├── SaveService.js
│ │ │ └── Save.js
│ │ ├── BaseToolGroupService
│ │ │ ├── BaseToolGroupService.js
│ │ │ └── Base.js
│ │ └── index.js
│ ├── CommentsService
│ │ ├── plugins
│ │ │ └── CommentDecorationPluginKey.js
│ │ ├── comments.css
│ │ └── components
│ │ │ └── ui
│ │ │ └── trackChanges
│ │ │ ├── HideShowTool.js
│ │ │ ├── removeNode.js
│ │ │ └── TrackChangeEnable.js
│ ├── CustomTagService
│ │ ├── CustomTagService.js
│ │ ├── CustomTagToolGroupService
│ │ │ ├── CustomTagBlockToolGroupService
│ │ │ │ ├── CustomTagBlockToolGroupService.js
│ │ │ │ └── CustomTagBlockToolGroup.js
│ │ │ ├── CustomTagInlineToolGroupService
│ │ │ │ ├── CustomTagInlineToolGroupService.js
│ │ │ │ └── CustomTagInlineToolGroup.js
│ │ │ └── CustomTagBlockNewToolGroupService
│ │ │ │ ├── CustomTagBlockNewToolGroupService.js
│ │ │ │ └── CustomTagBlockNewToolGroup.js
│ │ ├── CustomTagBlockService
│ │ │ ├── CustomTagBlockService.js
│ │ │ └── schema
│ │ │ │ └── customBlockNode.js
│ │ ├── CustomTagInlineService
│ │ │ ├── CustomTagInlineTool.js
│ │ │ └── schema
│ │ │ │ └── customtagInlineMark.js
│ │ ├── CustomTagBlockNewService
│ │ │ └── CustomTagBlockNewService.js
│ │ └── index.js
│ ├── TextBlockLevel
│ │ ├── TextBlockLevelService.js
│ │ ├── TextToolGroupService
│ │ │ ├── TextToolGroupService.js
│ │ │ └── Text.js
│ │ ├── ParagraphService
│ │ │ └── ParagraphService.js
│ │ ├── SourceNoteService
│ │ │ ├── SourceNoteService.js
│ │ │ └── schema
│ │ │ │ └── sourceNoteNode.js
│ │ ├── ExtractProseService
│ │ │ ├── ExtractProseService.js
│ │ │ └── schema
│ │ │ │ └── extractProseNode.js
│ │ ├── ExtractPoetryService
│ │ │ ├── ExtractPoetryService.js
│ │ │ └── schema
│ │ │ │ └── extractPoetryNode.js
│ │ ├── ParagraphContinuedService
│ │ │ ├── ParagraphContinuedService.js
│ │ │ └── schema
│ │ │ │ └── paragraphContNode.js
│ │ └── index.js
│ ├── BottomInfoService
│ │ ├── BottomInfoService.js
│ │ ├── CounterInfoService
│ │ │ ├── CounterInfoService.js
│ │ │ └── CounterInfoTool.js
│ │ ├── ShortCutsInfoService
│ │ │ ├── ShortCutsInfoService.js
│ │ │ └── ShortCutsInfoTool.js
│ │ ├── InfoToolGroupService
│ │ │ ├── EditorInfoToolGroupService.js
│ │ │ └── InfoTool.js
│ │ └── index.js
│ ├── NoteService
│ │ ├── NoteToolGroupService
│ │ │ ├── NoteToolGroupService.js
│ │ │ └── Notes.js
│ │ ├── NoteEditor.js
│ │ ├── schema
│ │ │ └── footNoteNode.js
│ │ ├── note.css
│ │ ├── components
│ │ │ └── NoteNumber.js
│ │ └── NoteService.js
│ ├── AiService
│ │ ├── AiToolGroupService
│ │ │ ├── AiToolGroupService.js
│ │ │ └── ToggleAi.js
│ │ └── ToggleAiTool.js
│ ├── OENContainersService
│ │ ├── schema
│ │ │ ├── index.js
│ │ │ ├── OenSectionNode.js
│ │ │ ├── OenAsideNode.js
│ │ │ └── OenContainerNode.js
│ │ ├── OENLeftToolGroupService
│ │ │ └── OENLeftToolGroupService.js
│ │ ├── OENAsideLongToolGroupService
│ │ │ ├── OENAsideLongToolGroupService.js
│ │ │ └── OENAsideLongToolGroup.js
│ │ ├── OENAsideShortToolGroupService
│ │ │ ├── OENAsideShortToolGroupService.js
│ │ │ └── OENAsideShortToolGroup.js
│ │ └── OENContainersToolGroupService
│ │ │ ├── OENContainersToolGroup.js
│ │ │ └── OENContainersToolGroupService.js
│ ├── DisplayBlockLevel
│ │ ├── DisplayToolGroupService
│ │ │ └── DisplayToolGroupService.js
│ │ ├── DisplayBlockLevelService.js
│ │ ├── TitleService
│ │ │ ├── schema
│ │ │ │ └── titleNode.js
│ │ │ └── TitleService.js
│ │ ├── SubTitleService
│ │ │ ├── SubTitleService.js
│ │ │ └── schema
│ │ │ │ └── subTitleNode.js
│ │ ├── AuthorService
│ │ │ ├── AuthorService.js
│ │ │ └── schema
│ │ │ │ └── authorNode.js
│ │ ├── EpigraphProseService
│ │ │ ├── EpigraphProseService.js
│ │ │ └── schema
│ │ │ │ └── epigraphProseNode.js
│ │ ├── EpigraphPoetryService
│ │ │ ├── EpigraphPoetryService.js
│ │ │ └── schema
│ │ │ │ └── epigraphPoetryNode.js
│ │ └── index.js
│ ├── CodeBlockService
│ │ ├── CodeBlockToolGroupService
│ │ │ ├── CodeBlockToolGroupService.js
│ │ │ └── CodeBlock.js
│ │ ├── schema
│ │ │ └── codeBlockNode.js
│ │ ├── CodeBlockService.js
│ │ └── CodeBlockTool.js
│ ├── FullScreenService
│ │ ├── FullScreenToolGroupService
│ │ │ ├── FullScreenToolGroupService.js
│ │ │ └── FullScreen.js
│ │ ├── FullScreenService.js
│ │ └── FullScreenTool.js
│ ├── WaxToolGroups
│ │ ├── DisplayTextToolGroupService
│ │ │ └── DisplayTextToolGroupService.js
│ │ └── BlockDropDownToolGroupService
│ │ │ └── BlockDropDownToolGroupService.js
│ ├── TransformService
│ │ ├── TransformToolGroupService
│ │ │ ├── TransformToolGroupService.js
│ │ │ └── TransformToolGroup.js
│ │ └── TransformService.js
│ ├── EditingSuggestingService
│ │ ├── EditingSuggestingService.js
│ │ └── EditingSuggesting.js
│ ├── HighlightService
│ │ ├── TextHighlightToolGroupService
│ │ │ ├── TextHighlightToolGroupService.js
│ │ │ └── HightlightToolGroup.js
│ │ ├── schema
│ │ │ └── highlightMark.js
│ │ └── HightlightService.js
│ ├── EnterService
│ │ └── EnterService.js
│ ├── SpecialCharactersService
│ │ ├── SpecialCharactersToolGroupService
│ │ │ ├── SpecialCharactersToolGroupService.js
│ │ │ └── SpecialCharacters.js
│ │ ├── SpecialCharactersService.js
│ │ └── SpecialCharactersTool.js
│ ├── ExternalAPIContentService
│ │ ├── ExternalAPIContentToolGroupService
│ │ │ ├── ExternalAPIContentToolGroupService.js
│ │ │ └── ExternalAPIContent.js
│ │ ├── externalApiContent.css
│ │ └── ExternalAPIContentService.js
│ └── LinkService
│ │ └── schema
│ │ └── linkMark.js
└── .gitignore
├── .commitlintrc.js
├── .stylelintrc.js
├── wax-citation-service
├── index.js
├── src
│ ├── CitationToolGroupService
│ │ ├── CitationToolGroupService.js
│ │ └── Citation.js
│ └── CitationCalloutNodeView.js
├── .gitignore
└── README.md
├── .lintstagedrc.js
├── wax-questions-service
├── index.js
├── src
│ ├── FillTheGapQuestionService
│ │ ├── components
│ │ │ └── GapComponent.js
│ │ ├── FillTheGapToolGroupService
│ │ │ ├── FillTheGapToolGroupService.js
│ │ │ └── FillTheGap.js
│ │ ├── fillTheGap.css
│ │ ├── CreateGapService
│ │ │ └── CreateGapService.js
│ │ ├── schema
│ │ │ ├── fillTheGapContainerNode.js
│ │ │ └── fillTheGapNode.js
│ │ └── FillTheGapNodeView.js
│ ├── NumericalAnswerService
│ │ ├── numericalAnswer.css
│ │ └── NumericalAnswerContainerNodeView.js
│ ├── QuestionsDropDownToolGroupService
│ │ └── QuestionsDropDownToolGroupService.js
│ ├── MultipleDropDownService
│ │ ├── MultipleDropDownToolGroupService
│ │ │ ├── MultipleDropDownToolGroupService.js
│ │ │ └── MultipleDropDown.js
│ │ ├── schema
│ │ │ └── multipleDropDownContainerNode.js
│ │ ├── CreateDropDownService
│ │ │ └── MultipleDropDownNodeView.js
│ │ └── MultipleDropDownContainerNodeView.js
│ ├── EssayService
│ │ ├── essay.css
│ │ ├── schema
│ │ │ ├── essayContainerNode.js
│ │ │ ├── essayAnswerNode.js
│ │ │ ├── essayPromptNode.js
│ │ │ └── essayQuestionNode.js
│ │ ├── EssayAnswerNodeView.js
│ │ ├── components
│ │ │ ├── EssayQuestionComponent.js
│ │ │ └── EssayPromptComponent.js
│ │ ├── EssayPromptNodeView.js
│ │ └── EssayQuestionNodeView.js
│ ├── MultipleChoiceQuestionService
│ │ ├── schema
│ │ │ ├── questionNode.js
│ │ │ ├── multipleChoiceContainerNode.js
│ │ │ └── multipleChoiceNode.js
│ │ ├── plugins
│ │ │ └── MoveCursorPlugin.js
│ │ ├── TrueFalseSingleCorrectQuestionService
│ │ │ └── schema
│ │ │ │ ├── questionTrueFalseSingleNode.js
│ │ │ │ └── trueFalseSingleCorrectContainerNode.js
│ │ ├── TrueFalseQuestionService
│ │ │ └── schema
│ │ │ │ ├── trueFalseContainerNode.js
│ │ │ │ ├── questionTrueFalseNode.js
│ │ │ │ └── trueFalseNode.js
│ │ ├── MultipleChoiceSingleCorrectQuestionService
│ │ │ └── schema
│ │ │ │ ├── questionSingleNode.js
│ │ │ │ └── multipleChoiceSingleCorrectContainerNode.js
│ │ ├── components
│ │ │ └── QuestionComponent.js
│ │ └── QuestionNodeView.js
│ └── MatchingService
│ │ └── MatchingOptionNodeView.js
└── .gitignore
├── .directory
├── wax-prosemirror-core
├── jsconfig.json
├── src
│ ├── config
│ │ ├── defaultServices
│ │ │ ├── LayoutService
│ │ │ │ ├── components
│ │ │ │ │ ├── LayoutFactory.js
│ │ │ │ │ └── componentPlugin.js
│ │ │ │ ├── DefaultLayout
│ │ │ │ │ └── DefaultLayout.js
│ │ │ │ └── LayoutService.js
│ │ │ ├── PortalService
│ │ │ │ └── Portals.js
│ │ │ ├── MenuService
│ │ │ │ ├── MenuWrapper.js
│ │ │ │ └── MenuCollection.js
│ │ │ ├── ShortCutsService
│ │ │ │ └── ShortCutsService.js
│ │ │ ├── OverlayService
│ │ │ │ ├── OverlayService.js
│ │ │ │ ├── OverLay.js
│ │ │ │ └── OverlayComponent.js
│ │ │ └── RulesService
│ │ │ │ └── RulesService.js
│ │ ├── plugins
│ │ │ ├── defaultPlugins.js
│ │ │ └── placeholder.js
│ │ ├── defaultConfig.js
│ │ └── Config.js
│ ├── Service.js
│ ├── components
│ │ ├── icons
│ │ │ └── Icon.js
│ │ ├── helpers
│ │ │ ├── useDebounce.js
│ │ │ └── useOnClickOutside.js
│ │ ├── ToolGroups.js
│ │ └── LeftMenuTitle.js
│ ├── PmPlugins.js
│ ├── utilities
│ │ ├── track-changes
│ │ │ └── helpers
│ │ │ │ └── removeNode.js
│ │ ├── schema
│ │ │ └── DefaultSchema.js
│ │ └── lib
│ │ │ └── Middleware.js
│ ├── ApplicationContext.js
│ └── StateContext.js
├── .gitignore
└── rollup.config.js
├── .prettierrc.js
├── lerna.json
├── docker-compose.deploy.yml
├── wax-table-service
├── index.js
├── src
│ ├── TablesService.js
│ ├── TableToolGroupService
│ │ ├── TableToolGroupService.js
│ │ └── Tables.js
│ ├── EditTableService
│ │ └── EditTableService.js
│ └── index.js
└── .gitignore
├── jsconfig.json
├── docker-compose.yml
├── .cz-config.js
├── .gitignore
├── .dockerignore
├── .gitlab
└── issue_templates
│ ├── Feature Request.md
│ └── bug-report.md
├── .gitlab-ci.yml
├── README.md
└── .eslintrc.js
/.nvmrc:
--------------------------------------------------------------------------------
1 | 16.19.1
2 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/theme/elements/ButtonStyles.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/config/index.js:
--------------------------------------------------------------------------------
1 | export { default as config } from './config';
2 |
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/theme/index.js:
--------------------------------------------------------------------------------
1 | export { default as cokoTheme } from './theme';
2 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/theme/index.js:
--------------------------------------------------------------------------------
1 | export { default as cokoTheme } from './theme';
2 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/config/index.js:
--------------------------------------------------------------------------------
1 | export { default as config } from './config';
2 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/layout/index.js:
--------------------------------------------------------------------------------
1 | export { default as OenLayout } from './OenLayout';
2 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/theme/index.js:
--------------------------------------------------------------------------------
1 | export { default as cokoTheme } from "./theme";
2 |
3 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/schema/trackChangesNodes/imageTrackNode.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/schema/trackChangesNodes/listItemTrackNode.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.commitlintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: ['@commitlint/config-conventional'],
3 | };
4 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/theme/index.js:
--------------------------------------------------------------------------------
1 | export { default as cokoTheme } from "./theme";
2 |
3 |
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/layout/index.js:
--------------------------------------------------------------------------------
1 | export { default as HhmiLayout } from './HhmiLayout';
2 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/schema/trackChangesNodes/bulletListTrackNode.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.stylelintrc.js:
--------------------------------------------------------------------------------
1 | const { stylelint } = require('@coko/lint');
2 |
3 | module.exports = stylelint;
4 |
--------------------------------------------------------------------------------
/wax-citation-service/index.js:
--------------------------------------------------------------------------------
1 | export { default as CitationService } from './src/CitationService';
2 |
--------------------------------------------------------------------------------
/.lintstagedrc.js:
--------------------------------------------------------------------------------
1 | const { lintstaged } = require('@coko/lint');
2 |
3 | module.exports = lintstaged;
4 |
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/theme/elements/index.js:
--------------------------------------------------------------------------------
1 | export { default as ButtonStyles } from "./ButtonStyles";
2 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/theme/elements/index.js:
--------------------------------------------------------------------------------
1 | export { default as ButtonStyles } from "./ButtonStyles";
2 |
--------------------------------------------------------------------------------
/wax-questions-service/index.js:
--------------------------------------------------------------------------------
1 | export { default as QuestionsService } from './src/QuestionsService';
2 |
--------------------------------------------------------------------------------
/editors/demo/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/theme/elements/index.js:
--------------------------------------------------------------------------------
1 | export { default as ButtonStyles } from "./ButtonStyles";
2 |
--------------------------------------------------------------------------------
/.directory:
--------------------------------------------------------------------------------
1 | [Dolphin]
2 | Timestamp=2019,4,23,18,59,6
3 | Version=3
4 |
5 | [Settings]
6 | HiddenFilesShown=true
7 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/editors/demo/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/christos8333/wax-prosemirror/HEAD/editors/demo/public/favicon.ico
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | const { prettier } = require('@coko/lint');
2 |
3 | prettier.semi = true;
4 |
5 | module.exports = prettier;
6 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "lerna": "2.6.0",
3 | "npmClient": "yarn",
4 | "version": "0.9.101",
5 | "useWorkspaces": true
6 | }
7 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrongService/strong.css:
--------------------------------------------------------------------------------
1 | /* strong */
2 |
3 | strong {
4 | font-weight: bold;
5 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SubscriptService/subscript.css:
--------------------------------------------------------------------------------
1 |
2 | /* subscript*/
3 | sub {
4 | line-height: 0;
5 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SuperscriptService/superscript.css:
--------------------------------------------------------------------------------
1 | /* superscript */
2 |
3 | sup {
4 | line-height: 0;
5 | }
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/config/index.js:
--------------------------------------------------------------------------------
1 | export { default as config } from './config';
2 | export { default as configMobile } from './configMobile';
3 |
--------------------------------------------------------------------------------
/docker-compose.deploy.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | client:
5 | image: cokoapps/wax-demo:latest
6 | ports:
7 | - ${PORT}:3000
8 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FindAndReplaceService/findAndReplace.css:
--------------------------------------------------------------------------------
1 |
2 | /* find and Replace */
3 | span.search-result {
4 | background: #bee594;
5 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ModalService/pmPlugins/actions.js:
--------------------------------------------------------------------------------
1 | export default {
2 | HIDE_OVERLAY: "HIDE_OVERLAY",
3 | SHOW_OVERLAY: "SHOW_OVERLAY"
4 | };
5 |
--------------------------------------------------------------------------------
/wax-table-service/index.js:
--------------------------------------------------------------------------------
1 | export { tableEditing, columnResizing } from './src/tableSrc';
2 | export { default as TablesService } from './src/TablesService';
3 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/layout/index.js:
--------------------------------------------------------------------------------
1 | export { default as EditoriaLayout } from './EditoriaLayout';
2 | export { default as EditoriaMobileLayout } from './EditoriaMobileLayout';
3 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Experimental Options */
4 | "experimentalDecorators": true,
5 | "emitDecoratorMetadata": true,
6 | }
7 | }
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | wax:
5 | build:
6 | context: .
7 | dockerfile: Dockerfile-production
8 | ports:
9 | - ${PORT}:3000
10 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/config/index.js:
--------------------------------------------------------------------------------
1 | export { default as configTitle } from './configTitle';
2 | export { default as configMini } from './configMini';
3 | export { default as configEnter } from './configEnter';
4 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/layout/index.js:
--------------------------------------------------------------------------------
1 | export { default as NcbiLayout } from './NcbiLayout';
2 | export { default as NcbiMiniLayout } from './NcbiMiniLayout';
3 | export { default as EnterLayout } from './EnterLayout';
4 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/LayoutService/components/LayoutFactory.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/jsx-props-no-spreading */
2 | import React from 'react';
3 |
4 | export default Component => props => Component;
5 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BlockQuoteService/blockQuote.css:
--------------------------------------------------------------------------------
1 | /* block quote */
2 | blockquote {
3 | padding-left: 1em;
4 | border-left: 3px solid #eee;
5 | margin-left: 0;
6 | margin-right: 0;
7 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ImageService/schema/index.js:
--------------------------------------------------------------------------------
1 | export { default as imageNode } from './imageNode';
2 | export { default as figureNode } from './figureNode';
3 | export { default as figureCaptionNode } from './figureCaptionNode';
4 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/schema/mathSelectMark.js:
--------------------------------------------------------------------------------
1 | const mathSelectMark = {
2 | toDOM() {
3 | return ['math-select', 0];
4 | },
5 | parseDOM: [{ tag: 'math-select' }],
6 | };
7 |
8 | export default mathSelectMark;
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/schema/index.js:
--------------------------------------------------------------------------------
1 | export { default as mathInlineNode } from './mathInlineNode';
2 | export { default as mathDisplayNode } from './mathDisplayNode';
3 | export { default as mathSelectMark } from './mathSelectMark';
4 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/LayoutService/DefaultLayout/DefaultLayout.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/prop-types */
2 | import React from 'react';
3 |
4 | const DefaultLayout = ({ editor }) => <>{editor}>;
5 |
6 | export default DefaultLayout;
7 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/BaseService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import BaseServices from './index';
3 |
4 | class BaseService extends Service {
5 | dependencies = BaseServices;
6 | }
7 |
8 | export default BaseService;
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CommentsService/plugins/CommentDecorationPluginKey.js:
--------------------------------------------------------------------------------
1 | import { PluginKey } from 'prosemirror-state';
2 |
3 | const CommentDecorationPluginKey = new PluginKey('commentDecorationPlugin');
4 |
5 | export default CommentDecorationPluginKey;
6 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/CodeService/schema/codeMark.js:
--------------------------------------------------------------------------------
1 | const codeMark = {
2 | parseDOM: { tag: 'code' },
3 | toDOM(hook, next) {
4 | hook.value = ['code', 0];
5 | next();
6 | },
7 | };
8 |
9 | export default codeMark;
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CommentsService/comments.css:
--------------------------------------------------------------------------------
1 | /* Comments */
2 |
3 | span.comment {
4 | border-bottom: 2px solid gold;
5 | border-radius: 3px 3px 0 0;
6 | }
7 |
8 | .active-comment {
9 | background-color: gold;
10 | /* color: black; */
11 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CustomService from './index';
3 |
4 | class CustomTagService extends Service {
5 | dependencies = CustomService;
6 | }
7 |
8 | export default CustomTagService;
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ModalService/ModalComponent.js:
--------------------------------------------------------------------------------
1 | import React, { useMemo } from "react";
2 |
3 | export default (Component, plugin) => ({ view }) => (
4 |
5 |
6 | Overlay Area
7 |
8 | );
9 | //
10 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/components/GapComponent.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import EditorComponent from './EditorComponent';
3 |
4 | export default ({ node, view, getPos }) => {
5 | return ;
6 | };
7 |
--------------------------------------------------------------------------------
/wax-table-service/src/TablesService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TablesServices from './index';
3 | import './table.css';
4 |
5 | class TablesService extends Service {
6 | dependencies = TablesServices;
7 | }
8 |
9 | export default TablesService;
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/TextBlockLevelService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TextServices from './index';
3 |
4 | class TextBlockLevelService extends Service {
5 | dependencies = TextServices;
6 | }
7 |
8 | export default TextBlockLevelService;
9 |
--------------------------------------------------------------------------------
/.cz-config.js:
--------------------------------------------------------------------------------
1 | const { commitizen } = require('@coko/lint');
2 |
3 | commitizen.scopes = [
4 | 'core',
5 | 'components',
6 | 'layouts',
7 | 'plugins',
8 | 'schema',
9 | 'services',
10 | 'utilities',
11 | 'editors',
12 | '*',
13 | ];
14 |
15 | module.exports = commitizen;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/BottomInfoService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import BottomInfoServices from './index';
3 |
4 | class BottomInfoService extends Service {
5 | dependencies = BottomInfoServices;
6 | }
7 |
8 | export default BottomInfoService;
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/RedoService/RedoService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Redo from './Redo';
3 |
4 | class RedoService extends Service {
5 | register() {
6 | this.container.bind('Redo').to(Redo);
7 | }
8 | }
9 |
10 | export default RedoService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/UndoService/UndoService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Undo from './Undo';
3 |
4 | class UndoService extends Service {
5 | register() {
6 | this.container.bind('Undo').to(Undo);
7 | }
8 | }
9 |
10 | export default UndoService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/InlineAnnotationsService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import InlineServices from './index';
3 |
4 | class InlineAnnotationsService extends Service {
5 | dependencies = InlineServices;
6 | }
7 |
8 | export default InlineAnnotationsService;
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/EmphasisService/schema/emphasisMark.js:
--------------------------------------------------------------------------------
1 | const emphasisMark = {
2 | parseDOM: [{ tag: 'i' }, { tag: 'em' }, { style: 'font-style=italic' }],
3 | toDOM(hook, next) {
4 | hook.value = ['em', 0];
5 | next();
6 | },
7 | };
8 |
9 | export default emphasisMark;
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/UnderlineService/schema/underlineMark.js:
--------------------------------------------------------------------------------
1 | const underlineMark = {
2 | parseDOM: [{ tag: 'u' }],
3 | toDOM: (hook, next) => {
4 | // eslint-disable-next-line no-param-reassign
5 | hook.value = ['u'];
6 | next();
7 | },
8 | };
9 |
10 | export default underlineMark;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BlockQuoteService/schema/blockQuoteNode.js:
--------------------------------------------------------------------------------
1 | const blockQuoteNode = {
2 | content: 'block+',
3 | group: 'block',
4 | defining: true,
5 | parseDOM: [{ tag: 'blockquote' }],
6 | toDOM() {
7 | return ['blockquote', 0];
8 | },
9 | };
10 |
11 | export default blockQuoteNode;
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/ListsService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ListsServices from './index';
3 | import './lists.css';
4 |
5 | class ListsService extends Service {
6 | name = 'ListsService';
7 | dependencies = ListsServices;
8 | }
9 |
10 | export default ListsService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/PortalService/Portals.js:
--------------------------------------------------------------------------------
1 | import { injectable } from 'inversify';
2 |
3 | @injectable()
4 | export default class Portals {
5 | portals = [];
6 | addPortal(portal) {
7 | this.portals.push(portal);
8 | }
9 |
10 | getPortals() {
11 | return this.portals;
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/SaveService/SaveService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Save from './Save';
3 |
4 | class SaveService extends Service {
5 | name = 'SaveService';
6 | register() {
7 | this.container.bind('Save').to(Save);
8 | }
9 | }
10 |
11 | export default SaveService;
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SubscriptService/schema/subscriptMark.js:
--------------------------------------------------------------------------------
1 | const subscriptMark = {
2 | excludes: 'superscript',
3 | parseDOM: [{ tag: 'sub' }, { style: 'vertical-align=sub' }],
4 | toDOM(hook, next) {
5 | hook.value = ['sub'];
6 | next();
7 | },
8 | };
9 |
10 | export default subscriptMark;
11 |
--------------------------------------------------------------------------------
/wax-table-service/src/TableToolGroupService/TableToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Tables from './Tables';
3 |
4 | class TableToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Tables').to(Tables);
7 | }
8 | }
9 |
10 | export default TableToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/BaseToolGroupService/BaseToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Base from './Base';
3 |
4 | class BaseToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Base').to(Base);
7 | }
8 | }
9 |
10 | export default BaseToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/plugins/defaultPlugins.js:
--------------------------------------------------------------------------------
1 | import { history } from 'prosemirror-history';
2 | import { dropCursor } from 'prosemirror-dropcursor';
3 | import { gapCursor } from 'prosemirror-gapcursor';
4 | import FakeCursorPlugin from './FakeCursorPlugin';
5 |
6 | export default [dropCursor(), gapCursor(), history(), FakeCursorPlugin()];
7 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CounterInfoTool from './CounterInfoTool';
3 |
4 | export default class CounterInfoService extends Service {
5 | register() {
6 | this.container.bind('CounterInfoTool').to(CounterInfoTool);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/ListToolGroupService/ListToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Lists from './Lists';
3 |
4 | class ListToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Lists').to(Lists);
7 | }
8 | }
9 |
10 | export default ListToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/NoteToolGroupService/NoteToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Notes from './Notes';
3 |
4 | class NoteToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Notes').to(Notes);
7 | }
8 | }
9 |
10 | export default NoteToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/TextToolGroupService/TextToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Text from './Text';
3 |
4 | class TextToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Text').to(Text);
7 | }
8 | }
9 |
10 | export default TextToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/LayoutService/LayoutService.js:
--------------------------------------------------------------------------------
1 | import Service from '../../../Service';
2 | import Layout from './Layout';
3 |
4 | export default class LayoutService extends Service {
5 | name = 'LayoutService';
6 |
7 | register() {
8 | this.container.bind('Layout').to(Layout).inSingletonScope();
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/AiService/AiToolGroupService/AiToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ToggleAi from './ToggleAi';
3 |
4 | class AiToolGroupService extends Service {
5 | register() {
6 | this.container.bind('ToggleAi').to(ToggleAi);
7 | }
8 | }
9 |
10 | export default AiToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SuperscriptService/schema/superscriptMark.js:
--------------------------------------------------------------------------------
1 | const superscriptMark = {
2 | excludes: 'subscript',
3 | parseDOM: [{ tag: 'sup' }, { style: 'vertical-align=super' }],
4 | toDOM: (hook, next) => {
5 | hook.value = ['sup'];
6 | next();
7 | },
8 | };
9 |
10 | export default superscriptMark;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/schema/index.js:
--------------------------------------------------------------------------------
1 | import OenAsideNode from './OenAsideNode';
2 | import OenContainerNode from './OenContainerNode';
3 | import OenSectionNode from './OenSectionNode';
4 |
5 | export default {
6 | oen_container: OenContainerNode,
7 | oen_section: OenSectionNode,
8 | oen_aside: OenAsideNode,
9 | };
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ParagraphService/ParagraphService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Paragraph from './Paragraph';
3 |
4 | class ParagraphService extends Service {
5 | register() {
6 | this.container.bind('Paragraph').to(Paragraph);
7 | }
8 | }
9 |
10 | export default ParagraphService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ImageService/ImageToolGroupService/ImageToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Images from './Images';
3 |
4 | class ImageToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Images').to(Images);
7 | }
8 | }
9 |
10 | export default ImageToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-citation-service/src/CitationToolGroupService/CitationToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Citation from './Citation';
3 |
4 | class CitationToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Citation').to(Citation);
7 | }
8 | }
9 |
10 | export default CitationToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ShortCutsInfoTool from './ShortCutsInfoTool';
3 |
4 | export default class ShortCutsInfoService extends Service {
5 | register() {
6 | this.container.bind('ShortCutsInfoTool').to(ShortCutsInfoTool);
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/schema/trackChangesMarks/index.js:
--------------------------------------------------------------------------------
1 | import insertionMark from './insertionMark';
2 | import deletionMark from './deletionMark';
3 | import formatChangeMark from './formatChangeMark';
4 |
5 | export default {
6 | format_change: formatChangeMark,
7 | insertion: insertionMark,
8 | deletion: deletionMark,
9 | };
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/DisplayToolGroupService/DisplayToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Display from './Display';
3 |
4 | class DisplayToolGroupService extends Service {
5 | register() {
6 | this.container.bind('Display').to(Display);
7 | }
8 | }
9 |
10 | export default DisplayToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/schema/mathInlineNode.js:
--------------------------------------------------------------------------------
1 | const mathInlineNode = {
2 | group: 'inline math',
3 | content: 'text*',
4 | inline: true,
5 | atom: true,
6 | toDOM: () => ['math-inline', { class: 'math-node' }, 0],
7 | parseDOM: [
8 | {
9 | tag: 'math-inline',
10 | },
11 | ],
12 | };
13 |
14 | export default mathInlineNode;
15 |
--------------------------------------------------------------------------------
/wax-table-service/src/EditTableService/EditTableService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TableDropDownOptions from './TableDropDownOptions';
3 |
4 | class EditTableService extends Service {
5 | register() {
6 | this.container.bind('TableDropDownOptions').to(TableDropDownOptions);
7 | }
8 | }
9 |
10 | export default EditTableService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/schema/mathDisplayNode.js:
--------------------------------------------------------------------------------
1 | const mathDisplayNode = {
2 | group: 'block math',
3 | content: 'text*',
4 | atom: true,
5 | code: true,
6 | toDOM: () => ['math-display', { class: 'math-node' }, 0],
7 | parseDOM: [
8 | {
9 | tag: 'math-display',
10 | },
11 | ],
12 | };
13 |
14 | export default mathDisplayNode;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/NoteEditor.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | import React from 'react';
3 | import Editor from './Editor';
4 |
5 | export default ({ notes, view }) => {
6 | return (
7 | <>
8 | {notes.map(note => (
9 |
10 | ))}
11 | >
12 | );
13 | };
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENLeftToolGroupService/OENLeftToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import OENTools from './OENTools';
3 |
4 | class OENLeftToolGroupService extends Service {
5 | register() {
6 | this.container.bind('OENTools').to(OENTools);
7 | }
8 | }
9 |
10 | export default OENLeftToolGroupService;
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # misc
11 | .DS_Store
12 | .env.local
13 | .env.development.local
14 | .env.test.local
15 | .env.production.local
16 |
17 | npm-debug.log*
18 | yarn-debug.log*
19 | yarn-error.log*
20 | yarn.lock
21 | package-lock.json
22 | lerna-debug.log
23 | README.md
24 |
25 | .vscode
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/Service.js:
--------------------------------------------------------------------------------
1 | export default class Service {
2 | setApp(app) {
3 | this.app = app;
4 | }
5 |
6 | get container() {
7 | return this.app.container;
8 | }
9 |
10 | get config() {
11 | return this.app.config.get(`config.${this.name}`) || this.app.config;
12 | }
13 |
14 | get schema() {
15 | return this.app.getSchema();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuWrapper.js:
--------------------------------------------------------------------------------
1 | /* eslint no-underscore-dangle: 0 */
2 | /* eslint react/prop-types: 0 */
3 |
4 | import React from 'react';
5 | import { map } from 'lodash';
6 |
7 | const MainMenuBar = ({ items = [], view }) => {
8 | return <>{map(items, item => item.renderTools(view))}>;
9 | };
10 |
11 | export default MainMenuBar;
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CodeBlockService/CodeBlockToolGroupService/CodeBlockToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CodeBlock from './CodeBlock';
3 |
4 | class CodeBlockToolGroupService extends Service {
5 | register() {
6 | this.container.bind('CodeBlock').to(CodeBlock);
7 | }
8 | }
9 |
10 | export default CodeBlockToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/NoteToolGroupService/Notes.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Notes extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('Note') note) {
8 | super();
9 | this.tools = [note];
10 | }
11 | }
12 |
13 | export default Notes;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ImageService/ImageToolGroupService/Images.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Images extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('Image') image) {
8 | super();
9 | this.tools = [image];
10 | }
11 | }
12 |
13 | export default Images;
14 |
--------------------------------------------------------------------------------
/wax-table-service/src/index.js:
--------------------------------------------------------------------------------
1 | import InsertTableService from './InsertTableService/InsertTableService';
2 | import EditTableService from './EditTableService/EditTableService';
3 | import TableToolGroupService from './TableToolGroupService/TableToolGroupService';
4 |
5 | export default [
6 | new InsertTableService(),
7 | new EditTableService(),
8 | new TableToolGroupService(),
9 | ];
10 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FullScreenService/FullScreenToolGroupService/FullScreenToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import FullScreen from './FullScreen';
3 |
4 | class FullScreenToolGroupService extends Service {
5 | register() {
6 | this.container.bind('FullScreen').to(FullScreen);
7 | }
8 | }
9 |
10 | export default FullScreenToolGroupService;
11 |
--------------------------------------------------------------------------------
/editors/demo/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/WaxToolGroups/DisplayTextToolGroupService/DisplayTextToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import DisplayText from './DisplayText';
3 |
4 | class DisplayTextToolGroupService extends Service {
5 | register() {
6 | this.container.bind('DisplayText').to(DisplayText);
7 | }
8 | }
9 |
10 | export default DisplayTextToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/FillTheGapToolGroupService/FillTheGapToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import FillTheGap from './FillTheGap';
3 |
4 | class FillTheGapToolGroupService extends Service {
5 | register() {
6 | this.container.bind('FillTheGap').to(FillTheGap);
7 | }
8 | }
9 |
10 | export default FillTheGapToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # dist
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .directory
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | yarn.lock
25 | package-lock.json
26 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # dist
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .directory
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | yarn.lock
25 | package-lock.json
26 |
--------------------------------------------------------------------------------
/wax-citation-service/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # dist
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .directory
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | yarn.lock
25 | package-lock.json
26 | README.md
--------------------------------------------------------------------------------
/wax-table-service/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # dist
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .directory
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | yarn.lock
25 | package-lock.json
26 | README.md
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/theme/elements/ButtonStyles.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from "styled-components";
2 |
3 | export default css`
4 | background: #fff;
5 | border: none;
6 | font-size: inherit;
7 | cursor: pointer;
8 | border-radius: 0;
9 | padding: 5px 10px;
10 | &:disabled {
11 | color: #ccc;
12 | pointer-events: none;
13 | }
14 | &:hover {
15 | background: #f6f6f6;
16 | }
17 | `;
18 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/theme/elements/ButtonStyles.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from "styled-components";
2 |
3 | export default css`
4 | background: #fff;
5 | border: none;
6 | font-size: inherit;
7 | cursor: pointer;
8 | border-radius: 0;
9 | padding: 5px 10px;
10 | &:disabled {
11 | color: #ccc;
12 | pointer-events: none;
13 | }
14 | &:hover {
15 | background: #f6f6f6;
16 | }
17 | `;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/DisplayBlockLevelService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import DisplayServices from './index';
3 |
4 | class DisplayBlockLevelService extends Service {
5 | // register() {
6 | // this.config.pushToArray("services", DisplayServices);
7 | // }
8 | dependencies = DisplayServices;
9 | }
10 |
11 | export default DisplayBlockLevelService;
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/TrackOptionsToolGroupService/TrackOptionsToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TrackOptions from './TrackOptions';
3 |
4 | class TrackOptionsToolGroupService extends Service {
5 | register() {
6 | this.container.bind('TrackOptions').to(TrackOptions);
7 | }
8 | }
9 |
10 | export default TrackOptionsToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/WaxToolGroups/BlockDropDownToolGroupService/BlockDropDownToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import BlockDropDown from './BlockDropDown';
3 |
4 | class BlockDropDownToolGroupService extends Service {
5 | register() {
6 | this.container.bind('BlockDropDown').to(BlockDropDown);
7 | }
8 | }
9 |
10 | export default BlockDropDownToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-questions-service/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 |
4 | # testing
5 | /coverage
6 |
7 | # production
8 | /build
9 |
10 | # dist
11 | /dist
12 |
13 | # misc
14 | .DS_Store
15 | .env.local
16 | .env.development.local
17 | .env.test.local
18 | .env.production.local
19 | .directory
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 | yarn.lock
25 | package-lock.json
26 | README.md
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/fillTheGap.css:
--------------------------------------------------------------------------------
1 | /* fill The Gap */
2 |
3 | .fill-the-gap {
4 | }
5 |
6 | .ProseMirror .fill-the-gap .ProseMirror {
7 | box-shadow: none;
8 | border-bottom: 3px solid #F5F5F7;
9 | line-height: 2.2;
10 | padding: 25px 10px 20px 10px;
11 | }
12 |
13 | .ProseMirror .fill-the-gap span > .ProseMirror {
14 | box-shadow: none;
15 | line-height: 1.6;
16 | }
17 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/theme/elements/ButtonStyles.js:
--------------------------------------------------------------------------------
1 | import styled, { css } from 'styled-components';
2 |
3 | export default css`
4 | background: #fff;
5 | border: none;
6 | font-size: inherit;
7 | cursor: pointer;
8 | border-radius: 0;
9 | padding: 5px 10px;
10 | &:disabled {
11 | color: #ccc;
12 | pointer-events: none;
13 | }
14 | &:hover {
15 | background: #f6f6f6;
16 | }
17 | `;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/AiService/AiToolGroupService/ToggleAi.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class ToggleAi extends ToolGroup {
6 | tools = [];
7 |
8 | constructor(@inject('ToggleAiTool') toggleAiTool) {
9 | super();
10 | this.tools = [toggleAiTool];
11 | }
12 | }
13 |
14 | export default ToggleAi;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CodeBlockService/CodeBlockToolGroupService/CodeBlock.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class CodeBlock extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('CodeBlockTool') codeblock) {
8 | super();
9 | this.tools = [codeblock];
10 | }
11 | }
12 |
13 | export default CodeBlock;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BlockQuoteService/BlockQuoteToolGroupService/BlockQuoteToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import BlockQuoteTool from './BlockQuoteTool';
3 |
4 | class BlockQuoteToolGroupService extends Service {
5 | register() {
6 | this.container.bind('BlockQuoteTool').to(BlockQuoteTool);
7 | }
8 | }
9 |
10 | export default BlockQuoteToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TransformService/TransformToolGroupService/TransformToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TransformToolGroup from './TransformToolGroup';
3 |
4 | class TransformToolGroupService extends Service {
5 | register() {
6 | this.container.bind('TransformToolGroup').to(TransformToolGroup);
7 | }
8 | }
9 |
10 | export default TransformToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-questions-service/src/NumericalAnswerService/numericalAnswer.css:
--------------------------------------------------------------------------------
1 | /* fill The Gap */
2 |
3 | .numerical-answer {}
4 |
5 | .ProseMirror .numerical-answer .ProseMirror {
6 | box-shadow: none;
7 | border-bottom: 3px solid #F5F5F7;
8 | line-height: 2.2;
9 | padding: 25px 10px 20px 10px;
10 | }
11 |
12 | .ProseMirror .numerical-answer span>.ProseMirror {
13 | box-shadow: none;
14 | line-height: 1.6;
15 | }
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/FillTheGapToolGroupService/FillTheGap.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class FillTheGap extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('CreateGap') CreateGap) {
8 | super();
9 | this.tools = [CreateGap];
10 | }
11 | }
12 |
13 | export default FillTheGap;
14 |
--------------------------------------------------------------------------------
/wax-questions-service/src/QuestionsDropDownToolGroupService/QuestionsDropDownToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import QuestionsDropDown from './QuestionsDropDown';
3 |
4 | class QuestionsDropDownToolGroupService extends Service {
5 | register() {
6 | this.container.bind('QuestionsDropDown').to(QuestionsDropDown);
7 | }
8 | }
9 |
10 | export default QuestionsDropDownToolGroupService;
11 |
--------------------------------------------------------------------------------
/editors/demo/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/InfoToolGroupService/EditorInfoToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import InfoToolGroup from './InfoTool';
3 |
4 | class EditorInfoToolGroupService extends Service {
5 | name = 'EditorInfoToolGroupService';
6 | register() {
7 | this.container.bind('InfoToolGroup').to(InfoToolGroup);
8 | }
9 | }
10 | export default EditorInfoToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-citation-service/src/CitationToolGroupService/Citation.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Citation extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('CitationDropDownOptions') citationDropDownOptions) {
8 | super();
9 | this.tools = [citationDropDownOptions];
10 | }
11 | }
12 |
13 | export default Citation;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/index.js:
--------------------------------------------------------------------------------
1 | import UndoService from './UndoService/UndoService';
2 | import RedoService from './RedoService/RedoService';
3 | import SaveService from './SaveService/SaveService';
4 | import BaseToolGroupService from './BaseToolGroupService/BaseToolGroupService';
5 |
6 | export default [
7 | new UndoService(),
8 | new RedoService(),
9 | new SaveService(),
10 | new BaseToolGroupService(),
11 | ];
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggestingService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import EditingSuggesting from './EditingSuggesting';
3 |
4 | class EditingSuggestingService extends Service {
5 | name = 'EditingSuggestingService';
6 |
7 | register() {
8 | this.container.bind('EditingSuggesting').to(EditingSuggesting);
9 | }
10 | }
11 | export default EditingSuggestingService;
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FullScreenService/FullScreenToolGroupService/FullScreen.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class FullScreen extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('FullScreenTool') fullScreenTool) {
8 | super();
9 | this.tools = [fullScreenTool];
10 | }
11 | }
12 |
13 | export default FullScreen;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/HighlightService/TextHighlightToolGroupService/TextHighlightToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import HighlightToolGroup from './HightlightToolGroup';
3 |
4 | class TextHighlightToolGroupServices extends Service {
5 | register() {
6 | this.container.bind('HighlightToolGroup').to(HighlightToolGroup);
7 | }
8 | }
9 |
10 | export default TextHighlightToolGroupServices;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ModalService/pmPlugins/ModalPlugin.js:
--------------------------------------------------------------------------------
1 | import { Plugin, PluginKey } from "prosemirror-state";
2 | import actions from "./actions";
3 | export default key =>
4 | new Plugin({
5 | key: new PluginKey(key),
6 | state: {
7 | init: function init() {
8 | return {
9 | action: actions.HIDE_OVERLAY
10 | };
11 | },
12 | apply: function apply(tr) {}
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/index.js:
--------------------------------------------------------------------------------
1 | import CounterInfoService from './CounterInfoService/CounterInfoService';
2 | import ShortCutsInfoService from './ShortCutsInfoService/ShortCutsInfoService';
3 | import EditorInfoToolGroupService from './InfoToolGroupService/EditorInfoToolGroupService';
4 |
5 | export default [
6 | new CounterInfoService(),
7 | new ShortCutsInfoService(),
8 | new EditorInfoToolGroupService(),
9 | ];
10 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleDropDownService/MultipleDropDownToolGroupService/MultipleDropDownToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import MultipleDropDown from './MultipleDropDown';
3 |
4 | class MultipleDropDownToolGroupService extends Service {
5 | register() {
6 | this.container.bind('MultipleDropDown').to(MultipleDropDown);
7 | }
8 | }
9 |
10 | export default MultipleDropDownToolGroupService;
11 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/layout/EditorElements.js:
--------------------------------------------------------------------------------
1 | import { css } from 'styled-components';
2 | import { th } from '@pubsweet/ui-toolkit';
3 |
4 | /* All styles regarding ProseMirror surface and elements */
5 |
6 | const fontWriting = css`
7 | color: ${th('colorText')};
8 | font-family: ${th('fontWriting')};
9 | font-size: ${th('fontSizeBase')};
10 | `;
11 |
12 | export default css`
13 | .ProseMirror {
14 | ${fontWriting}
15 | }
16 | `;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplaceToolGroupService/FindAndReplaceToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import FindAndReplaceTool from './FindAndReplaceTool';
3 |
4 | class FindAndReplaceToolGroupService extends Service {
5 | register() {
6 | this.container.bind('FindAndReplaceTool').to(FindAndReplaceTool);
7 | }
8 | }
9 |
10 | export default FindAndReplaceToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/AnnotationToolGroupService/AnnotationToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import Annotations from './Annotations';
3 |
4 | class AnnotationToolGroupService extends Service {
5 | name = 'AnnotationToolGroupService';
6 |
7 | register() {
8 | this.container.bind('Annotations').to(Annotations);
9 | }
10 | }
11 |
12 | export default AnnotationToolGroupService;
13 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENAsideLongToolGroupService/OENAsideLongToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import OENAsideLongToolGroup from './OENAsideLongToolGroup';
3 |
4 | class OENAsideLongToolGroupService extends Service {
5 | register() {
6 | this.container.bind('OENAsideLongToolGroup').to(OENAsideLongToolGroup);
7 | }
8 | }
9 |
10 | export default OENAsideLongToolGroupService;
11 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/layout/EditorElements.js:
--------------------------------------------------------------------------------
1 | import { css } from 'styled-components';
2 | import { th } from '@pubsweet/ui-toolkit';
3 |
4 | /* All styles regarding ProseMirror surface and elements */
5 |
6 | const fontWriting = css`
7 | color: ${th('colorText')};
8 | font-family: ${th('fontWriting')};
9 | font-size: ${th('fontSizeBase')};
10 | `;
11 |
12 | export default css`
13 | .ProseMirror {
14 | ${fontWriting}
15 | }
16 | `;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/EnterService/EnterService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import GetContentOnEnterPlugin from './plugins/GetContentOnEnterPlugin';
3 |
4 | class EnterService extends Service {
5 | name = 'EnterService';
6 |
7 | boot() {
8 | this.app.PmPlugins.add(
9 | 'getContentOnEnterPlugin',
10 | GetContentOnEnterPlugin(this.config),
11 | );
12 | }
13 | }
14 |
15 | export default EnterService;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENAsideShortToolGroupService/OENAsideShortToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import OENAsideShortToolGroup from './OENAsideShortToolGroup';
3 |
4 | class OENAsideShortToolGroupService extends Service {
5 | register() {
6 | this.container.bind('OENAsideShortToolGroup').to(OENAsideShortToolGroup);
7 | }
8 | }
9 |
10 | export default OENAsideShortToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersToolGroupService/SpecialCharactersToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import SpecialCharacters from './SpecialCharacters';
3 |
4 | class SpecialCharactersToolGroupService extends Service {
5 | register() {
6 | this.container.bind('SpecialCharacters').to(SpecialCharacters);
7 | }
8 | }
9 |
10 | export default SpecialCharactersToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/TrackingAndEditingToolGroupService/TrackingAndEditingToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TrackingAndEditing from './TrackingAndEditing';
3 |
4 | class TrackingAndEditingToolGroupService extends Service {
5 | register() {
6 | this.container.bind('TrackingAndEditing').to(TrackingAndEditing);
7 | }
8 | }
9 |
10 | export default TrackingAndEditingToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/essay.css:
--------------------------------------------------------------------------------
1 | /* -- Essay ---------------------------------- */
2 | .essay {
3 | border: 3px solid #f5f5f7;
4 | margin-bottom: 30px;
5 | margin-top: 30px;
6 | padding: 3px;
7 | }
8 |
9 | essay::before {
10 | background-color: #fff;
11 | bottom: 22px;
12 | color: #535e76;
13 | content: 'Essay';
14 | height: 10px;
15 | left: -1px;
16 | position: relative;
17 | width: 30px;
18 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TransformService/TransformToolGroupService/TransformToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class TransformToolGroup extends ToolGroup {
6 | tools = [];
7 |
8 | constructor(@inject('TransformTool') transformCase) {
9 | super();
10 | this.tools = [transformCase];
11 | }
12 | }
13 |
14 | export default TransformToolGroup;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/MenuService/MenuCollection.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-unused-vars */
2 | import { injectable, multiInject } from 'inversify';
3 |
4 | @injectable()
5 | class MenuCollection {
6 | menus = [];
7 | constructor(@multiInject('Menu') menus) {
8 | this.menus = menus;
9 | }
10 |
11 | getMenu(name) {
12 | return this.menus.find(menu => menu.name === name);
13 | }
14 | }
15 |
16 | export default MenuCollection;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ExternalAPIContentService/ExternalAPIContentToolGroupService/ExternalAPIContentToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ExternalAPIContent from './ExternalAPIContent';
3 |
4 | class ExternalAPIContentToolGroupService extends Service {
5 | register() {
6 | this.container.bind('ExternalAPIContent').to(ExternalAPIContent);
7 | }
8 | }
9 |
10 | export default ExternalAPIContentToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/HighlightService/TextHighlightToolGroupService/HightlightToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class HighlightToolGroup extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('TextHighlightTool') texthighlight) {
8 | super();
9 | this.tools = [texthighlight];
10 | }
11 | }
12 |
13 | export default HighlightToolGroup;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/TrackCommentOptionsToolGroupService/TrackCommentOptionsToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TrackCommentOptions from './TrackCommentOptions';
3 |
4 | class TrackCommentOptionsToolGroupService extends Service {
5 | register() {
6 | this.container.bind('TrackCommentOptions').to(TrackCommentOptions);
7 | }
8 | }
9 |
10 | export default TrackCommentOptionsToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleDropDownService/MultipleDropDownToolGroupService/MultipleDropDown.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class MultipleDropDown extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('CreateDropDown') CreateDropDown) {
8 | super();
9 | this.tools = [CreateDropDown];
10 | }
11 | }
12 |
13 | export default MultipleDropDown;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/BaseToolGroupService/Base.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Base extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('Undo') undo,
9 | @inject('Redo') redo,
10 | @inject('Save') save,
11 | ) {
12 | super();
13 | this.tools = [undo, redo, save];
14 | }
15 | }
16 |
17 | export default Base;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplaceToolGroupService/FindAndReplaceTool.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class FindAndReplaceTool extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('FindAndReplace') findAndReplace) {
8 | super();
9 | this.tools = [findAndReplace];
10 | }
11 | }
12 |
13 | export default FindAndReplaceTool;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/JoinUpService/JoinUpService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import JoinUp from './JoinUp';
3 |
4 | class JoinUpService extends Service {
5 | name = 'JoinUpService';
6 | register() {
7 | // this.container.bind('JoinUp').to(JoinUp);
8 | this.container.bind('JoinUp').toDynamicValue(() => {
9 | return new JoinUp(this.config);
10 | });
11 | }
12 | }
13 |
14 | export default JoinUpService;
15 |
--------------------------------------------------------------------------------
/wax-table-service/src/TableToolGroupService/Tables.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Tables extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('Table') table,
9 | @inject('TableDropDownOptions') tableDropDownOptions,
10 | ) {
11 | super();
12 | this.tools = [table, tableDropDownOptions];
13 | }
14 | }
15 |
16 | export default Tables;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/lists.css:
--------------------------------------------------------------------------------
1 | /* lists */
2 |
3 | ul,
4 | ol {
5 | padding-left: 30px;
6 | }
7 |
8 | /* ol {
9 | counter-reset: item
10 | }
11 |
12 | li {
13 | display: block;
14 | margin-top: 1em;
15 | margin-bottom: 1em;
16 | }
17 |
18 | li p {
19 | display: inline;
20 | }
21 |
22 | li:before {
23 | content: counters(item, ".") " ";
24 | counter-increment: item
25 | } */
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/ShowHideTrackChangeService/ShowHideTrackChangeService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ShowHideTrackChange from './ShowHideTrackChange';
3 |
4 | class ShowHideTrackChangeService extends Service {
5 | name = 'ShowHideTrackChangeService';
6 |
7 | register() {
8 | this.container.bind('ShowHideTrackChange').to(ShowHideTrackChange);
9 | }
10 | }
11 |
12 | export default ShowHideTrackChangeService;
13 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TransformService/TransformService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import TransformTool from './TransformTool';
3 | import TransformToolGroupService from './TransformToolGroupService/TransformToolGroupService';
4 |
5 | export default class TransformService extends Service {
6 | register() {
7 | this.container.bind('TransformTool').to(TransformTool);
8 | }
9 |
10 | dependencies = [new TransformToolGroupService()];
11 | }
12 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagBlockToolGroupService/CustomTagBlockToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CustomTagBlockToolGroup from './CustomTagBlockToolGroup';
3 |
4 | class CustomTagBlockToolGroupService extends Service {
5 | register() {
6 | this.container.bind('CustomTagBlockToolGroup').to(CustomTagBlockToolGroup);
7 | }
8 | }
9 |
10 | export default CustomTagBlockToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagInlineToolGroupService/CustomTagInlineToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CustomTagInlineToolGroup from './CustomTagInlineToolGroup';
3 |
4 | class CustomTagInlineToolGroupService extends Service {
5 | register() {
6 | this.container.bind('CustomTagInline').to(CustomTagInlineToolGroup);
7 | }
8 | }
9 |
10 | export default CustomTagInlineToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/ListItemService/ListItemService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import listItemNode from './schema/listItemNode';
3 |
4 | class ListItemService extends Service {
5 | register() {
6 | const createNode = this.container.get('CreateNode');
7 | createNode(
8 | {
9 | list_item: listItemNode,
10 | },
11 | { toWaxSchema: true },
12 | );
13 | }
14 | }
15 |
16 | export default ListItemService;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersToolGroupService/SpecialCharacters.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class SpecialCharacters extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('SpecialCharactersTool') specialCharactersTool) {
8 | super();
9 | this.tools = [specialCharactersTool];
10 | }
11 | }
12 |
13 | export default SpecialCharacters;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagBlockNewToolGroupService/CustomTagBlockNewToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CustomTagBlockNewToolGroup from './CustomTagBlockNewToolGroup';
3 |
4 | class CustomTagBlockNewToolGroupService extends Service {
5 | register() {
6 | this.container.bind('CustomTagBlock').to(CustomTagBlockNewToolGroup);
7 | }
8 | }
9 |
10 | export default CustomTagBlockNewToolGroupService;
11 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ExternalAPIContentService/ExternalAPIContentToolGroupService/ExternalAPIContent.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class ExternalAPIContent extends ToolGroup {
6 | tools = [];
7 | constructor(@inject('ExternalAPIContentTool') ExternalAPIContentTool) {
8 | super();
9 | this.tools = [ExternalAPIContentTool];
10 | }
11 | }
12 |
13 | export default ExternalAPIContent;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BlockQuoteService/BlockQuoteToolGroupService/BlockQuoteTool.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class BlockQuoteTool extends ToolGroup {
6 | tools = [];
7 | title = '';
8 |
9 | constructor(@inject('BlockQuote') blockQuote, @inject('Lift') lift) {
10 | super();
11 | this.tools = [blockQuote, lift];
12 | }
13 | }
14 |
15 | export default BlockQuoteTool;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/components/icons/Icon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 |
4 | import icons from './icons';
5 |
6 | /**
7 | * Only works with SVG icons from icons.js
8 | */
9 |
10 | const SVGIcon = props => {
11 | const { className, name } = props;
12 | const Component = icons[name];
13 | return ;
14 | };
15 |
16 | SVGIcon.propTypes = {
17 | name: PropTypes.string.isRequired,
18 | };
19 |
20 | export default SVGIcon;
21 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/components/helpers/useDebounce.js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from 'react';
2 |
3 | const useDebounce = (value, delay) => {
4 | const [debouncedValue, setDebouncedValue] = useState(value);
5 |
6 | useEffect(() => {
7 | const handler = setTimeout(() => {
8 | setDebouncedValue(value);
9 | }, delay);
10 |
11 | return () => {
12 | clearTimeout(handler);
13 | };
14 | }, [value]);
15 |
16 | return debouncedValue;
17 | };
18 |
19 | export default useDebounce;
20 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagInlineToolGroupService/CustomTagInlineToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class CustomTagInlineToolGroup extends ToolGroup {
6 | tools = [];
7 |
8 | constructor(@inject('CustomTagInlineTool') customTagInline) {
9 | super();
10 | this.tools = [customTagInline];
11 | }
12 | }
13 |
14 | export default CustomTagInlineToolGroup;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/AcceptTrackChangeService/AcceptTrackChangeService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import AcceptTrackChange from './AcceptTrackChange';
3 |
4 | class AcceptTrackChangeService extends Service {
5 | name = 'AcceptTrackChangeService';
6 | register() {
7 | this.container.bind('AcceptTrackChange').toDynamicValue(() => {
8 | return new AcceptTrackChange(this.config);
9 | });
10 | }
11 | }
12 |
13 | export default AcceptTrackChangeService;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENContainersToolGroupService/OENContainersToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class OENContainersToolGroup extends ToolGroup {
6 | tools = [];
7 | title = 'OEN Containers';
8 |
9 | constructor(@inject('OENContainersTool') OENContainersTool) {
10 | super();
11 | this.tools = [OENContainersTool];
12 | }
13 | }
14 |
15 | export default OENContainersToolGroup;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/EnableTrackChangeService/EnableTrackChangeService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import EnableTrackChange from './EnableTrackChange';
3 |
4 | class EnableTrackChangeService extends Service {
5 | name = 'EnableTrackChangeService';
6 |
7 | register() {
8 | this.container.bind('EnableTrackChange').toDynamicValue(() => {
9 | return new EnableTrackChange(this.config);
10 | });
11 | }
12 | }
13 |
14 | export default EnableTrackChangeService;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/RejectTrackChangeService/RejectTrackChangeService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import RejectTrackChange from './RejectTrackChange';
3 |
4 | class RejectTrackChangeService extends Service {
5 | name = 'RejectTrackChangeService';
6 |
7 | register() {
8 | this.container.bind('RejectTrackChange').toDynamicValue(() => {
9 | return new RejectTrackChange(this.config);
10 | });
11 | }
12 | }
13 |
14 | export default RejectTrackChangeService;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/InfoToolGroupService/InfoTool.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class InfoToolGroup extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('CounterInfoTool') counterinfotool,
9 | @inject('ShortCutsInfoTool') shortcutsinfotool,
10 | ) {
11 | super();
12 | this.tools = [shortcutsinfotool, counterinfotool];
13 | }
14 | }
15 |
16 | export default InfoToolGroup;
17 |
--------------------------------------------------------------------------------
/editors/demo/src/HHMI/layout/EditorElements.js:
--------------------------------------------------------------------------------
1 | import { css } from 'styled-components';
2 | import { th } from '@pubsweet/ui-toolkit';
3 |
4 | /* All styles regarding ProseMirror surface and elements */
5 |
6 | const fontWriting = css`
7 | color: ${th('colorText')};
8 | font-family: ${th('fontWriting')};
9 | font-size: ${th('fontSizeBase')};
10 | `;
11 |
12 | export default css`
13 | .ProseMirror {
14 | ${fontWriting}
15 |
16 | .ProseMirror-separator {
17 | display: none !important;
18 | }
19 | }
20 | `;
21 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/CreateGapService/CreateGapService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import CreateGap from './CreateGap';
3 | import FillTheGapToolGroupService from '../FillTheGapToolGroupService/FillTheGapToolGroupService';
4 |
5 | class FillTheGapQuestionService extends Service {
6 | register() {
7 | this.container.bind('CreateGap').to(CreateGap);
8 | }
9 |
10 | dependencies = [new FillTheGapToolGroupService()];
11 | }
12 |
13 | export default FillTheGapQuestionService;
14 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/AiService/ToggleAiTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { v4 as uuidv4 } from 'uuid';
3 | import { Tools } from 'wax-prosemirror-core';
4 | import ToggleAiComponent from './components/ToggleAiComponent';
5 |
6 | class ToggleAiTool extends Tools {
7 | title = 'Toggle Ai';
8 | icon = 'ai';
9 | name = 'ToggleAi';
10 |
11 | renderTool(view) {
12 | return (
13 |
14 | );
15 | }
16 | }
17 |
18 | export default ToggleAiTool;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagBlockToolGroupService/CustomTagBlockToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class CustomTagBlockToolGroup extends ToolGroup {
6 | tools = [];
7 | title = 'Custom Block';
8 |
9 | constructor(@inject('CustomTagBlockTool') customTagBlock) {
10 | super();
11 | this.tools = [customTagBlock];
12 | }
13 | }
14 |
15 | export default CustomTagBlockToolGroup;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/PmPlugins.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable no-underscore-dangle */
2 | import { injectable } from 'inversify';
3 |
4 | @injectable()
5 | export default class PmPlugins {
6 | _plugins = new Map();
7 | add(key, plugin) {
8 | this._plugins.set(key, plugin);
9 | }
10 |
11 | getAll() {
12 | return [...this._plugins.values()];
13 | }
14 |
15 | replace(key, plugin) {
16 | this._plugins.delete(key);
17 | this.add(key, plugin);
18 | }
19 |
20 | get(key) {
21 | return this._plugins.get(key);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/schema/footNoteNode.js:
--------------------------------------------------------------------------------
1 | const footNoteNode = {
2 | group: 'notes inline',
3 | content: 'inline*',
4 | inline: true,
5 | atom: true,
6 | attrs: {
7 | id: { default: '' },
8 | },
9 | toDOM: node => {
10 | return ['footnote', node.attrs];
11 | },
12 | parseDOM: [
13 | {
14 | tag: 'footnote',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | };
19 | },
20 | },
21 | ],
22 | };
23 |
24 | export default footNoteNode;
25 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/TrackingAndEditingToolGroupService/TrackingAndEditing.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class TrackingAndEditing extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('EditingSuggesting') editingSuggesting,
9 | // @inject('FindAndReplace') findAndReplace,
10 | ) {
11 | super();
12 | this.tools = [editingSuggesting];
13 | }
14 | }
15 |
16 | export default TrackingAndEditing;
17 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FullScreenService/FullScreenService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import FullScreenTool from './FullScreenTool';
3 | import FullScreenToolGroupService from './FullScreenToolGroupService/FullScreenToolGroupService';
4 |
5 | class FullScreenService extends Service {
6 | name = 'FullScreenService';
7 |
8 | register() {
9 | this.container.bind('FullScreenTool').to(FullScreenTool);
10 | }
11 |
12 | dependencies = [new FullScreenToolGroupService()];
13 | }
14 |
15 | export default FullScreenService;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/schema/titleNode.js:
--------------------------------------------------------------------------------
1 | const titleNode = {
2 | attrs: {
3 | level: { default: 1 },
4 | },
5 | content: 'inline*',
6 | group: 'block',
7 | defining: true,
8 | parseDOM: [
9 | {
10 | tag: 'h1',
11 | attrs: { level: 1 },
12 | },
13 | ],
14 | toDOM(hook, next) {
15 | const attrs = {};
16 | // eslint-disable-next-line no-param-reassign
17 | hook.value = [`h${hook.node.attrs.level}`, attrs, 0];
18 | next();
19 | },
20 | };
21 |
22 | export default titleNode;
23 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagToolGroupService/CustomTagBlockNewToolGroupService/CustomTagBlockNewToolGroup.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class CustomTagBlockToolGroup extends ToolGroup {
6 | tools = [];
7 | title = 'Custom Block';
8 |
9 | constructor(@inject('CustomTagBlockNewTool') customTagBlockNewTool) {
10 | super();
11 | this.tools = [customTagBlockNewTool];
12 | }
13 | }
14 |
15 | export default CustomTagBlockToolGroup;
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/SubTitleService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import subTitleNode from './schema/subTitleNode';
3 | import SubTitle from './SubTitle';
4 |
5 | class SubTitleService extends Service {
6 | register() {
7 | this.container.bind('SubTitle').to(SubTitle);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | subtitle: subTitleNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default SubTitleService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/AuthorService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import authorNode from './schema/authorNode';
3 | import Author from './Author';
4 |
5 | class AuthorService extends Service {
6 | // boot() {}
7 |
8 | register() {
9 | this.container.bind('Author').to(Author);
10 | const createNode = this.container.get('CreateNode');
11 | createNode(
12 | {
13 | author: authorNode,
14 | },
15 | { toWaxSchema: true },
16 | );
17 | }
18 | }
19 |
20 | export default AuthorService;
21 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/layout/EditorElements.js:
--------------------------------------------------------------------------------
1 | import { css } from 'styled-components';
2 |
3 | import { th } from '@pubsweet/ui-toolkit';
4 |
5 | /* All styles regarding ProseMirror surface and elements */
6 |
7 | const fontWriting = css`
8 | color: ${th('colorText')};
9 | font-family: ${th('fontWriting')};
10 | font-size: ${th('fontSizeBase')};
11 | `;
12 |
13 | export default css`
14 | .ProseMirror {
15 | background: white;
16 | line-height: 12px;
17 | width: 492px;
18 | white-space: pre !important;
19 | overflow-x: auto;
20 | ${fontWriting}
21 | }
22 | `;
23 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SmallCapsService/SmallCapsService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import smallcapsMark from './schema/smallcapsMark';
3 | import SmallCaps from './SmallCaps';
4 |
5 | class SmallCapsService extends Service {
6 | register() {
7 | this.container.bind('SmallCaps').to(SmallCaps);
8 | const createMark = this.container.get('CreateMark');
9 | createMark(
10 | {
11 | smallcaps: smallcapsMark,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default SmallCapsService;
19 |
--------------------------------------------------------------------------------
/editors/demo/src/OEN/config/defaultSchema.js:
--------------------------------------------------------------------------------
1 | const defaultSchema = {
2 | nodes: {
3 | doc: {
4 | content: 'inline*',
5 | },
6 | text: {
7 | group: 'inline',
8 | },
9 | paragraph: null,
10 | hard_break: null,
11 | title: {
12 | group: 'inline',
13 | content: 'inline*',
14 | inline: true,
15 | parseDOM: [
16 | {
17 | tag: 'title',
18 | },
19 | ],
20 | toDOM(node) {
21 | return ['title', node.attrs, 0];
22 | },
23 | },
24 | },
25 | marks: {},
26 | };
27 |
28 | export default defaultSchema;
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SmallCapsService/schema/smallcapsMark.js:
--------------------------------------------------------------------------------
1 | const smallcapsMark = {
2 | attrs: {
3 | class: { default: 'small-caps' },
4 | },
5 | // inclusive: false,
6 | parseDOM: [
7 | {
8 | tag: 'span.small-caps',
9 | getAttrs(hook, next) {
10 | Object.assign(hook, {
11 | class: hook.dom.getAttribute('class'),
12 | });
13 | next();
14 | },
15 | },
16 | ],
17 | toDOM(hook, next) {
18 | hook.value = ['span', hook.node.attrs, 0];
19 | next();
20 | },
21 | };
22 |
23 | export default smallcapsMark;
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/ListToolGroupService/Lists.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class Lists extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('BlockQuote') blockQuote,
9 | @inject('OrderedList') orderedlist,
10 | @inject('BulletList') bulletlist,
11 | @inject('JoinUp') joinup,
12 | @inject('Lift') lift,
13 | ) {
14 | super();
15 | this.tools = [blockQuote, orderedlist, bulletlist, joinup, lift];
16 | }
17 | }
18 |
19 | export default Lists;
20 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/SourceNoteService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import sourceNoteNode from './schema/sourceNoteNode';
3 | import SourceNote from './SourceNote';
4 |
5 | class SourceNoteService extends Service {
6 | register() {
7 | this.container.bind('SourceNote').to(SourceNote);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | sourceNote: sourceNoteNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default SourceNoteService;
19 |
--------------------------------------------------------------------------------
/editors/demo/src/Editoria/config/defaultSchema.js:
--------------------------------------------------------------------------------
1 | const defaultSchema = {
2 | nodes: {
3 | doc: {
4 | content: 'inline*',
5 | },
6 | text: {
7 | group: 'inline',
8 | },
9 | paragraph: null,
10 | hard_break: null,
11 | title: {
12 | group: 'inline',
13 | content: 'inline*',
14 | inline: true,
15 | parseDOM: [
16 | {
17 | tag: 'title',
18 | },
19 | ],
20 | toDOM(node) {
21 | return ['title', node.attrs, 0];
22 | },
23 | },
24 | },
25 | marks: {},
26 | };
27 |
28 | export default defaultSchema;
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/components/ToolGroups.js:
--------------------------------------------------------------------------------
1 | /* eslint no-underscore-dangle: 0 */
2 | import React from 'react';
3 | import { v4 as uuidv4 } from 'uuid';
4 | import ToolGroupComponent from './ToolGroupComponent';
5 |
6 | const ToolGroups = ({ toolGroups, view }) => {
7 | return toolGroups.map(toolGroup => {
8 | if (toolGroup._toolGroups.length > 0) {
9 | return ;
10 | }
11 | return (
12 |
13 | );
14 | });
15 | };
16 |
17 | export default ToolGroups;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/ExtractProseService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import extractProseNode from './schema/extractProseNode';
3 | import ExtractProse from './ExtractProse';
4 |
5 | class ExtractProseService extends Service {
6 | register() {
7 | this.container.bind('ExtractProse').to(ExtractProse);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | extractProse: extractProseNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default ExtractProseService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/TrackOptionsToolGroupService/TrackOptions.js:
--------------------------------------------------------------------------------
1 | import { injectable, inject } from 'inversify';
2 | import { ToolGroup } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class TrackOptions extends ToolGroup {
6 | tools = [];
7 | constructor(
8 | @inject('ShowHideTrackChange') showHideTrackChange,
9 | @inject('AcceptTrackChange') acceptTrackChange,
10 | @inject('RejectTrackChange') rejectTrackChange,
11 | ) {
12 | super();
13 | this.tools = [showHideTrackChange, acceptTrackChange, rejectTrackChange];
14 | }
15 | }
16 |
17 | export default TrackOptions;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/ShortCutsService/ShortCutsService.js:
--------------------------------------------------------------------------------
1 | import Service from '../../../Service';
2 | import ShortCuts from './ShortCuts';
3 |
4 | export default class ShortCutsService extends Service {
5 | name = 'ShortCutsService';
6 |
7 | register() {
8 | this.container.bind('ShortCuts').to(ShortCuts).inSingletonScope();
9 |
10 | this.container.bind('CreateShortCut').toFactory(context => {
11 | return shortCut => {
12 | const shortCutsInstance = context.container.get('ShortCuts');
13 | shortCutsInstance.addShortCut(shortCut);
14 | };
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/schema/essayContainerNode.js:
--------------------------------------------------------------------------------
1 | const essayContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'essay' },
5 | },
6 | group: 'block questions',
7 | isolating: true,
8 | content: 'block+',
9 | parseDOM: [
10 | {
11 | tag: 'div.essay',
12 | getAttrs(dom) {
13 | return {
14 | id: dom.getAttribute('id'),
15 | class: dom.getAttribute('class'),
16 | };
17 | },
18 | },
19 | ],
20 | toDOM(node) {
21 | return ['div', node.attrs, 0];
22 | },
23 | };
24 |
25 | export default essayContainerNode;
26 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ExternalAPIContentService/externalApiContent.css:
--------------------------------------------------------------------------------
1 | placeholder-external-api {
2 | display: inline-block;
3 | width: 20px;
4 | }
5 |
6 | placeholder-external-api:before {
7 | position: relative;
8 | top: 3px;
9 | content: url("data:image/svg+xml; utf8, ");
10 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrongService/schema/strongMark.js:
--------------------------------------------------------------------------------
1 | const strongMark = {
2 | parseDOM: [
3 | { tag: 'strong' },
4 | // This works around a Google Docs misbehavior where
5 | // pasted content will be inexplicably wrapped in ``
6 | // tags with a font-weight normal.
7 | { tag: 'b', getAttrs: node => node.style.fontWeight !== 'normal' && null },
8 | {
9 | style: 'font-weight',
10 | getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null,
11 | },
12 | ],
13 | toDOM() {
14 | return ['strong', 0];
15 | },
16 | };
17 |
18 | export default strongMark;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/OverlayService/OverlayService.js:
--------------------------------------------------------------------------------
1 | import Service from '../../../Service';
2 | import OverlayComponent from './OverlayComponent';
3 |
4 | export default class OverlayService extends Service {
5 | register() {
6 | this.container.bind('CreateOverlay').toFactory(context => {
7 | return (Component, componentProps, options) => {
8 | const layout = context.container.get('Layout');
9 | layout.addComponent(
10 | 'waxOverlays',
11 | OverlayComponent(Component, options),
12 | componentProps,
13 | );
14 | };
15 | });
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/utilities/track-changes/helpers/removeNode.js:
--------------------------------------------------------------------------------
1 | import { replaceStep } from 'prosemirror-transform';
2 | import { Selection } from 'prosemirror-state';
3 |
4 | const removeNode = (tr, node, nodePos, map) => {
5 | const newNodePos = map.map(nodePos);
6 | const selectionBefore = Selection.findFrom(tr.doc.resolve(newNodePos), -1);
7 | const start = selectionBefore.$anchor.pos;
8 | const end = newNodePos + 1;
9 |
10 | const delStep = replaceStep(tr.doc, start, end);
11 |
12 | tr.step(delStep);
13 | const stepMap = delStep.getMap();
14 | map.appendMap(stepMap);
15 | };
16 |
17 | export default removeNode;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CodeBlockService/schema/codeBlockNode.js:
--------------------------------------------------------------------------------
1 | const codeBlockNode = {
2 | content: 'text*',
3 | group: 'block',
4 | code: true,
5 | defining: true,
6 | marks: 'comment insertion deletion',
7 | attrs: { params: { default: '' } },
8 | parseDOM: [
9 | {
10 | tag: 'pre',
11 | preserveWhitespace: 'full',
12 | getAttrs(dom) {
13 | return {
14 | params: dom.dataset.params,
15 | };
16 | },
17 | },
18 | ],
19 | toDOM(node) {
20 | return ['pre', { 'data-params': node.attrs.params }, ['code', 0]];
21 | },
22 | };
23 |
24 | export default codeBlockNode;
25 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/EpigraphProseService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import epigraphProseNode from './schema/epigraphProseNode';
3 | import EpigraphProse from './EpigraphProse';
4 |
5 | class EpigraphProseService extends Service {
6 | register() {
7 | this.container.bind('EpigraphProse').to(EpigraphProse);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | epigraphProse: epigraphProseNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default EpigraphProseService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrikeThroughService/StrikeThroughService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import strikethroughMark from './schema/strikethroughMark';
3 | import StrikeThrough from './StrikeThrough';
4 |
5 | class StrikeThroughService extends Service {
6 | register() {
7 | this.container.bind('StrikeThrough').to(StrikeThrough);
8 | const createMark = this.container.get('CreateMark');
9 | createMark(
10 | {
11 | strikethrough: strikethroughMark,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default StrikeThroughService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import SpecialCharactersTool from './SpecialCharactersTool';
3 | import SpecialCharactersToolGroupService from './SpecialCharactersToolGroupService/SpecialCharactersToolGroupService';
4 |
5 | class SpecialCharactersService extends Service {
6 | name = 'SpecialCharactersService';
7 |
8 | register() {
9 | this.container.bind('SpecialCharactersTool').to(SpecialCharactersTool);
10 | }
11 |
12 | dependencies = [new SpecialCharactersToolGroupService()];
13 | }
14 | export default SpecialCharactersService;
15 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/ExtractPoetryService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import extractPoetryNode from './schema/extractPoetryNode';
3 | import ExtractPoetry from './ExtractPoetry';
4 |
5 | class ExtractPoetryService extends Service {
6 | register() {
7 | this.container.bind('ExtractPoetry').to(ExtractPoetry);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | extractPoetry: extractPoetryNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default ExtractPoetryService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/TitleService/TitleService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import titleNode from './schema/titleNode';
3 | import Title from './Title';
4 |
5 | class TitleService extends Service {
6 | register() {
7 | this.container.bind('Title').toDynamicValue(() => {
8 | return new Title(this.config.get('config.OENContainersService'));
9 | });
10 | const createNode = this.container.get('CreateNode');
11 | createNode(
12 | {
13 | title: titleNode,
14 | },
15 | { toWaxSchema: true },
16 | );
17 | }
18 | }
19 |
20 | export default TitleService;
21 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/note.css:
--------------------------------------------------------------------------------
1 | /* FootNote */
2 |
3 | .ProseMirror {
4 | counter-reset: footnote!important;
5 | }
6 |
7 | .ProseMirror footnote {
8 | font-variant-numeric: lining-nums proportional-nums;
9 | display: inline-block;
10 | text-align: center;
11 | width: 17px;
12 | height: 17px;
13 | background: white;
14 | border-bottom: 2px solid black;
15 | color: black;
16 | cursor: pointer;
17 | }
18 |
19 | .ProseMirror footnote::after {
20 | content: counter(footnote);
21 | position: relative;
22 | bottom: 2px;
23 | font-size: 16px;
24 | counter-increment: footnote;
25 | }
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/track-changes/helpers/removeNode.js:
--------------------------------------------------------------------------------
1 | import { replaceStep } from 'prosemirror-transform';
2 | import { Selection } from 'prosemirror-state';
3 |
4 | const removeNode = (tr, node, nodePos, map) => {
5 | const newNodePos = map.map(nodePos);
6 | const selectionBefore = Selection.findFrom(tr.doc.resolve(newNodePos), -1);
7 | const start = selectionBefore.$anchor.pos;
8 | const end = newNodePos + 1;
9 |
10 | const delStep = replaceStep(tr.doc, start, end);
11 |
12 | tr.step(delStep);
13 | const stepMap = delStep.getMap();
14 | map.appendMap(stepMap);
15 | };
16 |
17 | export default removeNode;
18 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/schema/questionNode.js:
--------------------------------------------------------------------------------
1 | const questionNode = {
2 | attrs: {
3 | class: { default: 'multiple-choice-question' },
4 | id: { default: '' },
5 | },
6 | group: 'block questions',
7 | content: 'block*',
8 | // defining: true,
9 |
10 | parseDOM: [
11 | {
12 | tag: 'div.multiple-choice-question',
13 | getAttrs(dom) {
14 | return {
15 | id: dom.getAttribute('id'),
16 | class: dom.getAttribute('class'),
17 | };
18 | },
19 | },
20 | ],
21 | toDOM: node => ['div', node.attrs, 0],
22 | };
23 |
24 | export default questionNode;
25 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/ApplicationContext.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | /* eslint react/destructuring-assignment: 0 */
3 | import React, { useEffect, useState } from 'react';
4 |
5 | export const ApplicationContext = React.createContext({
6 | app: null,
7 | getPlugins: null,
8 | });
9 |
10 | export default ({ app, children }) => {
11 | const [application, setApplication] = useState(app);
12 |
13 | useEffect(() => {
14 | setApplication({ ...app });
15 | }, [app]);
16 |
17 | return (
18 |
19 | {children}
20 |
21 | );
22 | };
23 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/OverlayService/OverLay.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/destructuring-assignment */
2 | /* eslint-disable react/jsx-props-no-spreading */
3 | import React from 'react';
4 | import styled from 'styled-components';
5 |
6 | const OverlayContainer = styled.div`
7 | left: ${props => `${props.position.left}px`};
8 | position: ${props => props.position.position};
9 | top: ${props => `${props.position.top}px`};
10 | z-index: ${props => props.position.zIndex};
11 | `;
12 |
13 | const Overlay = props => (
14 | {props.children}
15 | );
16 |
17 | export default Overlay;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/EpigraphPoetryService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import epigraphPoetryNode from './schema/epigraphPoetryNode';
3 | import EpigraphPoetry from './EpigraphPoetry';
4 |
5 | class EpigraphPoetryService extends Service {
6 | register() {
7 | this.container.bind('EpigraphPoetry').to(EpigraphPoetry);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | epigraphPoetry: epigraphPoetryNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default EpigraphPoetryService;
19 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/plugins/MoveCursorPlugin.js:
--------------------------------------------------------------------------------
1 | import { Plugin, PluginKey } from 'prosemirror-state';
2 |
3 | const testPlugin = new PluginKey('moveCursorPlugin');
4 |
5 | export default () => {
6 | return new Plugin({
7 | key: testPlugin,
8 | filterTransaction: (transaction, state, b) => {
9 | state.doc.descendants((editorNode, pos) => {
10 | if (editorNode.type.name === 'fill_the_gap_container') {
11 | if (transaction.selection.from - 2 === pos) {
12 | return false;
13 | }
14 | }
15 | });
16 |
17 | return true;
18 | },
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/layout/EditorMiniElements.js:
--------------------------------------------------------------------------------
1 | import { css } from 'styled-components';
2 |
3 | import { th } from '@pubsweet/ui-toolkit';
4 |
5 | /* All styles regarding ProseMirror surface and elements */
6 |
7 | const fontWriting = css`
8 | color: ${th('colorText')};
9 | font-family: ${th('fontWriting')};
10 | font-size: ${th('fontSizeBase')};
11 | `;
12 |
13 | export default css`
14 | .ProseMirror {
15 | background: white;
16 | counter-reset: footnote;
17 | line-height: 12px;
18 | width: 497px;
19 | ${fontWriting}
20 | }
21 |
22 | .ProseMirror title {
23 | display: inline;
24 | font-size: 14px;
25 | }
26 | `;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import customBlockNode from './schema/customBlockNode';
3 | import CustomTagBlockTool from './CustomTagBlockTool';
4 |
5 | class CustomTagBlockService extends Service {
6 | register() {
7 | this.container.bind('CustomTagBlockTool').to(CustomTagBlockTool);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | customTagBlock: customBlockNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default CustomTagBlockService;
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/schema/OenSectionNode.js:
--------------------------------------------------------------------------------
1 | const OenSectionNode = {
2 | content: 'block+',
3 | group: 'block',
4 | attrs: {
5 | id: { default: '' },
6 | class: { default: 'section' },
7 | },
8 | defining: true,
9 | parseDOM: [
10 | {
11 | tag: 'section',
12 | getAttrs(dom) {
13 | return {
14 | id: dom.getAttribute('id'),
15 | class: dom.getAttribute('class'),
16 | type: dom.dataset.group,
17 | };
18 | },
19 | },
20 | ],
21 | toDOM(node) {
22 | return ['section', node.attrs, 0];
23 | },
24 | };
25 |
26 | export default OenSectionNode;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ImageService/schema/figureCaptionNode.js:
--------------------------------------------------------------------------------
1 | const figureCaptionNode = {
2 | content: 'inline*',
3 | group: 'figure',
4 | draggable: false,
5 | attrs: {
6 | id: { default: '' },
7 | class: { default: '' },
8 | // tabindex: { default: 0 },
9 | },
10 | parseDOM: [
11 | {
12 | tag: 'figcaption',
13 | getAttrs(dom) {
14 | return {
15 | id: dom.getAttribute('id'),
16 | class: dom.getAttribute('class'),
17 | };
18 | },
19 | },
20 | ],
21 | toDOM: node => {
22 | return ['figcaption', node.attrs, 0];
23 | },
24 | };
25 |
26 | export default figureCaptionNode;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SubscriptService/SubscriptService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import subscriptMark from './schema/subscriptMark';
3 | import Subscript from './Subscript';
4 | import './subscript.css';
5 |
6 | class SubscriptService extends Service {
7 | name = 'SubscriptService';
8 |
9 | register() {
10 | this.container.bind('Subscript').to(Subscript);
11 | const createMark = this.container.get('CreateMark');
12 | createMark(
13 | {
14 | subscript: subscriptMark,
15 | },
16 | { toWaxSchema: true },
17 | );
18 | }
19 | }
20 |
21 | export default SubscriptService;
22 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TrackChangeService/ShowHideTrackChangeService/ShowHideTrackChange.js:
--------------------------------------------------------------------------------
1 | import { injectable } from 'inversify';
2 | import { Tools } from 'wax-prosemirror-core';
3 |
4 | @injectable()
5 | class ShowHideTrackChange extends Tools {
6 | title = 'Show/Hide Changes';
7 | icon = 'showTrack';
8 | label = 'Show suggestions';
9 | name = 'ShowHideTrackChange';
10 |
11 | get run() {
12 | return (state, dispatch) => {};
13 | }
14 |
15 | select = (state, activeViewId, activeView) => {
16 | return true;
17 | };
18 |
19 | get active() {
20 | return state => {};
21 | }
22 | }
23 |
24 | export default ShowHideTrackChange;
25 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/schema/essayAnswerNode.js:
--------------------------------------------------------------------------------
1 | import { v4 as uuidv4 } from 'uuid';
2 |
3 | const essayAnswerNode = {
4 | attrs: {
5 | class: { default: 'essay-answer' },
6 | id: { default: uuidv4() },
7 | },
8 | group: 'block questions',
9 | content: 'block*',
10 | defining: true,
11 |
12 | parseDOM: [
13 | {
14 | tag: 'div.essay-answer',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | };
20 | },
21 | },
22 | ],
23 | toDOM: node => ['div', node.attrs, 0],
24 | };
25 |
26 | export default essayAnswerNode;
27 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/schema/essayPromptNode.js:
--------------------------------------------------------------------------------
1 | import { v4 as uuidv4 } from 'uuid';
2 |
3 | const essayPromptNode = {
4 | attrs: {
5 | class: { default: 'essay-prompt' },
6 | id: { default: uuidv4() },
7 | },
8 | group: 'block questions',
9 | content: 'block*',
10 | defining: true,
11 |
12 | parseDOM: [
13 | {
14 | tag: 'div.essay-prompt',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | };
20 | },
21 | },
22 | ],
23 | toDOM: node => ['div', node.attrs, 0],
24 | };
25 |
26 | export default essayPromptNode;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/SaveService/Save.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { injectable } from 'inversify';
4 | import { Tools, icons } from 'wax-prosemirror-core';
5 | import SaveButton from './components/SaveButton';
6 |
7 | @injectable()
8 | export default class Save extends Tools {
9 | title = 'Save changes';
10 | icon = 'save';
11 | name = 'Save';
12 | content = icons.save;
13 | name = 'Save';
14 |
15 | renderTool(view) {
16 | if (isEmpty(view)) return null;
17 | return this.isDisplayed() ? (
18 |
19 | ) : null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/ParagraphContinuedService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import paragraphContNode from './schema/paragraphContNode';
3 | import ParagraphContinued from './ParagraphContinued';
4 |
5 | class ParagraphContinuedService extends Service {
6 | register() {
7 | this.container.bind('ParagraphContinued').to(ParagraphContinued);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | paragraphCont: paragraphContNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default ParagraphContinuedService;
19 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/schema/essayQuestionNode.js:
--------------------------------------------------------------------------------
1 | import { v4 as uuidv4 } from 'uuid';
2 |
3 | const essayQuestionNode = {
4 | attrs: {
5 | class: { default: 'essay-question' },
6 | id: { default: uuidv4() },
7 | },
8 | group: 'block questions',
9 | content: 'block*',
10 | // defining: true,
11 |
12 | parseDOM: [
13 | {
14 | tag: 'div.essay-question',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | };
20 | },
21 | },
22 | ],
23 | toDOM: node => ['div', node.attrs, 0],
24 | };
25 |
26 | export default essayQuestionNode;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagInlineService/CustomTagInlineTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { v4 as uuidv4 } from 'uuid';
3 | import { Tools } from 'wax-prosemirror-core';
4 | import CustomTagInlineComponent from '../components/CustomTagInlineComponent';
5 |
6 | class CustomTagInLineTool extends Tools {
7 | title = 'Custom Tag Inline';
8 | icon = 'cutomInline';
9 | name = 'CustomTagInline';
10 |
11 | renderTool(view) {
12 | return (
13 |
18 | );
19 | }
20 | }
21 |
22 | export default CustomTagInLineTool;
23 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/AuthorService/schema/authorNode.js:
--------------------------------------------------------------------------------
1 | const authorNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'author' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.author',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default authorNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/LiftService/Lift.js:
--------------------------------------------------------------------------------
1 | import { lift } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Lift extends Tools {
7 | title = 'Lift out of enclosing block';
8 | icon = 'indentDecrease';
9 | name = 'Lift';
10 |
11 | select = (state, activeViewId, activeView) => {
12 | const { disallowedTools } = activeView.props;
13 | if (disallowedTools.includes('lift')) return false;
14 | return lift(state);
15 | };
16 |
17 | get run() {
18 | return lift;
19 | }
20 |
21 | get enable() {
22 | return lift;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/schema/multipleChoiceContainerNode.js:
--------------------------------------------------------------------------------
1 | const multipleChoiceContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'multiple-choice' },
5 | },
6 | group: 'block questions',
7 | atom: true,
8 | content: 'block+',
9 | parseDOM: [
10 | {
11 | tag: 'div.multiple-choice',
12 | getAttrs(dom) {
13 | return {
14 | id: dom.getAttribute('id'),
15 | class: dom.getAttribute('class'),
16 | };
17 | },
18 | },
19 | ],
20 | toDOM(node) {
21 | return ['div', node.attrs, 0];
22 | },
23 | };
24 |
25 | export default multipleChoiceContainerNode;
26 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/SubTitleService/schema/subTitleNode.js:
--------------------------------------------------------------------------------
1 | const subTitleNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'cst' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.cst',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default subTitleNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SuperscriptService/SuperscriptService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import superscriptMark from './schema/superscriptMark';
3 | import Superscript from './Superscript';
4 | import './superscript.css';
5 |
6 | class SuperscriptService extends Service {
7 | name = 'SuperscriptService';
8 |
9 | register() {
10 | this.container.bind('Superscript').to(Superscript);
11 | const createMark = this.container.get('CreateMark');
12 | createMark(
13 | {
14 | superscript: superscriptMark,
15 | },
16 | { toWaxSchema: true },
17 | );
18 | }
19 | }
20 |
21 | export default SuperscriptService;
22 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/StateContext.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | /* eslint react/destructuring-assignment: 0 */
3 | import React, { useState } from 'react';
4 |
5 | export const StateContext = React.createContext({
6 | state: null,
7 | });
8 |
9 | export default ({ state, children }) => {
10 | const [context, setContext] = useState(state);
11 |
12 | return (
13 | {
17 | setContext({
18 | ...context,
19 | state: st,
20 | });
21 | },
22 | }}
23 | >
24 | {children}
25 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagBlockNewService/CustomTagBlockNewService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import customBlockNode from '../CustomTagBlockService/schema/customBlockNode';
3 | import CustomTagBlockNewTool from './CustomTagBlockNewTool';
4 |
5 | class CustomTagBlockNewService extends Service {
6 | register() {
7 | this.container.bind('CustomTagBlockNewTool').to(CustomTagBlockNewTool);
8 | const createNode = this.container.get('CreateNode');
9 | createNode(
10 | {
11 | customTagBlock: customBlockNode,
12 | },
13 | { toWaxSchema: true },
14 | );
15 | }
16 | }
17 |
18 | export default CustomTagBlockNewService;
19 |
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
1 | # docker
2 | Dockerfile*
3 | docker-compose*
4 |
5 | # git
6 | .git
7 | .gitignore
8 |
9 | # npm & yarn
10 | node_modules
11 | npm-debug.log
12 | package-lock.json
13 | yarn-error.log
14 |
15 | # misc
16 | .devcontainer
17 | .DS_Store
18 | .vscode
19 | app.pid
20 |
21 | # environment files
22 | .env*
23 | *.env
24 |
25 | # app
26 | editors/demo/build/
27 | coverage/
28 | cypress/
29 | logs/
30 | stories/
31 | tmp/
32 |
33 | # Include README.md and LICENSE.md, exlcude the rest
34 | *.md
35 | !README.md
36 | !LICENSE.md
37 |
38 | # development config files
39 | # .eslintrc.js
40 | .commitlintrc.js
41 | .cz-config.js
42 | .gitlab-ci.yml
43 | .linstagedrc.js
44 | # .prettierrc.js
45 | # .stylelintrc.js
46 |
--------------------------------------------------------------------------------
/wax-citation-service/src/CitationCalloutNodeView.js:
--------------------------------------------------------------------------------
1 | import { AbstractNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class CitationCalloutNodeView extends AbstractNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'citation_callout';
23 | }
24 |
25 | stopEvent(event) {
26 | return super.stopEvent(event);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/components/NoteNumber.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | import React from 'react';
3 | import styled from 'styled-components';
4 |
5 | const NoteNumberStyled = styled.div`
6 | display: flex;
7 | margin-right: 10px;
8 | margin-top: 10px;
9 | position: absolute;
10 | left: -20px;
11 |
12 | &:after {
13 | content: counter(footnote-view) '.';
14 | counter-increment: footnote-view;
15 | cursor: pointer;
16 | font-size: 14px;
17 | font-weight: 500;
18 | }
19 | `;
20 |
21 | const onClick = () => {};
22 |
23 | const NoteNumber = ({ number }) => {
24 | return ;
25 | };
26 |
27 | export default NoteNumber;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/SourceNoteService/schema/sourceNoteNode.js:
--------------------------------------------------------------------------------
1 | const sourceNoteNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'source-note' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.source-note',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default sourceNoteNode;
28 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/schema/questionTrueFalseSingleNode.js:
--------------------------------------------------------------------------------
1 | const questionTrueFalseNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'true-false-question-single' },
5 | },
6 | group: 'block questions',
7 | content: 'block*',
8 | // defining: true,
9 | parseDOM: [
10 | {
11 | tag: 'div.true-false-question-single',
12 | getAttrs(dom) {
13 | return {
14 | id: dom.getAttribute('id'),
15 | class: dom.getAttribute('class'),
16 | };
17 | },
18 | },
19 | ],
20 | toDOM: node => ['div', node.attrs, 0],
21 | };
22 |
23 | export default questionTrueFalseNode;
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/HighlightService/schema/highlightMark.js:
--------------------------------------------------------------------------------
1 | const highlightMark = {
2 | attrs: {
3 | style: { default: null },
4 | class: { default: 'highlight' },
5 | },
6 | inclusive: false,
7 | parseDOM: [
8 | {
9 | tag: 'span.highlight',
10 | getAttrs(hook, next) {
11 | Object.assign(hook, {
12 | class: hook.dom.getAttribute('class'),
13 | style: hook.dom.getAttribute('style'),
14 | });
15 | next();
16 | },
17 | },
18 | ],
19 | toDOM(hook, next) {
20 | // eslint-disable-next-line no-param-reassign
21 | hook.value = ['span', hook.node.attrs, 0];
22 | next();
23 | },
24 | };
25 |
26 | export default highlightMark;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/schema/OenAsideNode.js:
--------------------------------------------------------------------------------
1 | const OenAsideNode = {
2 | content: 'block+',
3 | group: 'block',
4 | attrs: {
5 | id: { default: '' },
6 | class: { default: '' },
7 | },
8 | defining: true,
9 | parseDOM: [
10 | {
11 | tag: 'aside',
12 | getAttrs(dom) {
13 | return {
14 | id: dom.getAttribute('id'),
15 | class: dom.getAttribute('class'),
16 | };
17 | },
18 | },
19 | ],
20 | toDOM(node) {
21 | return [
22 | 'aside',
23 | {
24 | id: node.attrs.id,
25 | class: node.attrs.class,
26 | },
27 | 0,
28 | ];
29 | },
30 | };
31 |
32 | export default OenAsideNode;
33 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ExtractProseService/schema/extractProseNode.js:
--------------------------------------------------------------------------------
1 | const extractProseNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'extract-prose' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.extract-prose',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default extractProseNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ExtractPoetryService/schema/extractPoetryNode.js:
--------------------------------------------------------------------------------
1 | const extractPoetryNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'extract-poetry' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.extract-poetry',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default extractPoetryNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphProseService/schema/epigraphProseNode.js:
--------------------------------------------------------------------------------
1 | const epigraphProseNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'epigraph-prose' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.epigraph-prose',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default epigraphProseNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/ParagraphContinuedService/schema/paragraphContNode.js:
--------------------------------------------------------------------------------
1 | const paragraphContNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'paragraph-cont' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.paragraph-cont',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default paragraphContNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/EpigraphPoetryService/schema/epigraphPoetryNode.js:
--------------------------------------------------------------------------------
1 | const epigraphPoetryNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: 'epigraph-poetry' },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'p.epigraph-poetry',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | class: hook.dom.getAttribute('class'),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = { class: hook.node.attrs.class };
22 | hook.value = ['p', attrs, 0];
23 | next();
24 | },
25 | };
26 |
27 | export default epigraphPoetryNode;
28 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/TrueFalseQuestionService/schema/trueFalseContainerNode.js:
--------------------------------------------------------------------------------
1 | const trueFalseContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'true-false' },
5 | },
6 | group: 'block questions',
7 | atom: true,
8 | selectable: true,
9 | draggable: true,
10 | content: 'block*',
11 | parseDOM: [
12 | {
13 | tag: 'div.true-false',
14 | getAttrs(dom) {
15 | return {
16 | id: dom.getAttribute('id'),
17 | class: dom.getAttribute('class'),
18 | };
19 | },
20 | },
21 | ],
22 | toDOM(node) {
23 | return ['div', node.attrs, 0];
24 | },
25 | };
26 |
27 | export default trueFalseContainerNode;
28 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/schema/questionSingleNode.js:
--------------------------------------------------------------------------------
1 | const questionSingleNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'multiple-choice-question-single' },
5 | },
6 | group: 'block questions',
7 | content: 'block*',
8 | // defining: true,
9 |
10 | // atom: true,
11 | parseDOM: [
12 | {
13 | tag: 'div.multiple-choice-question-single',
14 | getAttrs(dom) {
15 | return {
16 | id: dom.getAttribute('id'),
17 | class: dom.getAttribute('class'),
18 | };
19 | },
20 | },
21 | ],
22 | toDOM: node => ['div', node.attrs, 0],
23 | };
24 |
25 | export default questionSingleNode;
26 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/LiftService/LiftService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import { liftListItem, sinkListItem } from 'prosemirror-schema-list';
3 | import Lift from './Lift';
4 |
5 | class LiftService extends Service {
6 | register() {
7 | this.container.bind('Lift').to(Lift);
8 | const CreateShortCut = this.container.get('CreateShortCut');
9 | CreateShortCut({
10 | 'Mod-[': (state, dispatch) =>
11 | liftListItem(state.schema.nodes.list_item)(state, dispatch),
12 | });
13 | CreateShortCut({
14 | 'Mod-]': (state, dispatch) =>
15 | sinkListItem(state.schema.nodes.list_item)(state, dispatch),
16 | });
17 | }
18 | }
19 |
20 | export default LiftService;
21 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/HighlightService/HightlightService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import highlightMark from './schema/highlightMark';
3 | import TextHighlightTool from './TextHighlightTool';
4 | import TextHighlightToolGroupServices from './TextHighlightToolGroupService/TextHighlightToolGroupService';
5 |
6 | export default class HighlightService extends Service {
7 | register() {
8 | this.container.bind('TextHighlightTool').to(TextHighlightTool);
9 | const createMark = this.container.get('CreateMark');
10 | createMark(
11 | {
12 | highlight: highlightMark,
13 | },
14 | { toWaxSchema: true },
15 | );
16 | }
17 |
18 | dependencies = [new TextHighlightToolGroupServices()];
19 | }
20 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrongService/StrongService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import { toggleMark } from 'prosemirror-commands';
3 | import strongMark from './schema/strongMark';
4 | import Strong from './Strong';
5 | import './strong.css';
6 |
7 | class StrongService extends Service {
8 | register() {
9 | this.container.bind('Strong').to(Strong);
10 | const createMark = this.container.get('CreateMark');
11 | const CreateShortCut = this.container.get('CreateShortCut');
12 |
13 | createMark({
14 | strong: strongMark,
15 | });
16 |
17 | CreateShortCut({
18 | 'Mod-b': toggleMark(this.schema.marks.strong),
19 | });
20 | }
21 | }
22 |
23 | export default StrongService;
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/CodeService/CodeService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import { toggleMark } from 'prosemirror-commands';
3 | import codeMark from './schema/codeMark';
4 | import Code from './Code';
5 |
6 | class CodeService extends Service {
7 | register() {
8 | this.container.bind('Code').to(Code);
9 | const CreateShortCut = this.container.get('CreateShortCut');
10 |
11 | const createMark = this.container.get('CreateMark');
12 | createMark(
13 | {
14 | code: codeMark,
15 | },
16 | { toWaxSchema: true },
17 | );
18 |
19 | CreateShortCut({
20 | 'Mod-`': toggleMark(this.schema.marks.code),
21 | });
22 | }
23 | }
24 |
25 | export default CodeService;
26 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/schema/fillTheGapContainerNode.js:
--------------------------------------------------------------------------------
1 | const fillTheGapContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'fill-the-gap' },
5 | feedback: { default: '' },
6 | },
7 | group: 'block questions',
8 | isolating: true,
9 | content: 'paragraph+',
10 | parseDOM: [
11 | {
12 | tag: 'div.fill-the-gap',
13 | getAttrs(dom) {
14 | return {
15 | id: dom.getAttribute('id'),
16 | class: dom.getAttribute('class'),
17 | feedback: dom.getAttribute('feedback'),
18 | };
19 | },
20 | },
21 | ],
22 | toDOM(node) {
23 | return ['div', node.attrs, 0];
24 | },
25 | };
26 |
27 | export default fillTheGapContainerNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/index.js:
--------------------------------------------------------------------------------
1 | import ExtractPoetryService from './ExtractPoetryService/ExtractPoetryService';
2 | import ExtractProseService from './ExtractProseService/ExtractProseService';
3 | import ParagraphContinuedService from './ParagraphContinuedService/ParagraphContinuedService';
4 | import ParagraphService from './ParagraphService/ParagraphService';
5 | import SourceNoteService from './SourceNoteService/SourceNoteService';
6 | import TextToolGroupService from './TextToolGroupService/TextToolGroupService';
7 |
8 | export default [
9 | new ExtractPoetryService(),
10 | new ExtractProseService(),
11 | new ParagraphContinuedService(),
12 | new ParagraphService(),
13 | new SourceNoteService(),
14 | new TextToolGroupService(),
15 | ];
16 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/TrueFalseQuestionService/schema/questionTrueFalseNode.js:
--------------------------------------------------------------------------------
1 | const questionTrueFalseNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'true-false-question' },
5 | },
6 | group: 'block questions',
7 | // content: 'paragraph* bulletlist* orderedlist*',
8 | content: 'block*',
9 | // defining: true,
10 |
11 | // atom: true,
12 | parseDOM: [
13 | {
14 | tag: 'div.true-false-question',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | };
20 | },
21 | },
22 | ],
23 | toDOM: node => ['div', node.attrs, 0],
24 | };
25 |
26 | export default questionTrueFalseNode;
27 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/schema/fillTheGapNode.js:
--------------------------------------------------------------------------------
1 | const fillTheGapNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'fill-the-gap' },
5 | answer: { default: '' },
6 | },
7 | group: 'inline',
8 | content: 'text*',
9 | inline: true,
10 | atom: true,
11 | excludes: 'fill_the_gap',
12 | parseDOM: [
13 | {
14 | tag: 'span.fill-the-gap',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | answer: dom.getAttribute('answer'),
20 | };
21 | },
22 | },
23 | ],
24 | toDOM: node => {
25 | return ['span', node.attrs, 0];
26 | },
27 | };
28 |
29 | export default fillTheGapNode;
30 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/RulesService/RulesService.js:
--------------------------------------------------------------------------------
1 | import Service from '../../../Service';
2 | import Rules from './Rules';
3 |
4 | export default class RulesService extends Service {
5 | name = 'RulesService';
6 |
7 | boot() {
8 | const configRules = this.app.config.get('config.RulesService');
9 | const createRule = this.container.get('CreateRule');
10 | if (configRules) createRule(configRules);
11 | }
12 |
13 | register() {
14 | this.container.bind('Rules').to(Rules).inSingletonScope();
15 | this.container.bind('CreateRule').toFactory(context => {
16 | return rule => {
17 | const ruleInstance = context.container.get('Rules');
18 | ruleInstance.addRule(rule);
19 | };
20 | });
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BlockQuoteService/BlockQuoteService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import blockQuoteNode from './schema/blockQuoteNode';
3 | import BlockQuote from './BlockQuote';
4 | import BlockQuoteToolGroupService from './BlockQuoteToolGroupService/BlockQuoteToolGroupService';
5 | import './blockQuote.css';
6 |
7 | class BlockQuoteService extends Service {
8 | name = 'BlockQuoteService';
9 |
10 | register() {
11 | this.container.bind('BlockQuote').to(BlockQuote);
12 | const createNode = this.container.get('CreateNode');
13 | createNode({
14 | blockquote: blockQuoteNode,
15 | });
16 | }
17 |
18 | dependencies = [new BlockQuoteToolGroupService()];
19 | }
20 |
21 | export default BlockQuoteService;
22 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/index.js:
--------------------------------------------------------------------------------
1 | import BulletListService from './BulletListService/BulletListService';
2 | import OrderedListService from './OrderedListService/OrderedListService';
3 | import JoinUpService from './JoinUpService/JoinUpService';
4 | import LiftService from './LiftService/LiftService';
5 | import ListItemService from './ListItemService/ListItemService';
6 | import BlockQuoteService from './BlockQuoteService/BlockQuoteService';
7 | import ListToolGroupService from './ListToolGroupService/ListToolGroupService';
8 |
9 | export default [
10 | new BlockQuoteService(),
11 | new ListItemService(),
12 | new BulletListService(),
13 | new OrderedListService(),
14 | new JoinUpService(),
15 | new LiftService(),
16 | new ListToolGroupService(),
17 | ];
18 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/components/QuestionComponent.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react';
2 | import { WaxContext } from 'wax-prosemirror-core';
3 | import EditorComponent from './EditorComponent';
4 |
5 | export default ({ node, view, getPos }) => {
6 | const context = useContext(WaxContext);
7 | const {
8 | pmViews: { main },
9 | } = context;
10 |
11 | const customProps = main.props.customValues;
12 | const { testMode } = customProps;
13 |
14 | const isEditable = main.props.editable(editable => {
15 | return editable;
16 | });
17 |
18 | return (
19 |
25 | );
26 | };
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrikeThroughService/schema/strikethroughMark.js:
--------------------------------------------------------------------------------
1 | const strikethroughMark = {
2 | attrs: {
3 | class: { default: 'strikethrough' },
4 | style: { default: 'text-decoration:line-through' },
5 | },
6 | inclusive: false,
7 | parseDOM: [
8 | {
9 | tag: 'span.strikethrough',
10 | getAttrs(hook, next) {
11 | Object.assign(hook, {
12 | class: hook.dom.getAttribute('class'),
13 | style: hook.dom.getAttribute('style'),
14 | });
15 | next();
16 | },
17 | },
18 | ],
19 | toDOM(hook, next) {
20 | // eslint-disable-next-line no-param-reassign
21 | hook.value = ['span', hook.node.attrs, 0];
22 | next();
23 | },
24 | };
25 |
26 | export default strikethroughMark;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/EmphasisService/EmphasisService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import { toggleMark } from 'prosemirror-commands';
3 | import emphasisMark from './schema/emphasisMark';
4 | import Emphasis from './Emphasis';
5 |
6 | class EmphasisService extends Service {
7 | register() {
8 | this.container.bind('Emphasis').to(Emphasis);
9 | const createMark = this.container.get('CreateMark');
10 | const CreateShortCut = this.container.get('CreateShortCut');
11 |
12 | createMark(
13 | {
14 | em: emphasisMark,
15 | },
16 | { toWaxSchema: true },
17 | );
18 |
19 | CreateShortCut({
20 | 'Mod-i': toggleMark(this.schema.marks.em),
21 | });
22 | }
23 | }
24 |
25 | export default EmphasisService;
26 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENContainersToolGroupService/OENContainersToolGroupService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import OENContainersToolGroup from './OENContainersToolGroup';
3 | import OENAsideShortToolGroupService from '../OENAsideShortToolGroupService/OENAsideShortToolGroupService';
4 | import OENAsideLongToolGroupService from '../OENAsideLongToolGroupService/OENAsideLongToolGroupService';
5 |
6 | class OENContainersToolGroupService extends Service {
7 | register() {
8 | this.container.bind('OENContainersToolGroup').to(OENContainersToolGroup);
9 | }
10 |
11 | dependencies = [
12 | new OENAsideShortToolGroupService(),
13 | new OENAsideLongToolGroupService(),
14 | ];
15 | }
16 |
17 | export default OENContainersToolGroupService;
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/components/helpers/useOnClickOutside.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from 'react';
2 |
3 | // Hook
4 | const useOnClickOutside = (ref, handler) => {
5 | useEffect(() => {
6 | const listener = event => {
7 | /* Do nothing if clicking ref's element or descendent elements */
8 | if (!ref.current || ref.current.contains(event.target)) {
9 | return;
10 | }
11 |
12 | handler(event);
13 | };
14 |
15 | document.addEventListener('mousedown', listener);
16 | document.addEventListener('touchstart', listener);
17 |
18 | return () => {
19 | document.removeEventListener('mousedown', listener);
20 | document.removeEventListener('touchstart', listener);
21 | };
22 | }, [ref, handler]);
23 | };
24 |
25 | export default useOnClickOutside;
26 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/EssayAnswerNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class EssayAnswerNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'essay_answer';
23 | }
24 |
25 | stopEvent(event) {
26 | const innerView = this.context.pmViews[this.node.attrs.id];
27 | return innerView && innerView.dom.contains(event.target);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/DisplayBlockLevel/index.js:
--------------------------------------------------------------------------------
1 | import AuthorService from './AuthorService/AuthorService';
2 | import EpigraphPoetryService from './EpigraphPoetryService/EpigraphPoetryService';
3 | import EpigraphProseService from './EpigraphProseService/EpigraphProseService';
4 | import HeadingService from './HeadingService/HeadingService';
5 | import SubTitleService from './SubTitleService/SubTitleService';
6 | import TitleService from './TitleService/TitleService';
7 | import DisplayToolGroupService from './DisplayToolGroupService/DisplayToolGroupService';
8 |
9 | export default [
10 | new AuthorService(),
11 | new EpigraphProseService(),
12 | new EpigraphPoetryService(),
13 | new HeadingService(),
14 | new SubTitleService(),
15 | new TitleService(),
16 | new DisplayToolGroupService(),
17 | ];
18 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/UnderlineService/UnderlineService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import { toggleMark } from 'prosemirror-commands';
3 | import underlineMark from './schema/underlineMark';
4 | import Underline from './Underline';
5 |
6 | class UnderlineService extends Service {
7 | register() {
8 | this.container.bind('Underline').to(Underline);
9 | const CreateShortCut = this.container.get('CreateShortCut');
10 | const createMark = this.container.get('CreateMark');
11 | createMark(
12 | {
13 | underline: underlineMark,
14 | },
15 | { toWaxSchema: true },
16 | );
17 | CreateShortCut({
18 | 'Mod-u': toggleMark(this.schema.marks.underline),
19 | });
20 | }
21 | }
22 |
23 | export default UnderlineService;
24 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/TrueFalseSingleCorrectQuestionService/schema/trueFalseSingleCorrectContainerNode.js:
--------------------------------------------------------------------------------
1 | const trueFalseSingleCorrectContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'true-false-single-correct' },
5 | },
6 | group: 'block questions',
7 | atom: true,
8 | selectable: true,
9 | draggable: true,
10 | content: 'block*',
11 | parseDOM: [
12 | {
13 | tag: 'div.true-false-single-correct',
14 | getAttrs(dom) {
15 | return {
16 | id: dom.getAttribute('id'),
17 | class: dom.getAttribute('class'),
18 | };
19 | },
20 | },
21 | ],
22 | toDOM(node) {
23 | return ['div', node.attrs, 0];
24 | },
25 | };
26 |
27 | export default trueFalseSingleCorrectContainerNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplace.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { v4 as uuidv4 } from 'uuid';
4 | import { injectable } from 'inversify';
5 | import { Tools } from 'wax-prosemirror-core';
6 | import FindAndReplaceTool from './components/FindAndReplaceTool';
7 |
8 | @injectable()
9 | export default class FindAndReplace extends Tools {
10 | title = 'Find And Replace';
11 | icon = 'findAndReplace';
12 | name = 'find';
13 |
14 | get enable() {
15 | return () => {
16 | return true;
17 | };
18 | }
19 |
20 | renderTool(view) {
21 | if (isEmpty(view)) return null;
22 |
23 | return this.isDisplayed() ? (
24 |
25 | ) : null;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/CounterInfoService/CounterInfoTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { injectable } from 'inversify';
4 | import { Tools } from 'wax-prosemirror-core';
5 | import EditorInfoTool from './components/EditorInfoTool';
6 |
7 | @injectable()
8 | class CounterInfoTool extends Tools {
9 | title = 'Counter Info';
10 | name = 'CounterInfo';
11 |
12 | get run() {
13 | return () => true;
14 | }
15 |
16 | get enable() {
17 | return () => {
18 | return true;
19 | };
20 | }
21 |
22 | renderTool(view) {
23 | if (isEmpty(view)) return null;
24 | return this.isDisplayed() ? (
25 |
26 | ) : null;
27 | }
28 | }
29 |
30 | export default CounterInfoTool;
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/CodeService/Code.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Code extends Tools {
7 | title = 'Toggle code';
8 | icon = 'code';
9 | name = 'Code';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.code)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.code)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-questions-service/src/NumericalAnswerService/NumericalAnswerContainerNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class NumericalAnswerContainerNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'numerical_answer_container';
23 | }
24 |
25 | selectNode() {
26 | this.context.pmViews[this.node.attrs.id].focus();
27 | }
28 |
29 | stopEvent(event) {
30 | return true;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrongService/Strong.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Strong extends Tools {
7 | title = 'Toggle strong';
8 | icon = 'bold';
9 | name = 'Strong';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.strong)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.strong)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FindAndReplaceService/FindAndReplaceService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import FindAndReplacePlugin from './plugins/FindAndReplacePlugin';
3 | import FindAndReplace from './FindAndReplace';
4 | import './findAndReplace.css';
5 | import FindAndReplaceToolGroupService from './FindAndReplaceToolGroupService/FindAndReplaceToolGroupService';
6 |
7 | class FindAndReplaceService extends Service {
8 | name = 'FindAndReplaceService';
9 |
10 | boot() {
11 | this.app.PmPlugins.add(
12 | 'findAndReplacePlugin',
13 | FindAndReplacePlugin('findAndReplacePlugin'),
14 | );
15 | }
16 |
17 | register() {
18 | this.container.bind('FindAndReplace').to(FindAndReplace);
19 | }
20 |
21 | dependencies = [new FindAndReplaceToolGroupService()];
22 | }
23 | export default FindAndReplaceService;
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/EmphasisService/Emphasis.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Emphasis extends Tools {
7 | title = 'Toggle emphasis';
8 | icon = 'italic';
9 | name = 'Emphasis';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.em)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.em)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/SpecialCharactersService/SpecialCharactersTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { v4 as uuidv4 } from 'uuid';
4 | import { injectable } from 'inversify';
5 | import { Tools } from 'wax-prosemirror-core';
6 | import SpecialCharactersTool from './components/SpecialCharactersTool';
7 |
8 | @injectable()
9 | export default class SpecialCharacters extends Tools {
10 | title = 'Special Characters';
11 | icon = 'specialCharacters';
12 | name = 'specialCharacters';
13 |
14 | get enable() {
15 | return () => {
16 | return true;
17 | };
18 | }
19 |
20 | renderTool(view) {
21 | if (isEmpty(view)) return null;
22 |
23 | return this.isDisplayed() ? (
24 |
25 | ) : null;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.gitlab/issue_templates/Feature Request.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Context
4 |
5 |
6 |
7 | ## Proposal
8 |
9 |
10 |
11 | ## Design
12 |
13 |
14 |
15 | ## Implementation (if applicable)
16 |
17 |
18 |
19 | ## Alternative approaches (if applicable)
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultConfig.js:
--------------------------------------------------------------------------------
1 | import SchemaService from './defaultServices/SchemaService/SchemaService';
2 | import RulesService from './defaultServices/RulesService/RulesService';
3 | import ShortCutsService from './defaultServices/ShortCutsService/ShortCutsService';
4 | import LayoutService from './defaultServices/LayoutService/LayoutService';
5 | import PortalService from './defaultServices/PortalService/PortalService';
6 | import MenuService from './defaultServices/MenuService/MenuService';
7 | import OverlayService from './defaultServices/OverlayService/OverlayService';
8 |
9 | export default () => ({
10 | services: [
11 | new SchemaService(),
12 | new RulesService(),
13 | new ShortCutsService(),
14 | new LayoutService(),
15 | new PortalService(),
16 | new MenuService(),
17 | new OverlayService(),
18 | ],
19 | });
20 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/InlineInputRule.js:
--------------------------------------------------------------------------------
1 | import { InputRule } from 'prosemirror-inputrules';
2 |
3 | const inlineInputRule = (pattern, nodeType, getAttrs) => {
4 | return new InputRule(pattern, (state, match, start, end) => {
5 | const $start = state.doc.resolve(start);
6 | const index = $start.index();
7 | const $end = state.doc.resolve(end);
8 | // get attrs
9 | const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
10 | // check if replacement valid
11 | if (!$start.parent.canReplaceWith(index, $end.index(), nodeType)) {
12 | return null;
13 | }
14 | // perform replacement
15 | return state.tr.replaceRangeWith(
16 | start,
17 | end,
18 | nodeType.create(attrs, nodeType.schema.text(match[1])),
19 | );
20 | });
21 | };
22 |
23 | export default inlineInputRule;
24 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleDropDownService/schema/multipleDropDownContainerNode.js:
--------------------------------------------------------------------------------
1 | const multipleDropDownContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'multiple-drop-down-container' },
5 | feedback: { default: '' },
6 | },
7 | group: 'block questions',
8 | isolating: true,
9 | // content: 'paragraph* bulletlist* orderedlist*',
10 | content: 'block*',
11 | parseDOM: [
12 | {
13 | tag: 'div.multiple-drop-down-container',
14 | getAttrs(dom) {
15 | return {
16 | id: dom.getAttribute('id'),
17 | class: dom.getAttribute('class'),
18 | feedback: dom.getAttribute('feedback'),
19 | };
20 | },
21 | },
22 | ],
23 | toDOM(node) {
24 | return ['div', node.attrs, 0];
25 | },
26 | };
27 |
28 | export default multipleDropDownContainerNode;
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CodeBlockService/CodeBlockService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import codeBlockNode from './schema/codeBlockNode';
3 | import highlightPlugin from './plugins/highlightPlugin';
4 | import CodeBlockTool from './CodeBlockTool';
5 | import CodeBlockToolGroupService from './CodeBlockToolGroupService/CodeBlockToolGroupService';
6 | import './highlightStyles.css';
7 |
8 | export default class CodeBlockService extends Service {
9 | boot() {
10 | this.app.PmPlugins.add('highlightPlugin', highlightPlugin());
11 | }
12 |
13 | register() {
14 | this.container.bind('CodeBlockTool').to(CodeBlockTool);
15 | const createNode = this.container.get('CreateNode');
16 |
17 | createNode({
18 | code_block: codeBlockNode,
19 | });
20 | }
21 |
22 | dependencies = [new CodeBlockToolGroupService()];
23 | }
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/NoteService/NoteService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import footNoteNode from './schema/footNoteNode';
3 | import Note from './Note';
4 | import NoteComponent from './NoteComponent';
5 | import NoteToolGroupService from './NoteToolGroupService/NoteToolGroupService';
6 | import './note.css';
7 |
8 | class NoteService extends Service {
9 | name = 'NoteService';
10 |
11 | boot() {
12 | const layout = this.container.get('Layout');
13 | layout.addComponent('notesArea', NoteComponent);
14 | }
15 |
16 | register() {
17 | const createNode = this.container.get('CreateNode');
18 | this.container.bind('Note').to(Note);
19 |
20 | createNode({
21 | footnote: footNoteNode,
22 | });
23 | }
24 |
25 | dependencies = [new NoteToolGroupService()];
26 | }
27 |
28 | export default NoteService;
29 |
--------------------------------------------------------------------------------
/.gitlab/issue_templates/bug-report.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Expected behaviour
4 |
5 |
6 |
7 | ## Current behaviour
8 |
9 |
10 |
11 | ## Steps to reproduce
12 |
13 |
14 |
15 | 1.
16 | 2.
17 | 3.
18 | 4.
19 |
20 | ## Environment
21 |
22 |
23 |
24 | ## Possible solution
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ModalService/ModalService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ModalPlugin from './pmPlugins/ModalPlugin';
3 | import ModalComponent from './ModalComponent';
4 | const PLUGIN_KEY = 'overlay';
5 |
6 | export default class ModalService extends Service {
7 | boot() {
8 | this.app.PmPlugins.add(PLUGIN_KEY, ModalPlugin(PLUGIN_KEY));
9 | }
10 | register() {
11 | this.container.bind('CreateModal').toFactory(context => {
12 | return (Component, pluginName) => {
13 | const PmPlugins = context.container.get('PmPlugins');
14 | const plugin = PmPlugins.get(pluginName);
15 | const layout = context.container.get('Layout');
16 | layout.addComponent(
17 | 'editorOverlays',
18 | ModalComponent(Component, plugin),
19 | );
20 | };
21 | });
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SmallCapsService/SmallCaps.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class SmallCaps extends Tools {
7 | title = 'Toggle Small Caps';
8 | icon = 'smallCaps';
9 | name = 'SmallCaps';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.smallcaps)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.smallcaps)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SubscriptService/Subscript.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Subscript extends Tools {
7 | title = 'Toggle subscript';
8 | icon = 'subscript';
9 | name = 'Subscript';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.subscript)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.subscript)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENAsideLongToolGroupService/OENAsideLongToolGroup.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { injectable, inject } from 'inversify';
3 | import { ToolGroup, LeftMenuTitle } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | class OENAsideLongToolGroup extends ToolGroup {
7 | tools = [];
8 | title = ();
9 |
10 | constructor(
11 | @inject('OENAsideLongToolCaseStudy') OENAsideLongToolCaseStudy,
12 | @inject('OENAsideLongToolBiography') OENAsideLongToolBiography,
13 | @inject('OENAsideLongToolWorkedExample') OENAsideLongToolWorkedExample,
14 | ) {
15 | super();
16 | this.tools = [
17 | OENAsideLongToolCaseStudy,
18 | OENAsideLongToolBiography,
19 | OENAsideLongToolWorkedExample,
20 | ];
21 | }
22 | }
23 |
24 | export default OENAsideLongToolGroup;
25 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/FullScreenService/FullScreenTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { injectable } from 'inversify';
4 | import { Tools } from 'wax-prosemirror-core';
5 | import FullScreenButton from './components/FullScreenButton';
6 |
7 | @injectable()
8 | export default class FullScreenTool extends Tools {
9 | title = 'Full screen';
10 | icon = 'fullScreen';
11 | name = 'FullScreen';
12 |
13 | get run() {
14 | return () => true;
15 | }
16 |
17 | select = () => {
18 | return true;
19 | };
20 |
21 | get enable() {
22 | return () => {
23 | return true;
24 | };
25 | }
26 |
27 | renderTool(view) {
28 | if (isEmpty(view)) return null;
29 | return this.isDisplayed() ? (
30 |
31 | ) : null;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/MathService/BlockInputRule.js:
--------------------------------------------------------------------------------
1 | import { InputRule } from 'prosemirror-inputrules';
2 | import { NodeSelection } from 'prosemirror-state';
3 |
4 | const blockInputRule = (pattern, nodeType, getAttrs) => {
5 | return new InputRule(pattern, (state, match, start, end) => {
6 | const $start = state.doc.resolve(start);
7 | const attrs = getAttrs instanceof Function ? getAttrs(match) : getAttrs;
8 |
9 | if (
10 | !$start
11 | .node(-1)
12 | .canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)
13 | )
14 | return null;
15 |
16 | const tr = state.tr
17 | .delete(start, end)
18 | .setBlockType(start, start, nodeType, attrs);
19 | return tr.setSelection(
20 | NodeSelection.create(tr.doc, tr.mapping.map($start.pos - 1)),
21 | );
22 | });
23 | };
24 | export default blockInputRule;
25 |
--------------------------------------------------------------------------------
/editors/demo/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | // import ReactDOM from 'react-dom/client';
3 | import ReactDOM from 'react-dom';
4 | import Editors from './Editors';
5 | import * as serviceWorker from './serviceWorker';
6 | import '../../../wax-prosemirror-core/dist/index.css';
7 | import '../../../wax-prosemirror-services/dist/index.css';
8 | import '../../../wax-questions-service/dist/index.css';
9 | import '../../../wax-table-service/dist/index.css';
10 | // const root = ReactDOM.createRoot(document.getElementById('root'));
11 | // root.render();
12 |
13 | ReactDOM.render(, document.getElementById('root'));
14 |
15 | // If you want your app to work offline and load faster, you can change
16 | // unregister() to register() below. Note this comes with some pitfalls.
17 | // Learn more about service workers: https://bit.ly/CRA-PWA
18 | serviceWorker.unregister();
19 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/SuperscriptService/Superscript.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Superscript extends Tools {
7 | title = 'Toggle superscript';
8 | icon = 'superscript';
9 | name = 'Superscript';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.superscript)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.superscript)(state);
28 | };
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/components/EssayQuestionComponent.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react';
2 | import { WaxContext } from 'wax-prosemirror-core';
3 | import EditorComponent from '../../MultipleChoiceQuestionService/components/EditorComponent';
4 |
5 | export default ({ node, view, getPos }) => {
6 | const context = useContext(WaxContext);
7 | const {
8 | pmViews: { main },
9 | } = context;
10 |
11 | const customProps = main.props.customValues;
12 | const { testMode } = customProps;
13 |
14 | const isEditable = main.props.editable(editable => {
15 | return editable;
16 | });
17 | return (
18 |
26 | );
27 | };
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/Config.js:
--------------------------------------------------------------------------------
1 | import { set, get, isArrayLikeObject } from 'lodash';
2 | import { injectable, inject } from 'inversify';
3 |
4 | @injectable()
5 | export default class Config {
6 | _config = {};
7 | constructor(@inject('config') config) {
8 | this._config = config;
9 | }
10 |
11 | set(key, value) {
12 | set(this._config, key, value);
13 | return this._config;
14 | }
15 |
16 | get(key) {
17 | return get(this._config, key);
18 | }
19 |
20 | pushToArray(key, value) {
21 | let oldValue = this.get(key);
22 | if (oldValue) {
23 | if (isArrayLikeObject(value)) {
24 | value.forEach(v => {
25 | oldValue.push(v);
26 | });
27 | } else {
28 | oldValue.push(value);
29 | }
30 | } else {
31 | oldValue = value;
32 | }
33 | this.set(key, oldValue);
34 | return this;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/ListItemService/schema/listItemNode.js:
--------------------------------------------------------------------------------
1 | import { SchemaHelpers } from 'wax-prosemirror-core';
2 |
3 | const listItemNode = {
4 | content: 'paragraph block*',
5 | attrs: {
6 | track: { default: [] },
7 | },
8 | parseDOM: [
9 | {
10 | tag: 'li',
11 | getAttrs(hook, next) {
12 | Object.assign(hook, {
13 | track: SchemaHelpers.parseTracks(hook.dom.dataset.track),
14 | });
15 | next();
16 | },
17 | },
18 | ],
19 | toDOM(hook, next) {
20 | const attrs = {};
21 | if (hook.node.attrs.track && hook.node.attrs.track.length) {
22 | attrs['data-track'] = JSON.stringify(hook.node.attrs.track);
23 | }
24 | // eslint-disable-next-line no-param-reassign
25 | hook.value = ['li', attrs, 0];
26 | next();
27 | },
28 | defining: true,
29 | };
30 |
31 | export default listItemNode;
32 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/schema/OenContainerNode.js:
--------------------------------------------------------------------------------
1 | const OenContainerNode = {
2 | content: 'block+',
3 | group: 'block',
4 | attrs: {
5 | id: { default: '' },
6 | class: { default: '' },
7 | type: { default: 'content_structure_element' },
8 | },
9 | defining: true,
10 | parseDOM: [
11 | {
12 | tag: 'div[data-type="content_structure_element"]',
13 | getAttrs(dom) {
14 | return {
15 | id: dom.getAttribute('id'),
16 | class: dom.getAttribute('class'),
17 | type: dom.dataset.type,
18 | };
19 | },
20 | },
21 | ],
22 | toDOM(node) {
23 | return [
24 | 'div',
25 | {
26 | id: node.attrs.id,
27 | class: node.attrs.class,
28 | 'data-type': node.attrs.type,
29 | },
30 | 0,
31 | ];
32 | },
33 | };
34 |
35 | export default OenContainerNode;
36 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/TextBlockLevel/TextToolGroupService/Text.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { injectable, inject } from 'inversify';
3 | import { ToolGroup, LeftMenuTitle } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | class Text extends ToolGroup {
7 | tools = [];
8 | title = ();
9 |
10 | constructor(
11 | @inject('Paragraph') paragraph,
12 | @inject('ParagraphContinued') paragraphContinued,
13 | @inject('ExtractProse') extractProse,
14 | @inject('ExtractPoetry') extractPoetry,
15 | @inject('SourceNote') sourceNote,
16 | // @inject('BlockQuote') blockQuote,
17 | ) {
18 | super();
19 | this.tools = [
20 | paragraph,
21 | paragraphContinued,
22 | extractProse,
23 | extractPoetry,
24 | sourceNote,
25 | // blockQuote,
26 | ];
27 | }
28 | }
29 |
30 | export default Text;
31 |
--------------------------------------------------------------------------------
/editors/demo/src/NCBI/config/configMini.js:
--------------------------------------------------------------------------------
1 | import { DefaultSchema } from 'wax-prosemirror-core';
2 | import {
3 | InlineAnnotationsService,
4 | ListsService,
5 | BaseService,
6 | LinkService,
7 | } from 'wax-prosemirror-services';
8 |
9 | const config = {
10 | MenuService: [
11 | {
12 | templateArea: 'topBar',
13 | toolGroups: [
14 | 'Base',
15 | {
16 | name: 'Annotations',
17 | exclude: ['Code', 'StrikeThrough', 'Underline', 'SmallCaps'],
18 | },
19 | 'Lists',
20 | ],
21 | },
22 | ],
23 |
24 | RulesService: [],
25 | ShortCutsService: {},
26 | LinkService: {},
27 | SchemaService: DefaultSchema,
28 | PmPlugins: [],
29 |
30 | services: [
31 | new InlineAnnotationsService(),
32 | new LinkService(),
33 | new BaseService(),
34 | new ListsService(),
35 | ],
36 | };
37 |
38 | export default config;
39 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BulletListService/schema/bulletListNode.js:
--------------------------------------------------------------------------------
1 | import { SchemaHelpers } from 'wax-prosemirror-core';
2 |
3 | const bulletListNode = {
4 | group: 'block',
5 | content: 'list_item+',
6 | attrs: {
7 | track: { default: [] },
8 | },
9 | parseDOM: [
10 | {
11 | tag: 'ul',
12 | getAttrs(hook, next) {
13 | Object.assign(hook, {
14 | track: SchemaHelpers.parseTracks(hook.dom.dataset.track),
15 | });
16 | next();
17 | },
18 | },
19 | ],
20 | toDOM(hook, next) {
21 | const attrs = {};
22 | if (hook.node.attrs.track && hook.node.attrs.track.length) {
23 | attrs['data-track'] = JSON.stringify(hook.node.attrs.track);
24 | }
25 | // eslint-disable-next-line no-param-reassign
26 | hook.value = ['ul', attrs, 0];
27 | next();
28 | },
29 | };
30 |
31 | export default bulletListNode;
32 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/schema/customBlockNode.js:
--------------------------------------------------------------------------------
1 | const customBlockNode = {
2 | content: 'inline*',
3 | group: 'block',
4 | priority: 0,
5 | defining: true,
6 | attrs: {
7 | class: { default: '' },
8 | type: { default: 'block' },
9 | },
10 | parseDOM: [
11 | {
12 | tag: 'p[data-type="block"]',
13 | getAttrs(hook, next) {
14 | Object.assign(hook, {
15 | class: hook.dom.getAttribute('class'),
16 | type: hook.dom.dataset.type,
17 | });
18 | next();
19 | },
20 | },
21 | ],
22 | toDOM(hook, next) {
23 | const attrs = {
24 | class: hook.node.attrs.class,
25 | 'data-type': hook.node.attrs.type,
26 | };
27 | // eslint-disable-next-line no-param-reassign
28 | hook.value = ['p', attrs, 0];
29 | next();
30 | },
31 | };
32 |
33 | export default customBlockNode;
34 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/UnderlineService/Underline.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class Underline extends Tools {
7 | title = 'Toggle underline';
8 | // content = icons.underline;
9 | icon = 'underline';
10 | name = 'Underline';
11 |
12 | get run() {
13 | return (state, dispatch) => {
14 | toggleMark(state.config.schema.marks.underline)(state, dispatch);
15 | };
16 | }
17 |
18 | select = state => {
19 | const {
20 | selection: { from },
21 | } = state;
22 | if (from === null) return false;
23 | return true;
24 | };
25 |
26 | get active() {
27 | return state => {
28 | return Commands.markActive(state.config.schema.marks.underline)(state);
29 | };
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BottomInfoService/ShortCutsInfoService/ShortCutsInfoTool.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { injectable } from 'inversify';
4 | import { Tools } from 'wax-prosemirror-core';
5 | import EditorShortCutsTool from './components/EditorShortCutsTool';
6 |
7 | @injectable()
8 | class ShortCutsInfoTool extends Tools {
9 | title = 'ShortCuts Info';
10 | name = 'ShortCutsInfo';
11 |
12 | get run() {
13 | return () => true;
14 | }
15 |
16 | get enable() {
17 | return () => {
18 | return true;
19 | };
20 | }
21 |
22 | renderTool(view) {
23 | if (isEmpty(view)) return null;
24 | return this.isDisplayed() ? (
25 |
30 | ) : null;
31 | }
32 | }
33 |
34 | export default ShortCutsInfoTool;
35 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CodeBlockService/CodeBlockTool.js:
--------------------------------------------------------------------------------
1 | import { injectable } from 'inversify';
2 | import { setBlockType } from 'prosemirror-commands';
3 | import { Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | class CodeBlockTool extends Tools {
7 | title = 'Insert Code Block';
8 | icon = 'codeBlock';
9 | name = 'CodeBlockTool';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | setBlockType(state.config.schema.nodes.code_block)(state, dispatch);
14 | };
15 | }
16 |
17 | select = (state, activeViewId, activeView) => {
18 | const { disallowedTools } = activeView.props;
19 | if (disallowedTools.includes('CodeBlock')) return false;
20 | return true;
21 | };
22 |
23 | get enable() {
24 | return state => {
25 | return setBlockType(state.config.schema.nodes.code_block)(state);
26 | };
27 | }
28 | }
29 |
30 | export default CodeBlockTool;
31 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/EssayPromptNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class EssayPromptNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'essay_prompt';
23 | }
24 |
25 | stopEvent(event) {
26 | if (event.target.type === 'text' || event.target.type === 'textarea') {
27 | return true;
28 | }
29 | const innerView = this.context.pmViews[this.node.attrs.id];
30 | return innerView && innerView.dom.contains(event.target);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | # include:
2 | # - project: 'cokoapps/ci'
3 | # ref: main
4 | # file: 'ci-templates.yml'
5 |
6 | variables:
7 | IMAGE_NAME_DEMO: $CI_REGISTRY/wax/wax-prosemirror/wax-demo
8 | BUILD_PATH: .
9 |
10 | stages:
11 | - Build
12 | - Deploy
13 |
14 | build demo:
15 | stage: Build
16 | image: docker:26
17 | services:
18 | - docker:26-dind
19 | before_script:
20 | - echo "$CI_REGISTRY_PASSWORD" | docker login "$CI_REGISTRY" -u "$CI_REGISTRY_USER" --password-stdin
21 | script:
22 | - docker build --tag $IMAGE_NAME_DEMO:$CI_COMMIT_SHA -f $BUILD_PATH/Dockerfile-production $BUILD_PATH
23 | - docker push $IMAGE_NAME_DEMO:$CI_COMMIT_SHA
24 | only:
25 | - master
26 |
27 | pages:
28 | stage: Deploy
29 | image: $IMAGE_NAME_DEMO:$CI_COMMIT_SHA
30 | script:
31 | - cp -r /home/wax/_build public
32 | artifacts:
33 | paths:
34 | - public
35 | only:
36 | - master
37 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/LinkService/schema/linkMark.js:
--------------------------------------------------------------------------------
1 | const linkMark = {
2 | attrs: {
3 | href: { default: null },
4 | rel: { default: '' },
5 | target: { default: 'blank' },
6 | title: { default: null },
7 | },
8 | excludes: 'link',
9 | inclusive: false,
10 | parseDOM: [
11 | {
12 | tag: 'a[href]',
13 | getAttrs(hook, next) {
14 | const href = hook.dom.getAttribute('href');
15 | const target = href && href.indexOf('#') === 0 ? '' : 'blank';
16 | Object.assign(hook, {
17 | href: hook.dom.getAttribute('href'),
18 | title: hook.dom.getAttribute('title'),
19 | target,
20 | });
21 | next();
22 | },
23 | },
24 | ],
25 | toDOM(hook, next) {
26 | // eslint-disable-next-line no-param-reassign
27 | hook.value = ['a', hook.node.attrs, 0];
28 | next();
29 | },
30 | };
31 |
32 | export default linkMark;
33 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/EssayQuestionNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class EssayQuestionNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'essay_question';
23 | }
24 |
25 | stopEvent(event) {
26 | if (event.target.type === 'text' || event.target.type === 'textarea') {
27 | return true;
28 | }
29 | const innerView = this.context.pmViews[this.node.attrs.id];
30 | return innerView && innerView.dom.contains(event.target);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/StrikeThroughService/StrikeThrough.js:
--------------------------------------------------------------------------------
1 | import { toggleMark } from 'prosemirror-commands';
2 | import { injectable } from 'inversify';
3 | import { Commands, Tools } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | export default class StrikeThrough extends Tools {
7 | title = 'Toggle strikethrough';
8 | icon = 'strikethrough';
9 | name = 'StrikeThrough';
10 |
11 | get run() {
12 | return (state, dispatch) => {
13 | toggleMark(state.config.schema.marks.strikethrough)(state, dispatch);
14 | };
15 | }
16 |
17 | select = state => {
18 | const {
19 | selection: { from },
20 | } = state;
21 | if (from === null) return false;
22 | return true;
23 | };
24 |
25 | get active() {
26 | return state => {
27 | return Commands.markActive(state.config.schema.marks.strikethrough)(
28 | state,
29 | );
30 | };
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MatchingService/MatchingOptionNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class MatchingOptionNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'matching_option';
23 | }
24 |
25 | stopEvent(event) {
26 | if (event.target.type === 'text' || event.target.type === 'button') {
27 | return true;
28 | }
29 | const innerView = this.context.pmViews[this.node.attrs.id];
30 | return innerView && innerView.dom.contains(event.target);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
Wax Editor
3 |
4 |
5 | | [](https://gitlab.coko.foundation/wax/wax-prosemirror/raw/master/LICENSE) |
6 | | :------------------------------------------------------------------------------------------------------------------------------------------: |
7 |
8 |
9 | Wax Editor is built on top of the Prosemirror library. Check Prosemirror [website](https://prosemirror.net/) and [GitHub repo](https://github.com/ProseMirror) for more information.
10 |
11 | ## [Various Demos.](https://demo.waxjs.net/)
12 |
13 |
14 | ## Get up and running
15 |
16 | Run a local version of the demos
17 |
18 | 1. `yarn with node >= 14`
19 |
20 | 2. `yarn build`
21 |
22 | 3. `yarn start` Will bring up a demos of different ediitors
23 |
24 | ## Documentation
25 |
26 | Documentation can be found [here](https://waxjs.net/docs/wax/).
27 |
--------------------------------------------------------------------------------
/wax-citation-service/README.md:
--------------------------------------------------------------------------------
1 | ## Wax citation package
2 |
3 | Wax Citation Package
4 |
5 | ## How to use
6 |
7 | ### Editor's config
8 |
9 | ```
10 | import { TablesService, tableEditing, columnResizing } from 'wax-table-service';
11 | ```
12 |
13 | ### Styles(preferably in your layout)
14 |
15 | ```
16 | import 'wax-table-service/dist/index.css'
17 | ```
18 |
19 | ### Tools
20 |
21 | ```
22 | MenuService: [
23 | {
24 | templateArea: 'mainMenuToolBar',
25 | toolGroups: [
26 | 'Tables',
27 | ],
28 | },
29 | ],
30 |
31 | ```
32 |
33 | ### ProseMirror Plugins
34 |
35 | In case you need tableEditing or columnResizing plugins add the to the array of `PmPlugins` in your editor's config
36 |
37 | ```
38 | PmPlugins: [
39 | tableEditing(),
40 | columnResizing(),
41 | ],
42 | ```
43 |
44 | ### Start the Service
45 |
46 | ```
47 | services: [
48 | new TablesService(),
49 | ]
50 | ```
51 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/utilities/schema/DefaultSchema.js:
--------------------------------------------------------------------------------
1 | export default {
2 | nodes: {
3 | doc: {
4 | content: 'block+',
5 | },
6 | text: {
7 | group: 'inline',
8 | },
9 | hard_break: {
10 | inline: true,
11 | group: 'inline',
12 | selectable: false,
13 | parseDOM: [{ tag: 'br' }],
14 | toDOM() {
15 | return ['br'];
16 | },
17 | },
18 | paragraph: {
19 | group: 'block',
20 | content: 'inline*',
21 | attrs: {
22 | class: { default: 'paragraph' },
23 | },
24 | parseDOM: [
25 | {
26 | tag: 'p.paragraph',
27 | getAttrs(dom) {
28 | return {
29 | class: dom.getAttribute('class'),
30 | };
31 | },
32 | },
33 | ],
34 | toDOM(node) {
35 | return ['p', node.attrs, 0];
36 | },
37 | },
38 | },
39 | marks: {},
40 | };
41 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/MultipleChoiceSingleCorrectQuestionService/schema/multipleChoiceSingleCorrectContainerNode.js:
--------------------------------------------------------------------------------
1 | const multipleChoiceSingleCorrectContainerNode = {
2 | attrs: {
3 | id: { default: '' },
4 | class: { default: 'multiple-choice-single-correct' },
5 | correctId: { default: '' },
6 | },
7 | group: 'block questions',
8 | atom: true,
9 | selectable: true,
10 | draggable: true,
11 | content: 'block*',
12 | parseDOM: [
13 | {
14 | tag: 'div.multiple-choice-single-correct',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | correctId: dom.getAttribute('correctId'),
20 | };
21 | },
22 | },
23 | ],
24 | toDOM(node) {
25 | return ['div', node.attrs, 0];
26 | },
27 | };
28 |
29 | export default multipleChoiceSingleCorrectContainerNode;
30 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/rollup.config.js:
--------------------------------------------------------------------------------
1 | import babel from '@rollup/plugin-babel';
2 | import commonjs from '@rollup/plugin-commonjs';
3 | import external from 'rollup-plugin-peer-deps-external';
4 | import css from 'rollup-plugin-import-css';
5 | import { terser } from 'rollup-plugin-terser';
6 |
7 | export default {
8 | input: './index.js',
9 | output: [
10 | {
11 | file: 'dist/index.js',
12 | format: 'esm',
13 | sourcemap: false,
14 | },
15 | ],
16 | plugins: [
17 | css(),
18 | external({
19 | includeDependencies: true,
20 | }),
21 | babel({
22 | babelHelpers: 'runtime',
23 | presets: ['react-app'],
24 | plugins: [
25 | ['@babel/plugin-proposal-decorators', { legacy: true }],
26 | 'babel-plugin-parameter-decorator',
27 | ],
28 | exclude: 'node_modules/**',
29 | }),
30 | commonjs(),
31 | // terser(),
32 | ],
33 | external: [],
34 | };
35 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/HideShowTool.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | import React, { useState, useMemo } from 'react';
3 | import { MenuButton } from 'wax-prosemirror-core';
4 |
5 | const HideShowTool = ({ view = {}, item, enabled }) => {
6 | const [isEnabled, setEnabled] = useState(enabled);
7 |
8 | const handleMouseDown = e => {
9 | e.preventDefault();
10 | setEnabled(!isEnabled);
11 | item.run(view.state, view.dispatch);
12 | };
13 |
14 | const HideShowToolComponent = useMemo(
15 | () => (
16 | handleMouseDown(e)}
21 | title={item.title}
22 | />
23 | ),
24 | [isEnabled],
25 | );
26 |
27 | return HideShowToolComponent;
28 | };
29 |
30 | export default HideShowTool;
31 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/QuestionNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class QuestionNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'question_node_multiple';
23 | }
24 |
25 | stopEvent(event) {
26 | if (event.target.type === 'text' || event.target.type === 'textarea') {
27 | return true;
28 | }
29 | const innerView = this.context.pmViews[this.node.attrs.id];
30 | return innerView && innerView.dom.contains(event.target);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleDropDownService/CreateDropDownService/MultipleDropDownNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class MultipleDropDownNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'multiple_drop_down_option';
23 | }
24 |
25 | stopEvent(event) {
26 | if (event.target.type === 'text') {
27 | return true;
28 | }
29 | const innerView = this.context.pmViews[this.node.attrs.id];
30 | return innerView && innerView.dom.contains(event.target);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/RedoService/Redo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { redo } from 'prosemirror-history';
4 | import { injectable } from 'inversify';
5 | import { Tools } from 'wax-prosemirror-core';
6 | import UndoRedoButton from '../components/UndoRedoButton';
7 |
8 | @injectable()
9 | export default class Redo extends Tools {
10 | title = 'Redo';
11 | icon = 'redo';
12 | name = 'Redo';
13 |
14 | get run() {
15 | return (state, dispatch) => {
16 | redo(state, tr => dispatch(tr.setMeta('inputType', 'Redo')));
17 | };
18 | }
19 |
20 | get enable() {
21 | return redo;
22 | }
23 |
24 | select(state) {
25 | return redo(state);
26 | }
27 |
28 | renderTool(view) {
29 | if (isEmpty(view)) return null;
30 | return this.isDisplayed() ? (
31 |
32 | ) : null;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/BaseService/UndoService/Undo.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { isEmpty } from 'lodash';
3 | import { undo } from 'prosemirror-history';
4 | import { injectable } from 'inversify';
5 | import { Tools } from 'wax-prosemirror-core';
6 | import UndoRedoButton from '../components/UndoRedoButton';
7 |
8 | @injectable()
9 | export default class Undo extends Tools {
10 | title = 'Undo';
11 | icon = 'undo';
12 | name = 'Undo';
13 |
14 | get run() {
15 | return (state, dispatch) => {
16 | undo(state, tr => dispatch(tr.setMeta('inputType', 'Undo')));
17 | };
18 | }
19 |
20 | get enable() {
21 | return undo;
22 | }
23 |
24 | select(state) {
25 | return undo(state);
26 | }
27 |
28 | renderTool(view) {
29 | if (isEmpty(view)) return null;
30 | return this.isDisplayed() ? (
31 |
32 | ) : null;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/OENContainersService/OENAsideShortToolGroupService/OENAsideShortToolGroup.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { injectable, inject } from 'inversify';
3 | import { ToolGroup, LeftMenuTitle } from 'wax-prosemirror-core';
4 |
5 | @injectable()
6 | class OENAsideShortToolGroup extends ToolGroup {
7 | tools = [];
8 | title = ();
9 |
10 | constructor(
11 | @inject('OENAsideShortToolNote') OENAsideShortToolNote,
12 | @inject('OENAsideShortToolTip') OENAsideShortToolTip,
13 | @inject('OENAsideShortToolWarning') OENAsideShortToolWarning,
14 | @inject('OENAsideShortToolReminder') OENAsideShortToolReminder,
15 | ) {
16 | super();
17 | this.tools = [
18 | OENAsideShortToolNote,
19 | OENAsideShortToolTip,
20 | OENAsideShortToolWarning,
21 | OENAsideShortToolReminder,
22 | ];
23 | }
24 | }
25 |
26 | export default OENAsideShortToolGroup;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/OrderedListService/OrderedListService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import orderedListNode from './schema/orderedListNode';
3 | import OrderedList from './OrderedList';
4 |
5 | class OrderedListService extends Service {
6 | name = 'OrderedListService';
7 |
8 | register() {
9 | const CreateShortCut = this.container.get('CreateShortCut');
10 | this.container.bind('OrderedList').toDynamicValue(() => {
11 | return new OrderedList(this.config);
12 | });
13 | const createNode = this.container.get('CreateNode');
14 | createNode(
15 | {
16 | orderedlist: orderedListNode,
17 | },
18 | { toWaxSchema: true },
19 | );
20 | CreateShortCut({
21 | 'Shift-Ctrl-9': (state, dispatch) => {
22 | this.container.get('OrderedList').run(state, dispatch);
23 | },
24 | });
25 | }
26 | }
27 |
28 | export default OrderedListService;
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/removeNode.js:
--------------------------------------------------------------------------------
1 | import { replaceStep, ReplaceStep } from 'prosemirror-transform';
2 | import { Slice } from 'prosemirror-model';
3 | import { Selection } from 'prosemirror-state';
4 |
5 | const removeNode = (tr, node, nodePos, map) => {
6 | const newNodePos = map.map(nodePos);
7 | let delStep;
8 | const selectionBefore = Selection.findFrom(tr.doc.resolve(newNodePos), -1);
9 | const start = selectionBefore.$anchor.pos;
10 | const end = newNodePos + 1;
11 |
12 | if (node.isLeaf || ['figure', 'table'].includes(node.type.name)) {
13 | delStep = new ReplaceStep(
14 | newNodePos,
15 | map.map(nodePos + node.nodeSize),
16 | Slice.empty,
17 | );
18 | } else {
19 | delStep = replaceStep(tr.doc, start, end);
20 | }
21 |
22 | tr.step(delStep);
23 | const stepMap = delStep.getMap();
24 | map.appendMap(stepMap);
25 | };
26 |
27 | export default removeNode;
28 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ListsService/BulletListService/BulletListService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import bulletListNode from './schema/bulletListNode';
3 | import BulletList from './BulletList';
4 |
5 | class BulletListService extends Service {
6 | name = 'BulletListService';
7 |
8 | register() {
9 | const CreateShortCut = this.container.get('CreateShortCut');
10 | const createNode = this.container.get('CreateNode');
11 |
12 | this.container.bind('BulletList').toDynamicValue(() => {
13 | return new BulletList(this.config);
14 | });
15 |
16 | createNode(
17 | {
18 | bulletlist: bulletListNode,
19 | },
20 | { toWaxSchema: true },
21 | );
22 |
23 | CreateShortCut({
24 | 'Shift-Ctrl-8': (state, dispatch) => {
25 | this.container.get('BulletList').run(state, dispatch);
26 | },
27 | });
28 | }
29 | }
30 |
31 | export default BulletListService;
32 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/LayoutService/components/componentPlugin.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/jsx-props-no-spreading */
2 | /* eslint-disable react/no-array-index-key */
3 | import React from 'react';
4 | // import { useInjection } from '../../../../WaxContext';
5 |
6 | const ComponentPlugin = renderArea => layoutProps => {
7 | // const { instance } = useInjection('Layout');
8 |
9 | const instance = layoutProps.app.container.isBound('Layout')
10 | ? { instance: context.app.container.get('Layout') }
11 | : null;
12 |
13 | const components = instance.render(renderArea);
14 | return components
15 | ? components.map(({ component: Component, componentProps }, key) => {
16 | return (
17 |
22 | );
23 | })
24 | : null;
25 | };
26 | export default ComponentPlugin;
27 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/utilities/lib/Middleware.js:
--------------------------------------------------------------------------------
1 | export default class Middleware {
2 | constructor() {
3 | // Array prototype last
4 | if (!Array.prototype.last) {
5 | Array.prototype.last = function () {
6 | return this[this.length - 1];
7 | };
8 | }
9 |
10 | // Array prototype reduceOneRight
11 | if (!Array.prototype.reduceOneRight) {
12 | Array.prototype.reduceOneRight = function () {
13 | return this.slice(0, -1);
14 | };
15 | }
16 | }
17 |
18 | use(fn) {
19 | this.go = (stack => (...args) =>
20 | stack(...args.reduceOneRight(), () => {
21 | let _next = args.last();
22 | fn.apply(this, [
23 | ...args.reduceOneRight(),
24 | _next.bind.apply(_next, [null, ...args.reduceOneRight()]),
25 | ]);
26 | }))(this.go);
27 | }
28 |
29 | go(...args) {
30 | let _next = args.last();
31 | _next.apply(this, args.reduceOneRight());
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CommentsService/components/ui/trackChanges/TrackChangeEnable.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 | import React, { useState, useMemo } from 'react';
3 | import { MenuButton } from 'wax-prosemirror-core';
4 |
5 | const TrackChangeEnable = ({ view = {}, item, enabled }) => {
6 | const [isEnabled, setEnabled] = useState(enabled);
7 |
8 | const handleMouseDown = e => {
9 | e.preventDefault();
10 | setEnabled(!isEnabled);
11 | item.run(view.state, view.dispatch);
12 | };
13 |
14 | const TrackChangeEnableComponent = useMemo(
15 | () => (
16 | handleMouseDown(e)}
21 | title={item.title}
22 | />
23 | ),
24 | [isEnabled],
25 | );
26 |
27 | return TrackChangeEnableComponent;
28 | };
29 |
30 | export default TrackChangeEnable;
31 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/schema/multipleChoiceNode.js:
--------------------------------------------------------------------------------
1 | const multipleChoiceNode = {
2 | attrs: {
3 | class: { default: 'multiple-choice-option' },
4 | id: { default: '' },
5 | correct: { default: false },
6 | answer: { default: false },
7 | feedback: { default: '' },
8 | },
9 | group: 'block questions',
10 | content: 'block*',
11 | // defining: true,
12 | parseDOM: [
13 | {
14 | tag: 'div.multiple-choice-option',
15 | getAttrs(dom) {
16 | return {
17 | id: dom.getAttribute('id'),
18 | class: dom.getAttribute('class'),
19 | correct: JSON.parse(dom.getAttribute('correct').toLowerCase()),
20 | answer: JSON.parse(dom.getAttribute('answer').toLowerCase()),
21 | feedback: dom.getAttribute('feedback'),
22 | };
23 | },
24 | },
25 | ],
26 | toDOM: node => ['div', node.attrs, 0],
27 | };
28 |
29 | export default multipleChoiceNode;
30 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | const { eslint } = require('@coko/lint');
2 |
3 | eslint.parserOptions = {
4 | ecmaVersion: 6,
5 | ecmaFeatures: {
6 | legacyDecorators: true,
7 | experimentalObjectRestSpread: true,
8 | },
9 | };
10 |
11 | eslint.rules['no-unused-vars'] = ['error', { varsIgnorePattern: 'inject' }];
12 |
13 | eslint.rules['no-underscore-dangle'] = [
14 | 'error',
15 | { allow: ['_tools', '_config'] },
16 | ];
17 |
18 | eslint.rules['class-methods-use-this'] = [
19 | 1,
20 | { exceptMethods: ['run', 'enable', 'active', 'select'] },
21 | ];
22 | // eslint.rules['import/no-named-as-default'] = 0,
23 |
24 | eslint.rules['react/prop-types'] = [
25 | 2,
26 | {
27 | ignore: [
28 | 'children',
29 | 'className',
30 | 'onClick',
31 | 'onMouseDown',
32 | 'onMouseEnter',
33 | 'theme',
34 | 'node',
35 | 'view',
36 | 'getPos',
37 | 'readOnly',
38 | ],
39 | },
40 | ];
41 |
42 | module.exports = eslint;
43 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleChoiceQuestionService/TrueFalseQuestionService/schema/trueFalseNode.js:
--------------------------------------------------------------------------------
1 | const trueFalseNode = {
2 | attrs: {
3 | class: { default: 'true-false-option' },
4 | id: { default: '' },
5 | correct: { default: false },
6 | answer: { default: false },
7 | feedback: { default: '' },
8 | },
9 | group: 'block questions',
10 | content: 'block*',
11 | // defining: true,
12 |
13 | parseDOM: [
14 | {
15 | tag: 'div.true-false-option',
16 | getAttrs(dom) {
17 | return {
18 | id: dom.getAttribute('id'),
19 | class: dom.getAttribute('class'),
20 | correct: JSON.parse(dom.getAttribute('correct').toLowerCase()),
21 | answer: JSON.parse(dom.getAttribute('answer').toLowerCase()),
22 | feedback: dom.getAttribute('feedback'),
23 | };
24 | },
25 | },
26 | ],
27 | toDOM: node => ['div', node.attrs, 0],
28 | };
29 |
30 | export default trueFalseNode;
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/defaultServices/OverlayService/OverlayComponent.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable react/jsx-props-no-spreading */
2 | import React, { useMemo, useContext } from 'react';
3 | import Overlay from './OverLay';
4 | import { WaxContext } from '../../../WaxContext';
5 | import usePosition from './usePosition';
6 |
7 | export default (Component, markType) => props => {
8 | const context = useContext(WaxContext);
9 | const [position, setPosition, mark] = usePosition(markType);
10 |
11 | const component = useMemo(
12 | () => (
13 |
19 | ),
20 | [JSON.stringify(mark), position, context.activeViewId],
21 | );
22 | const visible = position.left !== null;
23 | return (
24 |
25 | {props.activeViewId === context.activeViewId && visible && component}
26 |
27 | );
28 | };
29 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/ExternalAPIContentService/ExternalAPIContentService.js:
--------------------------------------------------------------------------------
1 | import { Service } from 'wax-prosemirror-core';
2 | import ExternalAPIContentTool from './ExternalAPIContentTool';
3 | import ExternalAPIContentToolGroupService from './ExternalAPIContentToolGroupService/ExternalAPIContentToolGroupService';
4 | import ExternalAPIContentPlaceHolderPlugin from './plugins/ExternalAPIContentPlaceHolderPlugin';
5 | import './externalApiContent.css';
6 |
7 | class ExternalAPIContentService extends Service {
8 | name = 'ExternalAPIContentService';
9 |
10 | boot() {
11 | this.app.PmPlugins.add(
12 | 'ExternalAPIContentPlaceHolder',
13 | ExternalAPIContentPlaceHolderPlugin('ExternalAPIContentPlaceHolder'),
14 | );
15 | }
16 |
17 | register() {
18 | this.container.bind('ExternalAPIContentTool').to(ExternalAPIContentTool);
19 | }
20 |
21 | dependencies = [new ExternalAPIContentToolGroupService()];
22 | }
23 |
24 | export default ExternalAPIContentService;
25 |
--------------------------------------------------------------------------------
/wax-questions-service/src/FillTheGapQuestionService/FillTheGapNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class FillTheGapNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'fill_the_gap';
23 | }
24 |
25 | selectNode() {
26 | this.context.pmViews[this.node.attrs.id].focus();
27 | }
28 |
29 | stopEvent(event) {
30 | return (
31 | this.context.pmViews[this.node.attrs.id] !== undefined &&
32 | event.target !== undefined &&
33 | this.context.pmViews[this.node.attrs.id].dom.contains(event.target)
34 | );
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/EditingSuggestingService/EditingSuggesting.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { injectable } from 'inversify';
3 | import { isEmpty } from 'lodash';
4 | import { v4 as uuidv4 } from 'uuid';
5 | import { Tools } from 'wax-prosemirror-core';
6 | import EditingSuggestingDropDown from './components/EditingSuggestingDropDown';
7 |
8 | @injectable()
9 | export default class EditingSuggesting extends Tools {
10 | title = '';
11 | label = '';
12 | name = 'EditingSuggesting';
13 |
14 | get run() {
15 | return () => {
16 | return true;
17 | };
18 | }
19 |
20 | get enable() {
21 | return () => {
22 | return true;
23 | };
24 | }
25 |
26 | renderTool(view) {
27 | if (isEmpty(view)) return null;
28 | return this.isDisplayed() ? (
29 |
35 | ) : null;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/wax-questions-service/src/EssayService/components/EssayPromptComponent.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from 'react';
2 | import styled from 'styled-components';
3 | import { WaxContext } from 'wax-prosemirror-core';
4 | import EditorComponent from '../../MultipleChoiceQuestionService/components/EditorComponent';
5 |
6 | const EditorWrapper = styled.div`
7 | display: ${props => (props.testMode ? 'none' : 'block')};
8 | `;
9 |
10 | export default ({ node, view, getPos }) => {
11 | const context = useContext(WaxContext);
12 | const {
13 | pmViews: { main },
14 | } = context;
15 | const customProps = main.props.customValues;
16 |
17 | const { testMode } = customProps;
18 |
19 | return (
20 |
21 |
28 |
29 | );
30 | };
31 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/CustomTagInlineService/schema/customtagInlineMark.js:
--------------------------------------------------------------------------------
1 | const customtagInlineMark = {
2 | attrs: {
3 | class: { default: null },
4 | tags: [],
5 | type: { default: 'inline' },
6 | },
7 | inclusive: false,
8 | parseDOM: [
9 | {
10 | tag: 'span[data-type="inline"]',
11 | getAttrs(hook, next) {
12 | Object.assign(hook, {
13 | class: hook.dom.getAttribute('class'),
14 | tags: JSON.parse(hook.dom.dataset.tags),
15 | type: hook.dom.dataset.type,
16 | });
17 | next();
18 | },
19 | },
20 | ],
21 | toDOM(hook, next) {
22 | // eslint-disable-next-line no-param-reassign
23 | hook.value = [
24 | 'span',
25 | {
26 | class: hook.node.attrs.class,
27 | 'data-type': hook.node.attrs.type,
28 | 'data-tags': JSON.stringify(hook.node.attrs.tags),
29 | },
30 | ];
31 | next();
32 | },
33 | };
34 |
35 | export default customtagInlineMark;
36 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/CustomTagService/index.js:
--------------------------------------------------------------------------------
1 | import CustomTagBlockService from './CustomTagBlockService/CustomTagBlockService';
2 | import CustomTagBlockNewService from './CustomTagBlockNewService/CustomTagBlockNewService';
3 | import CustomTagInlineService from './CustomTagInlineService/CustomTagInlineService';
4 | import CustomTagBlockToolGroupService from './CustomTagToolGroupService/CustomTagBlockToolGroupService/CustomTagBlockToolGroupService';
5 | import CustomTagInlineToolGroupService from './CustomTagToolGroupService/CustomTagInlineToolGroupService/CustomTagInlineToolGroupService';
6 | import CustomTagBlockNewToolGroupService from './CustomTagToolGroupService/CustomTagBlockNewToolGroupService/CustomTagBlockNewToolGroupService';
7 |
8 | export default [
9 | new CustomTagBlockNewService(),
10 | new CustomTagBlockService(),
11 | new CustomTagInlineService(),
12 | new CustomTagBlockToolGroupService(),
13 | new CustomTagInlineToolGroupService(),
14 | new CustomTagBlockNewToolGroupService(),
15 | ];
16 |
--------------------------------------------------------------------------------
/wax-prosemirror-services/src/InlineAnnotations/index.js:
--------------------------------------------------------------------------------
1 | import CodeService from './CodeService/CodeService';
2 | import StrongService from './StrongService/StrongService';
3 | import EmphasisService from './EmphasisService/EmphasisService';
4 | import SubscriptService from './SubscriptService/SubscriptService';
5 | import SuperscriptService from './SuperscriptService/SuperscriptService';
6 | import StrikeThroughService from './StrikeThroughService/StrikeThroughService';
7 | import UnderlineService from './UnderlineService/UnderlineService';
8 | import SmallCapsService from './SmallCapsService/SmallCapsService';
9 | import AnnotationToolGroupService from './AnnotationToolGroupService/AnnotationToolGroupService';
10 |
11 | export default [
12 | new CodeService(),
13 | new StrongService(),
14 | new EmphasisService(),
15 | new SubscriptService(),
16 | new SuperscriptService(),
17 | new StrikeThroughService(),
18 | new UnderlineService(),
19 | new SmallCapsService(),
20 | new AnnotationToolGroupService(),
21 | ];
22 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/components/LeftMenuTitle.js:
--------------------------------------------------------------------------------
1 | /* eslint react/prop-types: 0 */
2 |
3 | import React from 'react';
4 | import { isEmpty } from 'lodash';
5 | import { useTranslation } from 'react-i18next';
6 | import styled from 'styled-components';
7 |
8 | const LeftMenuStyled = styled.div`
9 | border-bottom: 1px solid #d9d9d9;
10 | color: #979797;
11 | font-family: 'Fira Sans';
12 | font-size: 15px;
13 | font-weight: bold;
14 | letter-spacing: 0.6px;
15 | list-style: none;
16 | line-height: 0;
17 | margin: 5px 0;
18 | display: block;
19 | padding: 20px 0 10px;
20 | margin-left: 10px;
21 | text-align: left;
22 | text-transform: uppercase;
23 | width: 51%;
24 | `;
25 |
26 | const LeftMenuTitle = ({ title }) => {
27 | const { t, i18n } = useTranslation();
28 | return (
29 |
30 | {!isEmpty(i18n) && i18n.exists(`Wax.Various.${title}`)
31 | ? t(`Wax.Various.${title}`)
32 | : title}
33 |
34 | );
35 | };
36 |
37 | export default LeftMenuTitle;
38 |
--------------------------------------------------------------------------------
/wax-questions-service/src/MultipleDropDownService/MultipleDropDownContainerNodeView.js:
--------------------------------------------------------------------------------
1 | import { QuestionsNodeView } from 'wax-prosemirror-core';
2 |
3 | export default class MultipleDropDownContainerNodeView extends QuestionsNodeView {
4 | constructor(
5 | node,
6 | view,
7 | getPos,
8 | decorations,
9 | createPortal,
10 | Component,
11 | context,
12 | ) {
13 | super(node, view, getPos, decorations, createPortal, Component, context);
14 |
15 | this.node = node;
16 | this.outerView = view;
17 | this.getPos = getPos;
18 | this.context = context;
19 | }
20 |
21 | static name() {
22 | return 'multiple_drop_down_container';
23 | }
24 |
25 | stopEvent(event) {
26 | if (
27 | event.target.type === 'textarea' ||
28 | event.target.type === 'text' ||
29 | !event.target.type
30 | ) {
31 | return true;
32 | }
33 | const innerView = this.context.pmViews[this.node.attrs.id];
34 | return innerView && innerView.dom.contains(event.target);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/wax-prosemirror-core/src/config/plugins/placeholder.js:
--------------------------------------------------------------------------------
1 | import { Plugin, PluginKey } from 'prosemirror-state';
2 | import { Decoration, DecorationSet } from 'prosemirror-view';
3 |
4 | const placeHolderText = new PluginKey('placeHolderText');
5 |
6 | export default props => {
7 | return new Plugin({
8 | key: placeHolderText,
9 | props: {
10 | decorations: state => {
11 | const decorations = [];
12 | const decorate = (node, pos) => {
13 | if (
14 | node.type.isBlock &&
15 | node.childCount === 0 &&
16 | state.doc.content.childCount === 1
17 | ) {
18 | decorations.push(
19 | Decoration.node(pos, pos + node.nodeSize, {
20 | class: 'empty-node',
21 | 'data-content': props.content,
22 | }),
23 | );
24 | }
25 | };
26 | state.doc.descendants(decorate);
27 |
28 | return DecorationSet.create(state.doc, decorations);
29 | },
30 | },
31 | });
32 | };
33 |
--------------------------------------------------------------------------------