diff --git a/editors/editoria/src/Editoria.js b/editors/editoria/src/Editoria.js index 33d5439b3c08ea3e9dfe0925cef274c90a71b700..00db23f7e2959044da90519fc9882b82b5877471 100644 --- a/editors/editoria/src/Editoria.js +++ b/editors/editoria/src/Editoria.js @@ -62,7 +62,8 @@ const Editoria = () => { autoFocus placeholder="Type Something..." fileUpload={file => renderImage(file)} - value={demo} + value={`<p class="paragraph">hello</p><p class="custom-tag-label-3" data-type="block">Lorem this is <span class="custom-tag-label-1,custom-tag-label-2" data-type="inline" data-tags="["custom-tag-label-1","custom-tag-label-2"]">text </span>dolor si</p>`} + // value={demo} // readonly layout={layout} // onChange={source => console.log(source)} diff --git a/editors/editoria/src/config/config.js b/editors/editoria/src/config/config.js index 96bdb592bd41434bc14e2e2eaa262e136d69ae7b..b6b0b6be8d057c85b27567e21fee24298b6ca555 100644 --- a/editors/editoria/src/config/config.js +++ b/editors/editoria/src/config/config.js @@ -62,6 +62,10 @@ const saveTags = tags => { // console.log(tags); }; +const updateTrackStatus = status => { + // console.log('status', status); +}; + export default { MenuService: [ { @@ -109,7 +113,7 @@ export default { TitleService: { updateTitle }, RulesService: [emDash, ellipsis], ShortCutsService: {}, - EnableTrackChangeService: { enabled: false, toggle: true }, + EnableTrackChangeService: { enabled: false, toggle: true, updateTrackStatus }, AcceptTrackChangeService: { own: { accept: true, diff --git a/editors/editoria/src/layout/EditorElements.js b/editors/editoria/src/layout/EditorElements.js index 7322e4916a73a35ac0b17e8af01f4a789377f98f..e2e896a3663293f4913c2f9e692fd45ce1d3a1a2 100644 --- a/editors/editoria/src/layout/EditorElements.js +++ b/editors/editoria/src/layout/EditorElements.js @@ -393,38 +393,38 @@ export default css` padding-top: 2px; } - .custom-tag-inline { + span[data-type='inline'] { display: inline; font-weight: 500; } - custom-tag-inline:before { + span[data-type='inline']:before { color: #006f19; content: ' | '; font-weight: 600; margin-left: 0; } - custom-tag-inline:after { + span[data-type='inline']:after { color: #006f19; content: ' | '; display: inline; font-weight: 600; } - custom-tag-block { + p[data-type='block'] { display: block; margin-top: 1em; } - custom-tag-block:before { + p[data-type='block']:before { color: #006f19; content: '|'; display: inline; font-weight: 600; } - custom-tag-block:after { + p[data-type='block']:after { color: #006f19; content: '|'; display: inline; diff --git a/wax-prosemirror-components/package.json b/wax-prosemirror-components/package.json index 7cc02702310cb033ef1450bddd9735bd69b296c2..4d46af1847e480f63e9206e2df25efc15813f52d 100644 --- a/wax-prosemirror-components/package.json +++ b/wax-prosemirror-components/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror UI components", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ], diff --git a/wax-prosemirror-components/src/components/customtag/CustomTagInlineComponent.js b/wax-prosemirror-components/src/components/customtag/CustomTagInlineComponent.js index 522afa887e5b23564358d7eb47947d0314abd445..a75341ccc23bd4a3410ef853a3e07344fa077676 100644 --- a/wax-prosemirror-components/src/components/customtag/CustomTagInlineComponent.js +++ b/wax-prosemirror-components/src/components/customtag/CustomTagInlineComponent.js @@ -1,8 +1,16 @@ import React, { useMemo, useState, useContext } from 'react'; import { WaxContext } from 'wax-prosemirror-core'; +import styled from 'styled-components'; import MenuButton from '../../ui/buttons/MenuButton'; +const StyledButton = styled(MenuButton)` + svg { + height: 15px; + width: 17px; + } +`; + const CustomTagInlineComponent = ({ view: { state }, item }) => { const { icon, title } = item; const localInline = JSON.parse(localStorage.getItem('isInline')); @@ -27,7 +35,7 @@ const CustomTagInlineComponent = ({ view: { state }, item }) => { return useMemo( () => ( - <MenuButton + <StyledButton active={isOpen} disabled={isDisabled} iconName={icon} @@ -35,7 +43,7 @@ const CustomTagInlineComponent = ({ view: { state }, item }) => { title={title} /> ), - [isOpen], + [isOpen, isDisabled], ); }; diff --git a/wax-prosemirror-components/src/components/customtag/CustomTagInlineOverlayCompoment.js b/wax-prosemirror-components/src/components/customtag/CustomTagInlineOverlayCompoment.js index 730ce240ea205b9d61d533d569dd7459c5a21e6b..7f293860a0d979ccd46f97167932cfaca8135717 100644 --- a/wax-prosemirror-components/src/components/customtag/CustomTagInlineOverlayCompoment.js +++ b/wax-prosemirror-components/src/components/customtag/CustomTagInlineOverlayCompoment.js @@ -14,6 +14,7 @@ import { v4 as uuidv4 } from 'uuid'; import Icon from '../../helpers/Icon'; const IconRemove = styled(Icon)` + cursor: pointer; height: 10px; width: 10px; `; @@ -60,7 +61,6 @@ const StyledButton = styled.button` `; const ListStyle = styled.div` - cursor: pointer; margin: 5px 7px 7px 0px; padding: 2px 3px; `; @@ -69,8 +69,13 @@ const Flex = styled.div` display: flex; justify-content: space-between; `; +const ItemActive = styled.div` + color: #006f19; + width: 90%; +`; -const ItemWrapper = styled.div` +const Item = styled.div` + cursor: pointer; width: 100%; `; @@ -80,7 +85,6 @@ const CustomTagInlineOverlayComponent = ({ mark, setPosition, position }) => { const ref = useRef(null); const [inputValue, setInputValue] = useState(''); - const [selectedTagNames, setSelectedTagNames] = useState([]); const [isCustomTagInline, setCustomTag] = useState( JSON.parse(localStorage.getItem('isInline')), @@ -128,8 +132,8 @@ const CustomTagInlineOverlayComponent = ({ mark, setPosition, position }) => { }; const addToSelection = item => { - const tagNames = mark ? mark.attrs.tagNames : []; - tagNames.push(item); + const tags = mark ? mark.attrs.tags : []; + tags.push(item); dispatch( state.tr.addMark( @@ -137,34 +141,40 @@ const CustomTagInlineOverlayComponent = ({ mark, setPosition, position }) => { $to.pos, state.schema.marks.customTagInline.create({ ...((mark && mark.attrs) || {}), - tagNames, - class: tagNames.toString(), + tags, + class: tags.toString(), }), ), ); }; const removeFromSelection = tagName => { - // if (finalTag.length === 0) { - // dispatch( - // state.tr.removeMark( - // $from.pos, - // $to.pos, - // state.schema.marks.customTagInline, - // ), - // ); - // } else { - // dispatch( - // state.tr.addMark( - // $from.pos, - // $to.pos, - // state.schema.marks.customTagInline.create({ - // tagNames: JSON.stringify(finalTag), - // class: classNames, - // }), - // ), - // ); - // } + const { tags } = mark.attrs; + if (tags.length === 1) { + dispatch( + state.tr.removeMark( + mark.from, + mark.to, + state.schema.marks.customTagInline, + ), + ); + } else { + const index = tags.indexOf(tagName); + if (index > -1) { + tags.splice(index, 1); + dispatch( + state.tr.addMark( + mark.from, + mark.to, + state.schema.marks.customTagInline.create({ + ...((mark && mark.attrs) || {}), + tags, + class: tags.toString(), + }), + ), + ); + } + } }; useEffect(() => { @@ -175,36 +185,52 @@ const CustomTagInlineOverlayComponent = ({ mark, setPosition, position }) => { return tag.tagType === 'inline'; }); + const disabledStyles = { + cursor: 'default', + opacity: '0.4', + pointerEvents: 'none', + }; + + const styles = $from.pos === $to.pos ? disabledStyles : {}; + return isCustomTagInline === true ? ( <Wrapper> <InlineHeader>Custom Inline</InlineHeader> - {inlineTags.map(item => ( - <ListStyle key={uuidv4()}> - <Flex> - <ItemWrapper onMouseDown={() => addToSelection(item.label)}> - {item.label} - </ItemWrapper> - {/* {console.log(mark)} */} - {/* {selectedTagNames.map(value => { - return ( - <Fragment key={uuidv4()}> - {value === item.label ? ( - <span - aria-hidden="true" - onClick={() => removeFromSelection(item.label)} - role="button" - > - <IconRemove name="removeTag" /> - </span> - ) : ( - '' - )} - </Fragment> - ); - })} */} - </Flex> - </ListStyle> - ))} + {inlineTags.map(item => { + return ( + <ListStyle key={uuidv4()}> + <Flex> + {mark && mark.attrs.tags.includes(item.label) ? ( + <ItemActive>{item.label}</ItemActive> + ) : ( + <Item + onMouseDown={() => addToSelection(item.label)} + style={styles} + > + {item.label} + </Item> + )} + + {mark && + mark.attrs.tags.map(value => { + return ( + <Fragment key={uuidv4()}> + {value === item.label ? ( + <span + aria-hidden="true" + onClick={() => removeFromSelection(item.label)} + role="button" + > + <IconRemove name="removeTag" /> + </span> + ) : null} + </Fragment> + ); + })} + </Flex> + </ListStyle> + ); + })} <CustomWrapper> <Input onChange={onChangeTagName} diff --git a/wax-prosemirror-components/src/components/editingSuggesting/EditingSuggestingDropDown.js b/wax-prosemirror-components/src/components/editingSuggesting/EditingSuggestingDropDown.js index 7c0dadbae971428d049524392a394bc4fcf31144..7d639b5e90c4c879d2b8688ac807770f8fc4937e 100644 --- a/wax-prosemirror-components/src/components/editingSuggesting/EditingSuggestingDropDown.js +++ b/wax-prosemirror-components/src/components/editingSuggesting/EditingSuggestingDropDown.js @@ -76,22 +76,28 @@ const dropDownOptions = [ ]; const EditingSuggesting = ({ view: { dispatch, state }, item }) => { - const { app, activeView } = useContext(WaxContext); - const isDisabled = app.config.get('config.EnableTrackChangeService').toggle; + const { app, activeView, view } = useContext(WaxContext); + const enableService = app.config.get('config.EnableTrackChangeService'); + const isDisabled = enableService.toggle; + + const isEditable = view.main.props.editable(editable => { + return editable; + }); const enableDisableTrackChanges = () => { - app.config.get('config.EnableTrackChangeService').enabled = !app.config.get( - 'config.EnableTrackChangeService', - ).enabled; + enableService.enabled = !enableService.enabled; + if (enableService.updateTrackStatus) + enableService.updateTrackStatus(enableService.enabled); + setTimeout(() => { activeView.focus(); }, 100); }; const selectedOption = () => { - if (app.config.get('config.EnableTrackChangeService').enabled) + if (enableService.enabled) { return dropDownOptions[1]; - + } return dropDownOptions[0]; }; @@ -109,7 +115,7 @@ const EditingSuggesting = ({ view: { dispatch, state }, item }) => { [], ); - if (app.config.get('readonly')) return <Viewing />; + if (!isEditable) return <Viewing />; return EditingSuggestingComponent; }; diff --git a/wax-prosemirror-components/src/components/findAndReplace/FindAndReplaceTool.js b/wax-prosemirror-components/src/components/findAndReplace/FindAndReplaceTool.js index 0d843993ad1ebb507a890afd87e69d0a974c7f9c..0475fad67a66352a943aff4c279bea31c8361dc1 100644 --- a/wax-prosemirror-components/src/components/findAndReplace/FindAndReplaceTool.js +++ b/wax-prosemirror-components/src/components/findAndReplace/FindAndReplaceTool.js @@ -69,7 +69,7 @@ const FindAndReplaceTool = ({ view = {}, item }) => { /> {isOpen && ( - <DropWrapper style={style} ref={dropElement}> + <DropWrapper ref={dropElement} style={style}> <FindAndReplaceComponent close={() => { setIsOpen(false); @@ -79,7 +79,7 @@ const FindAndReplaceTool = ({ view = {}, item }) => { )} </Wrapper> ), - [isOpen, style], + [isOpen, style, isDisabled], ); return MemorizedDropdown; diff --git a/wax-prosemirror-components/src/components/images/ImageUpload.js b/wax-prosemirror-components/src/components/images/ImageUpload.js index ef15bb56aaf820467b399f7776660fcb2026a841..300b60b924c33a5c0814aa281d09041d90d2773d 100644 --- a/wax-prosemirror-components/src/components/images/ImageUpload.js +++ b/wax-prosemirror-components/src/components/images/ImageUpload.js @@ -21,7 +21,7 @@ const ImageUpload = ({ item, fileUpload, view }) => { const inputRef = useRef(null); const placeholderPlugin = app.PmPlugins.get('imagePlaceHolder'); - const imageServiceConfig = app.config.get('config.ImageServie'); + const imageServiceConfig = app.config.get('config.ImageService'); const handleMouseDown = () => { if (imageServiceConfig && imageServiceConfig.handleAssetManager) { diff --git a/wax-prosemirror-components/src/components/images/Upload.js b/wax-prosemirror-components/src/components/images/Upload.js index faaacc0e55657b1e0b8886d0f002d225d625be08..b85deed1ec74864867f863742452e7358082dd1d 100644 --- a/wax-prosemirror-components/src/components/images/Upload.js +++ b/wax-prosemirror-components/src/components/images/Upload.js @@ -30,7 +30,7 @@ const insertImage = (urls, view, placeholderPlugin) => { pos, pos, view.state.schema.nodes.image.create({ - src: urls[i], + src: urls[i].source, }), ) .setMeta(placeholderPlugin, { remove: { id } }), diff --git a/wax-prosemirror-components/src/components/specialCharacters/SpecialCharactersTool.js b/wax-prosemirror-components/src/components/specialCharacters/SpecialCharactersTool.js index 4576c95337ed4353b835a4560a9dc1c27fab3e72..2f5d74d33835c49747a8c351cc8a550796d435e1 100644 --- a/wax-prosemirror-components/src/components/specialCharacters/SpecialCharactersTool.js +++ b/wax-prosemirror-components/src/components/specialCharacters/SpecialCharactersTool.js @@ -62,7 +62,7 @@ const SpecialCharactersTool = ({ view = {}, item }) => { )} </Wrapper> ), - [isOpen], + [isOpen, isDisabled], ); return MemorizedDropdown; diff --git a/wax-prosemirror-components/src/components/trackChanges/TrackChangeOptionsComponent.js b/wax-prosemirror-components/src/components/trackChanges/TrackChangeOptionsComponent.js index ae95ecb265d236b97de8b47033bdc942ab1edab2..7f4a06f437fc1db058fa9b2714544a3e0406982d 100644 --- a/wax-prosemirror-components/src/components/trackChanges/TrackChangeOptionsComponent.js +++ b/wax-prosemirror-components/src/components/trackChanges/TrackChangeOptionsComponent.js @@ -108,7 +108,7 @@ const AcceptRejectAllControls = styled.div` position: absolute; right: 207px; transform-origin: 50% 50% 0px; - width: 200px; + width: 209px; z-index: 9999; `; diff --git a/wax-prosemirror-core/package.json b/wax-prosemirror-core/package.json index b75e41b66938d4a5a889294b8d28aecf5c0e75cd..a24cafd744f092299207c30a7484217537673542 100644 --- a/wax-prosemirror-core/package.json +++ b/wax-prosemirror-core/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror core", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ], diff --git a/wax-prosemirror-core/src/WaxView.js b/wax-prosemirror-core/src/WaxView.js index 2ca97051b8ea6f06733d73d017d025f2e05d9830..b195a3a641ec5b3c501102474cd78341887b4b8f 100644 --- a/wax-prosemirror-core/src/WaxView.js +++ b/wax-prosemirror-core/src/WaxView.js @@ -1,4 +1,4 @@ -import React, { useRef, useContext, useCallback } from 'react'; +import React, { useRef, useContext, useCallback, useMemo } from 'react'; import applyDevTools from 'prosemirror-dev-tools'; import { EditorState } from 'prosemirror-state'; @@ -12,60 +12,61 @@ import transformPasted from './helpers/TransformPasted'; export default props => { const { readonly, onBlur, options, debug, autoFocus, user } = props; - const editorRef = useRef(); let view; const context = useContext(WaxContext); - const setEditorRef = useCallback(node => { - if (editorRef.current) { - // this is where you do cleanup if you have to. the editorRef.current will - // still point to the old ref, the old node. so you have some time here to - // clean up the unmount if you need to. - } - - if (node) { - view = new EditorView( - { mount: node }, - { - editable: () => !readonly, - state: EditorState.create(options), - dispatchTransaction, - user, - scrollMargin: 200, - scrollThreshold: 200, - handleDOMEvents: { - blur: onBlur - ? view => { - onBlur(view.state.doc.content); - } - : null, + const setEditorRef = useCallback( + node => { + if (editorRef.current) { + // this is where you do cleanup if you have to. the editorRef.current will + // still point to the old ref, the old node. so you have some time here to + // clean up the unmount if you need to. + } + if (node) { + view = new EditorView( + { mount: node }, + { + editable: () => !readonly, + state: EditorState.create(options), + dispatchTransaction, + user, + scrollMargin: 200, + scrollThreshold: 200, + handleDOMEvents: { + blur: onBlur + ? view => { + onBlur(view.state.doc.content); + } + : null, + }, + transformPasted: slice => { + return transformPasted(slice, view); + }, + attributes: { + spellcheck: 'false', + }, }, - transformPasted: slice => { - return transformPasted(slice, view); - }, - attributes: { - spellcheck: 'false', - }, - }, - ); + ); - context.updateView( - { - main: view, - }, - 'main', - ); - if (debug) applyDevTools(view); - if (autoFocus) - setTimeout(() => { - view.focus(); - }, 1000); + context.updateView( + { + main: view, + }, + 'main', + ); + if (debug) applyDevTools(view); + if (autoFocus) + setTimeout(() => { + view.focus(); + }, 1000); - return () => view.destroy(); - } - editorRef.current = node; - }, []); + return () => view.destroy(); + } + editorRef.current = node; + }, + [readonly], + ); const dispatchTransaction = transaction => { const { TrackChange } = props; @@ -94,7 +95,11 @@ export default props => { }; const editor = <div ref={setEditorRef} />; - return props.children({ - editor, - }); + return useMemo( + () => + props.children({ + editor, + }), + [readonly], + ); }; diff --git a/wax-prosemirror-plugins/package.json b/wax-prosemirror-plugins/package.json index 449d80aa68045e710649f784d27518bd48a03d6f..f1e9e5afc62ebd16bbd0eb2aba02cbfb05b99144 100644 --- a/wax-prosemirror-plugins/package.json +++ b/wax-prosemirror-plugins/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror plugins", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ], diff --git a/wax-prosemirror-schema/package.json b/wax-prosemirror-schema/package.json index 0efa3837880c961ea9993c8165ec8d9e02148067..b3a25ac2e5143631dba069cd30d5a1d04e6d1fbc 100644 --- a/wax-prosemirror-schema/package.json +++ b/wax-prosemirror-schema/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror schema", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ], diff --git a/wax-prosemirror-schema/src/marks/customTagInlineMark.js b/wax-prosemirror-schema/src/marks/customTagInlineMark.js index f11a0ef973aabedf369ddf07c46e5c144b3ba9a4..62acd1dd0c9a06f51ef53b3c832a5b03140bc143 100644 --- a/wax-prosemirror-schema/src/marks/customTagInlineMark.js +++ b/wax-prosemirror-schema/src/marks/customTagInlineMark.js @@ -1,16 +1,18 @@ const customtagInline = { attrs: { class: { default: null }, - tagNames: { default: [] }, + tags: [], + type: { default: 'inline' }, }, inclusive: false, parseDOM: [ { - tag: 'custom-tag-inline', + tag: 'span[data-type="inline"]', getAttrs(hook, next) { Object.assign(hook, { class: hook.dom.getAttribute('class'), - tagNames: JSON.parse(hook.dom.dataset.tagNames), + tags: JSON.parse(hook.dom.dataset.tags), + type: hook.dom.dataset.type, }); next(); }, @@ -19,10 +21,11 @@ const customtagInline = { toDOM(hook, next) { // eslint-disable-next-line no-param-reassign hook.value = [ - 'custom-tag-inline', + 'span', { class: hook.node.attrs.class, - 'data-tagNames': JSON.stringify(hook.node.attrs.tagNames), + 'data-type': hook.node.attrs.type, + 'data-tags': JSON.stringify(hook.node.attrs.tags), }, ]; next(); diff --git a/wax-prosemirror-schema/src/nodes/customBlockNode.js b/wax-prosemirror-schema/src/nodes/customBlockNode.js index 86d3bc95d53bc0f617c26803f807d8485f7cc661..076af0ef7daac842f1ebcfd2cfd131ee7648a952 100644 --- a/wax-prosemirror-schema/src/nodes/customBlockNode.js +++ b/wax-prosemirror-schema/src/nodes/customBlockNode.js @@ -5,21 +5,27 @@ const customBlockNode = { defining: true, attrs: { class: { default: '' }, + type: { default: 'block' }, }, parseDOM: [ { - tag: 'custom-tag-block', + tag: 'p[data-type="block"]', getAttrs(hook, next) { Object.assign(hook, { class: hook.dom.getAttribute('class'), + type: hook.dom.dataset.type, }); next(); }, }, ], toDOM(hook, next) { - const attrs = { class: hook.attrs.class }; - return (hook.value = ['custom-tag-block', attrs, 0]); + const attrs = { + class: hook.node.attrs.class, + 'data-type': hook.node.attrs.type, + }; + hook.value = ['p', attrs, 0]; + next(); }, }; diff --git a/wax-prosemirror-services/package.json b/wax-prosemirror-services/package.json index 59707d754e6aa99c5c1837cd3d06d2ee934fe22b..fa47bb8b6075484bd19219d076cc8f9af96a1cbc 100644 --- a/wax-prosemirror-services/package.json +++ b/wax-prosemirror-services/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror services", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ], diff --git a/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockService.js b/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockService.js index a867b59b87a1b45e0ad5781d48e6ad04589c424e..e4792a3e27af8bf65fcd8bebede1c964b67b1182 100644 --- a/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockService.js +++ b/wax-prosemirror-services/src/CustomTagService/CustomTagBlockService/CustomTagBlockService.js @@ -6,9 +6,12 @@ class CustomTagBlockService extends Service { register() { this.container.bind('CustomTagBlockTool').to(CustomTagBlockTool); const createNode = this.container.get('CreateNode'); - createNode({ - customTagBlock: customBlockNode, - }); + createNode( + { + customTagBlock: customBlockNode, + }, + { toWaxSchema: true }, + ); } } diff --git a/wax-prosemirror-utilities/package.json b/wax-prosemirror-utilities/package.json index 17e0357d04ccff5d64e4558d713e9b3fa074d8f3..c3155805c8b2077296de697f7f26c548c5fb0edf 100644 --- a/wax-prosemirror-utilities/package.json +++ b/wax-prosemirror-utilities/package.json @@ -4,7 +4,7 @@ "version": "0.0.30", "description": "Wax prosemirror utilities", "license": "MIT", - "main": "index.js", + "main": "dist/index.js", "files": [ "dist" ],