@bhsd/codemirror-mediawiki 3.2.0 → 3.4.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
@@ -15,8 +15,6 @@ Nonetheless, this repository also provides a customized version with additional
15
15
 
16
16
  - [Installation](#installation)
17
17
  - [Browser Usage](#browser-usage)
18
- - [Download JavaScript](#download-javascript)
19
- - [Download CSS](#download-css)
20
18
  - [Language modes](#language-modes)
21
19
  - [css](#css)
22
20
  - [html](#html)
@@ -25,6 +23,11 @@ Nonetheless, this repository also provides a customized version with additional
25
23
  - [lua](#lua)
26
24
  - [mediawiki](#mediawiki)
27
25
  - [vue](#vue)
26
+ - [Other languages](#other-languages)
27
+ - [Themes](#themes)
28
+ - [light](#light)
29
+ - [nord](#nord)
30
+ - [Other themes](#other-themes)
28
31
  - [Constructor](#constructor)
29
32
  - [Accessors](#accessors)
30
33
  - [dialect](#dialect)
@@ -46,6 +49,7 @@ Nonetheless, this repository also provides a customized version with additional
46
49
  - [setIndent](#setindent)
47
50
  - [setLanguage](#setlanguage)
48
51
  - [setLineWrapping](#setlinewrapping)
52
+ - [setTheme](#settheme)
49
53
  - [toggle](#toggle)
50
54
  - [update](#update)
51
55
  - [Static methods](#static-methods)
@@ -98,13 +102,11 @@ import {
98
102
 
99
103
  # Browser Usage
100
104
 
101
- You can download the code via CDN, for example:
102
-
103
- ## Download JavaScript
104
-
105
105
  <details>
106
106
  <summary>Expand</summary>
107
107
 
108
+ You can download the code via CDN, for example:
109
+
108
110
  ```js
109
111
  // static import
110
112
  import {
@@ -167,23 +169,6 @@ const {
167
169
 
168
170
  </details>
169
171
 
170
- ## Download CSS
171
-
172
- <details>
173
- <summary>Expand</summary>
174
-
175
- ```html
176
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@bhsd/codemirror-mediawiki/mediawiki.css">
177
- ```
178
-
179
- or
180
-
181
- ```html
182
- <link rel="stylesheet" href="https://unpkg.com/@bhsd/codemirror-mediawiki/mediawiki.css">
183
- ```
184
-
185
- </details>
186
-
187
172
  # Language modes
188
173
 
189
174
  ## css
@@ -398,6 +383,41 @@ registerLanguageCore('python', python);
398
383
 
399
384
  </details>
400
385
 
386
+ # Themes
387
+
388
+ ## light
389
+
390
+ This is the default theme, which is a light theme.
391
+
392
+ ## nord
393
+
394
+ <details>
395
+ <summary>Expand</summary>
396
+
397
+ This is a dark theme created by [Takuya Matsuyama](https://www.npmjs.com/package/cm6-theme-nord) and [鬼影233](https://zh.moegirl.org.cn/User:%E9%AC%BC%E5%BD%B1233/Nord). You need to register this theme before using it:
398
+
399
+ ```js
400
+ import {registerTheme, nord} from '@bhsd/codemirror-mediawiki';
401
+ registerTheme('nord', nord);
402
+ ```
403
+
404
+ </details>
405
+
406
+ ## Other themes
407
+
408
+ <details>
409
+ <summary>Expand</summary>
410
+
411
+ You can also register other themes by importing the `registerTheme` function:
412
+
413
+ ```js
414
+ import {registerTheme} from '@bhsd/codemirror-mediawiki';
415
+ import {oneDark} from '@codemirror/theme-one-dark';
416
+ registerTheme('one-dark', oneDark);
417
+ ```
418
+
419
+ </details>
420
+
401
421
  # Constructor
402
422
 
403
423
  <details>
@@ -779,6 +799,24 @@ cm.setLineWrapping(true);
779
799
 
780
800
  </details>
781
801
 
802
+ ## setTheme
803
+
804
+ <details>
805
+ <summary>Expand</summary>
806
+
807
+ *version added: 3.3.0*
808
+
809
+ **param**: `string` the theme name
810
+ Set the theme of the editor. The default theme is `light`, other themes need to be registered using the `registerTheme` function first:
811
+
812
+ ```js
813
+ import {registerTheme, nord} from '@bhsd/codemirror-mediawiki';
814
+ registerTheme('nord', nord);
815
+ cm.setTheme('nord');
816
+ ```
817
+
818
+ </details>
819
+
782
820
  ## toggle
783
821
 
784
822
  <details>
@@ -28,6 +28,7 @@ export declare const avail: Record<string, Addon<any>>;
28
28
  export declare const linterRegistry: Record<string, LintSourceGetter>;
29
29
  export declare const menuRegistry: MenuItem[];
30
30
  export declare const destroyListeners: ((view: EditorView) => void)[];
31
+ export declare const themes: Record<string, Extension>;
31
32
  export declare const optionalFunctions: OptionalFunctions;
32
33
  /** CodeMirror 6 editor */
33
34
  export declare class CodeMirror6 {
@@ -130,6 +131,12 @@ export declare class CodeMirror6 {
130
131
  anchor: number;
131
132
  head: number;
132
133
  }): void;
134
+ /**
135
+ * Set the editor theme
136
+ * @param theme theme name
137
+ * @since 3.3.0
138
+ */
139
+ setTheme(theme: string): void;
133
140
  /**
134
141
  * Replace the current selection with the result of a function
135
142
  * @param view EditorView instance
@@ -4,6 +4,7 @@ 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 { light } from './theme';
7
8
  export const plain = () => EditorView.contentAttributes.of({ spellcheck: 'true' });
8
9
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
10
  export const languages = { plain };
@@ -12,6 +13,7 @@ export const avail = {};
12
13
  export const linterRegistry = {};
13
14
  export const menuRegistry = [];
14
15
  export const destroyListeners = [];
16
+ export const themes = { light };
15
17
  export const optionalFunctions = {
16
18
  statusBar() {
17
19
  return [];
@@ -37,6 +39,7 @@ export class CodeMirror6 {
37
39
  #extraKeys = new Compartment();
38
40
  #phrases = new Compartment();
39
41
  #lineWrapping = new Compartment();
42
+ #theme = new Compartment();
40
43
  #view;
41
44
  #lang;
42
45
  #visible = false;
@@ -95,6 +98,7 @@ export class CodeMirror6 {
95
98
  this.#extraKeys.of([]),
96
99
  this.#phrases.of(EditorState.phrases.of(phrases)),
97
100
  this.#lineWrapping.of(EditorView.lineWrapping),
101
+ this.#theme.of(light),
98
102
  syntaxHighlighting(defaultHighlightStyle),
99
103
  EditorView.contentAttributes.of({
100
104
  accesskey: accessKey,
@@ -117,7 +121,18 @@ export class CodeMirror6 {
117
121
  },
118
122
  ]),
119
123
  EditorView.theme({
120
- '.cm-panels': { direction: document.dir },
124
+ '.cm-panels': {
125
+ direction: document.dir,
126
+ },
127
+ '& .cm-lineNumbers .cm-gutterElement': {
128
+ textAlign: 'end',
129
+ },
130
+ '.cm-textfield, .cm-button, .cm-panel.cm-search label, .cm-panel.cm-gotoLine label': {
131
+ fontSize: 'inherit',
132
+ },
133
+ '.cm-panel [name="close"]': {
134
+ color: 'inherit',
135
+ },
121
136
  }),
122
137
  EditorView.updateListener.of(({ state: { doc }, startState: { doc: startDoc }, docChanged, focusChanged, }) => {
123
138
  if (docChanged) {
@@ -139,7 +154,9 @@ export class CodeMirror6 {
139
154
  EditorState.readOnly.of(true),
140
155
  EditorState.transactionFilter.of(tr => tr.docChanged ? [] : tr),
141
156
  EditorView.theme({
142
- 'input[type="color"]': { pointerEvents: 'none' },
157
+ 'input[type="color"]': {
158
+ pointerEvents: 'none',
159
+ },
143
160
  }),
144
161
  ]
145
162
  : [
@@ -411,6 +428,18 @@ export class CodeMirror6 {
411
428
  this.#view.dispatch({ effects });
412
429
  }
413
430
  }
431
+ /**
432
+ * Set the editor theme
433
+ * @param theme theme name
434
+ * @since 3.3.0
435
+ */
436
+ setTheme(theme) {
437
+ if (theme in themes) {
438
+ this.#view?.dispatch({
439
+ effects: this.#theme.reconfigure(themes[theme]),
440
+ });
441
+ }
442
+ }
414
443
  /**
415
444
  * Replace the current selection with the result of a function
416
445
  * @param view EditorView instance
package/dist/fold.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { EditorView, Command } from '@codemirror/view';
1
+ import { EditorView } from '@codemirror/view';
2
+ import type { Command } from '@codemirror/view';
2
3
  import type { EditorState, Extension } from '@codemirror/state';
3
4
  import type { SyntaxNode, Tree } from '@lezer/common';
4
5
  export interface DocRange {
package/dist/fold.js CHANGED
@@ -1,4 +1,4 @@
1
- import { showTooltip, keymap, GutterMarker, gutter, ViewPlugin } from '@codemirror/view';
1
+ import { showTooltip, keymap, GutterMarker, gutter, ViewPlugin, EditorView } from '@codemirror/view';
2
2
  import { StateField, RangeSetBuilder, RangeSet } from '@codemirror/state';
3
3
  import { syntaxTree, ensureSyntaxTree, foldEffect, unfoldEffect, foldedRanges, unfoldAll, codeFolding, foldGutter, foldKeymap, foldState, language, } from '@codemirror/language';
4
4
  import { getRegex } from '@bhsd/common';
@@ -334,6 +334,7 @@ const foldCommand = (refOnly) => view => {
334
334
  };
335
335
  export const foldRef = /* @__PURE__ */ foldCommand(true);
336
336
  export default ((e = defaultFoldExtension) => e);
337
+ const selector = '.cm-tooltip-fold';
337
338
  export const mediaWikiFold = /* @__PURE__ */ (() => [
338
339
  codeFolding({
339
340
  placeholderDOM(view) {
@@ -446,6 +447,17 @@ export const mediaWikiFold = /* @__PURE__ */ (() => [
446
447
  },
447
448
  },
448
449
  }),
450
+ EditorView.theme({
451
+ [selector]: {
452
+ cursor: 'pointer',
453
+ lineHeight: 1.2,
454
+ padding: '0 1px',
455
+ opacity: 0.6,
456
+ },
457
+ [`${selector}:hover`]: {
458
+ opacity: 1,
459
+ },
460
+ }),
449
461
  ])();
450
462
  /**
451
463
  * 点击提示折叠模板参数
package/dist/hover.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import type { TooltipView, EditorView } from '@codemirror/view';
1
+ import { EditorView } from '@codemirror/view';
2
+ import type { TooltipView } from '@codemirror/view';
2
3
  import type { Text, Extension } from '@codemirror/state';
3
4
  import type { Position } from 'vscode-languageserver-types';
4
5
  import type { CodeMirror6 } from './codemirror';
package/dist/hover.js CHANGED
@@ -1,4 +1,4 @@
1
- import { hoverTooltip } from '@codemirror/view';
1
+ import { hoverTooltip, EditorView } from '@codemirror/view';
2
2
  import { loadScript, getLSP } from '@bhsd/browser';
3
3
  /**
4
4
  * 将索引转换为位置
@@ -31,20 +31,42 @@ export const createTooltipView = (view, innerHTML) => {
31
31
  inner.innerHTML = innerHTML;
32
32
  return { dom };
33
33
  };
34
- export default (cm) => hoverTooltip(async (view, pos) => {
35
- const { state: { doc } } = view, hover = await getLSP(view, false, cm.getWikiConfig)
36
- ?.provideHover(doc.toString(), indexToPos(doc, pos));
37
- if (hover) {
38
- await loadScript('npm/marked/lib/marked.umd.js', 'marked', true);
39
- const { end } = hover.range;
40
- return {
41
- pos,
42
- end: posToIndex(doc, end),
43
- above: true,
44
- create() {
45
- return createTooltipView(view, marked.parse(hover.contents.value));
46
- },
47
- };
48
- }
49
- return null;
50
- });
34
+ const selector = '.cm-tooltip-hover';
35
+ export default (cm) => [
36
+ hoverTooltip(async (view, pos) => {
37
+ const { state: { doc } } = view, hover = await getLSP(view, false, cm.getWikiConfig)
38
+ ?.provideHover(doc.toString(), indexToPos(doc, pos));
39
+ if (hover) {
40
+ await loadScript('npm/marked/lib/marked.umd.js', 'marked', true);
41
+ const { end } = hover.range;
42
+ return {
43
+ pos,
44
+ end: posToIndex(doc, end),
45
+ above: true,
46
+ create() {
47
+ return createTooltipView(view, marked.parse(hover.contents.value));
48
+ },
49
+ };
50
+ }
51
+ return null;
52
+ }),
53
+ EditorView.theme({
54
+ [selector]: {
55
+ padding: '2px 5px',
56
+ width: 'max-content',
57
+ maxWidth: '60vw',
58
+ },
59
+ [`${selector} *`]: {
60
+ marginTop: '0!important',
61
+ marginBottom: '0!important',
62
+ },
63
+ [`${selector}>div`]: {
64
+ fontSize: '90%',
65
+ lineHeight: 1.4,
66
+ },
67
+ [`${selector} code`]: {
68
+ padding: '.1em .4em',
69
+ borderRadius: '.4em',
70
+ },
71
+ }),
72
+ ];
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { CodeMirror6 } from './codemirror';
2
+ import type { Extension } from '@codemirror/state';
2
3
  import type { LanguageSupport } from '@codemirror/language';
3
4
  import type { MwConfig } from './token';
4
5
  import type { LintSourceGetter } from './lintsource';
@@ -100,3 +101,5 @@ export declare const registerLanguage: (name: string, lang: (config?: unknown) =
100
101
  * @param lintSource optional linter
101
102
  */
102
103
  export declare const registerLanguageCore: (name: string, lang: (config?: unknown) => LanguageSupport, lintSource?: LintSourceGetter) => void;
104
+ export declare const registerTheme: (name: string, theme: Extension) => void;
105
+ export { nord } from './theme';
package/dist/index.js CHANGED
@@ -28,7 +28,7 @@ import css from './css';
28
28
  import lua from './lua';
29
29
  import vue from './vue';
30
30
  import html from './html';
31
- import { CodeMirror6, avail, languages, linterRegistry, destroyListeners, plain, optionalFunctions } from './codemirror';
31
+ import { CodeMirror6, avail, languages, linterRegistry, destroyListeners, plain, optionalFunctions, themes, } from './codemirror';
32
32
  export { CodeMirror6 };
33
33
  /**
34
34
  * 注册通用扩展
@@ -105,7 +105,7 @@ export const registerColorPicker = () => {
105
105
  };
106
106
  /** 注册所有通用扩展(除`colorPicker`) */
107
107
  const registerExtensions = () => {
108
- highlightSpecialChars();
108
+ registerHighlightSpecialChars();
109
109
  registerHighlightActiveLine();
110
110
  registerHighlightWhitespace();
111
111
  registerHighlightTrailingWhitespace();
@@ -189,7 +189,7 @@ export const registerInlayHints = () => {
189
189
  export const registerColorPickerForMediaWiki = () => {
190
190
  registerLangExtension('mediawiki', 'colorPicker', [
191
191
  [makeColorPicker({ discoverColors }), colorPickerTheme],
192
- { marginLeft: '0.6ch' },
192
+ { marginLeft: '.6ch' },
193
193
  ]);
194
194
  };
195
195
  /** Register the `bracketMatching` extension for MediaWiki */
@@ -338,3 +338,7 @@ export const registerLanguageCore = (name, lang, lintSource) => {
338
338
  registerLintSource(name, lintSource);
339
339
  }
340
340
  };
341
+ export const registerTheme = (name, theme) => {
342
+ themes[name] = theme;
343
+ };
344
+ export { nord } from './theme';
package/dist/inlay.js CHANGED
@@ -65,4 +65,12 @@ export default (cm) => [
65
65
  void updateField(update);
66
66
  }
67
67
  }),
68
+ EditorView.theme({
69
+ '.cm-inlay-hint': {
70
+ color: '#969696',
71
+ fontStyle: 'italic',
72
+ '-webkitUserSelect': 'none',
73
+ userSelect: 'none',
74
+ },
75
+ }),
68
76
  ];
@@ -125,7 +125,7 @@ export const getCssLintSource = async (opt) => {
125
125
  export const getVueLintSource = async (opt) => {
126
126
  const styleLint = await getCssLinter(), esLint = await getJsLinter();
127
127
  return async (state) => {
128
- const { doc } = state, option = await getOpt(opt) ?? {}, js = option['js'], css = option['css'];
128
+ const { doc } = state, option = await getOpt(opt, true) ?? {}, js = option['js'], css = option['css'];
129
129
  return [
130
130
  ...(await Promise.all(cssLanguage.findRegions(state)
131
131
  .map(({ from, to }) => cssLintSource(styleLint, state.sliceDoc(from, to), css, doc, from, to)))).flat(),
@@ -137,7 +137,7 @@ export const getVueLintSource = async (opt) => {
137
137
  export const getHTMLLintSource = async (opt, view, language) => {
138
138
  const vueLintSource = await getVueLintSource(opt), wikiLint = await getWikiLinter({ include: false, ...await getOpt(opt) }, view);
139
139
  return async (state) => {
140
- const { doc } = state, option = await getOpt(opt) ?? {}, wiki = option['wiki'];
140
+ const { doc } = state, option = await getOpt(opt, true) ?? {}, wiki = option['wiki'];
141
141
  return [
142
142
  ...await vueLintSource(state),
143
143
  ...(await Promise.all(language.findRegions(state)