diff --git a/editors/xpub/node_modules/.bin/react-app-rewired b/editors/xpub/node_modules/.bin/react-app-rewired new file mode 120000 index 0000000000000000000000000000000000000000..137c444d842340ef7269570bb5a0956f4aefb048 --- /dev/null +++ b/editors/xpub/node_modules/.bin/react-app-rewired @@ -0,0 +1 @@ +../../../../node_modules/react-app-rewired/bin/index.js \ No newline at end of file diff --git a/editors/xpub/node_modules/.bin/react-scripts b/editors/xpub/node_modules/.bin/react-scripts new file mode 120000 index 0000000000000000000000000000000000000000..34cbd3b652b5f16986fb09c5d4f80092b7b66147 --- /dev/null +++ b/editors/xpub/node_modules/.bin/react-scripts @@ -0,0 +1 @@ +../../../../node_modules/react-scripts/bin/react-scripts.js \ No newline at end of file diff --git a/wax-prosemirror-layouts/src/layouts/ComponentPlugins.js b/wax-prosemirror-layouts/src/layouts/ComponentPlugins.js new file mode 100644 index 0000000000000000000000000000000000000000..c0d0fe33312fff12d8c4c671629a52ad80daa027 --- /dev/null +++ b/wax-prosemirror-layouts/src/layouts/ComponentPlugins.js @@ -0,0 +1,16 @@ +import React from "react"; +const ComponentPlugin = props => { + const { state } = props; + const pluginComponent = state.plugins.map(plugin => { + if (state[plugin.key] && state[plugin.key].component) { + const Component = state[plugin.key].component; + return <Component {...props} />; + } + return null; + }); + + console.log(pluginComponent); + return pluginComponent[11]; +}; + +export default ComponentPlugin; diff --git a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js index 5f4c4dd0b2a36558bf455bba44e8d0b632ed3a47..c632c186cc740c172530e45c706087ea3c5633ec 100644 --- a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js +++ b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js @@ -3,6 +3,7 @@ import React, { Fragment } from "react"; import { MainMenuBar, SideMenuBar, InfoArea } from "wax-prosemirror-components"; import EditorElements from "./EditorElements"; import { cokoTheme } from "wax-prosemirror-themes"; +import ComponentPlugins from "./ComponentPlugins"; const LayoutWrapper = styled.div` display: flex; @@ -44,6 +45,7 @@ const EditoriaLayout = ({ editor, view, ...props }) => ( <SideMenuBar view={view} {...props} /> <WaxSurfaceScroll className="wax-surface-scroll"> {editor} + <ComponentPlugins state={view.state} /> </WaxSurfaceScroll> </WaxSurfaceContainer> <InfoArea /> diff --git a/wax-prosemirror-plugins/index.js b/wax-prosemirror-plugins/index.js index 71af7e529ce957df1da80b7e1e382146e21b738f..63187147cfaba7d82279d568351509d357052d5d 100644 --- a/wax-prosemirror-plugins/index.js +++ b/wax-prosemirror-plugins/index.js @@ -1,3 +1,4 @@ export { default as TrackChangePlugin } from "./src/trackChanges/TrackChangePlugin"; +export { default as FindAndReplacePlugin } from "./src/FindAndReplacePlugin"; diff --git a/wax-prosemirror-plugins/src/FindAndReplacePlugin.js b/wax-prosemirror-plugins/src/FindAndReplacePlugin.js new file mode 100644 index 0000000000000000000000000000000000000000..a8031dea4ee4f54acab719b660f7675fe5780036 --- /dev/null +++ b/wax-prosemirror-plugins/src/FindAndReplacePlugin.js @@ -0,0 +1,103 @@ +import ReactDOM from "react-dom"; +import React from "react"; +import { EditorState, Plugin, PluginKey } from "prosemirror-state"; +import { TextSelection } from "prosemirror-state"; +import { EditorView } from "prosemirror-view"; + +const Component = ({ state }) => { + return <div>{state.selection.from}</div>; +}; + +const findNodesWithSameMark = (doc, from, to, markType) => { + let ii = from; + const finder = mark => mark.type === markType; + let firstMark = null; + let fromNode = null; + let toNode = null; + + while (ii <= to) { + const node = doc.nodeAt(ii); + if (!node || !node.marks) { + return null; + } + const mark = node.marks.find(finder); + if (!mark) { + return null; + } + if (firstMark && mark !== firstMark) { + return null; + } + fromNode = fromNode || node; + firstMark = firstMark || mark; + toNode = node; + ii++; + } + + let fromPos = from; + let toPos = to; + + let jj = 0; + ii = from - 1; + while (ii > jj) { + const node = doc.nodeAt(ii); + const mark = node && node.marks.find(finder); + if (!mark || mark !== firstMark) { + break; + } + fromPos = ii; + fromNode = node; + ii--; + } + + ii = to + 1; + jj = doc.nodeSize - 2; + while (ii < jj) { + const node = doc.nodeAt(ii); + const mark = node && node.marks.find(finder); + if (!mark || mark !== firstMark) { + break; + } + toPos = ii; + toNode = node; + ii++; + } + + return { + mark: firstMark, + from: { + node: fromNode, + pos: fromPos + }, + to: { + node: toNode, + pos: toPos + } + }; +}; + +const WithStatePLugin = Component => ({ state }) => { + const { doc, selection, schema } = state; + const markType = schema.marks.strong; + if (!markType) { + return null; + } + const { from, to } = selection; + const result = findNodesWithSameMark(doc, from, to, markType); + return result ? <Component state={state} /> : null; +}; + +export const FindAndReplaceKey = new PluginKey("findandreplace"); + +const FindAndReplacePlugin = new Plugin({ + key: FindAndReplaceKey, + state: { + init() { + return { show: false, component: WithStatePLugin(Component) }; + }, + apply(tr, oldState, newState) { + return this.getState(newState); + } + } +}); + +export default FindAndReplacePlugin;