Skip to content

Commit

Permalink
feat: sourcecode add onCodemirrorViewLoad callback prop
Browse files Browse the repository at this point in the history
  • Loading branch information
drl990114 committed Jul 22, 2024
1 parent 24972aa commit fb25176
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 31 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "rme",
"version": "0.0.65",
"version": "0.0.73",
"type": "module",
"scripts": {
"build": "yarn clear && yarn build-esbuild && yarn types",
Expand Down Expand Up @@ -177,6 +177,6 @@
"svgmoji": "^3.2.0",
"void-elements": "^3.1.0",
"yjs": "^13.6.14",
"zens": "^0.0.26"
"zens": "^0.0.32"
}
}
11 changes: 9 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import {
WysiwygThemeWrapper,
Preview,
createSourceCodeDelegate,
extractMatches,
} from '.'
import React, { FC, useLayoutEffect, useMemo, useRef, useState } from 'react'
import React, { FC, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import useDevTools from './playground/hooks/use-devtools'
import useContent from './playground/hooks/use-content'
import { DebugConsole } from './playground/components/DebugConsole'
Expand Down Expand Up @@ -54,6 +55,7 @@ function App() {
<Editor
initialType="wysiwyg"
key={contentId}
delegate={editorDelegate}
ref={editorRef}
content={content}
onChange={debounceChange}
Expand Down Expand Up @@ -106,7 +108,12 @@ function App() {
setEditorDelegate(createWysiwygDelegate())
editorRef.current?.toggleType('wysiwyg')
} else if (value === 'sourceCode') {
setEditorDelegate(createSourceCodeDelegate())
setEditorDelegate(createSourceCodeDelegate({
onCodemirrorViewLoad: (cmNodeView) => {
extractMatches(cmNodeView.cm)
console.log('cmNodeView', cmNodeView)
}
}))
editorRef.current?.toggleType('sourceCode')
} else {
editorRef.current?.toggleType('preview')
Expand Down
23 changes: 19 additions & 4 deletions src/editor/codemirror/codemirror.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@ import type { EditorSchema, EditorView, ProsemirrorNode } from '@remirror/pm'
import { exitCode } from '@remirror/pm/commands'
import { Selection, TextSelection } from '@remirror/pm/state'
import { lightTheme } from '../../editor/theme'
import type { LanguageDescription, LanguageSupport } from '@codemirror/language'
import { ensureSyntaxTree, type LanguageDescription, type LanguageSupport } from '@codemirror/language'
import { languages } from '@codemirror/language-data'
import { nanoid } from 'nanoid'
import type { LoadLanguage } from '../extensions/CodeMirror/codemirror-node-view'
import { createTheme } from './theme'
import type { CreateThemeOptions } from './theme'
import { redo, undo } from '@remirror/pm/history'
import { Tree, SyntaxNodeRef } from '@lezer/common'

const cmInstanceMap = new Map<string, MfCodemirrorView>()
const themeRef = { current: createTheme(lightTheme.codemirrorTheme as CreateThemeOptions) }
Expand All @@ -34,6 +35,22 @@ export const changeTheme = (theme: CreateThemeOptions): void => {
})
}

export const extractMatches = (view: CodeMirrorEditorView) => {
const tree: Tree | null = ensureSyntaxTree(view.state, view.state.doc.length);
const matches: any[] = [];
tree?.iterate({
from: 0,
to: view.state.doc.length,
enter: ({ type, from, to }: SyntaxNodeRef) => {
if (type.name.startsWith('ATXHeading')) {
matches.push({ from, to, value: view.state.doc.sliceString(from, to), type: type.name });
}
}
});

return matches
}

export type CreateCodemirrorOptions = {
/**
* when it is true, undo and redo will use prosemirror view.
Expand All @@ -43,7 +60,7 @@ export type CreateCodemirrorOptions = {
codemirrorEditorViewConfig?: CodeMirrorEditorViewConfig
}

class MfCodemirrorView {
export class MfCodemirrorView {
private readonly view: EditorView

private readonly getPos: () => number
Expand Down Expand Up @@ -429,5 +446,3 @@ export function computeChange(

return { from: start, to: oldEnd, text: newVal.slice(start, newEnd) }
}

export default MfCodemirrorView
15 changes: 12 additions & 3 deletions src/editor/components/SourceEditor/delegate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,29 @@ import { LineCodeMirrorExtension } from '../../extensions/CodeMirror/codemirror-
import { markdown } from '@codemirror/lang-markdown'
import { basicSetup } from '../../extensions/CodeMirror/setup'
import { CountExtension } from '@remirror/extension-count'
import { MfCodemirrorView } from '../../codemirror/codemirror'

export function createSourceCodeManager(): RemirrorManager<any> {
type CreateSourceCodeManagerOptions = {
onCodemirrorViewLoad: (cm: MfCodemirrorView) => void
}
export function createSourceCodeManager(
options?: CreateSourceCodeManagerOptions,
): RemirrorManager<any> {
return createReactManager(() => [
new CountExtension({}),
new DocExtension({ content: 'codeMirror' }),
new LineCodeMirrorExtension({
hideDecoration: true,
extensions: [basicSetup, markdown()],
onCodemirrorViewLoad: options?.onCodemirrorViewLoad,
}),
])
}

export const createSourceCodeDelegate = (): EditorDelegate<any> => {
const manager = createSourceCodeManager()
export const createSourceCodeDelegate = (
options?: CreateSourceCodeManagerOptions,
): EditorDelegate<any> => {
const manager = createSourceCodeManager(options)

const stringToDoc: StringToDoc = (content: string) => {
const schema = manager.schema
Expand Down
7 changes: 5 additions & 2 deletions src/editor/extensions/CodeMirror/codemirror-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ export const fakeIndentedLanguage = 'indent-code'
hideDecoration: false,
extensions: null,
toggleName: 'paragraph',
useProsemirrorHistoryKey: false
useProsemirrorHistoryKey: false,
onCodemirrorViewLoad: () => {}
},
staticKeys: [],
handlerKeys: [],
customHandlerKeys: []
})
export class LineCodeMirrorExtension extends NodeExtension<CodeMirrorExtensionOptions> {
private nodeview: CodeMirror6NodeView | undefined

get name() {
return 'codeMirror' as const
}
Expand Down Expand Up @@ -92,7 +94,8 @@ export class LineCodeMirrorExtension extends NodeExtension<CodeMirrorExtensionOp
toggleName: this.options.toggleName,
options: {
useProsemirrorHistoryKey: this.options.useProsemirrorHistoryKey
}
},
onCodemirrorViewLoad: this.options.onCodemirrorViewLoad
})

return this.nodeview
Expand Down
12 changes: 9 additions & 3 deletions src/editor/extensions/CodeMirror/codemirror-node-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { LanguageSupport } from '@codemirror/language'
import type { Extension as CodeMirrorExtension } from '@codemirror/state'
import type { EditorView as CodeMirrorEditorView } from '@codemirror/view'
import type { EditorView, NodeView, ProsemirrorNode } from '@remirror/pm'
import MfCodemirrorView, { CreateCodemirrorOptions } from '../../codemirror/codemirror'
import { CreateCodemirrorOptions, MfCodemirrorView } from '../../codemirror/codemirror'

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

Expand All @@ -20,14 +20,16 @@ export class CodeMirror6NodeView implements NodeView {
view,
getPos,
extensions,
options
options,
onCodemirrorViewLoad
}: {
node: ProsemirrorNode
view: EditorView
getPos: () => number
extensions: CodeMirrorExtension[] | null
options?: CreateCodemirrorOptions
toggleName: string
toggleName: string,
onCodemirrorViewLoad: (cm: MfCodemirrorView) => void
}) {
this.node = node
this.view = view
Expand All @@ -42,6 +44,10 @@ export class CodeMirror6NodeView implements NodeView {
languageName: this.languageName,
options
})

if (onCodemirrorViewLoad) {
onCodemirrorViewLoad(this.mfCodemirrorView)
}
// Create a CodeMirror instance
this.cm = this.mfCodemirrorView.cm

Expand Down
13 changes: 9 additions & 4 deletions src/editor/extensions/CodeMirror/codemirror-types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { MfCodemirrorView } from '@/editor/codemirror/codemirror'
import type { Extension as CodeMirrorExtension } from '@codemirror/state'
import type { ProsemirrorAttributes } from '@remirror/core'

Expand All @@ -7,7 +8,7 @@ export interface CodeMirrorExtensionOptions {
*
* @defaultValue false
*/
hideDecoration?: boolean;
hideDecoration?: boolean
/**
* The CodeMirror extensions to use.
*
Expand All @@ -20,19 +21,23 @@ export interface CodeMirrorExtensionOptions {
*
* @defaultValue null
*/
extensions?: CodeMirrorExtension[] | null;
extensions?: CodeMirrorExtension[] | null

/**
* The name of the node that the codeMirror block should toggle back and forth from.
*
* @defaultValue "paragraph"
*/
toggleName?: string;
toggleName?: string

/**
* @defaultValue false
*/
useProsemirrorHistoryKey?: boolean
/**
* This will return the codemirror node view instance, which is very useful in source code mode
*/
onCodemirrorViewLoad?: (cm: MfCodemirrorView) => void
}

export interface CodeMirrorExtensionAttributes extends ProsemirrorAttributes {
Expand All @@ -42,5 +47,5 @@ export interface CodeMirrorExtensionAttributes extends ProsemirrorAttributes {
*
* @defaultValue ''
*/
language?: string;
language?: string
}
2 changes: 1 addition & 1 deletion src/editor/extensions/HtmlNode/html-block-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import type { ProsemirrorNode } from 'remirror'
import { type EditorSchema } from 'remirror'
import type { EditorView as CodeMirrorEditorView } from '@codemirror/view'
import { Compartment } from '@codemirror/state'
import MfCodemirrorView from '@/editor/codemirror/codemirror'
import { MfCodemirrorView } from '@/editor/codemirror/codemirror'
import { minimalSetup } from '../CodeMirror/setup'
import { html } from '@codemirror/lang-html'

Expand Down
12 changes: 6 additions & 6 deletions src/editor/theme/WysiwygThemeWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1000,37 +1000,37 @@ export const WysiwygThemeWrapper = styled.div.attrs<WarpperProps>((p) => ({
`
return css`
& h1 {
&:hover::before {
&::before {
content: 'h1';
${style}
}
}
& h2 {
&:hover::before {
&::before {
content: 'h2';
${style}
}
}
& h3 {
&:hover::before {
&::before {
content: 'h3';
${style}
}
}
& h4 {
&:hover::before {
&::before {
content: 'h4';
${style}
}
}
& h5 {
&:hover::before {
&::before {
content: 'h5';
${style}
}
}
& h6 {
&:hover::before {
&::before {
content: 'h6';
${style}
}
Expand Down
4 changes: 4 additions & 0 deletions src/playground/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ console.log("hello world")

const defaultContent = [
`
# Exploring the Dystopian Depths of "Wool"
The world is almost ruined. None of the remaining <img src="https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg" /> people live on the surface, where deadly toxic air makes life impossible. To survive, humankind has no option but to live in a massive underground silo with numerous levels, bound by strict social rules.  <br/> <br/>Holston, the silo's sheriff, who has dedicated himself to law enforcement for years, begins the story with a profound sadness at the loss of his wife. Three years ago, she ventured out for "cleaning," a grim sentence for those who wonder what the outside world is like or dare to discuss the past. This task, essential yet fatal, involves cleaning the lenses of the silo's external cameras, offering the inhabitants a glimpse of the destroyed surface.
# hello world!
![img](https://www.gstatic.com/images/branding/googlelogo/svg/googlelogo_clr_74x24px.svg)
Expand Down
15 changes: 11 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2742,6 +2742,11 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.0.tgz#d774355e41f372d5350a4d0714abb48194a489c3"
integrity sha512-t7dhREVv6dbNj0q17X12j7yDG4bD/DHYX7o5/DbDxobP0HnGPgpRz2Ej77aL7TZT3DSw13fqUTj8J4mMnqa7WA==

"@types/lodash@^4.17.6":
version "4.17.6"
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.6.tgz#193ced6a40c8006cfc1ca3f4553444fb38f0e543"
integrity sha512-OpXEVoCKSS3lQqjx9GGGOapBeuW5eUboYHRlHP9urXPX25IKZ6AnP5ZRxtVf63iieUbsHxLn8NQ5Nlftc6yzAA==

"@types/markdown-it@^14":
version "14.1.1"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-14.1.1.tgz#06bafb7a4e3f77b62b1f308acf7df76687887e0b"
Expand Down Expand Up @@ -10295,19 +10300,21 @@ yocto-queue@^1.0.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251"
integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==

zens@^0.0.26:
version "0.0.26"
resolved "https://registry.yarnpkg.com/zens/-/zens-0.0.26.tgz#b809861a72b52fa8ae50f59216228b400dac4b86"
integrity sha512-FW/TIgBhlddmqDQhU/wXj9/2rjiEWFVpO3prdkoGkTmNnWXf6zCzLgaQIPZdfEyhmc0Y/SNRvdJCm5Z0dBypAQ==
zens@^0.0.32:
version "0.0.32"
resolved "https://registry.yarnpkg.com/zens/-/zens-0.0.32.tgz#8b334e7a3fe78a36eecf3c594e780e41d5b45778"
integrity sha512-DNTuv/AeOnXNLlq4lSgTwPwRaiyVk27/qyVB5XPwZx2ucKAlv+xqJso/CTeYGNQfLfvoR57NqtagB3XKxVTqZg==
dependencies:
"@ant-design/icons" "^5.3.7"
"@ariakit/react" "^0.4.5"
"@babel/runtime" "^7"
"@emotion/is-prop-valid" "^1.2.2"
"@floating-ui/dom" "^1.0.0"
"@types/lodash" "^4.17.6"
classnames "^2.3.0"
clsx "^2.0.0"
color "^4.2.3"
lodash "^4.17.21"
rc-image "^7.5.1"
react "^18.2.0"
react-dom "^18.2.0"
Expand Down

0 comments on commit fb25176

Please sign in to comment.