diff --git a/editors/editoria/src/Editoria.js b/editors/editoria/src/Editoria.js index 8bad7ed11b5377d51501935b08ff0228434438d5..c06b17c1da39976f00ae28db51471035178e103b 100644 --- a/editors/editoria/src/Editoria.js +++ b/editors/editoria/src/Editoria.js @@ -52,6 +52,7 @@ const Editoria = () => ( layout={EditoriaLayout} user={user} /> + <div id="editors"></div> </Fragment> ); diff --git a/editors/editoria/src/index.js b/editors/editoria/src/index.js index 0e2c96f0f74dab0d06a89ae7a46b098a57629470..76ceac7b96749074afe72a73fccd90a17e127561 100644 --- a/editors/editoria/src/index.js +++ b/editors/editoria/src/index.js @@ -2,7 +2,8 @@ import React from "react"; import ReactDOM from "react-dom"; import Editoria from "./Editoria"; import * as serviceWorker from "./serviceWorker"; - +const { whyDidYouUpdate } = require("why-did-you-update"); +whyDidYouUpdate(React); ReactDOM.render(<Editoria />, document.getElementById("root")); // If you want your app to work offline and load faster, you can change diff --git a/wax-prosemirror-components/src/components/Button.js b/wax-prosemirror-components/src/components/Button.js index c8034b1b9beab6743b38c29ed499da833f2e60fc..ad3c1ec9a820d2ba1ee9a3060767ae10b2200092 100644 --- a/wax-prosemirror-components/src/components/Button.js +++ b/wax-prosemirror-components/src/components/Button.js @@ -15,20 +15,22 @@ const ButtonStyled = styled.button` } `; -const Button = ({ view = {}, item }) => ( - <ButtonStyled - type="button" - isActive={item.active && item.active(view.state)} - title={item.title} - disabled={item.enable && !item.enable(view.state)} - onMouseDown={e => { - e.preventDefault(); - item.run(view.state, view.dispatch); - }} - select={item.select && item.select(view.state)} - > - {item.content} - </ButtonStyled> -); +const Button = ({ view = {}, item }) => { + return ( + <ButtonStyled + type="button" + isActive={item.active && item.active(view.state)} + title={item.title} + disabled={item.enable && !item.enable(view.state)} + onMouseDown={e => { + e.preventDefault(); + item.run(view.state, view.dispatch); + }} + select={item.select && item.select(view.state)} + > + {item.content} + </ButtonStyled> + ); +}; export default Button; diff --git a/wax-prosemirror-components/src/components/Overlay.js b/wax-prosemirror-components/src/components/Overlay.js index 7268593601742cdecab649ab2bd7b2d6c28f58c8..d894e957b3719e57b525b446d525d939a75e8716 100644 --- a/wax-prosemirror-components/src/components/Overlay.js +++ b/wax-prosemirror-components/src/components/Overlay.js @@ -1,6 +1,5 @@ import React from "react"; import styled from "styled-components"; - const OverlayContainer = styled.div` position: absolute; top: 10px; diff --git a/wax-prosemirror-core/index.js b/wax-prosemirror-core/index.js index f4f9f0f296feeb9a3af54636b9e6a38a8d87a864..3b761a2640914a896c09c25399aeefae9447f7bb 100644 --- a/wax-prosemirror-core/index.js +++ b/wax-prosemirror-core/index.js @@ -1,2 +1,4 @@ export { default as Wax } from "./src/Wax"; export { default as Service } from "./src/services/Service"; +export { default as WaxContext } from "./src/ioc-react"; +export { default as componentPlugin } from "./src/services/LayoutService/components/componentPlugin"; diff --git a/wax-prosemirror-core/src/Application.js b/wax-prosemirror-core/src/Application.js index 54f0b4fb0e4f36724da11c712d2127e9beff0622..bc376c346905e53de0d6d1077f178b878bdc2d18 100644 --- a/wax-prosemirror-core/src/Application.js +++ b/wax-prosemirror-core/src/Application.js @@ -25,6 +25,10 @@ export default class Application { */ service.setApp(this); + if (service.dependencies) { + this.config.pushToArray("services", service.dependencies); + } + if (service.register) { service.register(); } diff --git a/wax-prosemirror-core/src/Wax.js b/wax-prosemirror-core/src/Wax.js index 0bc808b5ff2e521f3b99aa6e50cb485267bc8802..44947d8219097c3788303485020d231b08f20bae 100644 --- a/wax-prosemirror-core/src/Wax.js +++ b/wax-prosemirror-core/src/Wax.js @@ -43,7 +43,6 @@ class Wax extends Component { super(props); this.application = Application.create(props); const schema = this.application.getSchema(); - console.log(schema); this.application.bootServices(); const { value, onChange } = this.props; @@ -95,28 +94,27 @@ class Wax extends Component { if (layout) { Layout.setLayout(layout); } + const WaxRender = Layout.layoutComponent; return ( <LayoutWrapper className={`${className}`}> - <WaxView - autoFocus={autoFocus} - readonly={readonly} - options={this.WaxOptions} - placeholder={placeholder} - fileUpload={fileUpload} - onBlur={onBlur || (value => true)} - onChange={this.onChange || (value => true)} - debug={debug} - TrackChange={TrackChange} - user={user} - > - {({ view, editor }) => ( - <WaxProvider view={view} app={this.application}> - <WaxRender editor={editor} /> - </WaxProvider> - )} - </WaxView> + <WaxProvider app={this.application}> + <WaxView + autoFocus={autoFocus} + readonly={readonly} + options={this.WaxOptions} + placeholder={placeholder} + fileUpload={fileUpload} + onBlur={onBlur || (value => true)} + onChange={this.onChange || (value => true)} + debug={debug} + TrackChange={TrackChange} + user={user} + > + {({ editor }) => <WaxRender editor={editor} />} + </WaxView> + </WaxProvider> </LayoutWrapper> ); } diff --git a/wax-prosemirror-core/src/WaxView.js b/wax-prosemirror-core/src/WaxView.js index da000c45c2fb82e38e9b8305f4d9281ee3415762..fe75f8dba063abdf6f15f849c0b75a18877b6c48 100644 --- a/wax-prosemirror-core/src/WaxView.js +++ b/wax-prosemirror-core/src/WaxView.js @@ -1,4 +1,11 @@ -import React, { Component } from "react"; +import React, { + useEffect, + useState, + useRef, + useContext, + Component +} from "react"; +import ReactDOM from "react-dom"; import applyDevTools from "prosemirror-dev-tools"; import { EditorState } from "prosemirror-state"; @@ -6,55 +13,49 @@ import { EditorView } from "prosemirror-view"; import "prosemirror-view/style/prosemirror.css"; import trackedTransaction from "./track-changes/trackedTransaction"; - -class WaxView extends Component { - constructor(props) { - super(props); - const { readonly, onBlur } = this.props; - const { options } = props; - this.editorRef = React.createRef(); - - // Create view of Editor - this.view = new EditorView(null, { - editable: () => !readonly, - state: EditorState.create(options), - dispatchTransaction: this.dispatchTransaction, - handleDOMEvents: { - blur: onBlur - ? view => { - onBlur(view.state.doc.content); - } - : null +import { WaxContext } from "./ioc-react"; + +export default props => { + const { readonly, onBlur, options, debug, autoFocus, WaxRender } = props; + const editorRef = useRef(); + + const context = useContext(WaxContext); + + useEffect(() => { + const view = new EditorView( + { mount: editorRef.current }, + { + editable: () => !readonly, + state: EditorState.create(options), + dispatchTransaction: transaction => { + const { TrackChange } = props; + const tr = TrackChange + ? trackedTransaction(transaction, view.state, this) + : transaction; + + const state = view.state.apply(tr); + view.updateState(state); + context.updateView({ view }); + + props.onChange(state.doc.content); + }, + handleDOMEvents: { + blur: onBlur + ? view => { + onBlur(view.state.doc.content); + } + : null + } } - }); - } - - componentDidMount() { - const { autoFocus, debug } = this.props; - this.editorRef.current.appendChild(this.view.dom); - - if (debug) applyDevTools(this.view); - if (autoFocus) this.view.focus(); - } - - dispatchTransaction = transaction => { - const { TrackChange } = this.props; - const tr = TrackChange - ? trackedTransaction(transaction, this.view.state, this) - : transaction; - const state = this.view.state.apply(tr); - this.view.updateState(state); - this.props.onChange(state.doc.content); - this.forceUpdate(); - }; - - render() { - const editor = <span ref={this.editorRef} />; - return this.props.children({ - view: this.view, - editor - }); - } -} - -export default WaxView; + ); + context.updateView({ view }); + + if (debug) applyDevTools(view); + if (autoFocus) view.focus(); + }, []); + + const editor = <div ref={editorRef}></div>; + return props.children({ + editor + }); +}; diff --git a/wax-prosemirror-core/src/config/defaultConfig.js b/wax-prosemirror-core/src/config/defaultConfig.js index 97d6d7b29e25e1f7cfc66496813a7b059a436f6c..5d4e5f56cab64962198f09ad5d791f71390e5774 100644 --- a/wax-prosemirror-core/src/config/defaultConfig.js +++ b/wax-prosemirror-core/src/config/defaultConfig.js @@ -10,7 +10,8 @@ import { ShortCutsService, TextStyleService, InlineAnnotationsService, - LinkService + LinkService, + OverlayService } from "wax-prosemirror-services"; export default { @@ -27,5 +28,6 @@ export default { new ImageService(), new InlineAnnotationsService(), new LinkService() + // new OverlayService() ] }; diff --git a/wax-prosemirror-core/src/ioc-react.js b/wax-prosemirror-core/src/ioc-react.js index 53e818b2ee11903ce0bdc2603ab6e90dc331d299..aa4ea9ae3194e5914281726a95da10a02c1305e8 100644 --- a/wax-prosemirror-core/src/ioc-react.js +++ b/wax-prosemirror-core/src/ioc-react.js @@ -1,14 +1,65 @@ -import React, { useContext } from "react"; +import React, { useContext, useState } from "react"; -const WaxContext = React.createContext({ view: null, app: null }); +export const WaxContext = React.createContext({ + view: null, + app: null, + updateView: null +}); -export default props => ( - <WaxContext.Provider value={{ app: props.app, view: props.view }}> - {props.children} - </WaxContext.Provider> -); +// export default class WaxContextComponent extends Component { +// constructor(props) { +// super(props); +// console.log("tesss"); +// this.state = { +// app: props.app, +// view: props.view, +// updateView: view => { +// this.setState(view); +// } +// }; +// } -export function useInjection(identifier) { +// componentWillReceiveProps(next, prev) { +// console.log(next, prev); +// } + +// render() { +// console.log("provider"); +// return ( +// <WaxContext.Provider +// value={{ +// app: this.state.app, +// view: this.state.view, +// updateView: this.state.updateView +// }} +// > +// {this.props.children} +// </WaxContext.Provider> +// ); +// } +// } + +export default props => { + const [context, setContext] = useState({ + app: props.app, + view: props.view, + updateView: view => { + setContext({ ...context, view: view }); + } + }); + + return ( + <WaxContext.Provider + value={{ + ...context + }} + > + {props.children} + </WaxContext.Provider> + ); +}; + +export const useInjection = identifier => { const { app: { container }, view @@ -21,4 +72,4 @@ export function useInjection(identifier) { return container.isBound(identifier) ? { view, instance: container.get(identifier) } : null; -} +}; diff --git a/wax-prosemirror-core/src/services/LayoutService/components/LayoutFactory.js b/wax-prosemirror-core/src/services/LayoutService/components/LayoutFactory.js index 1134a27eaee1f042bcb6b056c93d0cb84272faa1..776982f7b6ae1a8245011e603c0d1471d676b222 100644 --- a/wax-prosemirror-core/src/services/LayoutService/components/LayoutFactory.js +++ b/wax-prosemirror-core/src/services/LayoutService/components/LayoutFactory.js @@ -1,6 +1,3 @@ import React from "react"; -import componentPlugin from "./componentPlugin"; -export default Component => props => ( - <Component componentPlugin={componentPlugin} {...props} /> -); +export default Component => props => <Component {...props} />; diff --git a/wax-prosemirror-core/src/services/LayoutService/components/componentPlugin.js b/wax-prosemirror-core/src/services/LayoutService/components/componentPlugin.js index 040a70c15fd771e4a8061dcacd47cfaaece4fabd..79308d99547e191643f89b379796f8ad0b3bd49a 100644 --- a/wax-prosemirror-core/src/services/LayoutService/components/componentPlugin.js +++ b/wax-prosemirror-core/src/services/LayoutService/components/componentPlugin.js @@ -1,6 +1,22 @@ -import React from "react"; +import React, { Component } from "react"; import { useInjection } from "../../../ioc-react"; -import { v4 as uuid } from "uuid"; +class UpdateView extends Component { + constructor(props) { + super(props); + + this.state = { + view: this.props.view + }; + } + + updateView(view) { + this.setState(view); + } + + render() { + return this.props.children({ view: this.state.view }); + } +} const ComponentPlugin = renderArea => props => { const { view, instance } = useInjection("Layout"); @@ -8,8 +24,8 @@ const ComponentPlugin = renderArea => props => { const components = instance.render(renderArea); return components - ? components.map(Component => { - return <Component view={view} key={uuid()} />; + ? components.map((Component, key) => { + return <Component view={view} key={`${renderArea}-${key}`} />; }) : null; }; diff --git a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js index b2f7ee15a2f7352c41645916377ce190858dc2b7..2ee3917ef7885cd48c5f63b7fc15749bec5abd16 100644 --- a/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js +++ b/wax-prosemirror-layouts/src/layouts/EditoriaLayout.js @@ -1,6 +1,7 @@ -import React from "react"; +import React, { useMemo, Component } from "react"; import styled, { ThemeProvider } from "styled-components"; import { InfoArea } from "wax-prosemirror-components"; +import { componentPlugin, Service } from "wax-prosemirror-core"; import EditorElements from "./EditorElements"; import { cokoTheme } from "wax-prosemirror-themes"; @@ -78,24 +79,26 @@ const SideMenuInner = styled.div` } `; -const EditoriaLayout = ({ editor, componentPlugin }) => { - const LeftSideBar = componentPlugin("leftSideBar"); - const RightSideBar = componentPlugin("rightSideBar"); - const TopBar = componentPlugin("topBar"); - const BottomBar = componentPlugin("bottomBar"); - const EditorOverlays = componentPlugin("editorOverlays"); +const LeftSideBar = componentPlugin("leftSideBar"); +const RightSideBar = componentPlugin("rightSideBar"); +const TopBar = componentPlugin("topBar"); +const BottomBar = componentPlugin("bottomBar"); +const EditorOverlays = componentPlugin("editorOverlays"); + +const EditoriaLayout = ({ editor }) => { + console.log("dsaasdsd"); return ( <ThemeProvider theme={cokoTheme}> <LayoutWrapper> <MainMenuContainer> <MainMenuInner> - <TopBar /> + <TopBar id="topBar" /> </MainMenuInner> </MainMenuContainer> <WaxSurfaceContainer> <SideMenuContainer> <SideMenuInner> - <LeftSideBar /> + <LeftSideBar id="leftSideBar" /> </SideMenuInner> </SideMenuContainer> <WaxSurfaceScroll className="wax-surface-scroll"> diff --git a/wax-prosemirror-services/index.js b/wax-prosemirror-services/index.js index 3a8e4b44f65b2f297fb47aa84eee55e91f561df0..388ef2f282bfcb5091c782b62d03ae71d8182657 100644 --- a/wax-prosemirror-services/index.js +++ b/wax-prosemirror-services/index.js @@ -1,26 +1,15 @@ export { default as LinkService } from "./src/LinkService/LinkService"; export { default as MenuService } from "./src/MenuService/MenuService"; -export { - default as RedoUndoService -} from "./src/RedoUndoService/RedoUndoService"; -export { - default as AnnotationService -} from "./src/AnnotationService/AnnotationService"; -export { - default as TextStyleService -} from "./src/TextStyleService/TextStyleService"; -export { - default as PlaceholderService -} from "./src/PlaceholderService/PlaceholderService"; +export { default as RedoUndoService } from "./src/RedoUndoService/RedoUndoService"; +export { default as AnnotationService } from "./src/AnnotationService/AnnotationService"; +export { default as TextStyleService } from "./src/TextStyleService/TextStyleService"; +export { default as PlaceholderService } from "./src/PlaceholderService/PlaceholderService"; export { default as ImageService } from "./src/ImageService/ImageService"; export { default as RulesService } from "./src/RulesService/RulesService"; export { default as SchemaService } from "./src/SchemaService/SchemaService"; -export { - default as ShortCutsService -} from "./src/ShortCutsService/ShortCutsService"; -export { - default as InlineAnnotationsService -} from "./src/InlineAnnotations/InlineAnnotationsService"; +export { default as ShortCutsService } from "./src/ShortCutsService/ShortCutsService"; +export { default as InlineAnnotationsService } from "./src/InlineAnnotations/InlineAnnotationsService"; +export { default as OverlayService } from "./src/OverlayService/OverlayService"; export { default as Tool } from "./src/lib/Tools"; diff --git a/wax-prosemirror-services/package.json b/wax-prosemirror-services/package.json index 65b05fccc43903426a7c38cc2cdda7e07d2be101..fcf527c1b976d41c7d43cdcb3f7bc2f7d6155ff9 100644 --- a/wax-prosemirror-services/package.json +++ b/wax-prosemirror-services/package.json @@ -9,13 +9,13 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "prosemirror-state": "^1.2.2", - "prosemirror-view": "^1.13.1", "inversify": "^5.0.1", "inversify-inject-decorators": "^3.1.0", - "reflect-metadata": "^0.1.13", - "wax-prosemirror-layouts": "^0.0.3", + "prosemirror-state": "^1.2.2", + "prosemirror-view": "^1.13.1", + "wax-prosemirror-components": "^0.0.3", "wax-prosemirror-core": "^0.0.3", - "wax-prosemirror-components": "^0.0.3" + "wax-prosemirror-layouts": "^0.0.3", + "why-did-you-update": "0.1.1" } } diff --git a/wax-prosemirror-services/src/AnnotationService/tools/TableDropDownOptions.js b/wax-prosemirror-services/src/AnnotationService/tools/TableDropDownOptions.js index 9deea97f43b9a336be4fb505ba64a18f95e33e8a..aeb6864e302ce46d18ccda2d80daf325fca48e6e 100644 --- a/wax-prosemirror-services/src/AnnotationService/tools/TableDropDownOptions.js +++ b/wax-prosemirror-services/src/AnnotationService/tools/TableDropDownOptions.js @@ -28,6 +28,7 @@ export default class TableDropDownOptions extends Tools { } renderTool(view) { + if (!view) return null; return this._isEnabled ? ( <TableDropDown key={uuid()} item={this.toJSON()} {...view} /> ) : null; diff --git a/wax-prosemirror-services/src/ImageService/Image.js b/wax-prosemirror-services/src/ImageService/Image.js index caf1a39bbae4041c314811db9f206483ed91d20e..ae04877fa07c1c848591221cdb5d495e0c7d0dbb 100644 --- a/wax-prosemirror-services/src/ImageService/Image.js +++ b/wax-prosemirror-services/src/ImageService/Image.js @@ -21,7 +21,8 @@ export default class Image extends Tools { }; } - renderTool({ view }) { + renderTool(view) { + if (!view) return null; const upload = fileUpload( view, this.config.get("fileUpload"), diff --git a/wax-prosemirror-services/src/InlineAnnotations/InlineAnnotationsService.js b/wax-prosemirror-services/src/InlineAnnotations/InlineAnnotationsService.js index 3c783c4ff5d3d3be3ff47445bc4c6dc432b8c2fc..7dde0d0c21e3dbb75b6c841ae09a4a79e5f93e92 100644 --- a/wax-prosemirror-services/src/InlineAnnotations/InlineAnnotationsService.js +++ b/wax-prosemirror-services/src/InlineAnnotations/InlineAnnotationsService.js @@ -2,9 +2,7 @@ import InlineServices from "./index"; import Service from "wax-prosemirror-core/src/services/Service"; class InlineAnnotationsService extends Service { - register() { - this.config.pushToArray("services", InlineServices); - } + dependencies = InlineServices; } export default InlineAnnotationsService; diff --git a/wax-prosemirror-services/src/LinkService/LinkComponent.js b/wax-prosemirror-services/src/LinkService/LinkComponent.js index b4f58d0117f2f972ab633e768f78dc702b4b32e0..30dc630e6a0e56dfbdf80d34a52178155ff13f4b 100644 --- a/wax-prosemirror-services/src/LinkService/LinkComponent.js +++ b/wax-prosemirror-services/src/LinkService/LinkComponent.js @@ -1,9 +1,27 @@ -import React from "react"; -export default props => { - console.log(props); - return ( - <div> - <input type="text" /> - </div> - ); -}; +import React, { Component, PureComponent } from "react"; + +class LinkComponent extends PureComponent { + // componentWillReceiveProps(nextProps) { + // console.log(nextProps, this.props); + // if (nextProps == this.props) { + // debugger; + // } + // return nextProps; + // } + + render() { + console.log("paoooooooooo", this.props); + return ( + <div> + <input + type="text" + onChange={() => { + //this.setState({ count: this.state.count + 1 }); + }} + /> + </div> + ); + } +} + +export default LinkComponent; diff --git a/wax-prosemirror-services/src/LinkService/LinkPlugin.js b/wax-prosemirror-services/src/LinkService/LinkPlugin.js deleted file mode 100644 index b555b2ddcfe7ac49dee6852459c15df969a9956e..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/LinkService/LinkPlugin.js +++ /dev/null @@ -1,40 +0,0 @@ -import React from "react"; -import { injectable, multiInject, inject, named } from "inversify"; - -const Component1 = props => <div>{props.renderArea}</div>; -const Component2 = props => <div>{props.renderArea}</div>; - -@injectable() -export default class LinkPlugin { - items = [ - { - link: "1", - link2: "3" - }, - { - link: "2", - link2: "4" - } - ]; - plugins = []; - - constructor( - //@inject("Layout") layout, - @inject("findPlugin") find, - @inject("placeholderPlugin") placeholder - ) { - this.find = find; - this.placeholder = placeholder; - - //console.log(this.find, this.placeholder); - // layout - // .addComponent("topBar", Component2) - // .addComponent("leftSideBar", Component1); - - this.initPlugins(); - } - - initPlugins() { - this.plugins = [this.placeholder(this.items[1]), this.find("s")]; - } -} diff --git a/wax-prosemirror-services/src/LinkService/LinkService.js b/wax-prosemirror-services/src/LinkService/LinkService.js index 695d9a7c4c617c3dcfb0fbef4aca08ce6423fe32..26ec61fddb66fede230bb94b8589a4566baae8b0 100644 --- a/wax-prosemirror-services/src/LinkService/LinkService.js +++ b/wax-prosemirror-services/src/LinkService/LinkService.js @@ -1,15 +1,21 @@ import Service from "wax-prosemirror-core/src/services/Service"; + import LinkComponent from "./LinkComponent"; +import LinkPlugin from "./pmPlugins/LinkPlugin"; import { linkMark } from "wax-prosemirror-schema"; import LinkTool from "./LinkTool"; +import { OverlayService } from "../.."; + +const PLUGIN_KEY = "LinkPlugin"; export default class LinkService extends Service { name = "LinkPlugin"; boot() { - //Set Layout - const layout = this.container.get("Layout"); - layout.addComponent("editorOverlays", LinkComponent); + // this.app.PmPlugins.add(PLUGIN_KEY, LinkPlugin(PLUGIN_KEY)); + + const createOverlay = this.container.get("CreateOverlay"); + createOverlay(LinkComponent); } register() { @@ -22,4 +28,6 @@ export default class LinkService extends Service { }) .whenTargetNamed("mark"); } + + dependencies = [new OverlayService()]; } diff --git a/wax-prosemirror-services/src/LinkService/pmPlugins/LinkPlugin.js b/wax-prosemirror-services/src/LinkService/pmPlugins/LinkPlugin.js new file mode 100644 index 0000000000000000000000000000000000000000..81662b72b70fc40607f1d223905d0df03349f851 --- /dev/null +++ b/wax-prosemirror-services/src/LinkService/pmPlugins/LinkPlugin.js @@ -0,0 +1,26 @@ +import { Plugin, PluginKey } from "prosemirror-state"; + +export default keyPlugin => { + const plugin_key = new PluginKey(keyPlugin); + return new Plugin({ + key: plugin_key, + state: { + init: function init() { + return { + action: "HIDE_OVERLAY" + }; + }, + apply(tr, oldState, newState, test) { + const { key } = plugin_key; + + newState[key].action = "OPEN_OVERLAY"; + // console.log("first time"); + // newState[key].action = + // newState[key].action === "OPEN_OVERLAY" + // ? "HIDE_OVERLAY" + // : "OPEN_OVERLAY"; + return this.getState(newState); + } + } + }); +}; diff --git a/wax-prosemirror-services/src/LinkService/pmPlugins/find.js b/wax-prosemirror-services/src/LinkService/pmPlugins/find.js deleted file mode 100644 index 4a6d8bbb585b54773bbfc1d3c04420d674ea70b2..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/LinkService/pmPlugins/find.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; -export const findLink = new PluginKey("findLink"); - -export default items => { - return () => - new Plugin({ - key: findLink, - state: { - init() { - return items; - } - } - }); -}; diff --git a/wax-prosemirror-services/src/LinkService/pmPlugins/placeholder.js b/wax-prosemirror-services/src/LinkService/pmPlugins/placeholder.js deleted file mode 100644 index 6ca4468e400e53805fef5356e43d531ef96135f7..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/LinkService/pmPlugins/placeholder.js +++ /dev/null @@ -1,14 +0,0 @@ -import { Plugin, PluginKey } from "prosemirror-state"; -export const placeholderLink = new PluginKey("placeholderLink"); - -export default items => { - return () => - new Plugin({ - key: placeholderLink, - state: { - init() { - return items; - } - } - }); -}; diff --git a/wax-prosemirror-services/src/MenuService/Menu.js b/wax-prosemirror-services/src/MenuService/Menu.js index 68056165ee893ffa3ae609ffd4d15f5f26033999..09c0d5c98a084437dd06932e710cb2cfaed98e8b 100644 --- a/wax-prosemirror-services/src/MenuService/Menu.js +++ b/wax-prosemirror-services/src/MenuService/Menu.js @@ -1,8 +1,9 @@ -import React from "react"; +import React, { useMemo } from "react"; import { injectable } from "inversify"; import ToolGroup from "../lib/ToolGroup"; import MenuWrapper from "./MenuWrapper"; + @injectable() export default class Menu { toolGroups = []; @@ -24,6 +25,14 @@ export default class Menu { } render() { - return view => <MenuWrapper items={this.toolGroups} view={view} />; + return ({ view }) => { + if (!view) return null; + + const Bar = useMemo( + () => <MenuWrapper items={this.toolGroups} view={{ view }} />, + [view] + ); + return <>{Bar}</>; + }; } } diff --git a/wax-prosemirror-services/src/MenuService/MenuService.js b/wax-prosemirror-services/src/MenuService/MenuService.js index 97f3e45776a6170da7cdfd57c367f785183d1aec..8a8f2a92b206d5f68b21c94b6a4bb0a2b58a28cd 100644 --- a/wax-prosemirror-services/src/MenuService/MenuService.js +++ b/wax-prosemirror-services/src/MenuService/MenuService.js @@ -45,9 +45,7 @@ export default class MenuService extends Service { tools.push(tl); } catch (error) { throw Error( - `Could not load Service ${ - tool.name - }. Please configure service through config` + `Could not load Service ${tool.name}. Please configure service through config` ); } }); diff --git a/wax-prosemirror-services/src/MenuService/MenuWrapper.js b/wax-prosemirror-services/src/MenuService/MenuWrapper.js index 6c2bf21b96a73e5fa5d6c1466236c32b38feeb4f..308e850d6d8bce66963cd233c326ae7b1e1c1848 100644 --- a/wax-prosemirror-services/src/MenuService/MenuWrapper.js +++ b/wax-prosemirror-services/src/MenuService/MenuWrapper.js @@ -1,6 +1,5 @@ import React from "react"; import styled from "styled-components"; -import { useContext } from "react"; import { map } from "lodash"; @@ -11,10 +10,12 @@ const MainMenu = styled.div` background: transparent; `; -const MainMenuBar = ({ items = [], view }) => ( - <MainMenu key="MainMenu"> - {map(items, item => item.renderTools(view))} - </MainMenu> -); +const MainMenuBar = ({ items = [], view: { view } }) => { + return ( + <MainMenu key="MainMenu"> + {map(items, item => item.renderTools(view))} + </MainMenu> + ); +}; export default MainMenuBar; diff --git a/wax-prosemirror-services/src/ModalService/ModalComponent.js b/wax-prosemirror-services/src/ModalService/ModalComponent.js new file mode 100644 index 0000000000000000000000000000000000000000..1524d87e8ed9300e5596bf96f0e345d9dc1896c2 --- /dev/null +++ b/wax-prosemirror-services/src/ModalService/ModalComponent.js @@ -0,0 +1,9 @@ +import React, { useMemo } from "react"; + +export default (Component, plugin) => ({ view }) => ( + <div> + <Component {...plugin.getState(view.state)} /> + Overlay Area + </div> +); +// diff --git a/wax-prosemirror-services/src/ModalService/ModalService.js b/wax-prosemirror-services/src/ModalService/ModalService.js new file mode 100644 index 0000000000000000000000000000000000000000..b0251439311809f117e70e25de6ecf9448e0a4d5 --- /dev/null +++ b/wax-prosemirror-services/src/ModalService/ModalService.js @@ -0,0 +1,23 @@ +import Service from "wax-prosemirror-core/src/services/Service"; +import ModalPlugin from "./pmPlugins/ModalPlugin"; +import ModalComponent from "./ModalComponent"; +const PLUGIN_KEY = "overlay"; + +export default class ModalService extends Service { + boot() { + this.app.PmPlugins.add(PLUGIN_KEY, ModalPlugin(PLUGIN_KEY)); + } + register() { + this.container.bind("CreateModal").toFactory(context => { + return (Component, pluginName) => { + const PmPlugins = context.container.get("PmPlugins"); + const plugin = PmPlugins.get(pluginName); + const layout = context.container.get("Layout"); + layout.addComponent( + "editorOverlays", + ModalComponent(Component, plugin) + ); + }; + }); + } +} diff --git a/wax-prosemirror-services/src/ModalService/pmPlugins/ModalPlugin.js b/wax-prosemirror-services/src/ModalService/pmPlugins/ModalPlugin.js new file mode 100644 index 0000000000000000000000000000000000000000..2d744579a02b21189a7c5df0e356181b7076bb3d --- /dev/null +++ b/wax-prosemirror-services/src/ModalService/pmPlugins/ModalPlugin.js @@ -0,0 +1,14 @@ +import { Plugin, PluginKey } from "prosemirror-state"; +import actions from "./actions"; +export default key => + new Plugin({ + key: new PluginKey(key), + state: { + init: function init() { + return { + action: actions.HIDE_OVERLAY + }; + }, + apply: function apply(tr) {} + } + }); diff --git a/wax-prosemirror-services/src/ModalService/pmPlugins/actions.js b/wax-prosemirror-services/src/ModalService/pmPlugins/actions.js new file mode 100644 index 0000000000000000000000000000000000000000..37467a091ba7f7bc69065e235aed2517709a63c3 --- /dev/null +++ b/wax-prosemirror-services/src/ModalService/pmPlugins/actions.js @@ -0,0 +1,4 @@ +export default { + HIDE_OVERLAY: "HIDE_OVERLAY", + SHOW_OVERLAY: "SHOW_OVERLAY" +}; diff --git a/wax-prosemirror-services/src/OverlayService/Overlay.js b/wax-prosemirror-services/src/OverlayService/Overlay.js deleted file mode 100644 index aa4f13e7de28ef2692a54b2f0214d47f4a36b865..0000000000000000000000000000000000000000 --- a/wax-prosemirror-services/src/OverlayService/Overlay.js +++ /dev/null @@ -1,6 +0,0 @@ -import { injectable } from "inversify"; - -@injectable() -export default class Overlay { - constructor() {} -} diff --git a/wax-prosemirror-services/src/OverlayService/OverlayComponent.js b/wax-prosemirror-services/src/OverlayService/OverlayComponent.js new file mode 100644 index 0000000000000000000000000000000000000000..bb0aa2016d25aed00f47393ae584f66ebf487bde --- /dev/null +++ b/wax-prosemirror-services/src/OverlayService/OverlayComponent.js @@ -0,0 +1,5 @@ +import React, { useMemo } from "react"; + +export default () => { + return <div style={{ width: "100px", height: "100px" }}>Overlay Area</div>; +}; diff --git a/wax-prosemirror-services/src/OverlayService/OverlayService.js b/wax-prosemirror-services/src/OverlayService/OverlayService.js index 0021dcd24b53905fafa913148c9a968bcee3ddcb..2785691fb5222aa13167c5e666cbc1eb3042f9cd 100644 --- a/wax-prosemirror-services/src/OverlayService/OverlayService.js +++ b/wax-prosemirror-services/src/OverlayService/OverlayService.js @@ -1,7 +1,20 @@ import Service from "wax-prosemirror-core/src/services/Service"; +import OverlayPlugin from "./pmPlugins/OverlayPlugin"; +import OverlayComponent from "./OverlayComponent"; -export default class OverlayService extends Service { - register() {} +const PLUGIN_KEY = "overlay"; +export default class OverlayService extends Service { boot() {} + + register() { + const Components = []; + this.container.bind("CreateOverlay").toFactory(context => { + return Component => { + const PmPlugins = context.container.get("PmPlugins"); + Components.push(Component); + //PmPlugins.add(PLUGIN_KEY, OverlayPlugin(Components)); + }; + }); + } } diff --git a/wax-prosemirror-services/src/OverlayService/pmPlugins/Overlay.js b/wax-prosemirror-services/src/OverlayService/pmPlugins/Overlay.js new file mode 100644 index 0000000000000000000000000000000000000000..c0e510dfe2e8c5c036fee8d1cb795db82774bff1 --- /dev/null +++ b/wax-prosemirror-services/src/OverlayService/pmPlugins/Overlay.js @@ -0,0 +1,84 @@ +import React from "react"; +import { render as renderReact } from "react-dom"; +import OverlayComponent from "../OverlayComponent"; + +export default class Overlay { + constructor(view) { + this.tooltip = document.createElement("div"); + this.tooltip.className = "fds"; + console.log(view.dom); + + view.dom.parentNode.appendChild(this.tooltip); + + this.update(view, null); + } + + render(view) { + const { state } = view; + const { doc, selection, schema } = state; + const markType = schema.marks.link; + if (!markType) return; + + const { from, to, empty } = view.state.selection; + + const start = view.coordsAtPos(from); + const end = view.coordsAtPos(to); + const box = 0; //this.tooltip.getBoundingClientRect(); + const left = Math.max((start.left + end.left) / 2, start.left + 3); + + const leftSpacing = `${left - box}px`; + const bottomSpacing = `${box - start.top}px`; + const numberOfCharactersInSelection = to - from; + + return ( + <OverlayComponent + display={empty ? "none" : undefined} + left={leftSpacing} + bottom={bottomSpacing} + > + {numberOfCharactersInSelection} + </OverlayComponent> + ); + } + + update(view, lastState) { + const { state } = view; + + const { doc, selection, schema } = state; + const markType = schema.marks.link; + if (!markType) return; + const { from, to } = selection; + + const domFound = view.domAtPos(from); + if (!domFound) { + this.destroy(); + return; + } + + // debugger; + // const anchorEl = lookUpElement(domFound.node, el => el.nodeName === "A"); + // if (!anchorEl) { + // this.destroy(); + // return; + // } + + //if (areStatesEqual(state, lastState)) return; + + // Don't do anything if the document/selection didn't change + if ( + lastState && + lastState.doc.eq(state.doc) && + lastState.selection.eq(state.selection) + ) + return; + + //const tooltipComponent = this.render(view); + console.log(view.dom); + + //renderReact(tooltipComponent, view.dom); + } + + destroy() { + //this.tooltip.remove(); + } +} diff --git a/wax-prosemirror-services/src/OverlayService/pmPlugins/OverlayPlugin.js b/wax-prosemirror-services/src/OverlayService/pmPlugins/OverlayPlugin.js new file mode 100644 index 0000000000000000000000000000000000000000..83c5da919a06fae9c448041c86cbd2d7186f1b6c --- /dev/null +++ b/wax-prosemirror-services/src/OverlayService/pmPlugins/OverlayPlugin.js @@ -0,0 +1,9 @@ +import { Plugin, PluginKey } from "prosemirror-state"; +import Overlay from "./Overlay"; +export default Components => + new Plugin({ + key: new PluginKey("test"), + view(editorView) { + return new Overlay(editorView); + } + }); diff --git a/wax-prosemirror-services/src/PlaceholderService/pmPlugins/placeholderPlugin.js b/wax-prosemirror-services/src/PlaceholderService/pmPlugins/placeholderPlugin.js index d0918b9e05bde6f588cd041e41feef0292c7ac33..805e5027592a417421549e7a78e7388e26e97a4f 100644 --- a/wax-prosemirror-services/src/PlaceholderService/pmPlugins/placeholderPlugin.js +++ b/wax-prosemirror-services/src/PlaceholderService/pmPlugins/placeholderPlugin.js @@ -9,6 +9,7 @@ export default key => return DecorationSet.empty; }, apply: function apply(tr, set) { + console.log(tr, "placeholderPLugin"); // Adjust decoration positions to changes made by the transaction set = set.map(tr.mapping, tr.doc); // See if the transaction adds or removes any placeholders diff --git a/wax-prosemirror-services/src/SchemaService/Schema.js b/wax-prosemirror-services/src/SchemaService/Schema.js index 0cb402b484fc8e28b85dc810413ad701ceafb1d2..a72582e2af85f09f3fa1f620c044c47164629d86 100644 --- a/wax-prosemirror-services/src/SchemaService/Schema.js +++ b/wax-prosemirror-services/src/SchemaService/Schema.js @@ -9,6 +9,7 @@ import { EditoriaSchema } from "wax-prosemirror-schema"; export default class Schema { _nodes = {}; _marks = {}; + prosemirrorSchema = { nodes: {}, marks: {} }; schema = null; constructor( @@ -88,6 +89,13 @@ export default class Schema { } } + addProsemirrorSchema(nodes, type) { + this.prosemirrorSchema[type] = Object.assign( + this.prosemirrorSchema[type], + nodes + ); + } + getSchema() { /* this is temporally until all of the packages moved to schemas */ if (this.schema) return this.schema; @@ -101,7 +109,11 @@ export default class Schema { for (let index in this._marks) { marks[index] = this._marks[index].toJSON(); } - this.schema = new PmPschema({ nodes, marks }); + + this.schema = new PmPschema({ + nodes: Object.assign(nodes, this.prosemirrorSchema.nodes), + marks: Object.assign(marks, this.prosemirrorSchema.marks) + }); return this.schema; } } diff --git a/wax-prosemirror-services/src/SchemaService/SchemaService.js b/wax-prosemirror-services/src/SchemaService/SchemaService.js index 3703a5215264c1354293665c9920c7f4e488a1d6..459abe2d111cd591b22f9d47ade67c844016ff2d 100644 --- a/wax-prosemirror-services/src/SchemaService/SchemaService.js +++ b/wax-prosemirror-services/src/SchemaService/SchemaService.js @@ -12,42 +12,32 @@ export default class SchemaService extends Service { .to(Schema) .inSingletonScope(); - // this.container.bind("CreateNode").toFactory(context => { - // return schemaConfig => { - // const schema = context.container.get("Schema"); - // const name = Object.keys(schemaConfig)[0]; - // const config = schemaConfig[name]; + this.container.bind("CreateNode").toFactory(context => { + return (schema, options) => { + if (options.toWaxSchema) { + context + .bind("schema") + .toConstantValue(schema) + .whenTargetNamed("node"); + } else { + const schema = context.get("Schema"); + schema.addProsemirrorSchema(schema, "nodes"); + } + }; + }); - // const node = new Node(name); - // let nd = {}; - // if ((nd = schema.has(node))) { - // nd.fromJSON(config); - // return nd; - // } else { - // node.fromJSON(config); - // schema.addSchema(node); - // return node; - // } - // }; - // }); - - // this.container.bind("CreateMark").toFactory(context => { - // return schemaConfig => { - // const schema = context.container.get("Schema"); - // const name = Object.keys(schemaConfig)[0]; - // const config = schemaConfig[name]; - - // const mark = new Mark(name); - // let mr = {}; - // if ((mr = schema.has(mark))) { - // mr.fromJSON(config); - // return mr; - // } else { - // mark.fromJSON(config); - // schema.addSchema(mark); - // return mark; - // } - // }; - // }); + this.container.bind("CreateMark").toFactory(context => { + return (schema, options) => { + if (options.toWaxSchema) { + context + .bind("schema") + .toConstantValue(schema) + .whenTargetNamed("mark"); + } else { + const schema = context.get("Schema"); + schema.addProsemirrorSchema(schema, "marks"); + } + }; + }); } } diff --git a/wax-prosemirror-services/src/lib/Tools.js b/wax-prosemirror-services/src/lib/Tools.js index de15527b7ff43de41e0c8a55bc966821d279af12..a89cf6f46d245a42b72e45ff6dc85d5d3eb88315 100644 --- a/wax-prosemirror-services/src/lib/Tools.js +++ b/wax-prosemirror-services/src/lib/Tools.js @@ -44,6 +44,7 @@ export default class Tools { } renderTool(view) { + if (!view) return null; return this._isEnabled ? ( <Button key={uuid()} item={this.toJSON()} {...view} /> ) : null;