@bhsd/codemirror-mediawiki 3.1.0 → 3.3.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.
- package/README.md +101 -10
- package/dist/codemirror.d.ts +28 -1
- package/dist/codemirror.js +52 -10
- package/dist/css.d.ts +2 -0
- package/dist/css.js +3 -2
- package/dist/escape.js +66 -25
- package/dist/fold.js +1 -1
- package/dist/html.d.ts +4 -0
- package/dist/html.js +31 -0
- package/dist/indent.js +1 -1
- package/dist/index.d.ts +8 -1
- package/dist/index.js +48 -20
- package/dist/lintsource.d.ts +3 -1
- package/dist/lintsource.js +46 -33
- package/dist/main.min.js +25 -25
- package/dist/mediawiki.d.ts +0 -5
- package/dist/mediawiki.js +0 -75
- package/dist/mw.min.js +30 -30
- package/dist/static.d.ts +0 -4
- package/dist/static.js +0 -4
- package/dist/statusBar.d.ts +2 -1
- package/dist/statusBar.js +58 -37
- package/dist/theme.d.ts +8 -0
- package/dist/theme.js +108 -0
- package/dist/token.d.ts +0 -3
- package/dist/token.js +1 -12
- package/dist/vue.js +2 -2
- package/dist/wiki.min.js +29 -29
- package/i18n/en.json +3 -1
- package/i18n/zh-hans.json +3 -1
- package/i18n/zh-hant.json +3 -1
- package/mediawiki.css +2 -2
- package/package.json +9 -6
- package/dist/demo.min.js +0 -38
package/dist/static.d.ts
CHANGED
|
@@ -19,9 +19,5 @@ export declare const tagModes: {
|
|
|
19
19
|
combobox: string;
|
|
20
20
|
combooption: string;
|
|
21
21
|
inputbox: string;
|
|
22
|
-
templatedata: string;
|
|
23
|
-
mapframe: string;
|
|
24
|
-
maplink: string;
|
|
25
|
-
graph: string;
|
|
26
22
|
};
|
|
27
23
|
export declare const getStaticMwConfig: ({ variable, parserFunction: [p0, p1, ...p2], protocol, nsid, functionHook, variants, redirection, ext, doubleUnderscore: [d0, d1, d2, d3], img, }: ConfigData, modes: Record<string, string>) => MwConfig;
|
package/dist/static.js
CHANGED
|
@@ -17,10 +17,6 @@ export const tagModes = {
|
|
|
17
17
|
combobox: 'text/combobox',
|
|
18
18
|
combooption: 'mediawiki',
|
|
19
19
|
inputbox: 'text/inputbox',
|
|
20
|
-
templatedata: 'json',
|
|
21
|
-
mapframe: 'json',
|
|
22
|
-
maplink: 'json',
|
|
23
|
-
graph: 'json',
|
|
24
20
|
};
|
|
25
21
|
export const getStaticMwConfig = ({ variable, parserFunction: [p0, p1, ...p2], protocol, nsid, functionHook, variants, redirection, ext, doubleUnderscore: [d0, d1, d2, d3], img, }, modes) => ({
|
|
26
22
|
tags: Object.fromEntries(ext.map(s => [s, true])),
|
package/dist/statusBar.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Extension } from '@codemirror/state';
|
|
2
|
+
import type { CodeMirror6 } from './codemirror';
|
|
2
3
|
import type { LintSource } from './lintsource';
|
|
3
|
-
declare const _default: (fixer: LintSource["fixer"]) => Extension;
|
|
4
|
+
declare const _default: (cm: CodeMirror6, fixer: LintSource["fixer"]) => Extension;
|
|
4
5
|
export default _default;
|
package/dist/statusBar.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { showPanel } from '@codemirror/view';
|
|
2
2
|
import { nextDiagnostic, setDiagnosticsEffect } from '@codemirror/lint';
|
|
3
|
+
import { menuRegistry } from './codemirror';
|
|
4
|
+
const optionAll = /* @__PURE__ */ (() => {
|
|
5
|
+
const ele = document.createElement('div');
|
|
6
|
+
ele.textContent = 'Fix all auto-fixable problems';
|
|
7
|
+
return ele;
|
|
8
|
+
})();
|
|
3
9
|
function getLintMarker(view, severity, menu) {
|
|
4
10
|
const marker = document.createElement('div'), icon = document.createElement('div');
|
|
5
11
|
marker.className = `cm-status-${severity}`;
|
|
@@ -37,9 +43,19 @@ const updateDiagnosticsCount = (diagnostics, s, marker) => {
|
|
|
37
43
|
marker.lastChild.textContent = String(diagnostics.filter(({ severity }) => severity === s).length);
|
|
38
44
|
};
|
|
39
45
|
const hasFix = (diagnostic) => diagnostic.actions?.some(({ name }) => name === 'fix' || name.startsWith('Fix:'));
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
const isItemActionable = (cm, { name, isActionable }) => cm.hasPreference(name) && isActionable(cm);
|
|
47
|
+
const toggleClass = (classList, enabled) => {
|
|
48
|
+
classList.toggle('cm-status-fix-enabled', enabled);
|
|
49
|
+
classList.toggle('cm-status-fix-disabled', !enabled);
|
|
50
|
+
};
|
|
51
|
+
const getDiagnostics = (all, main) => all.filter(({ from, to }) => from <= main.to && to >= main.from);
|
|
52
|
+
const updateDiagnosticMessage = (cm, allDiagnostics, main, msg) => {
|
|
53
|
+
const diagnostics = getDiagnostics(allDiagnostics, main);
|
|
54
|
+
if (diagnostics.length === 0) {
|
|
55
|
+
msg.textContent = '';
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const diagnostic = diagnostics.find(({ from, to }) => from <= main.head && to >= main.head) ?? diagnostics[0], view = cm.view;
|
|
43
59
|
msg.textContent = diagnostic.message;
|
|
44
60
|
if (diagnostic.actions) {
|
|
45
61
|
msg.append(...diagnostic.actions.map(({ name, apply }) => {
|
|
@@ -55,52 +71,58 @@ const updateDiagnosticMessage = (view, allDiagnostics, main, msg, menu) => {
|
|
|
55
71
|
}));
|
|
56
72
|
}
|
|
57
73
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
74
|
+
};
|
|
75
|
+
const updateMenu = (cm, allDiagnostics, main, classList, menu, fixer) => {
|
|
61
76
|
if (menu) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
77
|
+
const actionable = menuRegistry.filter(item => isItemActionable(cm, item)), fixable = new Set(fixer && getDiagnostics(allDiagnostics, main).filter(hasFix)
|
|
78
|
+
.map(({ message }) => / \(([^()]+)\)$/u.exec(message)?.[1])
|
|
79
|
+
.filter(Boolean));
|
|
80
|
+
if (actionable.length === 0 && fixable.size === 0) {
|
|
81
|
+
toggleClass(classList, false);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
toggleClass(classList, true);
|
|
85
|
+
const actions = actionable.flatMap(({ getItems }) => getItems(cm)), quickfix = [...fixable].map(rule => {
|
|
67
86
|
const option = document.createElement('div');
|
|
68
87
|
option.textContent = `Fix all ${rule} problems`;
|
|
69
88
|
option.dataset['rule'] = rule;
|
|
70
89
|
return option;
|
|
71
|
-
})
|
|
90
|
+
});
|
|
91
|
+
if (fixable.size > 0) {
|
|
92
|
+
quickfix.push(optionAll);
|
|
93
|
+
}
|
|
94
|
+
menu.replaceChildren(...actions, ...quickfix);
|
|
72
95
|
}
|
|
73
96
|
};
|
|
74
97
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
75
|
-
export default (fixer) => showPanel.of(view => {
|
|
98
|
+
export default (cm, fixer) => showPanel.of(view => {
|
|
76
99
|
let diagnostics = [], menu;
|
|
77
|
-
if (fixer) {
|
|
78
|
-
const optionAll = document.createElement('div');
|
|
79
|
-
optionAll.textContent = 'Fix all auto-fixable problems';
|
|
100
|
+
if (!view.state.readOnly && (fixer || menuRegistry.length > 0)) {
|
|
80
101
|
menu = document.createElement('div');
|
|
81
102
|
menu.className = 'cm-status-fix-menu';
|
|
82
103
|
menu.tabIndex = -1;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
(async () => {
|
|
89
|
-
const { doc } = view.state, output = await fixer(doc, target.dataset['rule']);
|
|
90
|
-
if (output !== doc.toString()) {
|
|
91
|
-
view.dispatch({
|
|
92
|
-
changes: { from: 0, to: doc.length, insert: output },
|
|
93
|
-
});
|
|
104
|
+
if (fixer) {
|
|
105
|
+
menu.addEventListener('click', ({ target }) => {
|
|
106
|
+
if (target === menu) {
|
|
107
|
+
return;
|
|
94
108
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
109
|
+
(async () => {
|
|
110
|
+
const { doc } = view.state, output = await fixer(doc, target.dataset['rule']);
|
|
111
|
+
if (output !== doc.toString()) {
|
|
112
|
+
view.dispatch({
|
|
113
|
+
changes: { from: 0, to: doc.length, insert: output },
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
view.focus();
|
|
117
|
+
})();
|
|
118
|
+
});
|
|
119
|
+
}
|
|
98
120
|
menu.addEventListener('focusout', () => {
|
|
99
121
|
menu.style.display = 'none';
|
|
100
122
|
});
|
|
101
123
|
view.dom.append(menu);
|
|
102
124
|
}
|
|
103
|
-
const dom = document.createElement('div'), worker = document.createElement('div'), message = document.createElement('div'), position = document.createElement('div'), error = getLintMarker(view, 'error'), warning = getLintMarker(view, 'warning'), fix = getLintMarker(view, 'fix', menu);
|
|
125
|
+
const dom = document.createElement('div'), worker = document.createElement('div'), message = document.createElement('div'), position = document.createElement('div'), error = getLintMarker(view, 'error'), warning = getLintMarker(view, 'warning'), fix = getLintMarker(view, 'fix', menu), { classList } = fix.firstChild;
|
|
104
126
|
worker.className = 'cm-status-worker';
|
|
105
127
|
worker.append(error, warning, fix);
|
|
106
128
|
message.className = 'cm-status-message';
|
|
@@ -110,23 +132,22 @@ export default (fixer) => showPanel.of(view => {
|
|
|
110
132
|
dom.append(worker, message, position);
|
|
111
133
|
return {
|
|
112
134
|
dom,
|
|
113
|
-
update({ state: { selection: { main }, doc
|
|
135
|
+
update({ state: { selection: { main }, doc }, transactions, docChanged, selectionSet }) {
|
|
114
136
|
for (const tr of transactions) {
|
|
115
137
|
for (const effect of tr.effects) {
|
|
116
138
|
if (effect.is(setDiagnosticsEffect)) {
|
|
117
139
|
diagnostics = effect.value;
|
|
118
|
-
const fixable = !readOnly && Boolean(fixer) && diagnostics.some(hasFix), { classList } = fix.firstChild;
|
|
119
|
-
classList.toggle('cm-status-fix-enabled', fixable);
|
|
120
|
-
classList.toggle('cm-status-fix-disabled', !fixable);
|
|
121
140
|
worker.classList.toggle('cm-status-worker-enabled', diagnostics.length > 0);
|
|
122
141
|
updateDiagnosticsCount(diagnostics, 'error', error);
|
|
123
142
|
updateDiagnosticsCount(diagnostics, 'warning', warning);
|
|
124
|
-
updateDiagnosticMessage(
|
|
143
|
+
updateDiagnosticMessage(cm, diagnostics, main, message);
|
|
144
|
+
updateMenu(cm, diagnostics, main, classList, menu, fixer);
|
|
125
145
|
}
|
|
126
146
|
}
|
|
127
147
|
}
|
|
128
148
|
if (docChanged || selectionSet) {
|
|
129
|
-
updateDiagnosticMessage(
|
|
149
|
+
updateDiagnosticMessage(cm, diagnostics, main, message);
|
|
150
|
+
updateMenu(cm, diagnostics, main, classList, menu, fixer);
|
|
130
151
|
const { number, from } = doc.lineAt(main.head);
|
|
131
152
|
position.textContent = `${number}:${main.head - from}`;
|
|
132
153
|
if (!main.empty) {
|
package/dist/theme.d.ts
ADDED
package/dist/theme.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { EditorView } from '@codemirror/view';
|
|
2
|
+
import { nord as nordBase } from 'cm6-theme-nord';
|
|
3
|
+
export const light = /* @__PURE__ */ EditorView.theme({
|
|
4
|
+
'&': {
|
|
5
|
+
backgroundColor: '#fff',
|
|
6
|
+
},
|
|
7
|
+
'&.cm-focused .cm-matchingTag': {
|
|
8
|
+
backgroundColor: 'rgb(50,140,130,.32)',
|
|
9
|
+
},
|
|
10
|
+
'&.cm-focused .cm-nonmatchingTag': {
|
|
11
|
+
backgroundColor: 'rgb(187,85,85,.27)',
|
|
12
|
+
},
|
|
13
|
+
'.cm-tooltip-hover code': {
|
|
14
|
+
backgroundColor: '#e0e6eb',
|
|
15
|
+
},
|
|
16
|
+
'.cm-status-fix-menu': {
|
|
17
|
+
backgroundColor: '#f5f5f5',
|
|
18
|
+
boxShadow: '0 2px 2px 0 rgb(0,0,0,.25)',
|
|
19
|
+
},
|
|
20
|
+
'.cm-status-fix-menu>div:hover': {
|
|
21
|
+
backgroundColor: '#e2f2ff',
|
|
22
|
+
},
|
|
23
|
+
'.cm-status-message': {
|
|
24
|
+
borderColor: '#c8ccd1',
|
|
25
|
+
},
|
|
26
|
+
'.cm-content': {
|
|
27
|
+
'--cm-arg': '#b0c',
|
|
28
|
+
'--cm-attr': '#179b1c',
|
|
29
|
+
'--cm-comment': '#7b8c8f',
|
|
30
|
+
'--cm-convert': '#b68',
|
|
31
|
+
'--cm-entity': '#00a1a1',
|
|
32
|
+
'--cm-error': '#d73333',
|
|
33
|
+
'--cm-func': '#a11',
|
|
34
|
+
'--cm-hr': '#0076dd',
|
|
35
|
+
'--cm-hr-bg': 'rgb(0,0,0,.07)',
|
|
36
|
+
'--cm-link': '#000aaa',
|
|
37
|
+
'--cm-sect': '#006fe6',
|
|
38
|
+
'--cm-sp': 'rgb(134,206,255,.3)',
|
|
39
|
+
'--cm-table': '#d08',
|
|
40
|
+
'--cm-table-attr': '#f500d4',
|
|
41
|
+
'--cm-tag': '#14866d',
|
|
42
|
+
'--cm-tpl': '#80c',
|
|
43
|
+
'--cm-var': '#ad9300',
|
|
44
|
+
'--cm-var-name': '#ac6600',
|
|
45
|
+
},
|
|
46
|
+
}),
|
|
47
|
+
/**
|
|
48
|
+
* @author 鬼影233
|
|
49
|
+
* @author Bhsd
|
|
50
|
+
* @see https://zh.moegirl.org.cn/User:%E9%AC%BC%E5%BD%B1233/nord-moeskin.css
|
|
51
|
+
*/
|
|
52
|
+
nord = [
|
|
53
|
+
nordBase,
|
|
54
|
+
/* @__PURE__ */ EditorView.theme({
|
|
55
|
+
'div.cm-activeLine': {
|
|
56
|
+
backgroundColor: '#4c566a44',
|
|
57
|
+
},
|
|
58
|
+
'&.cm-focused .cm-matchingTag, &.cm-focused .cm-nonmatchingTag': {
|
|
59
|
+
outline: '1px solid #8fbcbb',
|
|
60
|
+
},
|
|
61
|
+
'&.cm-focused .cm-matchingTag': {
|
|
62
|
+
backgroundColor: '#eceff4',
|
|
63
|
+
color: '#434c5e',
|
|
64
|
+
},
|
|
65
|
+
['&.cm-focused>.cm-scroller>.cm-selectionLayer div.cm-selectionBackground,'
|
|
66
|
+
+ '.cm-tooltip-hover code, .cm-status-fix-menu>div:hover, .cm-diagnosticAction, div.cm-tooltip-fold']: {
|
|
67
|
+
backgroundColor: '#4c566a',
|
|
68
|
+
},
|
|
69
|
+
'div.cm-panels': {
|
|
70
|
+
color: '#d8dee9',
|
|
71
|
+
},
|
|
72
|
+
'.cm-status-fix-menu': {
|
|
73
|
+
backgroundColor: '#252a33',
|
|
74
|
+
},
|
|
75
|
+
'.cm-status-message': {
|
|
76
|
+
borderColor: '#000',
|
|
77
|
+
},
|
|
78
|
+
'&.cm-focused .cm-searchMatch.cm-searchMatch-selected': {
|
|
79
|
+
color: '#b48ead',
|
|
80
|
+
},
|
|
81
|
+
'div.cm-tooltip-autocomplete ul li[aria-selected]': {
|
|
82
|
+
color: 'inherit',
|
|
83
|
+
},
|
|
84
|
+
'div.cm-gutters': {
|
|
85
|
+
color: '#5e81ac',
|
|
86
|
+
},
|
|
87
|
+
'.cm-content': {
|
|
88
|
+
'--cm-arg': '#9f78a5',
|
|
89
|
+
'--cm-attr': '#97b757',
|
|
90
|
+
'--cm-comment': '#4c566a',
|
|
91
|
+
'--cm-convert': '#b68',
|
|
92
|
+
'--cm-entity': '#00a1a1',
|
|
93
|
+
'--cm-error': '#bf616a',
|
|
94
|
+
'--cm-func': '#bf616a',
|
|
95
|
+
'--cm-hr': '#5e81ac',
|
|
96
|
+
'--cm-hr-bg': '#3b4252',
|
|
97
|
+
'--cm-link': '#5e81ac',
|
|
98
|
+
'--cm-sect': '#81a1c1',
|
|
99
|
+
'--cm-sp': '#88c0d0',
|
|
100
|
+
'--cm-table': '#b48ead',
|
|
101
|
+
'--cm-table-attr': '#9f78a5',
|
|
102
|
+
'--cm-tag': '#a3be8c',
|
|
103
|
+
'--cm-tpl': '#9f78a5',
|
|
104
|
+
'--cm-var': '#d08770',
|
|
105
|
+
'--cm-var-name': '#d08770',
|
|
106
|
+
},
|
|
107
|
+
}),
|
|
108
|
+
];
|
package/dist/token.d.ts
CHANGED
|
@@ -181,8 +181,5 @@ export declare class MediaWiki {
|
|
|
181
181
|
'text/inputbox'(): StreamParser<State>;
|
|
182
182
|
inGallery(section?: boolean): Tokenizer;
|
|
183
183
|
'text/gallery'(tags: string[]): StreamParser<State>;
|
|
184
|
-
javascript(): StreamParser<unknown>;
|
|
185
|
-
json(): StreamParser<unknown>;
|
|
186
|
-
lua(): StreamParser<unknown>;
|
|
187
184
|
}
|
|
188
185
|
export {};
|
package/dist/token.js
CHANGED
|
@@ -41,8 +41,6 @@ import { Tag } from '@lezer/highlight';
|
|
|
41
41
|
import { getRegex } from '@bhsd/common';
|
|
42
42
|
import { decodeHTML } from '@bhsd/browser';
|
|
43
43
|
import { otherParserFunctions } from '@bhsd/cm-util';
|
|
44
|
-
import { javascript, json } from '@codemirror/legacy-modes/mode/javascript';
|
|
45
|
-
import { lua } from '@codemirror/legacy-modes/mode/lua';
|
|
46
44
|
import { htmlTags, voidHtmlTags, selfClosingTags, tokenTable, tokens } from './config';
|
|
47
45
|
class MediaWikiData {
|
|
48
46
|
constructor(tags) {
|
|
@@ -1268,7 +1266,7 @@ let MediaWiki = (() => {
|
|
|
1268
1266
|
else if (stream.eat('>')) {
|
|
1269
1267
|
const { config: { tagModes } } = this;
|
|
1270
1268
|
state.extName = name;
|
|
1271
|
-
state.extMode ||= name in tagModes
|
|
1269
|
+
state.extMode ||= name in tagModes && (tagModes[name]) in this
|
|
1272
1270
|
&& this[tagModes[name]](state.data.tags.filter(tag => tag !== name));
|
|
1273
1271
|
if (state.extMode) {
|
|
1274
1272
|
state.extState = state.extMode.startState(0);
|
|
@@ -1992,15 +1990,6 @@ let MediaWiki = (() => {
|
|
|
1992
1990
|
},
|
|
1993
1991
|
};
|
|
1994
1992
|
}
|
|
1995
|
-
javascript() {
|
|
1996
|
-
return javascript;
|
|
1997
|
-
}
|
|
1998
|
-
json() {
|
|
1999
|
-
return json;
|
|
2000
|
-
}
|
|
2001
|
-
lua() {
|
|
2002
|
-
return lua;
|
|
2003
|
-
}
|
|
2004
1993
|
};
|
|
2005
1994
|
})();
|
|
2006
1995
|
export { MediaWiki };
|
package/dist/vue.js
CHANGED
|
@@ -3,12 +3,12 @@ import { htmlLanguage, htmlCompletionSource } from '@codemirror/lang-html';
|
|
|
3
3
|
import { javascript } from '@codemirror/lang-javascript';
|
|
4
4
|
import { LanguageSupport } from '@codemirror/language';
|
|
5
5
|
import { jsCompletion } from './javascript';
|
|
6
|
-
import
|
|
6
|
+
import { cssCompletion } from './css';
|
|
7
7
|
export default () => vue({
|
|
8
8
|
base: new LanguageSupport(htmlLanguage, [
|
|
9
9
|
htmlLanguage.data.of({ autocomplete: htmlCompletionSource }),
|
|
10
10
|
javascript().support,
|
|
11
11
|
jsCompletion,
|
|
12
|
-
|
|
12
|
+
cssCompletion(),
|
|
13
13
|
]),
|
|
14
14
|
});
|