@lstsystems/ckeditor5-source-editing-codemirror 47.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,146 @@
1
+ import { Plugin } from 'ckeditor5';
2
+
3
+ // CodeMirror 6 imports
4
+ import {
5
+ EditorView,
6
+ lineNumbers,
7
+ highlightActiveLine,
8
+ highlightActiveLineGutter
9
+ } from '@codemirror/view';
10
+
11
+ import { EditorState, type Extension } from '@codemirror/state';
12
+ import { html } from '@codemirror/lang-html';
13
+ import {
14
+ syntaxHighlighting,
15
+ defaultHighlightStyle,
16
+ indentOnInput,
17
+ indentUnit
18
+ } from '@codemirror/language';
19
+ import { indentSelection } from '@codemirror/commands';
20
+
21
+ // Prettier 3 imports
22
+ import prettier from "prettier/standalone";
23
+ import * as prettierHtml from "prettier/plugins/html";
24
+ import * as prettierCss from "prettier/plugins/postcss";
25
+ import * as prettierTs from "prettier/plugins/typescript";
26
+ import * as prettierMarkdown from "prettier/plugins/markdown";
27
+ import * as prettierYaml from "prettier/plugins/yaml";
28
+
29
+ interface CodeMirrorConfig {
30
+ extensions?: Extension[];
31
+ }
32
+
33
+ export default class SourceEditingCodeMirror extends Plugin {
34
+ public static get pluginName() {
35
+ return 'SourceEditingCodeMirror' as const;
36
+ }
37
+
38
+ public static get requires() {
39
+ return [ 'SourceEditing' ] as const;
40
+ }
41
+
42
+ private view: EditorView | null = null;
43
+
44
+ // Prettier 3 formatter
45
+ private async formatWithPrettier(code: string): Promise<string> {
46
+ return await prettier.format(code, {
47
+ parser: "html",
48
+ plugins: [
49
+ prettierHtml,
50
+ prettierCss,
51
+ prettierTs,
52
+ prettierMarkdown,
53
+ prettierYaml
54
+ ],
55
+ tabWidth: 4,
56
+ useTabs: false
57
+ });
58
+ }
59
+
60
+ // Listen to SourceEditing mode changes
61
+ public afterInit(): void {
62
+ const editor = this.editor;
63
+ const sourceEditing = editor.plugins.get('SourceEditing');
64
+
65
+ this.listenTo(
66
+ sourceEditing,
67
+ 'change:isSourceEditingMode',
68
+ async (_evt, _name, isOn: boolean) => {
69
+ if (isOn) {
70
+ await this.enableCodeMirror();
71
+ } else {
72
+ this.disableCodeMirror();
73
+ }
74
+ }
75
+ );
76
+ }
77
+ // Enable CodeMirror with Prettier formatting
78
+ private async enableCodeMirror(): Promise<void> {
79
+ const editor = this.editor;
80
+ const sourceEditing = editor.plugins.get('SourceEditing');
81
+
82
+ // Sync CKEditor → source view
83
+ sourceEditing.updateEditorData();
84
+
85
+ // Format HTML using Prettier 3
86
+ const htmlData = await this.formatWithPrettier(editor.getData());
87
+
88
+ const container = document.querySelector('.ck-source-editing-area');
89
+ if (!container) return;
90
+
91
+ const textarea = container.querySelector('textarea') as HTMLTextAreaElement | null;
92
+ if (textarea) textarea.style.display = 'none';
93
+
94
+ const cmDiv = document.createElement('div');
95
+ cmDiv.classList.add('cm-wrapper');
96
+ container.appendChild(cmDiv);
97
+
98
+ const cmExtensions: Extension[] = [
99
+ lineNumbers(),
100
+ highlightActiveLine(),
101
+ highlightActiveLineGutter(),
102
+ syntaxHighlighting(defaultHighlightStyle),
103
+ indentOnInput(),
104
+ indentUnit.of(' ')
105
+ ];
106
+
107
+ const config = editor.config.get('sourceEditingCodeMirror') as CodeMirrorConfig;
108
+ const extraExtensions = config?.extensions ?? [];
109
+
110
+ this.view = new EditorView({
111
+ state: EditorState.create({
112
+ doc: htmlData,
113
+ extensions: [
114
+ ...cmExtensions,
115
+ html(),
116
+ ...extraExtensions,
117
+ EditorView.updateListener.of(update => {
118
+ if (update.docChanged) {
119
+ editor.setData(update.state.doc.toString());
120
+ }
121
+ })
122
+ ]
123
+ }),
124
+ parent: cmDiv
125
+ });
126
+
127
+ // Select entire document
128
+ this.view.dispatch({
129
+ selection: { anchor: 0, head: this.view.state.doc.length }
130
+ });
131
+
132
+ // Indent entire document (after Prettier formatting)
133
+ indentSelection(this.view);
134
+ }
135
+
136
+ // Disable CodeMirror and show original textarea
137
+ private disableCodeMirror(): void {
138
+ if (this.view) {
139
+ this.view.destroy();
140
+ this.view = null;
141
+ }
142
+
143
+ const textarea = document.querySelector('.ck-source-editing-area textarea') as HTMLTextAreaElement | null;
144
+ if (textarea) textarea.style.display = '';
145
+ }
146
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "lib": ["ES2020", "DOM"],
7
+ "strict": false,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "declaration": true,
11
+ "emitDeclarationOnly": true,
12
+ "noEmit": false,
13
+ "outDir": "./dist",
14
+ "declarationMap": false
15
+ },
16
+ "include": ["src/**/*"]
17
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Node",
6
+ "lib": ["ES2020", "DOM"],
7
+ "strict": true,
8
+ "esModuleInterop": true,
9
+ "skipLibCheck": true,
10
+ "allowSyntheticDefaultImports": true
11
+ },
12
+ "include": ["./**/*.ts"]
13
+ }
package/vite.config.js ADDED
@@ -0,0 +1,50 @@
1
+ import { defineConfig } from 'vite';
2
+ import path from 'path';
3
+
4
+ export default defineConfig({
5
+ root: 'Sample',
6
+
7
+ build: {
8
+ // Build from project root, not Sample/
9
+ outDir: '../dist',
10
+ emptyOutDir: false,
11
+ lib: {
12
+ entry: path.resolve(__dirname, 'src/index.ts'),
13
+ name: 'SourceEditingCodeMirror',
14
+ fileName: 'sourceediting-codemirror',
15
+ formats: ['es'] // You only need ESM for CKEditor
16
+ },
17
+ rollupOptions: {
18
+ external: [
19
+ 'ckeditor5',
20
+ '@codemirror/view',
21
+ '@codemirror/state',
22
+ '@codemirror/language',
23
+ '@codemirror/lang-html',
24
+ 'prettier/standalone',
25
+ 'prettier/plugins/html',
26
+ 'prettier/plugins/postcss',
27
+ 'prettier/plugins/typescript',
28
+ 'prettier/plugins/markdown',
29
+ 'prettier/plugins/yaml'
30
+ ],
31
+ output: {
32
+ globals: {
33
+ 'ckeditor5': 'CKEditor',
34
+ '@codemirror/view': 'CodeMirrorView',
35
+ '@codemirror/state': 'CodeMirrorState',
36
+ '@codemirror/language': 'CodeMirrorLanguage',
37
+ '@codemirror/lang-html': 'CodeMirrorHtml',
38
+ 'prettier/standalone': 'prettier',
39
+ 'prettier/plugins/html': 'prettierHtml',
40
+ 'prettier/plugins/postcss': 'prettierPostCss',
41
+ 'prettier/plugins/typescript': 'prettierTs',
42
+ 'prettier/plugins/markdown': 'prettierMarkdown',
43
+ 'prettier/plugins/yaml': 'prettierYaml'
44
+ }
45
+ }
46
+
47
+ }
48
+ },
49
+
50
+ });