update codemirror
This commit is contained in:
parent
43980ae43c
commit
737014b90f
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@kevisual/codemirror",
|
"name": "@kevisual/codemirror",
|
||||||
"version": "0.0.8",
|
"version": "0.0.12",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "dist/editor.js",
|
"main": "dist/editor.js",
|
||||||
"private": false,
|
"private": false,
|
||||||
@ -27,6 +27,7 @@
|
|||||||
"@codemirror/state": "^6.5.2",
|
"@codemirror/state": "^6.5.2",
|
||||||
"@codemirror/view": "^6.36.7",
|
"@codemirror/view": "^6.36.7",
|
||||||
"codemirror": "^6.0.1",
|
"codemirror": "^6.0.1",
|
||||||
|
"eventemitter3": "^5.0.1",
|
||||||
"prettier": "^3.5.3"
|
"prettier": "^3.5.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -52,6 +53,10 @@
|
|||||||
"./json": {
|
"./json": {
|
||||||
"import": "./dist/editor.json.js",
|
"import": "./dist/editor.json.js",
|
||||||
"types": "./dist/editor.json.d.ts"
|
"types": "./dist/editor.json.d.ts"
|
||||||
|
},
|
||||||
|
"./utils": {
|
||||||
|
"import": "./dist/editor.utils.js",
|
||||||
|
"types": "./dist/editor.utils.d.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||||
import typescript from '@rollup/plugin-typescript';
|
import typescript from '@rollup/plugin-typescript';
|
||||||
|
|
||||||
const entrys = ['editor', 'editor.json', 'editor.base'];
|
const entrys = ['editor', 'editor.json', 'editor.base', 'editor.utils'];
|
||||||
const configs = entrys.map((entry) => ({
|
const configs = entrys.map((entry) => ({
|
||||||
input: `./src/${entry}.ts`, // 修改输入文件为 TypeScript 文件
|
input: `./src/${entry}.ts`, // 修改输入文件为 TypeScript 文件
|
||||||
output: {
|
output: {
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
import { EditorView, basicSetup } from 'codemirror';
|
import { basicSetup } from 'codemirror';
|
||||||
|
import { EditorView } from '@codemirror/view';
|
||||||
|
import { StateEffect } from '@codemirror/state';
|
||||||
|
import { ViewUpdate } from '@codemirror/view';
|
||||||
import { formatKeymap } from './extensions/tab';
|
import { formatKeymap } from './extensions/tab';
|
||||||
let editor: EditorView = null;
|
import EventEmitter from 'eventemitter3';
|
||||||
|
export type CodeEditor = EditorView & {
|
||||||
|
emitter?: EventEmitter;
|
||||||
|
};
|
||||||
|
let editor: CodeEditor = null;
|
||||||
|
|
||||||
export type EditorOptions = {
|
export type EditorOptions = {
|
||||||
extensions?: any[];
|
extensions?: any[];
|
||||||
hasBasicSetup?: boolean;
|
hasBasicSetup?: boolean;
|
||||||
|
onChange?: (content: string) => void;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 创建单例
|
* 创建单例
|
||||||
@ -24,12 +32,15 @@ const createEditorInstance = (el?: HTMLDivElement, opts?: EditorOptions) => {
|
|||||||
if (hasBaseicSetup) {
|
if (hasBaseicSetup) {
|
||||||
extensions.unshift(basicSetup);
|
extensions.unshift(basicSetup);
|
||||||
}
|
}
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
createOnChangeListener(emitter, opts.onChange).appendTo(extensions);
|
||||||
editor = new EditorView({
|
editor = new EditorView({
|
||||||
extensions: extensions,
|
extensions: extensions,
|
||||||
parent: el || document.body,
|
parent: el || document.body,
|
||||||
});
|
});
|
||||||
|
editor.emitter = emitter;
|
||||||
editor.dom.style.height = '100%';
|
editor.dom.style.height = '100%';
|
||||||
return editor;
|
return editor as CodeEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,13 +55,38 @@ export const createEditor = (el: HTMLDivElement, opts?: EditorOptions) => {
|
|||||||
extensions.unshift(basicSetup);
|
extensions.unshift(basicSetup);
|
||||||
}
|
}
|
||||||
extensions.push(formatKeymap);
|
extensions.push(formatKeymap);
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
createOnChangeListener(emitter, opts.onChange).appendTo(extensions);
|
||||||
const editor = new EditorView({
|
const editor = new EditorView({
|
||||||
extensions,
|
extensions,
|
||||||
parent: el || document.body,
|
parent: el || document.body,
|
||||||
});
|
}) as CodeEditor;
|
||||||
|
|
||||||
|
editor.emitter = emitter;
|
||||||
editor.dom.style.height = '100%';
|
editor.dom.style.height = '100%';
|
||||||
return editor;
|
|
||||||
|
return editor as CodeEditor;
|
||||||
};
|
};
|
||||||
export const getEditor = () => editor;
|
export const getEditor = () => editor;
|
||||||
|
|
||||||
export { editor, createEditorInstance };
|
export { editor, createEditorInstance };
|
||||||
|
|
||||||
|
export const createOnChangeListener = (emitter: EventEmitter, callback?: (content: string) => void) => {
|
||||||
|
const listener = EditorView.updateListener.of((update: ViewUpdate) => {
|
||||||
|
if (update.docChanged) {
|
||||||
|
const editor = update.view;
|
||||||
|
if (callback) {
|
||||||
|
callback(editor.state.doc.toString());
|
||||||
|
}
|
||||||
|
// 触发自定义事件
|
||||||
|
emitter.emit('change', editor.state.doc.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// 返回监听器配置,而不是直接应用它
|
||||||
|
return {
|
||||||
|
extension: listener,
|
||||||
|
appendTo: (ext: any[]) => {
|
||||||
|
ext.push(listener);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
import { EditorView, basicSetup } from 'codemirror';
|
import { basicSetup } from 'codemirror';
|
||||||
|
import { EditorView } from '@codemirror/view';
|
||||||
import { javascript } from '@codemirror/lang-javascript';
|
import { javascript } from '@codemirror/lang-javascript';
|
||||||
import { json } from '@codemirror/lang-json';
|
import { json } from '@codemirror/lang-json';
|
||||||
import { html } from '@codemirror/lang-html';
|
import { html } from '@codemirror/lang-html';
|
||||||
import { markdown } from '@codemirror/lang-markdown';
|
import { markdown } from '@codemirror/lang-markdown';
|
||||||
import { css } from '@codemirror/lang-css';
|
import { css } from '@codemirror/lang-css';
|
||||||
import { formatKeymap } from './extensions/tab';
|
import { formatKeymap } from './extensions/tab';
|
||||||
let editor: EditorView = null;
|
import { createOnChangeListener } from './editor.base';
|
||||||
|
import EventEmitter from 'eventemitter3';
|
||||||
|
|
||||||
|
export type CodeEditor = EditorView & {
|
||||||
|
emitter?: EventEmitter;
|
||||||
|
};
|
||||||
|
let editor: CodeEditor = null;
|
||||||
|
|
||||||
type CreateOpts = {
|
type CreateOpts = {
|
||||||
jsx?: boolean;
|
jsx?: boolean;
|
||||||
@ -14,6 +21,7 @@ type CreateOpts = {
|
|||||||
hasBasicSetup?: boolean;
|
hasBasicSetup?: boolean;
|
||||||
extensions?: any[];
|
extensions?: any[];
|
||||||
hasKeymap?: boolean;
|
hasKeymap?: boolean;
|
||||||
|
onChange?: (content: string) => void;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 创建单例
|
* 创建单例
|
||||||
@ -54,12 +62,15 @@ const createEditorInstance = (el?: HTMLDivElement, opts?: CreateOpts) => {
|
|||||||
extensions.push(markdown());
|
extensions.push(markdown());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
createOnChangeListener(emitter, opts.onChange).appendTo(extensions);
|
||||||
editor = new EditorView({
|
editor = new EditorView({
|
||||||
extensions: extensions,
|
extensions: extensions,
|
||||||
parent: el || document.body,
|
parent: el || document.body,
|
||||||
});
|
});
|
||||||
editor.dom.style.height = '100%';
|
editor.dom.style.height = '100%';
|
||||||
return editor;
|
editor.emitter = emitter;
|
||||||
|
return editor as CodeEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -95,12 +106,15 @@ export const createEditor = (el: HTMLDivElement, opts?: CreateOpts) => {
|
|||||||
extensions.push(markdown());
|
extensions.push(markdown());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
const emitter = new EventEmitter();
|
||||||
|
createOnChangeListener(emitter, opts.onChange).appendTo(extensions);
|
||||||
const editor = new EditorView({
|
const editor = new EditorView({
|
||||||
extensions: extensions,
|
extensions: extensions,
|
||||||
parent: el || document.body,
|
parent: el || document.body,
|
||||||
});
|
}) as CodeEditor;
|
||||||
editor.dom.style.height = '100%';
|
editor.dom.style.height = '100%';
|
||||||
return editor;
|
editor.emitter = emitter;
|
||||||
|
return editor as CodeEditor;
|
||||||
};
|
};
|
||||||
|
|
||||||
export { editor, createEditorInstance };
|
export { editor, createEditorInstance };
|
||||||
|
59
packages/codemirror/src/editor.utils.ts
Normal file
59
packages/codemirror/src/editor.utils.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { EditorView } from '@codemirror/view';
|
||||||
|
import { CodeEditor } from './editor.base';
|
||||||
|
type ChainOpts = {
|
||||||
|
editor?: CodeEditor;
|
||||||
|
};
|
||||||
|
export class Chain {
|
||||||
|
editor: CodeEditor | EditorView;
|
||||||
|
constructor(opts?: ChainOpts) {
|
||||||
|
this.editor = opts?.editor;
|
||||||
|
}
|
||||||
|
getEditor() {
|
||||||
|
return this.editor;
|
||||||
|
}
|
||||||
|
getContent() {
|
||||||
|
return this.editor?.state.doc.toString() || '';
|
||||||
|
}
|
||||||
|
setContent(content: string) {
|
||||||
|
if (this.editor) {
|
||||||
|
this.editor.dispatch({
|
||||||
|
changes: { from: 0, to: this.editor.state.doc.length, insert: content },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
setEditor(editor: EditorView) {
|
||||||
|
this.editor = editor;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
clearEditor() {
|
||||||
|
if (this.editor) {
|
||||||
|
this.editor.dispatch({
|
||||||
|
changes: { from: 0, to: this.editor.state.doc.length, insert: '' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
if (this.editor) {
|
||||||
|
this.editor.destroy();
|
||||||
|
this.editor = null;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
static create(opts?: ChainOpts) {
|
||||||
|
return new Chain(opts);
|
||||||
|
}
|
||||||
|
setOnChange(callback: (content: string) => void) {
|
||||||
|
if (this.editor) {
|
||||||
|
const editor = this.editor as CodeEditor;
|
||||||
|
if (editor.emitter) {
|
||||||
|
editor.emitter.on('change', callback);
|
||||||
|
return () => {
|
||||||
|
editor.emitter.off('change', callback);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return () => {};
|
||||||
|
}
|
||||||
|
}
|
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
@ -53,7 +53,7 @@ importers:
|
|||||||
version: 5.7.12(@types/node@22.15.17)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.2)(terser@5.36.0)(typescript@5.8.3)(yaml@2.5.1)
|
version: 5.7.12(@types/node@22.15.17)(jiti@2.4.2)(lightningcss@1.29.2)(rollup@4.40.2)(terser@5.36.0)(typescript@5.8.3)(yaml@2.5.1)
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.2.0
|
specifier: ^3.2.0
|
||||||
version: 3.2.0
|
version: 3.3.0
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^4.1.6
|
specifier: ^4.1.6
|
||||||
version: 4.1.6
|
version: 4.1.6
|
||||||
@ -95,7 +95,7 @@ importers:
|
|||||||
version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 11.0.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.2.0
|
specifier: ^3.2.0
|
||||||
version: 3.2.0
|
version: 3.3.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@astrojs/mdx':
|
'@astrojs/mdx':
|
||||||
specifier: ^4.2.6
|
specifier: ^4.2.6
|
||||||
@ -135,7 +135,7 @@ importers:
|
|||||||
version: 1.2.9
|
version: 1.2.9
|
||||||
|
|
||||||
packages/codemirror:
|
packages/codemirror:
|
||||||
devDependencies:
|
dependencies:
|
||||||
'@codemirror/autocomplete':
|
'@codemirror/autocomplete':
|
||||||
specifier: ^6.18.6
|
specifier: ^6.18.6
|
||||||
version: 6.18.6
|
version: 6.18.6
|
||||||
@ -163,18 +163,22 @@ importers:
|
|||||||
'@codemirror/view':
|
'@codemirror/view':
|
||||||
specifier: ^6.36.7
|
specifier: ^6.36.7
|
||||||
version: 6.36.7
|
version: 6.36.7
|
||||||
|
codemirror:
|
||||||
|
specifier: ^6.0.1
|
||||||
|
version: 6.0.1
|
||||||
|
eventemitter3:
|
||||||
|
specifier: ^5.0.1
|
||||||
|
version: 5.0.1
|
||||||
|
prettier:
|
||||||
|
specifier: ^3.5.3
|
||||||
|
version: 3.5.3
|
||||||
|
devDependencies:
|
||||||
'@rollup/plugin-node-resolve':
|
'@rollup/plugin-node-resolve':
|
||||||
specifier: ^16.0.1
|
specifier: ^16.0.1
|
||||||
version: 16.0.1(rollup@4.40.2)
|
version: 16.0.1(rollup@4.40.2)
|
||||||
'@rollup/plugin-typescript':
|
'@rollup/plugin-typescript':
|
||||||
specifier: ^12.1.2
|
specifier: ^12.1.2
|
||||||
version: 12.1.2(rollup@4.40.2)(tslib@2.8.1)(typescript@5.8.3)
|
version: 12.1.2(rollup@4.40.2)(tslib@2.8.1)(typescript@5.8.3)
|
||||||
codemirror:
|
|
||||||
specifier: ^6.0.1
|
|
||||||
version: 6.0.1
|
|
||||||
prettier:
|
|
||||||
specifier: ^3.5.3
|
|
||||||
version: 3.5.3
|
|
||||||
rollup:
|
rollup:
|
||||||
specifier: ^4.40.2
|
specifier: ^4.40.2
|
||||||
version: 4.40.2
|
version: 4.40.2
|
||||||
@ -271,8 +275,8 @@ importers:
|
|||||||
specifier: ^16.1.0
|
specifier: ^16.1.0
|
||||||
version: 16.1.0
|
version: 16.1.0
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.2.0
|
specifier: ^3.3.0
|
||||||
version: 3.2.0
|
version: 3.3.0
|
||||||
tailwindcss:
|
tailwindcss:
|
||||||
specifier: ^4.1.6
|
specifier: ^4.1.6
|
||||||
version: 4.1.6
|
version: 4.1.6
|
||||||
@ -4144,8 +4148,8 @@ packages:
|
|||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
tailwind-merge@3.2.0:
|
tailwind-merge@3.3.0:
|
||||||
resolution: {integrity: sha512-FQT/OVqCD+7edmmJpsgCsY820RTD5AkBryuG5IUqR5YQZSdj5xlH5nLgH7YPths7WsLPSpSBNneJdM8aS8aeFA==}
|
resolution: {integrity: sha512-fyW/pEfcQSiigd5SNn0nApUOxx0zB/dm6UDU/rEwc2c3sX2smWUNbapHv+QRqLGVp9GWX3THIa7MUGPo+YkDzQ==}
|
||||||
|
|
||||||
tailwindcss-animate@1.0.7:
|
tailwindcss-animate@1.0.7:
|
||||||
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
|
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
|
||||||
@ -9141,7 +9145,7 @@ snapshots:
|
|||||||
csso: 5.0.5
|
csso: 5.0.5
|
||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
|
|
||||||
tailwind-merge@3.2.0: {}
|
tailwind-merge@3.3.0: {}
|
||||||
|
|
||||||
tailwindcss-animate@1.0.7(tailwindcss@4.1.6):
|
tailwindcss-animate@1.0.7(tailwindcss@4.1.6):
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user