@bhsd/codemirror-mediawiki 3.12.2 → 3.12.3

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.
@@ -51,6 +51,7 @@ export const trySelectMatchingBrackets = (state, pos, dir, config, inside = fals
51
51
  };
52
52
  /** @test */
53
53
  export const customSelection = {
54
+ 0: state => ({ anchor: 0, head: state.doc.length }),
54
55
  2: (state, pos, config) => trySelectMatchingBrackets(state, pos, -1, config)
55
56
  || trySelectMatchingBrackets(state, pos, 1, config)
56
57
  || trySelectMatchingBrackets(state, pos + 1, -1, config, true)
@@ -66,7 +67,6 @@ export const customSelection = {
66
67
  head: Math.min(doc.length, (dir ? b : a).to + 1),
67
68
  };
68
69
  },
69
- 4: state => ({ anchor: 0, head: state.doc.length }),
70
70
  };
71
71
  const tryMatchBracetks = (state, pos, config) => matchBrackets(state, pos, -1, config)
72
72
  || pos > 0 && matchBrackets(state, pos - 1, 1, config)
@@ -97,8 +97,8 @@ export const myBracketDeco = (state, config) => {
97
97
  };
98
98
  const clickHandler = (e, view, facet, select) => {
99
99
  const pos = view.posAtCoords(e), { state } = view, config = state.facet(facet);
100
- if (pos === null
101
- || config.exclude?.(state, pos)) {
100
+ if (select !== customSelection[0] && (pos === null
101
+ || config.exclude?.(state, pos))) {
102
102
  return false;
103
103
  }
104
104
  const range = select(state, pos, config);
@@ -137,12 +137,10 @@ export default (configs) => {
137
137
  return [
138
138
  extension,
139
139
  EditorView.domEventHandlers({
140
- /**
141
- * @ignore
142
- * @todo 由于括号高亮的重绘,双击会被识别为两次单击,导致功能失效
143
- */
140
+ /** @ignore */
144
141
  mousedown(e, view) {
145
- selection = e.detail in customSelection && clickHandler(e, view, facet, customSelection[e.detail]);
142
+ const n = e.detail % 4;
143
+ selection = e.detail > 0 && n in customSelection && clickHandler(e, view, facet, customSelection[n]);
146
144
  return Boolean(selection);
147
145
  },
148
146
  /** @ignore */
package/dist/math.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { StreamParser } from '@codemirror/language';
2
+ /** @test */
3
+ export declare const math: StreamParser<object>;
package/dist/math.js ADDED
@@ -0,0 +1,58 @@
1
+ import { extCompletion, extData } from './constants.js';
2
+ import { getCompletions } from './util.js';
3
+ let mathFetch;
4
+ /** @test */
5
+ export const math = {
6
+ startState() {
7
+ if (typeof wikiparse === 'object') {
8
+ mathFetch ??= (async () => {
9
+ const data = await (await fetch(`${wikiparse.CDN}/data/ext/math.json`)).json();
10
+ extData['math'] = new Set(data);
11
+ extCompletion['math'] = getCompletions(data);
12
+ })();
13
+ }
14
+ return {};
15
+ },
16
+ token(stream) {
17
+ if (stream.eatSpace()) {
18
+ return '';
19
+ }
20
+ const ch = stream.next();
21
+ switch (ch) {
22
+ case '\\':
23
+ if (stream.eatWhile(/[a-z]/iu)) {
24
+ return extData['math']?.has(stream.current()) === false ? '' : /* #708 */ 'keyword';
25
+ }
26
+ else if (stream.eat(/[,;!\\]/u)) {
27
+ return /* #708 */ 'keyword';
28
+ }
29
+ return stream.eat(/[$&%#{}_]/u) ? /* #219 */ 'atom' : /* #f00 */ 'invalid';
30
+ case '^':
31
+ case '_':
32
+ case '&':
33
+ return 'operator';
34
+ case '{':
35
+ case '}':
36
+ return 'brace';
37
+ case '[':
38
+ case ']':
39
+ return 'squareBracket';
40
+ case '(':
41
+ case ')':
42
+ return 'paren';
43
+ case '.':
44
+ return stream.eatWhile(/\d/u) ? /* #164 */ 'number' : '';
45
+ default:
46
+ if (/\d/u.test(ch)) {
47
+ stream.match(/\d*(?:\.\d*)?/u);
48
+ return /* #164 */ 'number';
49
+ }
50
+ else if (/[a-z]/iu.test(ch)) {
51
+ stream.eatWhile(/[a-z]/iu);
52
+ return /* #256 */ 'variableName.special';
53
+ }
54
+ stream.eatWhile(/[^\\^&{}[\]().\w]/u);
55
+ return '';
56
+ }
57
+ },
58
+ };
@@ -43,7 +43,7 @@ export declare class FullMediaWiki extends MediaWiki {
43
43
  readonly protocols: Completion[];
44
44
  readonly imgKeys: Completion[];
45
45
  readonly htmlAttrs: Completion[];
46
- readonly elementAttrs: Map<string | undefined, Completion[]>;
46
+ readonly elementAttrs: Map<string, Completion[]>;
47
47
  readonly extAttrs: Map<string, Completion[]>;
48
48
  constructor(config: MwConfig, templatedata?: boolean);
49
49
  /**
package/dist/mediawiki.js CHANGED
@@ -9,10 +9,10 @@ import { insertCompletionText, pickedCompletion } from '@codemirror/autocomplete
9
9
  import { isUnderscore } from '@bhsd/cm-util';
10
10
  import { commonHtmlAttrs, htmlAttrs, extAttrs } from 'wikiparser-node/dist/util/sharable.mjs';
11
11
  import { htmlTags, tokens } from './config.js';
12
- import { hoverSelector, isWMF, } from './constants.js';
12
+ import { hoverSelector, extCompletion, isWMF, } from './constants.js';
13
13
  import { lightHighlightStyle } from './theme.js';
14
14
  import { MediaWiki } from './token.js';
15
- import { leadingSpaces, findTemplateName } from './util.js';
15
+ import { getCompletions, getExtTags, leadingSpaces, findTemplateName, } from './util.js';
16
16
  const ranks = { Required: 1, Suggested: 2, Optional: 3, Deprecated: 4 };
17
17
  /**
18
18
  * 是否是普通维基链接
@@ -67,15 +67,9 @@ export class FullMediaWiki extends MediaWiki {
67
67
  type: i ? 'constant' : 'function',
68
68
  label,
69
69
  })));
70
- this.doubleUnderscore = doubleUnderscore.flatMap(Object.keys).filter(isUnderscore).map((label) => ({
71
- type: 'constant',
72
- label,
73
- }));
74
- this.extTags = this.tags.map((label) => ({ type: 'type', label }));
75
- this.htmlTags = htmlTags.filter(tag => !this.tags.includes(tag)).map((label) => ({
76
- type: 'type',
77
- label,
78
- }));
70
+ this.doubleUnderscore = getCompletions(doubleUnderscore.flatMap(Object.keys).filter(isUnderscore), 'constant');
71
+ this.extTags = getCompletions(this.tags, 'type');
72
+ this.htmlTags = getCompletions(htmlTags.filter(tag => !this.tags.includes(tag)), 'type');
79
73
  this.protocols = urlProtocols.split('|').map((label) => ({
80
74
  type: 'namespace',
81
75
  label: label.replace(/\\\//gu, '/'),
@@ -84,17 +78,17 @@ export class FullMediaWiki extends MediaWiki {
84
78
  ? { type: 'property', label: label.slice(0, -2), detail: '$1' }
85
79
  : { type: 'keyword', label });
86
80
  this.htmlAttrs = [
87
- ...[...commonHtmlAttrs].map((label) => ({ type: 'property', label })),
81
+ ...getCompletions([...commonHtmlAttrs], 'property'),
88
82
  { type: 'variable', label: 'data-', detail: '*' },
89
83
  { type: 'namespace', label: 'xmlns:', detail: '*' },
90
84
  ];
91
85
  this.elementAttrs = new Map(Object.entries(htmlAttrs).map(([key, value]) => [
92
86
  key,
93
- [...value].map((label) => ({ type: 'property', label })),
87
+ getCompletions([...value], 'property'),
94
88
  ]));
95
89
  this.extAttrs = new Map(Object.entries(extAttrs).map(([key, value]) => [
96
90
  key,
97
- [...value].map((label) => ({ type: 'property', label })),
91
+ getCompletions([...value], 'property'),
98
92
  ]));
99
93
  }
100
94
  /**
@@ -305,6 +299,26 @@ export class FullMediaWiki extends MediaWiki {
305
299
  // 不可能是状态开关、标签、协议或图片参数名
306
300
  return null;
307
301
  }
302
+ else if ('math' in extCompletion
303
+ && hasTag(types, ['mw-tag-math', 'mw-tag-chem', 'mw-tag-ce'])
304
+ && (types.size === 1 || types.has('keyword') || types.has('invalid'))) {
305
+ const mt = context.matchBefore(/\\[a-z]*$/iu);
306
+ return mt && {
307
+ from: mt.from,
308
+ options: extCompletion['math'],
309
+ validFor: /^[a-z]*$/iu,
310
+ };
311
+ }
312
+ else if ('score' in extCompletion
313
+ && hasTag(types, 'mw-tag-score')
314
+ && (types.size === 1 || types.has('keyword'))) {
315
+ const mt = context.matchBefore(/\\[-a-z]*$/iu);
316
+ return mt && {
317
+ from: mt.from,
318
+ options: extCompletion['score'],
319
+ validFor: /^[-a-z]*$/iu,
320
+ };
321
+ }
308
322
  let mt = context.matchBefore(/__(?:(?!__)[\p{L}\p{N}_])*$/u);
309
323
  if (mt) {
310
324
  return {
@@ -314,8 +328,7 @@ export class FullMediaWiki extends MediaWiki {
314
328
  };
315
329
  }
316
330
  mt = context.matchBefore(/<\/?[a-z\d]*$/iu);
317
- const extTags = [...types].filter(type => type.startsWith('mw-tag-'))
318
- .map(s => s.slice(7));
331
+ const extTags = getExtTags([...types]);
319
332
  if (mt && (explicit || mt.to - mt.from > 1)) {
320
333
  const validFor = /^[a-z\d]*$/iu;
321
334
  if (mt.text[1] === '/') {
@@ -478,7 +491,7 @@ const wikiTheme = /* @__PURE__ */ EditorView.theme({
478
491
  '.cm-mw-entity': {
479
492
  color: 'var(--cm-entity)',
480
493
  },
481
- '.cm-mw-exttag': {
494
+ '.cm-mw-exttag,.cm-mw-tag-score-scheme': {
482
495
  backgroundColor: 'rgb(119,0,170,.04)',
483
496
  },
484
497
  /* eslint-disable no-sparse-arrays */