@bhsd/codemirror-mediawiki 3.11.5 → 3.12.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.
package/dist/theme.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Extension } from '@codemirror/state';
2
- export declare const getLightHighlightStyle: () => Extension;
2
+ export declare const lightHighlightStyle: Extension;
3
3
  export declare const light: Extension,
4
4
  /**
5
5
  * @author 鬼影233
package/dist/theme.js CHANGED
@@ -3,7 +3,7 @@ import { syntaxHighlighting, HighlightStyle, defaultHighlightStyle } from '@code
3
3
  import { nord as nordBase } from 'cm6-theme-nord';
4
4
  import { matchingCls, nonmatchingCls, actionSelector, panelsSelector, bgDark, } from './constants.js';
5
5
  const focused = '&.cm-focused', matching = `${focused} .${matchingCls}`, nonmatching = `${focused} .${nonmatchingCls}`;
6
- export const getLightHighlightStyle = () => syntaxHighlighting(HighlightStyle.define(defaultHighlightStyle.specs, { themeType: 'light' }));
6
+ export const lightHighlightStyle = /* @__PURE__ */ (() => syntaxHighlighting(HighlightStyle.define(defaultHighlightStyle.specs, { themeType: 'light' })))();
7
7
  export const light = /* @__PURE__ */ EditorView.theme({
8
8
  '&': {
9
9
  backgroundColor: '#fff',
@@ -30,6 +30,12 @@ export const light = /* @__PURE__ */ EditorView.theme({
30
30
  '.cm-globals, .cm-globals>*': {
31
31
  color: '#164',
32
32
  },
33
+ '.cm-doctag>*': {
34
+ color: '#219',
35
+ },
36
+ '.cm-doctag-type>*': {
37
+ color: '#085',
38
+ },
33
39
  [matching]: {
34
40
  backgroundColor: 'rgb(50,140,130,.32)',
35
41
  },
@@ -69,6 +75,12 @@ nord = /* @__PURE__ */ (() => [
69
75
  '.cm-globals, .cm-globals>*': {
70
76
  color: '#d08770',
71
77
  },
78
+ '.cm-doctag>*': {
79
+ color: '#81a1c1',
80
+ },
81
+ '.cm-doctag-type>*': {
82
+ color: '#ebcb8b',
83
+ },
72
84
  'div.cm-activeLine': {
73
85
  backgroundColor: 'rgb(76,86,106,.27)',
74
86
  },
package/dist/token.d.ts CHANGED
@@ -153,7 +153,7 @@ export declare class MediaWiki {
153
153
  */
154
154
  registerGroundTokens(): void;
155
155
  inChars({ length }: string, tag: TagName): Tokenizer<string>;
156
- inStr(str: string, tag: TagName | false, errorTag?: TagName): Tokenizer<string>;
156
+ inStr(str: string, tag: string | false, errorTag?: string): Tokenizer<string>;
157
157
  eatWikiText(style: string): Tokenizer;
158
158
  eatApostrophes(obj: Pick<State, 'bold' | 'italic'>): Tokenizer<string | false>;
159
159
  eatExternalLinkProtocol({ length }: string, free?: boolean): Tokenizer;
@@ -168,7 +168,7 @@ export declare class MediaWiki {
168
168
  inTableDefinition(tr?: boolean, quote?: string): Tokenizer;
169
169
  get inTable(): Tokenizer;
170
170
  inTableCell(style: string, needAttr?: boolean, firstLine?: boolean): Tokenizer;
171
- inSectionHeader(str: string): Tokenizer;
171
+ inSectionHeader(str: string, level: number): Tokenizer;
172
172
  get inComment(): Tokenizer<string>;
173
173
  eatExtTag(tagname: string, isCloseTag: boolean, state: State): string;
174
174
  eatHtmlTag(tagname: string, isCloseTag: boolean, state: State): string;
package/dist/token.js CHANGED
@@ -112,7 +112,8 @@ const startState = (tokenize, tags, urlProtocols, sof = false) => ({
112
112
  */
113
113
  const copyState = (state) => {
114
114
  const result = { ...state };
115
- for (const [key, val] of Object.entries(state)) {
115
+ for (const key in result) { // eslint-disable-line guard-for-in
116
+ const val = result[key];
116
117
  if (Array.isArray(val)) {
117
118
  // @ts-expect-error initial value
118
119
  result[key] = [...val];
@@ -120,9 +121,9 @@ const copyState = (state) => {
120
121
  else if (key === 'extState') {
121
122
  result[key] = (state.extName && state.extMode && state.extMode.copyState || copyState)(val);
122
123
  }
123
- else if (key !== 'data' && val && typeof val === 'object') {
124
+ else if (key !== 'data' && key !== 'extMode' && val && typeof val === 'object') {
124
125
  // @ts-expect-error initial value
125
- result[key] = { ...val };
126
+ result[key] = { ...val }; // eslint-disable-line @typescript-eslint/no-misused-spread
126
127
  }
127
128
  }
128
129
  return result;
@@ -261,6 +262,7 @@ export const makeLocalStyle = (style, state, endGround) => {
261
262
  const makeLocalTagStyle = (tag, state, endGround) => makeLocalStyle(tokens[tag], state, endGround);
262
263
  const makeStyle = (style, state, endGround) => [makeLocalStyle(style, state, endGround)];
263
264
  const makeTagStyle = (tag, state, endGround) => makeStyle(tokens[tag], state, endGround);
265
+ const getTagStyle = (tag) => tag in tokens ? tokens[tag] : tag;
264
266
  /**
265
267
  * Remembers position and status for rollbacking.
266
268
  * It is needed for changing from bold to italic with apostrophes before it, if required.
@@ -576,21 +578,21 @@ let MediaWiki = (() => {
576
578
  };
577
579
  }
578
580
  inStr(str, tag, errorTag = 'error') {
581
+ tag &&= getTagStyle(tag);
582
+ errorTag = getTagStyle(errorTag);
579
583
  return (stream, state) => {
580
584
  if (stream.match(str, Boolean(tag))) {
581
585
  pop(state);
582
- return tag ? makeLocalTagStyle(tag, state) : '';
586
+ return tag ? makeLocalStyle(tag, state) : '';
583
587
  }
584
588
  else if (!stream.skipTo(str)) {
585
589
  stream.skipToEnd();
586
590
  }
587
- return makeLocalTagStyle(errorTag, state);
591
+ return makeLocalStyle(errorTag, state);
588
592
  };
589
593
  }
590
594
  eatWikiText(style) {
591
- if (style in tokens) {
592
- style = tokens[style];
593
- }
595
+ style = getTagStyle(style);
594
596
  const regex = /^(?:(?:RFC|PMID)[\p{Zs}\t]+\d+|ISBN[\p{Zs}\t]+(?:97[89][\p{Zs}\t-]?)?(?:\d[\p{Zs}\t-]?){9}[\dxX])\b/u;
595
597
  return (stream, state) => {
596
598
  let ch;
@@ -641,8 +643,9 @@ let MediaWiki = (() => {
641
643
  // Title
642
644
  if (tmp) {
643
645
  stream.backUp(tmp[2].length);
644
- chain(state, this.inSectionHeader(tmp[3]));
645
- return makeLocalStyle(`${tokens.sectionHeader} mw-section--${tmp[1].length + 1}`, state);
646
+ const level = tmp[1].length + 1;
647
+ chain(state, this.inSectionHeader(tmp[3], level));
648
+ return makeLocalStyle(`${tokens.sectionHeader} mw-section--${level}`, state);
646
649
  }
647
650
  break;
648
651
  }
@@ -1137,7 +1140,8 @@ let MediaWiki = (() => {
1137
1140
  : this.eatWikiText(style)(stream, state);
1138
1141
  };
1139
1142
  }
1140
- inSectionHeader(str) {
1143
+ inSectionHeader(str, level) {
1144
+ const headerStyle = `${tokens.sectionHeader} mw-section--${level}`, style = `${tokens.section} mw-section--${level}`;
1141
1145
  return (stream, state) => {
1142
1146
  if (stream.sol()) {
1143
1147
  pop(state);
@@ -1146,16 +1150,16 @@ let MediaWiki = (() => {
1146
1150
  else if (stream.match(headerRegex)) {
1147
1151
  if (stream.eol()) {
1148
1152
  stream.backUp(str.length);
1149
- state.tokenize = this.inStr(str, 'sectionHeader');
1153
+ state.tokenize = this.inStr(str, headerStyle);
1150
1154
  }
1151
1155
  else if (stream.match(/^<!--(?!.*?-->.*?=)/u, false)) {
1152
1156
  // T171074: handle trailing comments
1153
1157
  stream.backUp(str.length);
1154
- state.tokenize = this.inStr('<!--', false, 'sectionHeader');
1158
+ state.tokenize = this.inStr('<!--', false, headerStyle);
1155
1159
  }
1156
- return makeLocalTagStyle('section', state);
1160
+ return makeLocalStyle(style, state);
1157
1161
  }
1158
- return this.eatWikiText('section')(stream, state);
1162
+ return this.eatWikiText(style)(stream, state);
1159
1163
  };
1160
1164
  }
1161
1165
  get inComment() {
@@ -1734,8 +1738,13 @@ let MediaWiki = (() => {
1734
1738
  stream.pos === oldToken?.pos
1735
1739
  && stream.string === oldToken.string
1736
1740
  && cmpNesting(state, oldToken.state)) {
1737
- const { pos, string, state: { bold, italic, ...other }, style } = readyTokens[0];
1738
- Object.assign(state, other);
1741
+ const { pos, string, state: other, style } = readyTokens[0];
1742
+ for (const key in other) {
1743
+ if (key !== 'bold' && key !== 'italic') {
1744
+ // @ts-expect-error assign readonly properties
1745
+ state[key] = other[key];
1746
+ }
1747
+ }
1739
1748
  if (!(state.extName && state.extMode)
1740
1749
  && state.nLink === 0
1741
1750
  && typeof style === 'string'
package/dist/util.d.ts CHANGED
@@ -1,8 +1,9 @@
1
- import type { EditorView, TooltipView } from '@codemirror/view';
2
- import type { Text, EditorState, SelectionRange } from '@codemirror/state';
1
+ import type { EditorView, TooltipView, Decoration } from '@codemirror/view';
2
+ import type { Text, EditorState, SelectionRange, Range } from '@codemirror/state';
3
3
  import type { SyntaxNode } from '@lezer/common';
4
4
  import type { Position } from 'vscode-languageserver-types';
5
5
  import type { ConfigGetter } from '@bhsd/browser';
6
+ import type { DocRange } from './fold';
6
7
  /**
7
8
  * 转义HTML字符串
8
9
  * @param text 原字符串
@@ -37,12 +38,28 @@ export declare const createTooltipView: (view: EditorView, innerHTML: string) =>
37
38
  */
38
39
  export declare const sliceDoc: (state: EditorState, node: SyntaxNode | SelectionRange) => string;
39
40
  /**
40
- * Update the stack of opening (+) or closing (-) brackets
41
+ * Update the stack of opening (+) or closing (-) braces
41
42
  * @param state
42
43
  * @param node 语法树节点
43
44
  * @test
44
45
  */
45
46
  export declare const braceStackUpdate: (state: EditorState, node: SyntaxNode) => [number, number];
47
+ /**
48
+ * Push a decoration to the array if the range is not empty
49
+ * @param decorations Decoration 数组
50
+ * @param decoration Decoration 实例
51
+ * @param from 起始位置或节点
52
+ * @param to 结束位置
53
+ */
54
+ export declare const pushDecoration: (decorations: Range<Decoration>[], decoration: Decoration, from: number | DocRange, to?: number) => void;
55
+ /**
56
+ * Mark the type in a JSDoc/LDoc comment
57
+ * @param decorations
58
+ * @param from 起始位置
59
+ * @param mt 正则表达式匹配结果,第1个捕获组为标签,第2个捕获组为类型的起始括号`{`
60
+ * @test
61
+ */
62
+ export declare const markDocTagType: (decorations: Range<Decoration>[], from: number, mt: RegExpExecArray) => Range<Decoration>[];
46
63
  /**
47
64
  * Check if the node is a template parameter value
48
65
  * @param node 语法树节点
package/dist/util.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import elt from 'crelt';
2
2
  import { tokens } from './config.js';
3
- import { hoverSelector, } from './constants.js';
3
+ import { hoverSelector, doctagMark, typeMark, } from './constants.js';
4
4
  const dict = { '\n': '<br>', '&': '&amp;', '<': '&lt;' };
5
5
  /**
6
6
  * 转义HTML字符串
@@ -47,7 +47,7 @@ export const createTooltipView = (view, innerHTML) => {
47
47
  */
48
48
  export const sliceDoc = (state, node) => state.sliceDoc(node.from, node.to);
49
49
  /**
50
- * Update the stack of opening (+) or closing (-) brackets
50
+ * Update the stack of opening (+) or closing (-) braces
51
51
  * @param state
52
52
  * @param node 语法树节点
53
53
  * @test
@@ -56,6 +56,46 @@ export const braceStackUpdate = (state, node) => {
56
56
  const brackets = sliceDoc(state, node);
57
57
  return [brackets.split('{{').length - 1, 1 - brackets.split('}}').length];
58
58
  };
59
+ /**
60
+ * Push a decoration to the array if the range is not empty
61
+ * @param decorations Decoration 数组
62
+ * @param decoration Decoration 实例
63
+ * @param from 起始位置或节点
64
+ * @param to 结束位置
65
+ */
66
+ export const pushDecoration = (decorations, decoration, from, to) => {
67
+ if (typeof from !== 'number') {
68
+ ({ from, to } = from);
69
+ }
70
+ if (from < to) {
71
+ decorations.push(decoration.range(from, to));
72
+ }
73
+ };
74
+ /**
75
+ * Mark the type in a JSDoc/LDoc comment
76
+ * @param decorations
77
+ * @param from 起始位置
78
+ * @param mt 正则表达式匹配结果,第1个捕获组为标签,第2个捕获组为类型的起始括号`{`
79
+ * @test
80
+ */
81
+ export const markDocTagType = (decorations, from, mt) => {
82
+ const { input, indices } = mt, [start, end] = indices[1];
83
+ pushDecoration(decorations, doctagMark, from + start, from + end);
84
+ if (mt[2]) {
85
+ const re = /[{}]/gu, [, left] = indices[2];
86
+ re.lastIndex = left;
87
+ let m = re.exec(input), balance = 1;
88
+ while (m) {
89
+ balance += m[0] === '{' ? 1 : -1;
90
+ if (balance === 0) {
91
+ pushDecoration(decorations, typeMark, from + left, from + m.index);
92
+ break;
93
+ }
94
+ m = re.exec(input);
95
+ }
96
+ }
97
+ return decorations;
98
+ };
59
99
  /**
60
100
  * Check if the node is a template parameter value
61
101
  * @param node 语法树节点
package/dist/vue.js CHANGED
@@ -3,13 +3,13 @@ import { htmlLanguage, htmlCompletionSource } from '@codemirror/lang-html';
3
3
  import { javascript } from '@codemirror/lang-javascript';
4
4
  import { LanguageSupport } from '@codemirror/language';
5
5
  import { cssCompletion } from './css.js';
6
- import { jsCompletion, markGlobalsPlugin } from './javascript.js';
6
+ import { jsCompletion, markGlobalsAndDocTagPlugin } from './javascript.js';
7
7
  export default (_, cm) => vue({
8
8
  base: new LanguageSupport(htmlLanguage, [
9
9
  htmlLanguage.data.of({ autocomplete: htmlCompletionSource }),
10
10
  javascript().support,
11
11
  jsCompletion,
12
12
  cssCompletion(),
13
- markGlobalsPlugin(cm),
13
+ markGlobalsAndDocTagPlugin(cm),
14
14
  ]),
15
15
  });