@bhsd/codemirror-mediawiki 3.1.0 → 3.2.0

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.
package/README.md CHANGED
@@ -2,10 +2,17 @@
2
2
  [![jsDelivr hits (npm scoped)](https://img.shields.io/jsdelivr/npm/hm/%40bhsd/codemirror-mediawiki)](https://www.npmjs.com/package/@bhsd/codemirror-mediawiki)
3
3
  [![Codacy Badge](https://app.codacy.com/project/badge/Grade/972fd5f6684c4fd8ac2f26e01d349948)](https://app.codacy.com/gh/bhsd-harry/codemirror-mediawiki/dashboard)
4
4
 
5
+ # @bhsd/codemirror-mediawiki
6
+
7
+ This repository contains a modified version of the frontend scripts and styles from [MediaWiki extension CodeMirror](https://www.mediawiki.org/wiki/Extension:CodeMirror). The goal is to support a standalone integration between [CodeMirror](https://codemimrror.net) and [Wikitext](https://www.mediawiki.org/wiki/Wikitext), without the need for a [MediaWiki environment](https://doc.wikimedia.org/mediawiki-core/master/js/).
8
+
9
+ Here is a [demo](https://bhsd-harry.github.io/codemirror-mediawiki). To experiment with the RTL (right-to-left) support, you can append `?rtl=1` to the URL.
10
+
11
+ Nonetheless, this repository also provides a customized version with additional functionality for use on a MediaWiki site. Browser editing tools such as [Wikiplus-highlight](https://www.npmjs.com/package/wikiplus-highlight) and an [InPageEdit plugin](https://github.com/inpageedit/Plugins/blob/master/src/plugins/code-mirror/cm6.js) are built upon it. Please refer to a separate [README](./mw/README.md) file for the information.
12
+
5
13
  <details>
6
14
  <summary>Expand</summary>
7
15
 
8
- - [Description](#description)
9
16
  - [Installation](#installation)
10
17
  - [Browser Usage](#browser-usage)
11
18
  - [Download JavaScript](#download-javascript)
@@ -68,14 +75,6 @@
68
75
 
69
76
  </details>
70
77
 
71
- # Description
72
-
73
- This repository contains a modified version of the frontend scripts and styles from [MediaWiki extension CodeMirror](https://www.mediawiki.org/wiki/Extension:CodeMirror). The goal is to support a standalone integration between [CodeMirror](https://codemimrror.net) and [Wikitext](https://www.mediawiki.org/wiki/Wikitext), without the need for a [MediaWiki environment](https://doc.wikimedia.org/mediawiki-core/master/js/).
74
-
75
- Here is a [demo](https://bhsd-harry.github.io/codemirror-mediawiki). To experiment with the RTL (right-to-left) support, you can append `?rtl=1` to the URL.
76
-
77
- Nonetheless, this repository also provides a customized version with additional functionality for use on a MediaWiki site. Browser editing tools such as [Wikiplus-highlight](https://github.com/bhsd-harry/Wikiplus-highlight) and an [InPageEdit plugin](https://github.com/inpageedit/Plugins) are built upon it. Please refer to a separate [README](./mw/README.md) file for the information.
78
-
79
78
  # Installation
80
79
 
81
80
  You can install the package via npm and import it as a module:
@@ -234,6 +233,17 @@ import {registerHTMLCore} from '@bhsd/codemirror-mediawiki';
234
233
  registerHTMLCore();
235
234
  ```
236
235
 
236
+ In addition to the common [extensions](#extensions), here are some HTML-specific extensions. Note that these extensions may not take effect if the corresponding common extensions are not registered:
237
+
238
+ ```js
239
+ import {
240
+ registerCloseBracketsForHTML,
241
+ registerColorPickerForHTML,
242
+ } from '@bhsd/codemirror-mediawiki';
243
+ registerCloseBracketsForHTML();
244
+ registerColorPickerForHTML();
245
+ ```
246
+
237
247
  </details>
238
248
 
239
249
  ## javascript
@@ -542,6 +552,23 @@ const tree = cm.getNodeAt(0);
542
552
 
543
553
  </details>
544
554
 
555
+ ## hasPreference
556
+
557
+ <details>
558
+ <summary>Expand</summary>
559
+
560
+ *version added: 3.2.0*
561
+
562
+ **param**: `string` extension name
563
+ **returns**: `boolean`
564
+ Check if the editor enables the given extension.
565
+
566
+ ```js
567
+ const hasAutocompletion = cm.hasPreference('autocompletion');
568
+ ```
569
+
570
+ </details>
571
+
545
572
  ## initialize
546
573
 
547
574
  <details>
@@ -608,7 +635,7 @@ cm.localize({
608
635
 
609
636
  *version added: 2.0.9*
610
637
 
611
- **param**: `string[] | Record<string, boolean>` the preferred [CodeMirror extensions](https://codemirror.net/docs/extensions/)
638
+ **param**: `string[] | Record<string, boolean>` the [extensions](#extensions) to enable
612
639
  Set the preferred CodeMirror extensions. Available extensions are introduced [later](#extensions).
613
640
 
614
641
  ```js
@@ -1151,6 +1178,9 @@ registerSignatureHelp();
1151
1178
 
1152
1179
  ## Syntax Highlighting
1153
1180
 
1181
+ <details>
1182
+ <summary>Expand</summary>
1183
+
1154
1184
  ### Extension
1155
1185
 
1156
1186
  1. [Extension:Translate](https://www.mediawiki.org/wiki/Extension:Translate) is not supported.
@@ -1183,3 +1213,5 @@ registerSignatureHelp();
1183
1213
  ### Language conversion
1184
1214
 
1185
1215
  1. BCP 47 language codes are not supported in language conversion ([Example](https://bhsd-harry.github.io/wikiparser-node/tests.html#Explicit%20definition%20of%20language%20variant%20alternatives%20(BCP%2047%20codes))).
1216
+
1217
+ </details>
@@ -4,17 +4,31 @@ import type { Extension } from '@codemirror/state';
4
4
  import type { SyntaxNode } from '@lezer/common';
5
5
  import type { ConfigData } from 'wikiparser-node';
6
6
  import type { MwConfig } from './token';
7
- import type { DocRange } from './fold';
7
+ import type { DocRange, foldHandler } from './fold';
8
8
  import type { Option, LiveOption } from './linter';
9
9
  import type { LintSource, LintSourceGetter } from './lintsource';
10
+ import type { detectIndent } from './indent';
11
+ import type statusBar from './statusBar';
10
12
  export type AddonMain<T> = (config?: T, cm?: CodeMirror6) => Extension;
11
13
  export type Addon<T> = [AddonMain<T>, Record<string, T>?];
12
14
  export type Dialect = 'sanitized-css' | undefined;
15
+ export interface MenuItem {
16
+ name: string;
17
+ isActionable(this: void, cm: CodeMirror6): boolean;
18
+ getItems(this: void, cm: CodeMirror6): HTMLDivElement[];
19
+ }
20
+ declare interface OptionalFunctions {
21
+ statusBar: typeof statusBar;
22
+ detectIndent: typeof detectIndent;
23
+ foldHandler: typeof foldHandler;
24
+ }
13
25
  export declare const plain: () => Extension;
14
26
  export declare const languages: Record<string, (config?: any) => Extension>;
15
27
  export declare const avail: Record<string, Addon<any>>;
16
28
  export declare const linterRegistry: Record<string, LintSourceGetter>;
29
+ export declare const menuRegistry: MenuItem[];
17
30
  export declare const destroyListeners: ((view: EditorView) => void)[];
31
+ export declare const optionalFunctions: OptionalFunctions;
18
32
  /** CodeMirror 6 editor */
19
33
  export declare class CodeMirror6 {
20
34
  #private;
@@ -55,6 +69,11 @@ export declare class CodeMirror6 {
55
69
  lint(lintSource?: LintSource): void;
56
70
  /** Update syntax checking immediately */
57
71
  update(): void;
72
+ /**
73
+ * Check if the editor enables a specific extension
74
+ * @param name extension name
75
+ */
76
+ hasPreference(name: string): boolean;
58
77
  /**
59
78
  * Add extensions
60
79
  * @param names extension names
@@ -124,3 +143,4 @@ export declare class CodeMirror6 {
124
143
  */
125
144
  abstract static getMwConfig(config: ConfigData): MwConfig;
126
145
  }
146
+ export {};
@@ -4,16 +4,25 @@ import { syntaxHighlighting, defaultHighlightStyle, indentOnInput, indentUnit, e
4
4
  import { defaultKeymap, historyKeymap, history, redo, indentWithTab } from '@codemirror/commands';
5
5
  import { searchKeymap } from '@codemirror/search';
6
6
  import { linter, lintGutter, lintKeymap } from '@codemirror/lint';
7
- import { foldHandler } from './fold';
8
- import statusBar from './statusBar';
9
- import { detectIndent } from './indent';
10
7
  export const plain = () => EditorView.contentAttributes.of({ spellcheck: 'true' });
11
8
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
9
  export const languages = { plain };
13
10
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
14
11
  export const avail = {};
15
12
  export const linterRegistry = {};
13
+ export const menuRegistry = [];
16
14
  export const destroyListeners = [];
15
+ export const optionalFunctions = {
16
+ statusBar() {
17
+ return [];
18
+ },
19
+ detectIndent(_, indent) {
20
+ return indent;
21
+ },
22
+ foldHandler() {
23
+ return () => { };
24
+ },
25
+ };
17
26
  const editExtensions = new Set(['closeBrackets', 'autocompletion', 'signatureHelp']);
18
27
  const linters = {};
19
28
  const phrases = {};
@@ -33,6 +42,7 @@ export class CodeMirror6 {
33
42
  #visible = false;
34
43
  #preferred = new Set();
35
44
  #indentStr = '\t';
45
+ #nestedMWLanguage;
36
46
  /** textarea element */
37
47
  get textarea() {
38
48
  return this.#textarea;
@@ -62,6 +72,15 @@ export class CodeMirror6 {
62
72
  this.initialize(config);
63
73
  }
64
74
  }
75
+ /**
76
+ * 获取语言扩展
77
+ * @param config 语言设置
78
+ */
79
+ #getLanguage(config) {
80
+ const lang = (languages[this.#lang] ?? plain)(config);
81
+ this.#nestedMWLanguage = lang.nestedMWLanguage;
82
+ return lang;
83
+ }
65
84
  /**
66
85
  * Initialize the editor
67
86
  * @param config language configuration
@@ -69,7 +88,7 @@ export class CodeMirror6 {
69
88
  initialize(config) {
70
89
  let timer;
71
90
  const { textarea, lang } = this, { value, dir: d, accessKey, tabIndex, lang: l, readOnly } = textarea, extensions = [
72
- this.#language.of(languages[lang](config)),
91
+ this.#language.of(this.#getLanguage(config)),
73
92
  this.#linter.of(linters[lang] ?? []),
74
93
  this.#extensions.of([]),
75
94
  this.#dir.of(EditorView.editorAttributes.of({ dir: d })),
@@ -126,7 +145,7 @@ export class CodeMirror6 {
126
145
  : [
127
146
  history(),
128
147
  indentOnInput(),
129
- this.#indent.of(indentUnit.of(detectIndent(value, this.#indentStr, lang))),
148
+ this.#indent.of(indentUnit.of(optionalFunctions.detectIndent(value, this.#indentStr, lang))),
130
149
  keymap.of([
131
150
  ...historyKeymap,
132
151
  indentWithTab,
@@ -145,7 +164,7 @@ export class CodeMirror6 {
145
164
  this.#view.scrollDOM.style.fontSize = fontSize;
146
165
  this.#view.scrollDOM.style.lineHeight = lineHeight;
147
166
  this.toggle(true);
148
- this.#view.dom.addEventListener('click', foldHandler(this.#view));
167
+ this.#view.dom.addEventListener('click', optionalFunctions.foldHandler(this.#view));
149
168
  this.prefer({});
150
169
  }
151
170
  /**
@@ -175,7 +194,7 @@ export class CodeMirror6 {
175
194
  async setLanguage(lang = 'plain', config) {
176
195
  this.#lang = lang;
177
196
  if (this.#view) {
178
- const ext = (languages[lang] ?? plain)(config);
197
+ const ext = this.#getLanguage(config);
179
198
  this.#effects([
180
199
  this.#language.reconfigure(ext),
181
200
  this.#linter.reconfigure(linters[lang] ?? []),
@@ -202,7 +221,7 @@ export class CodeMirror6 {
202
221
  }),
203
222
  lintGutter(),
204
223
  keymap.of(lintKeymap),
205
- statusBar(lintSource.fixer),
224
+ optionalFunctions.statusBar(this, lintSource.fixer),
206
225
  ]
207
226
  : [];
208
227
  if (lintSource) {
@@ -227,6 +246,13 @@ export class CodeMirror6 {
227
246
  }
228
247
  }
229
248
  }
249
+ /**
250
+ * Check if the editor enables a specific extension
251
+ * @param name extension name
252
+ */
253
+ hasPreference(name) {
254
+ return this.#preferred.has(name);
255
+ }
230
256
  /**
231
257
  * Add extensions
232
258
  * @param names extension names
@@ -259,7 +285,7 @@ export class CodeMirror6 {
259
285
  */
260
286
  setIndent(indent) {
261
287
  if (this.#view) {
262
- this.#effects(this.#indent.reconfigure(indentUnit.of(detectIndent(this.#view.state.doc, indent, this.#lang))));
288
+ this.#effects(this.#indent.reconfigure(indentUnit.of(optionalFunctions.detectIndent(this.#view.state.doc, indent, this.#lang))));
263
289
  }
264
290
  else {
265
291
  this.#indentStr = indent;
@@ -279,7 +305,7 @@ export class CodeMirror6 {
279
305
  * @param opt linter options
280
306
  */
281
307
  async getLinter(opt) {
282
- return linterRegistry[this.#lang]?.(opt, this.#view);
308
+ return linterRegistry[this.#lang]?.(opt, this.#view, this.#nestedMWLanguage);
283
309
  }
284
310
  /**
285
311
  * Set content
package/dist/css.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  import { LanguageSupport } from '@codemirror/language';
2
+ import type { Extension } from '@codemirror/state';
2
3
  import type { Dialect } from './codemirror';
4
+ export declare const cssCompletion: (dialect?: Dialect) => Extension;
3
5
  declare const _default: (dialect: Dialect) => LanguageSupport;
4
6
  export default _default;
package/dist/css.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { cssLanguage, cssCompletionSource } from '@codemirror/lang-css';
2
2
  import { LanguageSupport, syntaxTree } from '@codemirror/language';
3
- export default (dialect) => new LanguageSupport(cssLanguage, cssLanguage.data.of({
3
+ export const cssCompletion = (dialect) => cssLanguage.data.of({
4
4
  autocomplete(context) {
5
5
  const { state, pos } = context, node = syntaxTree(state).resolveInner(pos, -1), result = cssCompletionSource(context);
6
6
  if (result) {
@@ -27,4 +27,5 @@ export default (dialect) => new LanguageSupport(cssLanguage, cssLanguage.data.of
27
27
  }
28
28
  return result;
29
29
  },
30
- }));
30
+ });
31
+ export default (dialect) => new LanguageSupport(cssLanguage, cssCompletion(dialect));