@bhsd/codemirror-mediawiki 3.12.0 → 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/LICENSE +19 -0
- package/dist/bidi.js +9 -8
- package/dist/constants.d.ts +2 -1
- package/dist/constants.js +2 -1
- package/dist/fold.js +4 -1
- package/dist/html.js +2 -2
- package/dist/javascript.d.ts +3 -3
- package/dist/javascript.js +25 -8
- package/dist/lua.d.ts +16 -0
- package/dist/lua.js +57 -1
- package/dist/main.min.js +29 -28
- package/dist/matchBrackets.d.ts +5 -0
- package/dist/matchBrackets.js +38 -15
- package/dist/matchTag.js +5 -5
- package/dist/mw.min.js +30 -29
- package/dist/theme.js +12 -0
- package/dist/token.js +1 -1
- package/dist/util.d.ts +20 -3
- package/dist/util.js +42 -2
- package/dist/vue.js +2 -2
- package/dist/wiki.min.js +30 -29
- package/i18n/en.json +1 -1
- package/i18n/zh-hans.json +1 -1
- package/i18n/zh-hant.json +1 -1
- package/package.json +14 -11
package/LICENSE
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
@bhsd/codemirror-mediawiki
|
|
2
|
+
Copyright (C) 2022 Bhsd
|
|
3
|
+
|
|
4
|
+
This program is free software; you can redistribute it and/or modify
|
|
5
|
+
it under the terms of the GNU General Public License as published by
|
|
6
|
+
the Free Software Foundation; either version 2 of the License, or
|
|
7
|
+
(at your option) any later version.
|
|
8
|
+
|
|
9
|
+
This program is distributed in the hope that it will be useful,
|
|
10
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
GNU General Public License for more details.
|
|
13
|
+
|
|
14
|
+
You should have received a copy of the GNU General Public License along
|
|
15
|
+
with this program; if not, write to the Free Software Foundation, Inc.,
|
|
16
|
+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
1
20
|
GNU GENERAL PUBLIC LICENSE
|
|
2
21
|
Version 2, June 1991
|
|
3
22
|
|
package/dist/bidi.js
CHANGED
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
* @see https://gerrit.wikimedia.org/g/mediawiki/extensions/CodeMirror
|
|
5
5
|
*/
|
|
6
6
|
import { EditorView, Direction, ViewPlugin, Decoration } from '@codemirror/view';
|
|
7
|
-
import { Prec
|
|
7
|
+
import { Prec } from '@codemirror/state';
|
|
8
8
|
import { syntaxTree } from '@codemirror/language';
|
|
9
9
|
import { tokens } from './config.js';
|
|
10
10
|
import { getTag } from './matchTag.js';
|
|
11
|
+
import { pushDecoration } from './util.js';
|
|
11
12
|
const isolateSelector = '.cm-bidi-isolate', ltrSelector = '.cm-bidi-ltr', cls = isolateSelector.slice(1), isolateLTR = Decoration.mark({
|
|
12
13
|
class: `${cls} ${ltrSelector.slice(1)}`,
|
|
13
14
|
bidiIsolate: Direction.LTR,
|
|
@@ -18,7 +19,7 @@ const isolateSelector = '.cm-bidi-isolate', ltrSelector = '.cm-bidi-ltr', cls =
|
|
|
18
19
|
* @test
|
|
19
20
|
*/
|
|
20
21
|
export const computeIsolates = ({ visibleRanges, state, textDirection }) => {
|
|
21
|
-
const set =
|
|
22
|
+
const set = [];
|
|
22
23
|
if (textDirection === Direction.RTL) {
|
|
23
24
|
for (const { from, to } of visibleRanges) {
|
|
24
25
|
let node = syntaxTree(state).resolve(from, 1), td = 0, table = 0, parameter = 0;
|
|
@@ -27,13 +28,13 @@ export const computeIsolates = ({ visibleRanges, state, textDirection }) => {
|
|
|
27
28
|
if (/-(?:ext|html)tag-bracket/u.test(name) && state.sliceDoc(f, t).includes('<')) {
|
|
28
29
|
const tag = getTag(state, nextSibling);
|
|
29
30
|
if (tag) {
|
|
30
|
-
set
|
|
31
|
+
pushDecoration(set, isolateLTR, tag);
|
|
31
32
|
}
|
|
32
33
|
}
|
|
33
34
|
else if (!td && !table && name.includes(tokens.tableDefinition)) {
|
|
34
35
|
if (/-html-(?:table|tr)/u.test(name)) {
|
|
35
36
|
table = state.doc.lineAt(f).to;
|
|
36
|
-
set
|
|
37
|
+
pushDecoration(set, isolateLTR, f, table);
|
|
37
38
|
}
|
|
38
39
|
else {
|
|
39
40
|
td = f;
|
|
@@ -43,18 +44,18 @@ export const computeIsolates = ({ visibleRanges, state, textDirection }) => {
|
|
|
43
44
|
table = 0;
|
|
44
45
|
}
|
|
45
46
|
else if (td && name.includes(tokens.tableDelimiter2)) {
|
|
46
|
-
set
|
|
47
|
+
pushDecoration(set, isolateLTR, td, f);
|
|
47
48
|
td = 0;
|
|
48
49
|
}
|
|
49
50
|
else if (/-(?:template|parserfunction)-delimiter/u.test(name)) {
|
|
50
51
|
if (parameter) {
|
|
51
|
-
set
|
|
52
|
+
pushDecoration(set, isolate, parameter, f);
|
|
52
53
|
}
|
|
53
54
|
parameter = t;
|
|
54
55
|
}
|
|
55
56
|
else if (parameter && /-(?:template|parserfunction)-bracket/u.test(name)) {
|
|
56
57
|
if (state.sliceDoc(f, f + 1) === '}') {
|
|
57
|
-
set
|
|
58
|
+
pushDecoration(set, isolate, parameter, f);
|
|
58
59
|
}
|
|
59
60
|
parameter = 0;
|
|
60
61
|
}
|
|
@@ -62,7 +63,7 @@ export const computeIsolates = ({ visibleRanges, state, textDirection }) => {
|
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
return set
|
|
66
|
+
return Decoration.set(set, true);
|
|
66
67
|
};
|
|
67
68
|
export default [
|
|
68
69
|
ViewPlugin.fromClass(class {
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import { Decoration } from '@codemirror/view';
|
|
2
|
+
export declare const base: Record<'CDN', string | undefined>, hoverSelector = ".cm-tooltip-hover-mw", diagnosticSelector = ".cm-diagnosticText-clickable", panelSelector = ".cm-panel", panelsSelector = ".cm-panels", actionSelector = ".cm-diagnosticAction", doctagMark: Decoration, typeMark: Decoration, noDetectionLangs: Set<string>, bgDark = "#4c566a", matchingCls = "cm-matchingTag", nonmatchingCls = "cm-nonmatchingTag";
|
|
2
3
|
export declare const isWMF: boolean;
|
|
3
4
|
export declare const isMac: boolean;
|
package/dist/constants.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { Decoration } from '@codemirror/view';
|
|
1
2
|
import { wmf } from '@bhsd/common';
|
|
2
|
-
export const base = { CDN: undefined }, hoverSelector = '.cm-tooltip-hover-mw', diagnosticSelector = '.cm-diagnosticText-clickable', panelSelector = '.cm-panel', panelsSelector = '.cm-panels', actionSelector = '.cm-diagnosticAction', noDetectionLangs = new Set(['plain', 'mediawiki']), bgDark = '#4c566a', matchingCls = 'cm-matchingTag', nonmatchingCls = 'cm-nonmatchingTag';
|
|
3
|
+
export const base = { CDN: undefined }, hoverSelector = '.cm-tooltip-hover-mw', diagnosticSelector = '.cm-diagnosticText-clickable', panelSelector = '.cm-panel', panelsSelector = '.cm-panels', actionSelector = '.cm-diagnosticAction', doctagMark = /* @__PURE__ */ Decoration.mark({ class: 'cm-doctag' }), typeMark = /* @__PURE__ */ Decoration.mark({ class: 'cm-doctag-type' }), noDetectionLangs = new Set(['plain', 'mediawiki']), bgDark = '#4c566a', matchingCls = 'cm-matchingTag', nonmatchingCls = 'cm-nonmatchingTag';
|
|
3
4
|
export const isWMF = /* @__PURE__ */ (() => typeof location === 'object'
|
|
4
5
|
&& new RegExp(String.raw `\.(?:${wmf})\.org$`, 'u').test(location.hostname))();
|
|
5
6
|
export const isMac = /* @__PURE__ */ (() => {
|
package/dist/fold.js
CHANGED
|
@@ -337,14 +337,17 @@ export const buildMarkers = (view) => {
|
|
|
337
337
|
};
|
|
338
338
|
const markers = /* @__PURE__ */ ViewPlugin.fromClass(class {
|
|
339
339
|
constructor(view) {
|
|
340
|
+
this.tree = syntaxTree(view.state);
|
|
340
341
|
this.markers = buildMarkers(view);
|
|
341
342
|
}
|
|
342
343
|
update({ docChanged, viewportChanged, startState, state, view }) {
|
|
344
|
+
const tree = syntaxTree(state);
|
|
343
345
|
if (docChanged
|
|
344
346
|
|| viewportChanged
|
|
345
347
|
|| startState.facet(language) !== state.facet(language)
|
|
346
348
|
|| startState.field(foldState, false) !== state.field(foldState, false)
|
|
347
|
-
||
|
|
349
|
+
|| tree !== this.tree) {
|
|
350
|
+
this.tree = tree;
|
|
348
351
|
this.markers = buildMarkers(view);
|
|
349
352
|
}
|
|
350
353
|
}
|
package/dist/html.js
CHANGED
|
@@ -4,7 +4,7 @@ import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
|
|
|
4
4
|
import { cssLanguage } from '@codemirror/lang-css';
|
|
5
5
|
import { LanguageSupport } from '@codemirror/language';
|
|
6
6
|
import { cssCompletion } from './css.js';
|
|
7
|
-
import { jsCompletion,
|
|
7
|
+
import { jsCompletion, markGlobalsAndDocTagPlugin } from './javascript.js';
|
|
8
8
|
import { mediawikiBase } from './mediawiki.js';
|
|
9
9
|
import { lightHighlightStyle } from './theme.js';
|
|
10
10
|
export default (config, cm) => {
|
|
@@ -31,7 +31,7 @@ export default (config, cm) => {
|
|
|
31
31
|
cssCompletion(),
|
|
32
32
|
support,
|
|
33
33
|
lightHighlightStyle,
|
|
34
|
-
|
|
34
|
+
markGlobalsAndDocTagPlugin(cm),
|
|
35
35
|
]);
|
|
36
36
|
Object.assign(langSupport, { nestedMWLanguage: language });
|
|
37
37
|
return langSupport;
|
package/dist/javascript.d.ts
CHANGED
|
@@ -12,11 +12,11 @@ export declare const jsCompletion: Extension;
|
|
|
12
12
|
*/
|
|
13
13
|
export declare const exclude: (state: EditorState, pos: number) => boolean;
|
|
14
14
|
/**
|
|
15
|
-
*
|
|
15
|
+
* 高亮显示全局变量和JSDoc标签
|
|
16
16
|
* @ignore
|
|
17
17
|
* @test
|
|
18
18
|
*/
|
|
19
|
-
export declare const
|
|
20
|
-
export declare const
|
|
19
|
+
export declare const markGlobalsAndDocTag: (tree: Tree, visibleRanges: readonly DocRange[], state: EditorState, cm?: CodeMirror6) => DecorationSet;
|
|
20
|
+
export declare const markGlobalsAndDocTagPlugin: (cm?: CodeMirror6) => Extension;
|
|
21
21
|
declare const _default: (_?: unknown, cm?: CodeMirror6) => Extension;
|
|
22
22
|
export default _default;
|
package/dist/javascript.js
CHANGED
|
@@ -3,6 +3,8 @@ import { ViewPlugin, Decoration } from '@codemirror/view';
|
|
|
3
3
|
import { syntaxTree } from '@codemirror/language';
|
|
4
4
|
import { setDiagnosticsEffect } from '@codemirror/lint';
|
|
5
5
|
import { builtin } from './javascript-globals.js';
|
|
6
|
+
import { doctagMark } from './constants.js';
|
|
7
|
+
import { markDocTagType, pushDecoration } from './util.js';
|
|
6
8
|
export const jsCompletion = javascriptLanguage.data.of({ autocomplete: scopeCompletionSource(globalThis) });
|
|
7
9
|
const globalsMark = Decoration.mark({ class: 'cm-globals' }), builtinGlobals = new Set(Object.keys(builtin));
|
|
8
10
|
/**
|
|
@@ -14,11 +16,11 @@ const globalsMark = Decoration.mark({ class: 'cm-globals' }), builtinGlobals = n
|
|
|
14
16
|
export const exclude = (state, pos) => javascriptLanguage.isActiveAt(state, pos, 0)
|
|
15
17
|
&& syntaxTree(state).resolveInner(pos, 0).name === 'RegExp';
|
|
16
18
|
/**
|
|
17
|
-
*
|
|
19
|
+
* 高亮显示全局变量和JSDoc标签
|
|
18
20
|
* @ignore
|
|
19
21
|
* @test
|
|
20
22
|
*/
|
|
21
|
-
export const
|
|
23
|
+
export const markGlobalsAndDocTag = (tree, visibleRanges, state, cm) => {
|
|
22
24
|
const decorations = [];
|
|
23
25
|
let allGlobals = builtinGlobals;
|
|
24
26
|
if (cm?.lintSources.length && typeof eslint === 'object' && 'environments' in eslint) {
|
|
@@ -49,10 +51,25 @@ export const markGlobals = (tree, visibleRanges, state, cm) => {
|
|
|
49
51
|
to,
|
|
50
52
|
enter({ type, from: f, to: t }) {
|
|
51
53
|
const name = state.sliceDoc(f, t);
|
|
52
|
-
if (
|
|
54
|
+
if (!javascriptLanguage.isActiveAt(state, f)) {
|
|
55
|
+
//
|
|
56
|
+
}
|
|
57
|
+
else if (type.is('VariableName') && allGlobals.has(name)) {
|
|
53
58
|
const completions = localCompletionSource({ state, pos: t, explicit: true });
|
|
54
59
|
if (!completions?.options.some(({ label }) => label === name)) {
|
|
55
|
-
decorations
|
|
60
|
+
pushDecoration(decorations, globalsMark, f, t);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else if (type.is('BlockComment') && /^\/\*{2}(?!\*)/u.test(name)) {
|
|
64
|
+
const comment = name.slice(2), mtAll = comment.matchAll(/^[ \t]*\*\s*(@[a-z]+)(\s+\{(?!\}))?|\{(@[a-z]+)/dgimu);
|
|
65
|
+
for (const mt of mtAll) {
|
|
66
|
+
if (mt[3]) {
|
|
67
|
+
const [start, end] = mt.indices[3];
|
|
68
|
+
pushDecoration(decorations, doctagMark, f + start + 2, f + end + 2);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
markDocTagType(decorations, f + 2, mt);
|
|
72
|
+
}
|
|
56
73
|
}
|
|
57
74
|
}
|
|
58
75
|
},
|
|
@@ -60,10 +77,10 @@ export const markGlobals = (tree, visibleRanges, state, cm) => {
|
|
|
60
77
|
}
|
|
61
78
|
return Decoration.set(decorations);
|
|
62
79
|
};
|
|
63
|
-
export const
|
|
80
|
+
export const markGlobalsAndDocTagPlugin = (cm) => ViewPlugin.fromClass(class {
|
|
64
81
|
constructor({ state, visibleRanges }) {
|
|
65
82
|
this.tree = syntaxTree(state);
|
|
66
|
-
this.decorations =
|
|
83
|
+
this.decorations = markGlobalsAndDocTag(this.tree, visibleRanges, state, cm);
|
|
67
84
|
}
|
|
68
85
|
update({ docChanged, viewportChanged, state, view: { visibleRanges }, transactions }) {
|
|
69
86
|
const tree = syntaxTree(state);
|
|
@@ -76,7 +93,7 @@ export const markGlobalsPlugin = (cm) => ViewPlugin.fromClass(class {
|
|
|
76
93
|
flag = transactions.some(tr => tr.effects.some(e => e.is(setDiagnosticsEffect)));
|
|
77
94
|
}
|
|
78
95
|
if (flag) {
|
|
79
|
-
this.decorations =
|
|
96
|
+
this.decorations = markGlobalsAndDocTag(tree, visibleRanges, state, cm);
|
|
80
97
|
}
|
|
81
98
|
}
|
|
82
99
|
}, {
|
|
@@ -87,5 +104,5 @@ export const markGlobalsPlugin = (cm) => ViewPlugin.fromClass(class {
|
|
|
87
104
|
export default (_, cm) => [
|
|
88
105
|
js(),
|
|
89
106
|
jsCompletion,
|
|
90
|
-
|
|
107
|
+
markGlobalsAndDocTagPlugin(cm),
|
|
91
108
|
];
|
package/dist/lua.d.ts
CHANGED
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
import { ViewPlugin } from '@codemirror/view';
|
|
1
2
|
import { LanguageSupport } from '@codemirror/language';
|
|
3
|
+
import type { ViewUpdate, DecorationSet } from '@codemirror/view';
|
|
4
|
+
import type { EditorState } from '@codemirror/state';
|
|
5
|
+
import type { Tree } from '@lezer/common';
|
|
6
|
+
import type { DocRange } from './fold';
|
|
7
|
+
/**
|
|
8
|
+
* 高亮显示LDoc标签
|
|
9
|
+
* @ignore
|
|
10
|
+
* @test
|
|
11
|
+
*/
|
|
12
|
+
export declare const markDocTag: (tree: Tree, visibleRanges: readonly DocRange[], state: EditorState) => DecorationSet;
|
|
13
|
+
export declare const markDocTagPlugin: ViewPlugin<{
|
|
14
|
+
tree: Tree;
|
|
15
|
+
decorations: DecorationSet;
|
|
16
|
+
update({ docChanged, viewportChanged, state, view: { visibleRanges } }: ViewUpdate): void;
|
|
17
|
+
}, undefined>;
|
|
2
18
|
declare const _default: () => LanguageSupport;
|
|
3
19
|
export default _default;
|
package/dist/lua.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/* eslint-disable no-template-curly-in-string */
|
|
2
2
|
import { lua } from '@codemirror/legacy-modes/mode/lua';
|
|
3
|
+
import { ViewPlugin, Decoration } from '@codemirror/view';
|
|
3
4
|
import { syntaxTree, LanguageSupport, StreamLanguage, foldService, HighlightStyle, syntaxHighlighting, } from '@codemirror/language';
|
|
4
5
|
import { snippetCompletion } from '@codemirror/autocomplete';
|
|
5
6
|
import { tags } from '@lezer/highlight';
|
|
6
|
-
import { leadingSpaces, sliceDoc } from './util.js';
|
|
7
|
+
import { leadingSpaces, sliceDoc, markDocTagType } from './util.js';
|
|
7
8
|
import { lightHighlightStyle } from './theme.js';
|
|
8
9
|
const map = {
|
|
9
10
|
1: 'constant',
|
|
@@ -438,10 +439,65 @@ const fold = ({ doc, tabSize }, start, from) => {
|
|
|
438
439
|
}
|
|
439
440
|
return empty || j === number ? null : { from, to: doc.line(j).to };
|
|
440
441
|
};
|
|
442
|
+
/**
|
|
443
|
+
* 高亮显示LDoc标签
|
|
444
|
+
* @ignore
|
|
445
|
+
* @test
|
|
446
|
+
*/
|
|
447
|
+
export const markDocTag = (tree, visibleRanges, state) => {
|
|
448
|
+
const decorations = [];
|
|
449
|
+
for (const { from, to } of visibleRanges) {
|
|
450
|
+
let node = tree.resolveInner(from, 1);
|
|
451
|
+
while (node && node.from < to) {
|
|
452
|
+
if (node.name === 'comment') {
|
|
453
|
+
const firstLine = sliceDoc(state, node), block = firstLine.startsWith('--[[--');
|
|
454
|
+
if (block
|
|
455
|
+
|| firstLine.startsWith('---')
|
|
456
|
+
&& !(firstLine.endsWith('--') && /[^-]/u.test(firstLine))) {
|
|
457
|
+
while (node.name === 'comment') {
|
|
458
|
+
const comment = sliceDoc(state, node), mt = /^\s*(?:-{2,}\s*)?(@[a-z]+)(\s+\{(?!\}))?/diu.exec(comment);
|
|
459
|
+
if (mt) {
|
|
460
|
+
markDocTagType(decorations, node.from, mt);
|
|
461
|
+
}
|
|
462
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
463
|
+
const { nextSibling } = node;
|
|
464
|
+
if (!nextSibling || (block
|
|
465
|
+
? comment.endsWith(']]')
|
|
466
|
+
: state.sliceDoc(node.to, nextSibling.from)
|
|
467
|
+
.split('\n', 3).length > 2)) {
|
|
468
|
+
break;
|
|
469
|
+
}
|
|
470
|
+
node = nextSibling;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
node = node.nextSibling;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
return Decoration.set(decorations);
|
|
478
|
+
};
|
|
479
|
+
export const markDocTagPlugin = ViewPlugin.fromClass(class {
|
|
480
|
+
constructor({ state, visibleRanges }) {
|
|
481
|
+
this.tree = syntaxTree(state);
|
|
482
|
+
this.decorations = markDocTag(this.tree, visibleRanges, state);
|
|
483
|
+
}
|
|
484
|
+
update({ docChanged, viewportChanged, state, view: { visibleRanges } }) {
|
|
485
|
+
const tree = syntaxTree(state);
|
|
486
|
+
if (docChanged || viewportChanged || tree !== this.tree) {
|
|
487
|
+
this.tree = tree;
|
|
488
|
+
this.decorations = markDocTag(tree, visibleRanges, state);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}, {
|
|
492
|
+
decorations(v) {
|
|
493
|
+
return v.decorations;
|
|
494
|
+
},
|
|
495
|
+
});
|
|
441
496
|
const support = [
|
|
442
497
|
lightHighlightStyle,
|
|
443
498
|
syntaxHighlighting(HighlightStyle.define([{ tag: tags.standard(tags.variableName), class: 'cm-globals' }])),
|
|
444
499
|
lang.data.of({ autocomplete: source }),
|
|
445
500
|
foldService.of(fold),
|
|
501
|
+
markDocTagPlugin,
|
|
446
502
|
];
|
|
447
503
|
export default () => new LanguageSupport(lang, support);
|