editor types, checkbox fix, baseurl fix
This commit is contained in:
parent
70535f2366
commit
7d338149f0
|
@ -1,5 +1,5 @@
|
||||||
import { schema as markdownSchema } from 'prosemirror-markdown'
|
import { schema as markdownSchema } from 'prosemirror-markdown'
|
||||||
import { Schema } from 'prosemirror-model'
|
import { NodeSpec, Schema } from 'prosemirror-model'
|
||||||
import { baseKeymap } from 'prosemirror-commands'
|
import { baseKeymap } from 'prosemirror-commands'
|
||||||
import { sinkListItem, liftListItem } from 'prosemirror-schema-list'
|
import { sinkListItem, liftListItem } from 'prosemirror-schema-list'
|
||||||
import { history } from 'prosemirror-history'
|
import { history } from 'prosemirror-history'
|
||||||
|
@ -7,6 +7,7 @@ import { dropCursor } from 'prosemirror-dropcursor'
|
||||||
import { buildKeymap } from 'prosemirror-example-setup'
|
import { buildKeymap } from 'prosemirror-example-setup'
|
||||||
import { keymap } from 'prosemirror-keymap'
|
import { keymap } from 'prosemirror-keymap'
|
||||||
import type { ProseMirrorExtension } from '../helpers'
|
import type { ProseMirrorExtension } from '../helpers'
|
||||||
|
import type OrderedMap from 'orderedmap'
|
||||||
|
|
||||||
const plainSchema = new Schema({
|
const plainSchema = new Schema({
|
||||||
nodes: {
|
nodes: {
|
||||||
|
@ -29,7 +30,7 @@ const blockquoteSchema = {
|
||||||
content: 'block+',
|
content: 'block+',
|
||||||
group: 'block',
|
group: 'block',
|
||||||
toDOM: () => ['div', ['blockquote', 0]]
|
toDOM: () => ['div', ['blockquote', 0]]
|
||||||
}
|
} as NodeSpec
|
||||||
|
|
||||||
export default (plain = false): ProseMirrorExtension => ({
|
export default (plain = false): ProseMirrorExtension => ({
|
||||||
schema: () =>
|
schema: () =>
|
||||||
|
@ -39,7 +40,7 @@ export default (plain = false): ProseMirrorExtension => ({
|
||||||
marks: plainSchema.spec.marks
|
marks: plainSchema.spec.marks
|
||||||
}
|
}
|
||||||
: {
|
: {
|
||||||
nodes: (markdownSchema.spec.nodes as any).update('blockquote', blockquoteSchema),
|
nodes: (markdownSchema.spec.nodes as OrderedMap<NodeSpec>).update('blockquote', blockquoteSchema),
|
||||||
marks: markdownSchema.spec.marks
|
marks: markdownSchema.spec.marks
|
||||||
},
|
},
|
||||||
plugins: (prev, schema) => [
|
plugins: (prev, schema) => [
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Plugin, Transaction } from 'prosemirror-state'
|
||||||
import { Fragment, Node, Schema, Slice } from 'prosemirror-model'
|
import { Fragment, Node, Schema, Slice } from 'prosemirror-model'
|
||||||
import type { ProseMirrorExtension } from '../helpers'
|
import type { ProseMirrorExtension } from '../helpers'
|
||||||
import { createMarkdownParser } from '../../markdown'
|
import { createMarkdownParser } from '../../markdown'
|
||||||
import { openPrompt } from './prompt'
|
// import { openPrompt } from './prompt'
|
||||||
|
|
||||||
const URL_REGEX = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:\d+)?(\/|\/([\w!#%&+./:=?@-]))?/g
|
const URL_REGEX = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:\d+)?(\/|\/([\w!#%&+./:=?@-]))?/g
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ const transform = (schema: Schema, fragment: Fragment) => {
|
||||||
fragment.forEach((child: Node) => {
|
fragment.forEach((child: Node) => {
|
||||||
if (child.isText) {
|
if (child.isText) {
|
||||||
let pos = 0
|
let pos = 0
|
||||||
let match: any
|
let match: RegExpExecArray
|
||||||
|
|
||||||
while ((match = URL_REGEX.exec(child.text)) !== null) {
|
while ((match = URL_REGEX.exec(child.text)) !== null) {
|
||||||
const start = match.index
|
const start = match.index
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const prefix = 'ProseMirror-prompt'
|
const prefix = 'ProseMirror-prompt'
|
||||||
|
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
export function openPrompt(options: any) {
|
export function openPrompt(options) {
|
||||||
const wrapper = document.body.appendChild(document.createElement('div'))
|
const wrapper = document.body.appendChild(document.createElement('div'))
|
||||||
wrapper.className = prefix
|
wrapper.className = prefix
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ export function openPrompt(options: any) {
|
||||||
if (wrapper.parentNode) wrapper.remove()
|
if (wrapper.parentNode) wrapper.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
const domFields: Node[] = []
|
const domFields: HTMLElement[] = []
|
||||||
options.fields.forEach((name) => {
|
options.fields.forEach((name) => {
|
||||||
domFields.push(options.fields[name].render())
|
domFields.push(options.fields[name].render())
|
||||||
})
|
})
|
||||||
|
@ -33,7 +33,7 @@ export function openPrompt(options: any) {
|
||||||
if (options.title) {
|
if (options.title) {
|
||||||
form.appendChild(document.createElement('h5')).textContent = options.title
|
form.appendChild(document.createElement('h5')).textContent = options.title
|
||||||
}
|
}
|
||||||
domFields.forEach((field: Node) => {
|
domFields.forEach((field: HTMLElement) => {
|
||||||
form.appendChild(document.createElement('div')).appendChild(field)
|
form.appendChild(document.createElement('div')).appendChild(field)
|
||||||
})
|
})
|
||||||
const buttons = form.appendChild(document.createElement('div'))
|
const buttons = form.appendChild(document.createElement('div'))
|
||||||
|
@ -77,7 +77,7 @@ export function openPrompt(options: any) {
|
||||||
if (input) input.focus()
|
if (input) input.focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValues(fields: any, domFields: any) {
|
function getValues(fields: any, domFields: HTMLElement[]) {
|
||||||
const result = Object.create(null)
|
const result = Object.create(null)
|
||||||
let i = 0
|
let i = 0
|
||||||
fields.forEarch((name) => {
|
fields.forEarch((name) => {
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { inputRules } from 'prosemirror-inputrules'
|
import { inputRules } from 'prosemirror-inputrules'
|
||||||
import type { MarkType } from 'prosemirror-model'
|
import type { MarkSpec, MarkType } from 'prosemirror-model'
|
||||||
import { markInputRule } from './mark-input-rule'
|
import { markInputRule } from './mark-input-rule'
|
||||||
import type { ProseMirrorExtension } from '../helpers'
|
import type { ProseMirrorExtension } from '../helpers'
|
||||||
|
import type OrderedMap from 'orderedmap'
|
||||||
|
|
||||||
const strikethroughRule = (nodeType: MarkType) => markInputRule(/~{2}(.+)~{2}$/, nodeType)
|
const strikethroughRule = (nodeType: MarkType) => markInputRule(/~{2}(.+)~{2}$/, nodeType)
|
||||||
|
|
||||||
|
@ -10,12 +11,12 @@ const strikethroughSchema = {
|
||||||
parseDOM: [{ tag: 'del' }],
|
parseDOM: [{ tag: 'del' }],
|
||||||
toDOM: () => ['del']
|
toDOM: () => ['del']
|
||||||
}
|
}
|
||||||
}
|
} as MarkSpec
|
||||||
|
|
||||||
export default (): ProseMirrorExtension => ({
|
export default (): ProseMirrorExtension => ({
|
||||||
schema: (prev) => ({
|
schema: (prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
marks: (prev.marks as any).append(strikethroughSchema)
|
marks: (prev.marks as OrderedMap<MarkSpec>).append(strikethroughSchema)
|
||||||
}),
|
}),
|
||||||
plugins: (prev, schema) => [
|
plugins: (prev, schema) => [
|
||||||
...prev,
|
...prev,
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { EditorState, Selection } from 'prosemirror-state'
|
import { EditorState, Selection } from 'prosemirror-state'
|
||||||
import type { Node, Schema, ResolvedPos } from 'prosemirror-model'
|
import type { Node, Schema, ResolvedPos, NodeSpec } from 'prosemirror-model'
|
||||||
import { InputRule, inputRules } from 'prosemirror-inputrules'
|
import { InputRule, inputRules } from 'prosemirror-inputrules'
|
||||||
import { keymap } from 'prosemirror-keymap'
|
import { keymap } from 'prosemirror-keymap'
|
||||||
import type { ProseMirrorExtension } from '../helpers'
|
import type { ProseMirrorExtension } from '../helpers'
|
||||||
|
import type OrderedMap from 'orderedmap'
|
||||||
|
|
||||||
export const tableInputRule = (schema: Schema) =>
|
export const tableInputRule = (schema: Schema) =>
|
||||||
new InputRule(
|
new InputRule(
|
||||||
|
@ -95,7 +96,7 @@ const tableSchema = {
|
||||||
],
|
],
|
||||||
toDOM: (node: Node) => ['th', node.attrs, 0]
|
toDOM: (node: Node) => ['th', node.attrs, 0]
|
||||||
}
|
}
|
||||||
}
|
} as NodeSpec
|
||||||
|
|
||||||
const findParentPos = ($pos: ResolvedPos, fn: (n: Node) => boolean) => {
|
const findParentPos = ($pos: ResolvedPos, fn: (n: Node) => boolean) => {
|
||||||
for (let d = $pos.depth; d > 0; d--) {
|
for (let d = $pos.depth; d > 0; d--) {
|
||||||
|
@ -174,7 +175,7 @@ const getTextSize = (n: Node) => {
|
||||||
export default (): ProseMirrorExtension => ({
|
export default (): ProseMirrorExtension => ({
|
||||||
schema: (prev) => ({
|
schema: (prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
nodes: (prev.nodes as any).append(tableSchema)
|
nodes: (prev.nodes as OrderedMap<NodeSpec>).append(tableSchema)
|
||||||
}),
|
}),
|
||||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||||
plugins: (prev, schema) => [
|
plugins: (prev, schema) => [
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
import { DOMOutputSpec, DOMSerializer, Node as ProsemirrorNode, NodeType, Schema } from 'prosemirror-model'
|
import { DOMOutputSpec, DOMSerializer, Node as ProsemirrorNode, NodeSpec, NodeType, Schema } from 'prosemirror-model'
|
||||||
import type { EditorView } from 'prosemirror-view'
|
import type { EditorView } from 'prosemirror-view'
|
||||||
import { wrappingInputRule , inputRules } from 'prosemirror-inputrules'
|
import { wrappingInputRule , inputRules } from 'prosemirror-inputrules'
|
||||||
import { splitListItem } from 'prosemirror-schema-list'
|
import { splitListItem } from 'prosemirror-schema-list'
|
||||||
import { keymap } from 'prosemirror-keymap'
|
import { keymap } from 'prosemirror-keymap'
|
||||||
import type { NodeViewFn, ProseMirrorExtension } from '../helpers'
|
import type { NodeViewFn, ProseMirrorExtension } from '../helpers'
|
||||||
|
import type OrderedMap from 'orderedmap'
|
||||||
|
|
||||||
const todoListRule = (nodeType: NodeType) =>
|
const todoListRule = (nodeType: NodeType) =>
|
||||||
wrappingInputRule(new RegExp('^\\[( |x)]\\s$'), nodeType, (match) => ({
|
wrappingInputRule(new RegExp('^\\[( |x)]\\s$'), nodeType, (match) => ({
|
||||||
|
@ -44,7 +45,7 @@ const todoListSchema = {
|
||||||
['div', 0]
|
['div', 0]
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
} as NodeSpec
|
||||||
|
|
||||||
class TodoItemView {
|
class TodoItemView {
|
||||||
contentDOM: Node
|
contentDOM: Node
|
||||||
|
@ -78,7 +79,7 @@ const todoListKeymap = (schema: Schema) => ({
|
||||||
export default (): ProseMirrorExtension => ({
|
export default (): ProseMirrorExtension => ({
|
||||||
schema: (prev) => ({
|
schema: (prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
nodes: (prev.nodes as any).append(todoListSchema)
|
nodes: (prev.nodes as OrderedMap<NodeSpec>).append(todoListSchema)
|
||||||
}),
|
}),
|
||||||
plugins: (prev, schema) => [
|
plugins: (prev, schema) => [
|
||||||
keymap(todoListKeymap(schema)),
|
keymap(todoListKeymap(schema)),
|
||||||
|
|
|
@ -17,9 +17,9 @@ export type NodeViewFn = (
|
||||||
decorations: Decoration[]
|
decorations: Decoration[]
|
||||||
) => NodeView
|
) => NodeView
|
||||||
|
|
||||||
export const isInitialized = (state: any) => state !== undefined && state instanceof EditorState
|
export const isInitialized = (state) => state !== undefined && state instanceof EditorState
|
||||||
|
|
||||||
export const isEmpty = (state: any) =>
|
export const isEmpty = (state) =>
|
||||||
!isInitialized(state) ||
|
!isInitialized(state) ||
|
||||||
(state.doc.childCount === 1 &&
|
(state.doc.childCount === 1 &&
|
||||||
!state.doc.firstChild.type.spec.code &&
|
!state.doc.firstChild.type.spec.code &&
|
||||||
|
|
|
@ -6,7 +6,7 @@ import { selectAll, deleteSelection } from 'prosemirror-commands'
|
||||||
import { undo as yUndo, redo as yRedo } from 'y-prosemirror'
|
import { undo as yUndo, redo as yRedo } from 'y-prosemirror'
|
||||||
import debounce from 'lodash/debounce'
|
import debounce from 'lodash/debounce'
|
||||||
import { createSchema, createExtensions, createEmptyText } from '../prosemirror/setup'
|
import { createSchema, createExtensions, createEmptyText } from '../prosemirror/setup'
|
||||||
import { State, Draft, Config, ServiceError, newState, ExtensionsProps } from './context'
|
import { State, Draft, Config, ServiceError, newState, ExtensionsProps, EditorActions } from './context'
|
||||||
import { mod } from '../env'
|
import { mod } from '../env'
|
||||||
import { serialize, createMarkdownParser } from '../markdown'
|
import { serialize, createMarkdownParser } from '../markdown'
|
||||||
import db from '../db'
|
import db from '../db'
|
||||||
|
@ -16,11 +16,12 @@ const isText = (x) => x && x.doc && x.selection
|
||||||
const isState = (x) => typeof x.lastModified !== 'string' && Array.isArray(x.drafts || [])
|
const isState = (x) => typeof x.lastModified !== 'string' && Array.isArray(x.drafts || [])
|
||||||
const isDraft = (x): boolean => x && (x.text || x.path)
|
const isDraft = (x): boolean => x && (x.text || x.path)
|
||||||
|
|
||||||
export const createCtrl = (initial: State): [Store<State>, any] => {
|
|
||||||
|
export const createCtrl = (initial: State): [Store<State>, EditorActions] => {
|
||||||
const [store, setState] = createStore(initial)
|
const [store, setState] = createStore(initial)
|
||||||
|
|
||||||
const onUndo = () => {
|
const onUndo = () => {
|
||||||
if (!isInitialized(store.text)) return
|
if (!isInitialized(store.text)) return false
|
||||||
const text = store.text as EditorState
|
const text = store.text as EditorState
|
||||||
if (store.collab?.started) {
|
if (store.collab?.started) {
|
||||||
yUndo(text)
|
yUndo(text)
|
||||||
|
@ -53,12 +54,14 @@ export const createCtrl = (initial: State): [Store<State>, any] => {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const toggleMarkdown = () => {
|
const toggleMarkdown = () => {
|
||||||
const state = unwrap(store)
|
const state = unwrap(store)
|
||||||
const editorState = store.text as EditorState
|
const editorState = store.text as EditorState
|
||||||
const markdown = !state.markdown
|
const markdown = !state.markdown
|
||||||
const selection = { type: 'text', anchor: 1, head: 1 }
|
const selection = { type: 'text', anchor: 1, head: 1 }
|
||||||
let doc: any
|
let doc
|
||||||
|
|
||||||
if (markdown) {
|
if (markdown) {
|
||||||
const lines = serialize(editorState).split('\n')
|
const lines = serialize(editorState).split('\n')
|
||||||
|
@ -178,7 +181,7 @@ export const createCtrl = (initial: State): [Store<State>, any] => {
|
||||||
const room = window.location.pathname?.slice(1).trim()
|
const room = window.location.pathname?.slice(1).trim()
|
||||||
const args = { room: room ?? undefined }
|
const args = { room: room ?? undefined }
|
||||||
const data = await db.get('state')
|
const data = await db.get('state')
|
||||||
let parsed: any
|
let parsed: State
|
||||||
if (data !== undefined) {
|
if (data !== undefined) {
|
||||||
try {
|
try {
|
||||||
parsed = JSON.parse(data)
|
parsed = JSON.parse(data)
|
||||||
|
|
|
@ -89,6 +89,11 @@ export interface Draft {
|
||||||
extensions?: ProseMirrorExtension[]
|
extensions?: ProseMirrorExtension[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EditorActions {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
[key:string]: any
|
||||||
|
}
|
||||||
|
|
||||||
export class ServiceError extends Error {
|
export class ServiceError extends Error {
|
||||||
public errorObject: ErrorObject
|
public errorObject: ErrorObject
|
||||||
constructor(id: string, props: unknown) {
|
constructor(id: string, props: unknown) {
|
||||||
|
@ -97,7 +102,7 @@ export class ServiceError extends Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StateContext = createContext<[Store<State>, any]>([undefined, undefined])
|
export const StateContext = createContext<[Store<State>, EditorActions]>([undefined, undefined])
|
||||||
|
|
||||||
export const useState = () => useContext(StateContext)
|
export const useState = () => useContext(StateContext)
|
||||||
|
|
||||||
|
|
|
@ -308,7 +308,7 @@ input[type='checkbox'] {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
background: url('/icons/checkbox.svg') no-repeat;
|
// background: url('/icons/checkbox.svg') no-repeat;
|
||||||
content: '';
|
content: '';
|
||||||
height: 2rem;
|
height: 2rem;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
@ -320,7 +320,8 @@ input[type='checkbox'] {
|
||||||
|
|
||||||
&:checked + label {
|
&:checked + label {
|
||||||
&::before {
|
&::before {
|
||||||
background-image: url('/icons/checkbox-checked.svg');
|
// background-image: url('/icons/checkbox-checked.svg');
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
export const isDev = import.meta.env.MODE === 'development'
|
export const isDev = import.meta.env.MODE === 'development'
|
||||||
|
|
||||||
// export const apiBaseUrl = 'https://newapi.discours.io'
|
export const apiBaseUrl = 'https://newapi.discours.io'
|
||||||
export const apiBaseUrl = 'http://localhost:8080'
|
// export const apiBaseUrl = 'http://localhost:8000'
|
||||||
|
|
Loading…
Reference in New Issue
Block a user