From 642d8b9dd1e6ce0e88dbe86bffd2a22294d6b891 Mon Sep 17 00:00:00 2001 From: tonyrewin Date: Wed, 19 Oct 2022 20:26:07 +0300 Subject: [PATCH] demo --- .eslintrc.js | 1 + src/components/Editor/components/Editor.tsx | 16 +- src/components/Editor/components/Error.tsx | 31 +- src/components/Editor/components/Layout.tsx | 21 +- .../Editor/components/ProseMirror.tsx | 94 ++-- src/components/Editor/components/Sidebar.tsx | 146 +++--- src/components/Editor/env.ts | 3 + src/components/Editor/markdown.ts | 39 +- .../Editor/prosemirror/extension/base.ts | 20 +- .../Editor/prosemirror/extension/code.ts | 46 +- .../Editor/prosemirror/extension/collab.ts | 23 +- .../prosemirror/extension/drag-handle.ts | 10 +- .../Editor/prosemirror/extension/image.ts | 30 +- .../Editor/prosemirror/extension/link.ts | 14 +- .../prosemirror/extension/mark-input-rule.ts | 8 +- .../Editor/prosemirror/extension/markdown.ts | 10 +- .../Editor/prosemirror/extension/menu.ts | 161 ++++--- .../prosemirror/extension/paste-markdown.ts | 8 +- .../prosemirror/extension/placeholder.ts | 2 +- .../Editor/prosemirror/extension/prompt.ts | 56 +-- .../Editor/prosemirror/extension/scroll.ts | 4 +- .../Editor/prosemirror/extension/selection.ts | 75 ++-- .../prosemirror/extension/strikethrough.ts | 6 +- .../Editor/prosemirror/extension/table.ts | 10 +- .../Editor/prosemirror/extension/todo-list.ts | 15 +- src/components/Editor/prosemirror/helpers.ts | 14 +- src/components/Editor/prosemirror/setup.ts | 105 ++--- src/components/Editor/remote.ts | 2 +- src/components/Editor/store/actions.ts | 415 +++++++----------- src/components/Editor/store/context.ts | 101 ++--- .../Editor/styles/ArticlesList.scss | 2 - src/components/Editor/styles/Button.scss | 49 +-- src/components/Editor/styles/Editor.scss | 149 +++---- src/components/Editor/styles/Error.scss | 3 +- src/components/Editor/styles/Index.scss | 3 + src/components/Editor/styles/Layout.scss | 7 +- src/components/Editor/styles/Sidebar.scss | 56 ++- 37 files changed, 810 insertions(+), 945 deletions(-) create mode 100644 src/components/Editor/env.ts create mode 100644 src/components/Editor/styles/Index.scss diff --git a/.eslintrc.js b/.eslintrc.js index 13d10867..6b46108b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -27,6 +27,7 @@ module.exports = { // 'plugin:@typescript-eslint/recommended-requiring-type-checking' ], rules: { + 'no-nested-ternary': 'off', '@typescript-eslint/no-unused-vars': [ 'warn', { diff --git a/src/components/Editor/components/Editor.tsx b/src/components/Editor/components/Editor.tsx index af8f97bc..2266b8c1 100644 --- a/src/components/Editor/components/Editor.tsx +++ b/src/components/Editor/components/Editor.tsx @@ -1,5 +1,5 @@ -import type { EditorView } from 'prosemirror-view' -import type { EditorState } from 'prosemirror-state' +import { EditorView } from 'prosemirror-view' +import { EditorState } from 'prosemirror-state' import { useState } from '../store/context' import { ProseMirror } from './ProseMirror' import '../styles/Editor.scss' @@ -9,17 +9,11 @@ export const Editor = () => { const onInit = (text: EditorState, editorView: EditorView) => ctrl.setState({ editorView, text }) const onReconfigure = (text: EditorState) => ctrl.setState({ text }) const onChange = (text: EditorState) => ctrl.setState({ text, lastModified: new Date() }) - const style = () => { - if (store.error) { - return `display: none;` - } else { - return store.markdown ? `white-space: pre-wrap;` : '' - } - } + // const editorCss = (config) => css`` + const style = () => (store.error ? `display: none;` : store.markdown ? `white-space: pre-wrap;` : '') return ( { const [store] = useState() return ( }> - + - + - - + + ) @@ -25,17 +24,19 @@ const InvalidState = (props: { title: string }) => { const onClick = () => ctrl.clean() return ( -
-
+
+

{props.title}

- {t('Editing conflict, please copy your notes and refresh page')} + There is an error with the editor state. This is probably due to an old version in which the data + structure has changed. Automatic data migrations may be supported in the future. To fix this now, + you can copy important notes from below, clean the state and paste it again.

           {JSON.stringify(store.error.props)}
         
-
@@ -47,18 +48,18 @@ const Other = () => { const onClick = () => ctrl.discard() const getMessage = () => { - const err = (store.error.props as ErrorObject['props']).error + const err = (store.error.props as any).error return typeof err === 'string' ? err : err.message } return ( -
-
+
+

An error occurred.

           {getMessage()}
         
-
diff --git a/src/components/Editor/components/Layout.tsx b/src/components/Editor/components/Layout.tsx index 29bd2532..c1742db3 100644 --- a/src/components/Editor/components/Layout.tsx +++ b/src/components/Editor/components/Layout.tsx @@ -1,19 +1,16 @@ -import type { JSX } from 'solid-js/jsx-runtime' -import type { Config } from '../store/context' +import { Config } from '../store/context' import '../styles/Layout.scss' export type Styled = { - children: JSX.Element - config?: Config - 'data-testid'?: string - onClick?: () => void - onMouseEnter?: (ev: MouseEvent) => void + children: any; + config?: Config; + 'data-testid'?: string; + onClick?: () => void; + onMouseEnter?: (e: any) => void; } export const Layout = (props: Styled) => { - return ( -
- {props.children} -
- ) + return (
+ {props.children} +
) } diff --git a/src/components/Editor/components/ProseMirror.tsx b/src/components/Editor/components/ProseMirror.tsx index b85af777..dcf23d8a 100644 --- a/src/components/Editor/components/ProseMirror.tsx +++ b/src/components/Editor/components/ProseMirror.tsx @@ -1,19 +1,19 @@ import { createEffect, untrack } from 'solid-js' import { Store, unwrap } from 'solid-js/store' -import { EditorState, EditorStateConfig, Transaction } from 'prosemirror-state' +import { EditorState, Transaction } from 'prosemirror-state' import { EditorView } from 'prosemirror-view' import { Schema } from 'prosemirror-model' -import type { NodeViewFn, ProseMirrorExtension, ProseMirrorState } from '../prosemirror/helpers' +import { NodeViewFn, ProseMirrorExtension, ProseMirrorState } from '../prosemirror/helpers' interface Props { - style?: string - className?: string - text?: Store - editorView?: Store - extensions?: Store - onInit: (s: EditorState, v: EditorView) => void - onReconfigure: (s: EditorState) => void - onChange: (s: EditorState) => void + style?: string; + className?: string; + text?: Store; + editorView?: Store; + extensions?: Store; + onInit: (s: EditorState, v: EditorView) => void; + onReconfigure: (s: EditorState) => void; + onChange: (s: EditorState) => void; } export const ProseMirror = (props: Props) => { @@ -28,39 +28,45 @@ export const ProseMirror = (props: Props) => { props.onChange(newState) } - createEffect( - (payload: [EditorState, ProseMirrorExtension[]]) => { - const [prevText, prevExtensions] = payload - const text = unwrap(props.text) - const extensions: ProseMirrorExtension[] = unwrap(props.extensions) - if (!text || !extensions?.length) { - return [text, extensions] - } - - if (!props.editorView) { - const { editorState, nodeViews } = createEditorState(text, extensions) - const view = new EditorView(editorRef, { state: editorState, nodeViews, dispatchTransaction }) - view.focus() - props.onInit(editorState, view) - return [editorState, extensions] - } - - if (extensions !== prevExtensions || (!(text instanceof EditorState) && text !== prevText)) { - const { editorState, nodeViews } = createEditorState(text, extensions, prevText) - if (!editorState) return - editorView().updateState(editorState) - editorView().setProps({ nodeViews, dispatchTransaction }) - props.onReconfigure(editorState) - editorView().focus() - return [editorState, extensions] - } - + createEffect((payload: [EditorState, ProseMirrorExtension[]]) => { + const [prevText, prevExtensions] = payload + const text: EditorState = unwrap(props.text) + const extensions: ProseMirrorExtension[] = unwrap(props.extensions) + if (!text || !extensions?.length) { return [text, extensions] - }, - [props.text, props.extensions] + } + + if (!props.editorView) { + const { editorState, nodeViews } = createEditorState(text, extensions) + const view = new EditorView(editorRef, { state: editorState, nodeViews, dispatchTransaction }) + view.focus() + props.onInit(editorState, view) + return [editorState, extensions] + } + + if (extensions !== prevExtensions || (!(text instanceof EditorState) && text !== prevText)) { + const { editorState, nodeViews } = createEditorState(text, extensions, prevText) + if (!editorState) return + editorView().updateState(editorState) + editorView().setProps({ nodeViews, dispatchTransaction }) + props.onReconfigure(editorState) + editorView().focus() + return [editorState, extensions] + } + + return [text, extensions] + }, + [props.text, props.extensions] ) - return
+ return ( +
+ ) } const createEditorState = ( @@ -68,8 +74,8 @@ const createEditorState = ( extensions: ProseMirrorExtension[], prevText?: EditorState ): { - editorState: EditorState - nodeViews: { [key: string]: NodeViewFn } + editorState: EditorState; + nodeViews: { [key: string]: NodeViewFn }; } => { const reconfigure = text instanceof EditorState && prevText?.schema let schemaSpec = { nodes: {} } @@ -95,10 +101,10 @@ const createEditorState = ( let editorState: EditorState if (reconfigure) { - editorState = text.reconfigure({ schema, plugins } as EditorStateConfig) + editorState = text.reconfigure({ schema, plugins }) } else if (text instanceof EditorState) { editorState = EditorState.fromJSON({ schema, plugins }, text.toJSON()) - } else if (text) { + } else if (text){ console.debug(text) editorState = EditorState.fromJSON({ schema, plugins }, text) } diff --git a/src/components/Editor/components/Sidebar.tsx b/src/components/Editor/components/Sidebar.tsx index 95389275..899dfbd2 100644 --- a/src/components/Editor/components/Sidebar.tsx +++ b/src/components/Editor/components/Sidebar.tsx @@ -1,23 +1,23 @@ -import { For, Show, createEffect, createSignal, onCleanup, onMount } from 'solid-js' +import { For, Show, createEffect, createSignal, onCleanup } from 'solid-js' import { unwrap } from 'solid-js/store' import { undo, redo } from 'prosemirror-history' -import { Draft, useState } from '../store/context' +import { File, useState } from '../store/context' +import { mod } from '../env' import * as remote from '../remote' -import { isEmpty /*, isInitialized*/ } from '../prosemirror/helpers' -import type { Styled } from './Layout' +import { isEmpty } from '../prosemirror/helpers' +import { Styled } from './Layout' import '../styles/Sidebar.scss' -import { t } from '../../../utils/intl' -const Off = (props) => +const Off = ({ children }: Styled) => -const Label = (props: Styled) => +const Label = (props: Styled) => const Link = ( props: Styled & { withMargin?: boolean; disabled?: boolean; title?: string; className?: string } ) => (