diff --git a/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js b/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js index 23f882fff4cac8f825d87872079db30a19cbb8a9..ede8bc76a4bde45b5a5ce34ef9fb37639e94e667 100644 --- a/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js +++ b/wax-prosemirror-components/src/components/findAndReplace/FindComponent.js @@ -78,7 +78,6 @@ const FindComponent = ({ close, expand, setPreviousSearcValue }) => { app, view: { main }, view, - activeViewId, } = useContext(WaxContext); const { @@ -97,7 +96,7 @@ const FindComponent = ({ close, expand, setPreviousSearcValue }) => { const delayedSearch = useCallback( debounce(() => searchDocument(), 300), - [searchValue, JSON.stringify(allStates)], + [searchValue], ); const findAndReplacePlugin = app.PmPlugins.get('findAndReplacePlugin'); @@ -111,19 +110,17 @@ const FindComponent = ({ close, expand, setPreviousSearcValue }) => { }, [searchValue, delayedSearch, JSON.stringify(allStates)]); const searchDocument = () => { - console.log(activeViewId); - if (searchRef.current !== document.activeElement) { - } else { - setCounterText('0 of 0'); - const results = helpers.getMatchesByView( - view, - searchValue, - findAndReplacePlugin, - ); - if (results > 0) { - setCounterText(`1 of ${results}`); - } - } + setCounterText('0 of 0'); + let counter = 0; + findAndReplacePlugin.props.setSearchText(searchValue); + counter = helpers.getMatchesByView(view, searchValue); + + if (counter > 0) setCounterText(`1 of ${counter}`); + + each(view, (singleView, viewId) => { + singleView.dispatch(singleView.state.tr); + }); + // if (searchRef.current === document.activeElement) }; const closeFind = () => { diff --git a/wax-prosemirror-components/src/components/findAndReplace/helpers.js b/wax-prosemirror-components/src/components/findAndReplace/helpers.js index 01eda5b4b03c7b12da015e72121f635d4dc756b4..12602b236745e7b3e7e3f006681aeb76042e8cb2 100644 --- a/wax-prosemirror-components/src/components/findAndReplace/helpers.js +++ b/wax-prosemirror-components/src/components/findAndReplace/helpers.js @@ -52,16 +52,12 @@ const findMatches = (doc, searchValue) => { return results; }; -const getMatchesByView = (views, searchValue, findAndReplacePlugin) => { +const getMatchesByView = (views, searchValue) => { let allResults = 0; - eachRight(views, (singleView, viewId) => { + each(views, (singleView, viewId) => { const results = findMatches(singleView.state.doc, searchValue); allResults += results.length; - findAndReplacePlugin.props.setResults(results); - singleView.state.tr.setMeta('search', true); - singleView.dispatch(singleView.state.tr); }); - views.main.dispatch(views.main.state.tr); return allResults; }; diff --git a/wax-prosemirror-plugins/src/findAndReplace/FindAndReplacePlugin.js b/wax-prosemirror-plugins/src/findAndReplace/FindAndReplacePlugin.js index 012d4ace805429fc1e149eec712598f8c84dca83..0f66eb6abcbfcdb4361392339b7777e2827b3ca4 100644 --- a/wax-prosemirror-plugins/src/findAndReplace/FindAndReplacePlugin.js +++ b/wax-prosemirror-plugins/src/findAndReplace/FindAndReplacePlugin.js @@ -1,10 +1,63 @@ -/* eslint-disable */ import { Plugin, PluginKey } from 'prosemirror-state'; import { Decoration, DecorationSet } from 'prosemirror-view'; +import { eachRight } from 'lodash'; const findAndReplacePlugin = new PluginKey('findAndReplacePlugin'); -let allResults = []; +let searchText = ''; + +const findMatches = (doc, searchValue) => { + const allNodes = []; + + doc.descendants((node, pos) => { + allNodes.push({ node, pos }); + }); + + eachRight(allNodes, (node, index) => { + if (node.node.type.name === 'footnote') { + allNodes.splice(index + 1, node.node.childCount); + } + }); + + const results = []; + const mergedTextNodes = []; + let index = 0; + + allNodes.forEach((node, i) => { + if (node.node.isText) { + if (mergedTextNodes[index]) { + mergedTextNodes[index] = { + text: mergedTextNodes[index].text + node.node.text, + pos: mergedTextNodes[index].pos, + }; + } else { + mergedTextNodes[index] = { + text: node.node.text, + pos: node.pos, + }; + } + } else { + index += 1; + } + }); + mergedTextNodes.forEach(({ text, pos }) => { + const search = RegExp(searchValue, 'gui'); + let m; + // eslint-disable-next-line no-cond-assign + while ((m = search.exec(text))) { + if (m[0] === '') { + break; + } + + results.push({ + from: pos + m.index, + to: pos + m.index + m[0].length, + }); + } + }); + return results; +}; + export default props => { return new Plugin({ key: findAndReplacePlugin, @@ -13,12 +66,11 @@ export default props => { return DecorationSet.empty; }, apply(tr, prev, _, newState) { - let createDecoration; let decorations; let createdDecorations = DecorationSet.empty; - - if (allResults.length > 0) { - decorations = allResults.map((result, index) => { + const allMatches = findMatches(newState.doc, searchText); + if (allMatches.length > 0) { + decorations = allMatches.map((result, index) => { return Decoration.inline(result.from, result.to, { class: 'search-result', }); @@ -27,6 +79,7 @@ export default props => { } return { createdDecorations, + allMatches, }; }, }, @@ -39,6 +92,9 @@ export default props => { setResults: results => { allResults = results; }, + setSearchText: text => { + searchText = text; + }, }, view(editorState) { return { diff --git a/wax-prosemirror-services/src/NoteService/Editor.js b/wax-prosemirror-services/src/NoteService/Editor.js index cc569e9c8299fe0f5d3a458278600239979ce53a..b8bcb437df04ef465e2cce279185fb02413dcf88 100644 --- a/wax-prosemirror-services/src/NoteService/Editor.js +++ b/wax-prosemirror-services/src/NoteService/Editor.js @@ -43,9 +43,7 @@ export default ({ node, view }) => { transformPasted: slice => { return transformPasted(slice, noteView); }, - handleKeyPress: (noteEditorView, from, to, content) => { - updateMainView = false; - }, + attributes: { spellcheck: 'false', }, @@ -88,11 +86,9 @@ export default ({ node, view }) => { }); // TODO Remove timeout and use state to check if noteView has changed - if (updateMainView) { - setTimeout(() => { - context.updateView({}, noteId); - }, 20); - } + setTimeout(() => { + context.updateView({}, noteId); + }, 20); if (!tr.getMeta('fromOutside')) { const outerTr = view.state.tr; @@ -105,7 +101,6 @@ export default ({ node, view }) => { if (outerTr.docChanged) view.dispatch(outerTr.setMeta('outsideView', 'notes')); - updateMainView = true; } };