@bhsd/codemirror-mediawiki 3.11.4 → 3.12.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.
@@ -1,3 +1,4 @@
1
+ import type { DecorationSet } from '@codemirror/view';
1
2
  import type { Extension, EditorState } from '@codemirror/state';
2
3
  import type { Config, MatchResult } from '@codemirror/language';
3
4
  import type { SyntaxNode } from '@lezer/common';
@@ -5,6 +6,10 @@ export interface Selection {
5
6
  anchor: number;
6
7
  head: number;
7
8
  }
9
+ export interface BracketConfig extends Config {
10
+ exclude?: (state: EditorState, pos: number) => boolean;
11
+ }
12
+ export type RequiredConfig = Required<Config> & BracketConfig;
8
13
  /**
9
14
  * @ignore
10
15
  * @test
@@ -25,5 +30,10 @@ export declare const trySelectMatchingBrackets: (state: EditorState, pos: number
25
30
  * @test
26
31
  */
27
32
  export declare const selectMatchingBrackets: (state: EditorState, pos: number, config?: Config) => Selection | false;
28
- declare const _default: (configs?: Config) => Extension;
33
+ /**
34
+ * @ignore
35
+ * @test
36
+ */
37
+ export declare const bracketDeco: (state: EditorState, config: RequiredConfig) => DecorationSet;
38
+ declare const _default: (configs?: BracketConfig) => Extension;
29
39
  export default _default;
@@ -1,4 +1,4 @@
1
- import { Decoration, EditorView } from '@codemirror/view';
1
+ import { Decoration, EditorView, ViewPlugin } from '@codemirror/view';
2
2
  import { bracketMatching, matchBrackets, syntaxTree } from '@codemirror/language';
3
3
  /**
4
4
  * @ignore
@@ -56,30 +56,54 @@ export const selectMatchingBrackets = (state, pos, config) => trySelectMatchingB
56
56
  || trySelectMatchingBrackets(state, pos, 1, config)
57
57
  || trySelectMatchingBrackets(state, pos + 1, -1, config, true)
58
58
  || trySelectMatchingBrackets(state, pos - 1, 1, config, true);
59
+ /**
60
+ * @ignore
61
+ * @test
62
+ */
63
+ export const bracketDeco = (state, config) => {
64
+ const decorations = [], { afterCursor, brackets, renderMatch, exclude, } = config;
65
+ for (const { empty, head } of state.selection.ranges) {
66
+ if (!empty) {
67
+ continue;
68
+ }
69
+ const tree = syntaxTree(state), excluded = exclude?.(state, head), match = !excluded && // eslint-disable-line @stylistic/operator-linebreak
70
+ (matchBrackets(state, head, -1, config)
71
+ || head > 0 && matchBrackets(state, head - 1, 1, config)
72
+ || afterCursor && (matchBrackets(state, head, 1, config)
73
+ || head < state.doc.length && matchBrackets(state, head + 1, -1, config)))
74
+ || findEnclosingBrackets(tree.resolveInner(head, -1), head, brackets)
75
+ || afterCursor && findEnclosingBrackets(tree.resolveInner(head, 1), head, brackets)
76
+ || // eslint-disable-line @stylistic/operator-linebreak
77
+ !excluded && // eslint-disable-line @stylistic/operator-linebreak
78
+ findEnclosingPlainBrackets(state, head, config);
79
+ if (match) {
80
+ decorations.push(...renderMatch(match, state));
81
+ }
82
+ }
83
+ return Decoration.set(decorations, true);
84
+ };
59
85
  export default (configs) => {
60
- const extension = bracketMatching(configs), [{ facet }, [field]] = extension;
61
- Object.assign(field, {
62
- updateF(value, { state, docChanged, selection }) {
63
- if (!docChanged && !selection) {
64
- return value;
65
- }
66
- const decorations = [], config = state.facet(facet), { afterCursor, brackets, renderMatch } = config;
67
- for (const { empty, head } of state.selection.ranges) {
68
- if (!empty) {
69
- continue;
86
+ const extension = bracketMatching(configs), [{ facet }, plugins] = extension;
87
+ plugins[0] = ViewPlugin.fromClass(class {
88
+ constructor({ state }) {
89
+ this.decorations = bracketDeco(state, state.facet(facet));
90
+ this.paused = false;
91
+ }
92
+ update({ docChanged, selectionSet, changes, state, view: { composing } }) {
93
+ if (docChanged || selectionSet || this.paused) {
94
+ if (composing) {
95
+ this.decorations = this.decorations.map(changes);
96
+ this.paused = true;
70
97
  }
71
- const tree = syntaxTree(state), match = matchBrackets(state, head, -1, config)
72
- || head > 0 && matchBrackets(state, head - 1, 1, config)
73
- || afterCursor && (matchBrackets(state, head, 1, config)
74
- || head < state.doc.length && matchBrackets(state, head + 1, -1, config))
75
- || findEnclosingBrackets(tree.resolveInner(head, -1), head, brackets)
76
- || afterCursor && findEnclosingBrackets(tree.resolveInner(head, 1), head, brackets)
77
- || findEnclosingPlainBrackets(state, head, config);
78
- if (match) {
79
- decorations.push(...renderMatch(match, state));
98
+ else {
99
+ this.decorations = bracketDeco(state, state.facet(facet));
100
+ this.paused = false;
80
101
  }
81
102
  }
82
- return Decoration.set(decorations, true);
103
+ }
104
+ }, {
105
+ decorations({ decorations }) {
106
+ return decorations;
83
107
  },
84
108
  });
85
109
  return [
@@ -90,11 +114,12 @@ export default (configs) => {
90
114
  * @todo 由于括号高亮的重绘,双击会被识别为两次单击,导致功能失效
91
115
  */
92
116
  dblclick(e, view) {
93
- const pos = view.posAtCoords(e);
94
- if (pos === null) {
117
+ const pos = view.posAtCoords(e), { state } = view, config = state.facet(facet);
118
+ if (pos === null
119
+ || config.exclude?.(state, pos)) {
95
120
  return false;
96
121
  }
97
- const { state } = view, selection = selectMatchingBrackets(state, pos, state.facet(facet));
122
+ const selection = selectMatchingBrackets(state, pos, config);
98
123
  if (selection) {
99
124
  view.dispatch({ selection });
100
125
  return true;
@@ -28,6 +28,12 @@ export declare class Tag {
28
28
  * @test
29
29
  */
30
30
  export declare const getTag: (state: EditorState, node: SyntaxNode) => Tag | null;
31
+ /**
32
+ * 搜索匹配的标签
33
+ * @param state
34
+ * @param origin 起始标签
35
+ */
36
+ export declare const searchTag: (state: EditorState, origin: Tag) => Tag | null;
31
37
  /**
32
38
  * 匹配标签
33
39
  * @param state
package/dist/matchTag.js CHANGED
@@ -66,7 +66,7 @@ export const getTag = (state, node) => {
66
66
  * @param state
67
67
  * @param origin 起始标签
68
68
  */
69
- const searchTag = (state, origin) => {
69
+ export const searchTag = (state, origin) => {
70
70
  const { type, name, closing } = origin, siblingGetter = closing ? 'prevSibling' : 'nextSibling', endGetter = closing ? 'first' : 'last';
71
71
  let stack = closing ? -1 : 1, sibling = origin[endGetter][siblingGetter];
72
72
  while (sibling) {
@@ -30,7 +30,7 @@ export declare const apply: (view: EditorView, completion: Completion, from: num
30
30
  * @param names 指定类型
31
31
  * @test
32
32
  */
33
- export declare const hasTag: (types: Set<string>, names: TagName | TagName[]) => boolean;
33
+ export declare const hasTag: (types: Set<string> | string, names: TagName | TagName[]) => boolean;
34
34
  /** @test */
35
35
  export declare class FullMediaWiki extends MediaWiki {
36
36
  #private;
package/dist/mediawiki.js CHANGED
@@ -48,7 +48,12 @@ export const apply = (view, completion, from, to) => {
48
48
  * @param names 指定类型
49
49
  * @test
50
50
  */
51
- export const hasTag = (types, names) => (Array.isArray(names) ? names : [names]).some(name => types.has(name in tokens ? tokens[name] : name));
51
+ export const hasTag = (types, names) => {
52
+ if (typeof types === 'string') {
53
+ types = new Set(types.split('_'));
54
+ }
55
+ return (Array.isArray(names) ? names : [names]).some(name => types.has(name in tokens ? tokens[name] : name));
56
+ };
52
57
  /** @test */
53
58
  export class FullMediaWiki extends MediaWiki {
54
59
  constructor(config, templatedata = false) {
@@ -399,7 +404,7 @@ const theme = /* @__PURE__ */ EditorView.theme({
399
404
  fontSize: '1.5em',
400
405
  lineHeight: '1.2em',
401
406
  },
402
- [getSelector(['3~*', '4~*', '5~*', '6~*'], 'section--')]: {
407
+ [getSelector(['3', '3~*', '4', '4~*', '5', '5~*', '6', '6~*'], 'section--')]: {
403
408
  fontWeight: 'bold',
404
409
  },
405
410
  [`${getSelector(['section-header', 'template', 'parserfunction', 'file-delimiter', 'magic-link'])},${getSelector(['pagename', 'bracket', 'delimiter'], 'link-')},${getSelector(['extlink'], ['', 'free-'])},${getSelector(['bracket', 'attribute'], ['exttag-', 'htmltag-'])},${getSelector(['delimiter2', 'definition'], 'table-')}`]: {