@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.
@@ -25,20 +25,12 @@ export declare const findEnclosingPlainBrackets: (state: EditorState, pos: numbe
25
25
  * @test
26
26
  */
27
27
  export declare const trySelectMatchingBrackets: (state: EditorState, pos: number, dir: 1 | -1, config?: Config, inside?: boolean) => Selection | false;
28
+ /** @test */
29
+ export declare const customSelection: Record<number, (state: EditorState, pos: number, config?: Config) => Selection | false>;
28
30
  /**
29
31
  * @ignore
30
32
  * @test
31
33
  */
32
- export declare const selectMatchingBrackets: (state: EditorState, pos: number, config?: Config) => Selection | false;
33
- /**
34
- * @ignore
35
- * @test
36
- */
37
- export declare const selectLineBlock: (state: EditorState, pos: number, config?: Config) => Selection | false;
38
- /**
39
- * @ignore
40
- * @test
41
- */
42
- export declare const bracketDeco: (state: EditorState, config: RequiredConfig) => DecorationSet;
34
+ export declare const myBracketDeco: (state: EditorState, config: RequiredConfig) => DecorationSet;
43
35
  declare const _default: (configs?: BracketConfig) => Extension;
44
36
  export default _default;
@@ -1,4 +1,5 @@
1
1
  import { Decoration, EditorView, ViewPlugin } from '@codemirror/view';
2
+ import { EditorSelection } from '@codemirror/state';
2
3
  import { bracketMatching, matchBrackets, syntaxTree } from '@codemirror/language';
3
4
  /**
4
5
  * @ignore
@@ -48,14 +49,25 @@ export const trySelectMatchingBrackets = (state, pos, dir, config, inside = fals
48
49
  head: match.end[rightInside ? 'from' : 'to'],
49
50
  };
50
51
  };
51
- /**
52
- * @ignore
53
- * @test
54
- */
55
- export const selectMatchingBrackets = (state, pos, config) => trySelectMatchingBrackets(state, pos, -1, config)
56
- || trySelectMatchingBrackets(state, pos, 1, config)
57
- || trySelectMatchingBrackets(state, pos + 1, -1, config, true)
58
- || trySelectMatchingBrackets(state, pos - 1, 1, config, true);
52
+ /** @test */
53
+ export const customSelection = {
54
+ 2: (state, pos, config) => trySelectMatchingBrackets(state, pos, -1, config)
55
+ || trySelectMatchingBrackets(state, pos, 1, config)
56
+ || trySelectMatchingBrackets(state, pos + 1, -1, config, true)
57
+ || trySelectMatchingBrackets(state, pos - 1, 1, config, true),
58
+ 3: (state, pos, config) => {
59
+ const { doc } = state, matching = tryMatchBracetks(state, pos, { ...config, afterCursor: true });
60
+ if (!matching || !matching.matched) {
61
+ return false;
62
+ }
63
+ const { start, end } = matching, a = doc.lineAt(start.from), b = doc.lineAt(end.from), dir = a.from < b.from;
64
+ return {
65
+ anchor: (dir ? a : b).from,
66
+ head: Math.min(doc.length, (dir ? b : a).to + 1),
67
+ };
68
+ },
69
+ 4: state => ({ anchor: 0, head: state.doc.length }),
70
+ };
59
71
  const tryMatchBracetks = (state, pos, config) => matchBrackets(state, pos, -1, config)
60
72
  || pos > 0 && matchBrackets(state, pos - 1, 1, config)
61
73
  || config.afterCursor && (matchBrackets(state, pos, 1, config)
@@ -64,22 +76,7 @@ const tryMatchBracetks = (state, pos, config) => matchBrackets(state, pos, -1, c
64
76
  * @ignore
65
77
  * @test
66
78
  */
67
- export const selectLineBlock = (state, pos, config) => {
68
- const { doc } = state, matching = tryMatchBracetks(state, pos, { ...config, afterCursor: true });
69
- if (!matching || !matching.matched) {
70
- return false;
71
- }
72
- const { start, end } = matching, a = doc.lineAt(start.from), b = doc.lineAt(end.from), dir = a.from < b.from;
73
- return {
74
- anchor: (dir ? a : b).from,
75
- head: Math.min(doc.length, (dir ? b : a).to + 1),
76
- };
77
- };
78
- /**
79
- * @ignore
80
- * @test
81
- */
82
- export const bracketDeco = (state, config) => {
79
+ export const myBracketDeco = (state, config) => {
83
80
  const decorations = [], { afterCursor, brackets, renderMatch, exclude, } = config;
84
81
  for (const { empty, head } of state.selection.ranges) {
85
82
  if (!empty) {
@@ -104,10 +101,11 @@ const clickHandler = (e, view, facet, select) => {
104
101
  || config.exclude?.(state, pos)) {
105
102
  return false;
106
103
  }
107
- const selection = select(state, pos, config);
108
- if (selection) {
104
+ const range = select(state, pos, config);
105
+ if (range) {
106
+ const selection = EditorSelection.single(range.anchor, range.head);
109
107
  view.dispatch({ selection });
110
- return true;
108
+ return selection;
111
109
  }
112
110
  return false;
113
111
  };
@@ -115,7 +113,7 @@ export default (configs) => {
115
113
  const extension = bracketMatching(configs), [{ facet }, plugins] = extension;
116
114
  plugins[0] = ViewPlugin.fromClass(class {
117
115
  constructor({ state }) {
118
- this.decorations = bracketDeco(state, state.facet(facet));
116
+ this.decorations = myBracketDeco(state, state.facet(facet));
119
117
  this.paused = false;
120
118
  }
121
119
  update({ docChanged, selectionSet, changes, state, view: { composing } }) {
@@ -125,7 +123,7 @@ export default (configs) => {
125
123
  this.paused = true;
126
124
  }
127
125
  else {
128
- this.decorations = bracketDeco(state, state.facet(facet));
126
+ this.decorations = myBracketDeco(state, state.facet(facet));
129
127
  this.paused = false;
130
128
  }
131
129
  }
@@ -135,19 +133,35 @@ export default (configs) => {
135
133
  return decorations;
136
134
  },
137
135
  });
136
+ let selection = false;
138
137
  return [
139
138
  extension,
140
139
  EditorView.domEventHandlers({
141
- /** @ignore */
142
- click(e, view) {
143
- return e.detail === 3 && clickHandler(e, view, facet, selectLineBlock);
144
- },
145
140
  /**
146
141
  * @ignore
147
142
  * @todo 由于括号高亮的重绘,双击会被识别为两次单击,导致功能失效
148
143
  */
149
- dblclick(e, view) {
150
- return clickHandler(e, view, facet, selectMatchingBrackets);
144
+ mousedown(e, view) {
145
+ selection = e.detail in customSelection && clickHandler(e, view, facet, customSelection[e.detail]);
146
+ return Boolean(selection);
147
+ },
148
+ /** @ignore */
149
+ mouseup() {
150
+ selection = false;
151
+ },
152
+ /** @ignore */
153
+ mousemove(e, view) {
154
+ if (!selection) {
155
+ return false;
156
+ }
157
+ const head = view.posAtCoords(e), { from, to } = selection.main;
158
+ if (head === null || head >= from && head <= to) {
159
+ return false;
160
+ }
161
+ view.dispatch({
162
+ selection: { head, anchor: head < from ? to : from },
163
+ });
164
+ return true;
151
165
  },
152
166
  }),
153
167
  ];
@@ -5,11 +5,11 @@ import type { MatchResult } from '@codemirror/language';
5
5
  import type { SyntaxNode } from '@lezer/common';
6
6
  declare type TagType = 'ext' | 'html';
7
7
  export interface TagMatchResult extends MatchResult {
8
- start: Tag;
9
- end?: Tag;
8
+ start: WikiTag;
9
+ end?: WikiTag;
10
10
  }
11
11
  /** @test */
12
- export declare class Tag {
12
+ export declare class WikiTag {
13
13
  readonly type: TagType;
14
14
  readonly name: string;
15
15
  readonly first: SyntaxNode;
@@ -27,13 +27,13 @@ export declare class Tag {
27
27
  * @param node 语法树节点
28
28
  * @test
29
29
  */
30
- export declare const getTag: (state: EditorState, node: SyntaxNode) => Tag | null;
30
+ export declare const getTag: (state: EditorState, node: SyntaxNode) => WikiTag | null;
31
31
  /**
32
32
  * 搜索匹配的标签
33
33
  * @param state
34
34
  * @param origin 起始标签
35
35
  */
36
- export declare const searchTag: (state: EditorState, origin: Tag) => Tag | null;
36
+ export declare const searchTag: (state: EditorState, origin: WikiTag) => WikiTag | null;
37
37
  /**
38
38
  * 匹配标签
39
39
  * @param state
package/dist/matchTag.js CHANGED
@@ -5,7 +5,7 @@ import { voidHtmlTags, selfClosingTags } from './config.js';
5
5
  import { matchingCls, nonmatchingCls } from './constants.js';
6
6
  import { sliceDoc, pushDecoration } from './util.js';
7
7
  /** @test */
8
- export class Tag {
8
+ export class WikiTag {
9
9
  get closing() {
10
10
  return isClosing(this.first, this.type, this.state, true);
11
11
  }
@@ -59,7 +59,7 @@ export const getTag = (state, node) => {
59
59
  ({ prevSibling } = prevSibling);
60
60
  }
61
61
  const name = getName(state, nameNode);
62
- return new Tag(type, name, prevSibling, nextSibling, state);
62
+ return new WikiTag(type, name, prevSibling, nextSibling, state);
63
63
  };
64
64
  /**
65
65
  * 搜索匹配的标签
@@ -114,7 +114,7 @@ export const matchTag = (state, pos) => {
114
114
  const end = searchTag(state, start);
115
115
  return end ? { matched: true, start, end } : { matched: false, start };
116
116
  };
117
- const matchingMark = /* @__PURE__ */ Decoration.mark({ class: matchingCls }), nonmatchingMark = /* @__PURE__ */ Decoration.mark({ class: nonmatchingCls });
117
+ const matchingTag = /* @__PURE__ */ Decoration.mark({ class: matchingCls }), nonmatchingTag = /* @__PURE__ */ Decoration.mark({ class: nonmatchingCls });
118
118
  export default /* @__PURE__ */ StateField.define({
119
119
  create() {
120
120
  return Decoration.none;
@@ -128,7 +128,7 @@ export default /* @__PURE__ */ StateField.define({
128
128
  if (range.empty) {
129
129
  const match = matchTag(state, range.head);
130
130
  if (match) {
131
- const mark = match.matched ? matchingMark : nonmatchingMark, { start, end } = match;
131
+ const mark = match.matched ? matchingTag : nonmatchingTag, { start, end } = match;
132
132
  pushDecoration(decorations, mark, start);
133
133
  if (end) {
134
134
  pushDecoration(decorations, mark, end);
@@ -6,7 +6,7 @@
6
6
  import { LanguageSupport } from '@codemirror/language';
7
7
  import { EditorView } from '@codemirror/view';
8
8
  import { MediaWiki } from './token.js';
9
- import type { StreamParser, TagStyle } from '@codemirror/language';
9
+ import type { TagStyle } from '@codemirror/language';
10
10
  import type { CompletionSource, Completion } from '@codemirror/autocomplete';
11
11
  import type { MwConfig } from './token';
12
12
  import type { TagName } from './config';
@@ -52,7 +52,6 @@ export declare class FullMediaWiki extends MediaWiki {
52
52
  * @see https://codemirror.net/docs/ref/#language.TagStyle
53
53
  */
54
54
  getTagStyles(): TagStyle[];
55
- mediawiki(tags?: string[]): StreamParser<any>;
56
55
  /** 自动补全魔术字和标签名 */
57
56
  get completionSource(): CompletionSource;
58
57
  }
package/dist/mediawiki.js CHANGED
@@ -10,6 +10,7 @@ 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
12
  import { hoverSelector, isWMF, } from './constants.js';
13
+ import { lightHighlightStyle } from './theme.js';
13
14
  import { MediaWiki } from './token.js';
14
15
  import { leadingSpaces, findTemplateName } from './util.js';
15
16
  const ranks = { Required: 1, Suggested: 2, Optional: 3, Deprecated: 4 };
@@ -107,13 +108,6 @@ export class FullMediaWiki extends MediaWiki {
107
108
  class: `cm-${className}`,
108
109
  }));
109
110
  }
110
- mediawiki(tags) {
111
- const parser = super.mediawiki(tags);
112
- parser.languageData = {
113
- closeBrackets: { brackets: ['(', '[', '{', '"'], before: ')]}>' },
114
- };
115
- return parser;
116
- }
117
111
  /**
118
112
  * 提供链接建议
119
113
  * @param str 搜索字符串,开头不包含` `,但可能包含`_`
@@ -395,7 +389,7 @@ const getGrounds = (grounds, r, g, b, a) => ({
395
389
  * @license GPL-2.0-or-later
396
390
  * @see https://gerrit.wikimedia.org/g/mediawiki/extensions/CodeMirror
397
391
  */
398
- const theme = /* @__PURE__ */ EditorView.theme({
392
+ const wikiTheme = /* @__PURE__ */ EditorView.theme({
399
393
  [getSelector(['', '~*'], 'section--1')]: {
400
394
  fontSize: '1.8em',
401
395
  lineHeight: '1.2em',
@@ -546,8 +540,9 @@ const theme = /* @__PURE__ */ EditorView.theme({
546
540
  export const mediawikiBase = (config, templatedata) => {
547
541
  const mode = new FullMediaWiki(config, templatedata), lang = StreamLanguage.define(mode.mediawiki());
548
542
  return new LanguageSupport(lang, [
543
+ lightHighlightStyle,
549
544
  syntaxHighlighting(HighlightStyle.define(mode.getTagStyles())),
550
- theme,
545
+ wikiTheme,
551
546
  lang.data.of({ autocomplete: mode.completionSource }),
552
547
  ]);
553
548
  };