Skip to content

Commit

Permalink
fix(editor): codemirror multi-instance change theme
Browse files Browse the repository at this point in the history
  • Loading branch information
drl990114 committed Oct 21, 2023
1 parent ee98359 commit caa75f2
Show file tree
Hide file tree
Showing 18 changed files with 150 additions and 135 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useGlobalTheme } from "@/hooks"
import { useCommands } from "@markflowy/editor"
import { useEffect } from "react"
import { mfCodemirrorDark, mfCodemirrorLight } from '@markflowy/theme'

const useChangeCodeMirrorTheme = () => {
const { theme } = useGlobalTheme()
const commands = useCommands()

useEffect(() => {
commands.changeCodeMirrorTheme(theme)
commands.changeCodeMirrorTheme(theme === 'dark' ? mfCodemirrorDark : mfCodemirrorLight)
}, [theme, commands])
}

Expand Down
78 changes: 43 additions & 35 deletions packages/editor/src/codemirror/codemirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,39 @@ import { assertGet, isPromise, replaceNodeAtPosition } from '@remirror/core'
import type { EditorSchema, EditorView, ProsemirrorNode } from '@remirror/pm'
import { exitCode } from '@remirror/pm/commands'
import { Selection, TextSelection } from '@remirror/pm/state'
import { mfCodemirrorDark, mfCodemirrorLight } from '@/extensions/CodeMIrror'
import { mfCodemirrorLight } from '@markflowy/theme'
import type { LanguageDescription, LanguageSupport } from '@codemirror/language'
import type { LoadLanguage } from '@/extensions/CodeMIrror/codemirror-node-view'
import type { LoadLanguage } from '@/extensions/CodeMirror/codemirror-node-view'
import { languages } from '@codemirror/language-data'
import type { Extension } from '@codemirror/state'
import { nanoid } from 'nanoid'

const cmInstanceMap = new Map<string, MfCodemirrorView>()
const themeRef = { current: mfCodemirrorLight }

class MfCodemirrorView {
public cm: CodeMirrorEditorView
private readonly view: EditorView
private readonly getPos: () => number
node: ProsemirrorNode
private readonly editorTheme: Compartment
private readonly languageConf: Compartment
private readonly toggleName = 'paragraph'
private readonly schema: EditorSchema
public content = ''
private languageName: string

id = nanoid()
cm: CodeMirrorEditorView
content = ''
node: ProsemirrorNode
editorTheme: Compartment
updating = false
loadLanguage: LoadLanguage
private languageName: string

constructor({
view,
getPos,
node,
extensions = [],
languageName,
createParams = {}
createParams = {},
}: {
node: ProsemirrorNode
view: EditorView
Expand All @@ -57,7 +64,6 @@ class MfCodemirrorView {

this.content = this.node.textContent
const changeFilter = CodeMirrorEditorState.changeFilter.of((tr: CodeMirrorTransaction) => {
console.log('changeFilter', tr.docChanged, this.updating)
if (!tr.docChanged) {
this.forwardSelection()
}
Expand All @@ -71,7 +77,7 @@ class MfCodemirrorView {
keymap.of(this.codeMirrorKeymap()),
changeFilter,
this.languageConf.of([]),
this.editorTheme.of(mfCodemirrorLight),
this.editorTheme.of(themeRef.current),
...(extensions ?? []),
],
})
Expand All @@ -80,22 +86,24 @@ class MfCodemirrorView {
this.cm = new CodeMirrorEditorView({
state: startState,
dispatch: this.valueChanged.bind(this),
...createParams
...createParams,
})

cmInstanceMap.set(this.id, this)

this.updateLanguage()
}

changeTheme(theme: 'light' | 'dark'): void {
this.cm.dispatch({
effects: this.editorTheme.reconfigure(
theme === 'light' ? mfCodemirrorLight : mfCodemirrorDark,
),
changeTheme(theme: Extension): void {
themeRef.current = theme
cmInstanceMap.forEach((mfCmView) => {
mfCmView.cm.dispatch({
effects: mfCmView.editorTheme.reconfigure(theme),
})
})
}

update(node: ProsemirrorNode): boolean {
console.log('update', node.type, this.node.type)
if (node.type !== this.node.type) {
return false
}
Expand Down Expand Up @@ -147,6 +155,24 @@ class MfCodemirrorView {
this.languageName = languageName
}

destroy() {
this.cm.destroy()
cmInstanceMap.delete(this.id)
}

forwardSelection() {
if (!this.cm.hasFocus) {
return
}

const state = this.view.state
const selection = this.asProseMirrorSelection(state.doc)

if (!selection.eq(state.selection)) {
this.view.dispatch(state.tr.setSelection(selection))
}
}

private setLanguage(language: LanguageSupport) {
this.cm.dispatch({
effects: this.languageConf.reconfigure(language),
Expand All @@ -157,7 +183,6 @@ class MfCodemirrorView {

this.cm.update([tr])

console.log('valueChanged', tr.docChanged, this.updating)
if (!tr.docChanged || this.updating) {
return
}
Expand All @@ -181,21 +206,6 @@ class MfCodemirrorView {
return TextSelection.between(doc.resolve(anchor + start), doc.resolve(head + start))
}

forwardSelection() {
console.log('forwardSelection', this.cm.hasFocus, this.view.hasFocus())
if (!this.cm.hasFocus) {
return
}

const state = this.view.state
const selection = this.asProseMirrorSelection(state.doc)
console.log('forwardSelection', selection )

if (!selection.eq(state.selection)) {
this.view.dispatch(state.tr.setSelection(selection))
}
}

private codeMirrorKeymap(): CodeMirrorKeyBinding[] {
return [
{
Expand Down Expand Up @@ -277,7 +287,6 @@ class MfCodemirrorView {

const anchor = state.selection.main.anchor


const line = state.doc.lineAt(anchor)
const lineOffset = anchor - line.from

Expand Down Expand Up @@ -331,7 +340,6 @@ export function computeChange(
oldVal: string,
newVal: string,
): { from: number; to: number; text: string } | null {

if (oldVal === newVal) {
return null
}
Expand Down
6 changes: 3 additions & 3 deletions packages/editor/src/components/SourceEditor/delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { createReactManager } from '@remirror/react'
import type { StringToDoc, DocToString, EditorDelegate } from '../../types'
import { DocExtension } from 'remirror/extensions'
import type { RemirrorManager } from 'remirror'
import { LineCodeMirrorExtension } from '../../extensions/CodeMIrror/codemirror-extension'
import { LineCodeMirrorExtension } from '../../extensions/CodeMirror/codemirror-extension'
import { markdown } from '@codemirror/lang-markdown'
import { basicSetup } from '../../extensions/CodeMIrror/setup'
import { basicSetup } from '../../extensions/CodeMirror/setup'
import { CountExtension } from '@remirror/extension-count'
import { mfCodemirrorLight } from '@/extensions/CodeMIrror'
import { mfCodemirrorLight } from '@markflowy/theme'

export function createSourceCodeManager(): RemirrorManager<any> {
return createReactManager(() => [
Expand Down
85 changes: 0 additions & 85 deletions packages/editor/src/extensions/CodeMIrror/theme.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
setBlockType,
} from '@remirror/core'
import { TextSelection } from '@remirror/pm/state'

import type { Extension } from '@codemirror/state'
import { CodeMirror6NodeView } from './codemirror-node-view'
import type { CodeMirrorExtensionAttributes, CodeMirrorExtensionOptions } from './codemirror-types'
import { arrowHandler } from './codemirror-utils'
Expand Down Expand Up @@ -212,7 +212,7 @@ export class LineCodeMirrorExtension extends NodeExtension<CodeMirrorExtensionOp
}

@command()
changeCodeMirrorTheme(theme: 'light' | 'dark'): CommandFunction {
changeCodeMirrorTheme(theme: Extension): CommandFunction {
return () => {
this.nodeview?.changeTheme(theme)
return true
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import type { LanguageSupport } from '@codemirror/language'
import type { Extension as CodeMirrorExtension } from '@codemirror/state'
import { Compartment } from '@codemirror/state'
import type { EditorView as CodeMirrorEditorView } from '@codemirror/view'
import type { EditorView, NodeView, ProsemirrorNode } from '@remirror/pm'
import MfCodemirrorView from '@/codemirror/codemirror'
import type { Extension } from '@codemirror/state'

export type LoadLanguage = (lang: string) => Promise<LanguageSupport> | LanguageSupport | void

export class CodeMirror6NodeView implements NodeView {
public dom: HTMLElement
private readonly editorTheme: Compartment
private node: ProsemirrorNode
private readonly view: EditorView
private readonly getPos: () => number
Expand All @@ -32,7 +31,6 @@ export class CodeMirror6NodeView implements NodeView {
this.node = node
this.view = view
this.getPos = getPos
this.editorTheme = new Compartment()
this.languageName = ''

this.mfCodemirrorView = new MfCodemirrorView({
Expand All @@ -56,7 +54,7 @@ export class CodeMirror6NodeView implements NodeView {
return this.mfCodemirrorView.update(node)
}

changeTheme(theme: 'light' | 'dark'): void {
changeTheme(theme: Extension): void {
this.mfCodemirrorView.changeTheme(theme)
}

Expand All @@ -81,6 +79,6 @@ export class CodeMirror6NodeView implements NodeView {
}

destroy(): void {
this.cm.destroy()
this.mfCodemirrorView.destroy()
}
}
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export * from './codemirror-extension'
export * from './theme'
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { HtmlNodeView } from './html-block-view'
import type { InputRule } from '@remirror/pm/inputrules'
import { TextSelection } from '@remirror/pm/state'
import block_names from '@/markdown-it/lib/common/html_blocks'
import { arrowHandler } from '../CodeMIrror/codemirror-utils'
import { arrowHandler } from '../CodeMirror/codemirror-utils'

export class LineHtmlBlockExtension extends NodeExtension {
get name() {
Expand Down
6 changes: 5 additions & 1 deletion packages/editor/src/extensions/HtmlNode/html-block-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { type EditorSchema } from 'remirror'
import type { EditorView as CodeMirrorEditorView } from '@codemirror/view'
import { Compartment } from '@codemirror/state'
import MfCodemirrorView from '@/codemirror/codemirror'
import { minimalSetup } from '../CodeMIrror/setup'
import { minimalSetup } from '../CodeMirror/setup'
import { html } from '@codemirror/lang-html'

function removeNewlines(str: string) {
Expand Down Expand Up @@ -223,6 +223,10 @@ export class HtmlNodeView implements NodeView {
this._innerView.destroy()
this._innerView = undefined
}
if (this.mfCodemirrorView) {
this.mfCodemirrorView.destroy()
this.mfCodemirrorView = undefined
}

if (render) {
this.renderHtml()
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/extensions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { corePreset } from '@remirror/preset-core'
import { LineBlockquoteExtension } from './BlockQuote'
import { LineHardBreakExtension } from './HardBreak'
import { ReactComponentExtension } from '@remirror/react'
import { LineCodeMirrorExtension } from './CodeMIrror/codemirror-extension'
import { LineCodeMirrorExtension } from './CodeMirror/codemirror-extension'
import { LineTableExtension, LineTableRowExtension } from './Table'
import { languages } from '@codemirror/language-data'
import { LineHorizontalRuleExtension } from './HorizontalRule'
Expand Down
2 changes: 2 additions & 0 deletions packages/theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
"clear": "rimraf dist && rimraf tsconfig.tsbuildinfo"
},
"dependencies": {
"@lezer/highlight": "^1.1.6",
"@uiw/codemirror-themes": "^4.21.18",
"react": "^18.2.0",
"styled-components": "^6.0.8"
},
Expand Down
Loading

0 comments on commit caa75f2

Please sign in to comment.