@bhsd/codemirror-mediawiki 3.12.1 → 3.12.2

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/ref.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { EditorState, Extension } from '@codemirror/state';
2
2
  import type { CodeMirror6 } from './codemirror';
3
- import type { Tag } from './matchTag';
3
+ import type { WikiTag } from './matchTag';
4
4
  /**
5
5
  * 高亮<ref>内容
6
6
  * @param state 编辑器EditorState
@@ -13,6 +13,6 @@ export declare const highlightRef: (state: EditorState, text: string) => string;
13
13
  * @ignore
14
14
  * @test
15
15
  */
16
- export declare const needHover: (state: EditorState, { name, selfClosing, first, last }: Tag) => boolean;
16
+ export declare const needHover: (state: EditorState, { name, selfClosing, first, last }: WikiTag) => boolean;
17
17
  declare const _default: (articlePath?: string) => (cm: CodeMirror6) => Extension;
18
18
  export default _default;
package/dist/ref.js CHANGED
@@ -3,7 +3,7 @@ import { ensureSyntaxTree, language, highlightingFor } from '@codemirror/languag
3
3
  import { highlightCode } from '@lezer/highlight';
4
4
  import { getLSP } from '@bhsd/browser';
5
5
  import elt from 'crelt';
6
- import { base } from './constants.js';
6
+ import { baseData } from './constants.js';
7
7
  import { tokens } from './config.js';
8
8
  import { getTag } from './matchTag.js';
9
9
  import { sliceDoc, indexToPos, posToIndex, escHTML, toConfigGetter, } from './util.js';
@@ -13,7 +13,7 @@ const trees = new WeakMap(), selector = '.cm-tooltip-ref', noDef = '.cm-tooltip-
13
13
  * @param state
14
14
  * @param node 语法树节点
15
15
  */
16
- const getName = (state, node) => sliceDoc(state, node).trim();
16
+ const getRefName = (state, node) => sliceDoc(state, node).trim();
17
17
  /**
18
18
  * 高亮<ref>内容
19
19
  * @param state 编辑器EditorState
@@ -45,7 +45,7 @@ export const needHover = (state, { name, selfClosing, first, last }) => {
45
45
  if (name === 'ref' && selfClosing) {
46
46
  let prevSibling = last, nextSibling = null;
47
47
  while (prevSibling && prevSibling.from > first.to) {
48
- const key = getName(state, prevSibling);
48
+ const key = getRefName(state, prevSibling);
49
49
  if (prevSibling.name.split('_').includes(tokens.extTagAttribute)
50
50
  && /(?:^|\s)name(?:$|[\s=])/iu.test(key)) {
51
51
  if (/(?:^|\s)name\s*=/iu.test(key)) {
@@ -56,7 +56,7 @@ export const needHover = (state, { name, selfClosing, first, last }) => {
56
56
  ({ prevSibling } = prevSibling);
57
57
  }
58
58
  if (nextSibling?.name.includes(tokens.extTagAttributeValue)) {
59
- let target = getName(state, nextSibling);
59
+ let target = getRefName(state, nextSibling);
60
60
  const quote = target.charAt(0);
61
61
  if (quote === '"' || quote === "'") {
62
62
  target = target.slice(1, target.slice(-1) === quote ? -1 : undefined).trim();
@@ -75,7 +75,7 @@ export default (articlePath) => (cm) => {
75
75
  if (node?.name.includes('-exttag-')) {
76
76
  const tag = getTag(state, node);
77
77
  if (tag && needHover(state, tag)) {
78
- const { doc } = state, ref = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideDefinition(doc.toString(), indexToPos(doc, tag.first.to));
78
+ const { doc } = state, ref = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), baseData.CDN)?.provideDefinition(doc.toString(), indexToPos(doc, tag.first.to));
79
79
  return {
80
80
  pos,
81
81
  end: tag.to,
package/dist/signature.js CHANGED
@@ -2,16 +2,16 @@ import { EditorView, showTooltip } from '@codemirror/view';
2
2
  import { StateField, StateEffect } from '@codemirror/state';
3
3
  import { syntaxTree } from '@codemirror/language';
4
4
  import { getLSP } from '@bhsd/browser';
5
- import { base } from './constants.js';
6
- import { createTooltipView, indexToPos, escHTML, toConfigGetter, findTemplateName, isTemplate, } from './util.js';
7
- const stateEffect = StateEffect.define(), field = StateField.define({
5
+ import { baseData } from './constants.js';
6
+ import { createTooltipView, indexToPos, escHTML, toConfigGetter, findTemplateName, isTemplateParam, } from './util.js';
7
+ const signatureEffect = StateEffect.define(), signatureField = StateField.define({
8
8
  create() {
9
9
  return undefined;
10
10
  },
11
11
  update(oldValue, { state: { doc, selection: { main: { head } } }, effects }) {
12
12
  const text = doc.toString();
13
13
  for (const effect of effects) {
14
- if (effect.is(stateEffect)) {
14
+ if (effect.is(signatureEffect)) {
15
15
  const { value } = effect;
16
16
  if (head === value.cursor && text === value.text) {
17
17
  return value;
@@ -40,25 +40,25 @@ export const getSignatureHelp = ({ signatures, activeParameter: active }) => sig
40
40
  }).join('<br>');
41
41
  export default (articlePath) => (cm) => {
42
42
  return [
43
- field,
43
+ signatureField,
44
44
  EditorView.updateListener.of(({ view, state, docChanged, selectionSet }) => {
45
- if (docChanged || selectionSet && state.field(field)?.signatureHelp?.signatures.length) {
45
+ if (docChanged || selectionSet && state.field(signatureField)?.signatureHelp?.signatures.length) {
46
46
  const { doc, selection: { main } } = state, { head: cursor } = main, text = doc.toString();
47
47
  if (!main.empty) {
48
48
  view.dispatch({
49
- effects: stateEffect.of({ text, cursor }),
49
+ effects: signatureEffect.of({ text, cursor }),
50
50
  });
51
51
  return;
52
52
  }
53
53
  (async () => {
54
- let signatureHelp = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideSignatureHelp(text, indexToPos(doc, cursor));
54
+ let signatureHelp = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), baseData.CDN)?.provideSignatureHelp(text, indexToPos(doc, cursor));
55
55
  if (!signatureHelp && typeof cm.langConfig?.templateSignature === 'function') {
56
56
  const tree = syntaxTree(state);
57
57
  let node = tree.resolve(cursor, -1);
58
- if (node.to === cursor && !isTemplate(node)) {
58
+ if (node.to === cursor && !isTemplateParam(node)) {
59
59
  node = tree.resolve(cursor, 1);
60
60
  }
61
- if (isTemplate(node)) {
61
+ if (isTemplateParam(node)) {
62
62
  const [templateName, parameterName] = findTemplateName(state, node), tooltip = cm.langConfig.templateSignature(templateName, parameterName);
63
63
  if (tooltip) {
64
64
  signatureHelp = { signatures: [tooltip] };
@@ -66,7 +66,7 @@ export default (articlePath) => (cm) => {
66
66
  }
67
67
  }
68
68
  view.dispatch({
69
- effects: stateEffect.of({ text, cursor, signatureHelp }),
69
+ effects: signatureEffect.of({ text, cursor, signatureHelp }),
70
70
  });
71
71
  })();
72
72
  }
@@ -76,12 +76,12 @@ export default (articlePath) => (cm) => {
76
76
  if (key === 'Escape') {
77
77
  const { doc, selection: { main: { head } } } = view.state;
78
78
  view.dispatch({
79
- effects: stateEffect.of({ text: doc.toString(), cursor: head }),
79
+ effects: signatureEffect.of({ text: doc.toString(), cursor: head }),
80
80
  });
81
81
  }
82
82
  },
83
83
  }),
84
- showTooltip.from(field, (value) => {
84
+ showTooltip.from(signatureField, (value) => {
85
85
  if (!value) {
86
86
  return null;
87
87
  }
package/dist/static.d.ts CHANGED
@@ -21,6 +21,9 @@ export declare const tagModes: {
21
21
  combobox: string;
22
22
  combooption: string;
23
23
  inputbox: string;
24
+ templatedata: string;
25
+ maplink: string;
26
+ mapframe: string;
24
27
  };
25
28
  /**
26
29
  * @ignore
package/dist/static.js CHANGED
@@ -20,6 +20,9 @@ export const tagModes = {
20
20
  combobox: 'text/combobox',
21
21
  combooption: 'mediawiki',
22
22
  inputbox: 'text/inputbox',
23
+ templatedata: 'json',
24
+ maplink: 'jsonc',
25
+ mapframe: 'jsonc',
23
26
  };
24
27
  /**
25
28
  * @ignore
package/dist/theme.d.ts CHANGED
@@ -6,4 +6,4 @@ export declare const light: Extension,
6
6
  * @author Bhsd
7
7
  * @see https://zh.moegirl.org.cn/User:%E9%AC%BC%E5%BD%B1233/nord-moeskin.css
8
8
  */
9
- nord: Extension;
9
+ nordDark: Extension;
package/dist/theme.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { EditorView } from '@codemirror/view';
2
2
  import { syntaxHighlighting, HighlightStyle, defaultHighlightStyle } from '@codemirror/language';
3
- import { nord as nordBase } from 'cm6-theme-nord';
3
+ import { nord } 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
6
  export const lightHighlightStyle = /* @__PURE__ */ (() => syntaxHighlighting(HighlightStyle.define(defaultHighlightStyle.specs, { themeType: 'light' })))();
@@ -36,6 +36,9 @@ export const light = /* @__PURE__ */ EditorView.theme({
36
36
  '.cm-doctag-type>*': {
37
37
  color: '#085',
38
38
  },
39
+ '.cm-doctag-var>*': {
40
+ color: '#00f',
41
+ },
39
42
  [matching]: {
40
43
  backgroundColor: 'rgb(50,140,130,.32)',
41
44
  },
@@ -48,8 +51,8 @@ export const light = /* @__PURE__ */ EditorView.theme({
48
51
  * @author Bhsd
49
52
  * @see https://zh.moegirl.org.cn/User:%E9%AC%BC%E5%BD%B1233/nord-moeskin.css
50
53
  */
51
- nord = /* @__PURE__ */ (() => [
52
- nordBase,
54
+ nordDark = /* @__PURE__ */ (() => [
55
+ nord,
53
56
  EditorView.theme({
54
57
  '&': {
55
58
  '--cm-arg': '#9f78a5',
@@ -81,6 +84,9 @@ nord = /* @__PURE__ */ (() => [
81
84
  '.cm-doctag-type>*': {
82
85
  color: '#ebcb8b',
83
86
  },
87
+ '.cm-doctag-var>*': {
88
+ color: '#8fbcbb',
89
+ },
84
90
  'div.cm-activeLine': {
85
91
  backgroundColor: 'rgb(76,86,106,.27)',
86
92
  },
package/dist/token.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * @see https://gerrit.wikimedia.org/g/mediawiki/extensions/CodeMirror
5
5
  */
6
6
  import { Tag } from '@lezer/highlight';
7
+ import { jsonBasic, jsonc } from './json.js';
7
8
  import type { MwConfig as MwConfigBase } from '@bhsd/cm-util';
8
9
  import type { EditorState } from '@codemirror/state';
9
10
  import type { StreamParser, StringStream as StringStreamBase } from '@codemirror/language';
@@ -21,21 +22,21 @@ declare interface Nesting extends Record<NestCount, number> {
21
22
  export interface State extends Nesting {
22
23
  readonly stack: Tokenizer[];
23
24
  readonly inHtmlTag: string[];
25
+ readonly dt: Partial<Nesting> & {
26
+ n: number;
27
+ html: number;
28
+ };
29
+ readonly data: MediaWikiData;
24
30
  tokenize: Tokenizer;
25
31
  extMode: StreamParser<object> | false;
26
32
  lbrack: boolean | undefined;
27
33
  bold: boolean;
28
34
  italic: boolean;
29
- dt: Partial<Nesting> & {
30
- n: number;
31
- html: number;
32
- };
33
35
  sof: boolean;
34
36
  redirect: {
35
37
  colon: boolean;
36
38
  } | false;
37
39
  imgLink: boolean;
38
- data: MediaWikiData;
39
40
  }
40
41
  declare type ExtState = Omit<State, 'dt'> & Partial<Pick<State, 'dt'>>;
41
42
  declare interface Token {
@@ -206,5 +207,7 @@ export declare class MediaWiki {
206
207
  'text/inputbox'(): StreamParser<State>;
207
208
  inGallery(section?: boolean): Tokenizer;
208
209
  'text/gallery'(tags: string[]): StreamParser<State>;
210
+ json(): typeof jsonBasic;
211
+ jsonc(): typeof jsonc;
209
212
  }
210
213
  export {};
package/dist/token.js CHANGED
@@ -43,6 +43,7 @@ import { getRegex } from '@bhsd/common';
43
43
  import { decodeHTML } from '@bhsd/browser';
44
44
  import { otherParserFunctions } from '@bhsd/cm-util';
45
45
  import { htmlTags, voidHtmlTags, selfClosingTags, tokenTable, tokens } from './config.js';
46
+ import { jsonBasic, jsonc } from './json.js';
46
47
  class MediaWikiData {
47
48
  constructor(tags, urlProtocols) {
48
49
  this.tags = tags.includes('translate') ? tags.filter(tag => tag !== 'tvar') : tags;
@@ -1229,7 +1230,7 @@ let MediaWiki = (() => {
1229
1230
  }
1230
1231
  const t = state.stack[0], pipe = (['inTemplateArgument', 'inParserFunctionArgument', 'inVariable'].includes(t.name) ? '|' : '')
1231
1232
  + getEqual(t);
1232
- if (pipe.includes(stream.peek() ?? '')) {
1233
+ if (pipe.includes(stream.peek() || '')) {
1233
1234
  pop(state);
1234
1235
  return '';
1235
1236
  }
@@ -1267,8 +1268,8 @@ let MediaWiki = (() => {
1267
1268
  const mt = stream.match(re);
1268
1269
  if (isLang) {
1269
1270
  let lang = mt[0].trim().toLowerCase();
1270
- if (lang === 'js') {
1271
- lang = 'javascript';
1271
+ if (lang === 'wiki' || lang === 'wikitext') {
1272
+ lang = 'mediawiki';
1272
1273
  }
1273
1274
  if (lang in this) {
1274
1275
  state.extMode = this[lang]();
@@ -1877,6 +1878,12 @@ let MediaWiki = (() => {
1877
1878
  ? state.extMode.indent(state.extState, textAfter, context)
1878
1879
  : null;
1879
1880
  },
1881
+ languageData: {
1882
+ closeBrackets: {
1883
+ brackets: ['(', '[', '{', '"'],
1884
+ before: ')]}>',
1885
+ },
1886
+ },
1880
1887
  ...tags
1881
1888
  ? undefined
1882
1889
  : {
@@ -2021,6 +2028,12 @@ let MediaWiki = (() => {
2021
2028
  },
2022
2029
  };
2023
2030
  }
2031
+ json() {
2032
+ return jsonBasic;
2033
+ }
2034
+ jsonc() {
2035
+ return jsonc;
2036
+ }
2024
2037
  };
2025
2038
  })();
2026
2039
  export { MediaWiki };
package/dist/util.d.ts CHANGED
@@ -57,14 +57,15 @@ export declare const pushDecoration: (decorations: Range<Decoration>[], decorati
57
57
  * @param decorations
58
58
  * @param from 起始位置
59
59
  * @param mt 正则表达式匹配结果,第1个捕获组为标签,第2个捕获组为类型的起始括号`{`
60
+ * @param offset Decoration 向外扩展的大小,默认为0
60
61
  * @test
61
62
  */
62
- export declare const markDocTagType: (decorations: Range<Decoration>[], from: number, mt: RegExpExecArray) => Range<Decoration>[];
63
+ export declare const markDocTagType: (decorations: Range<Decoration>[], from: number, mt: RegExpExecArray, offset?: number) => number;
63
64
  /**
64
65
  * Check if the node is a template parameter value
65
66
  * @param node 语法树节点
66
67
  */
67
- export declare const isTemplate: (node: SyntaxNode) => boolean;
68
+ export declare const isTemplateParam: (node: SyntaxNode) => boolean;
68
69
  /**
69
70
  * Find the current template name and parameter name
70
71
  * @param state
package/dist/util.js CHANGED
@@ -76,9 +76,10 @@ export const pushDecoration = (decorations, decoration, from, to) => {
76
76
  * @param decorations
77
77
  * @param from 起始位置
78
78
  * @param mt 正则表达式匹配结果,第1个捕获组为标签,第2个捕获组为类型的起始括号`{`
79
+ * @param offset Decoration 向外扩展的大小,默认为0
79
80
  * @test
80
81
  */
81
- export const markDocTagType = (decorations, from, mt) => {
82
+ export const markDocTagType = (decorations, from, mt, offset = 0) => {
82
83
  const { input, indices } = mt, [start, end] = indices[1];
83
84
  pushDecoration(decorations, doctagMark, from + start, from + end);
84
85
  if (mt[2]) {
@@ -88,19 +89,19 @@ export const markDocTagType = (decorations, from, mt) => {
88
89
  while (m) {
89
90
  balance += m[0] === '{' ? 1 : -1;
90
91
  if (balance === 0) {
91
- pushDecoration(decorations, typeMark, from + left, from + m.index);
92
- break;
92
+ pushDecoration(decorations, typeMark, from + left - offset, from + m.index + offset);
93
+ return m.index + 1;
93
94
  }
94
95
  m = re.exec(input);
95
96
  }
96
97
  }
97
- return decorations;
98
+ return end;
98
99
  };
99
100
  /**
100
101
  * Check if the node is a template parameter value
101
102
  * @param node 语法树节点
102
103
  */
103
- export const isTemplate = (node) => node.name.split('_').includes(tokens.template);
104
+ export const isTemplateParam = (node) => node.name.split('_').includes(tokens.template);
104
105
  /**
105
106
  * Find the current template name and parameter name
106
107
  * @param state
@@ -109,7 +110,7 @@ export const isTemplate = (node) => node.name.split('_').includes(tokens.templat
109
110
  */
110
111
  export const findTemplateName = (state, node) => {
111
112
  let stack = -1, { prevSibling } = node,
112
- /** 可包含`_`、`:`等 */ page = '', parameter = '', need = isTemplate(node);
113
+ /** 可包含`_`、`:`等 */ page = '', parameter = '', need = isTemplateParam(node);
113
114
  while (prevSibling) {
114
115
  const { name } = prevSibling;
115
116
  if (name.includes(tokens.templateBracket)) {