@bhsd/codemirror-mediawiki 2.0.13 → 2.0.15
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 +8 -0
- package/dist/codemirror.d.ts +1 -1
- package/dist/config.d.ts +31 -17
- package/dist/main.min.js +23 -2
- package/dist/mediawiki.d.ts +5 -6
- package/mediawiki.css +10 -4
- package/mw/dist/base.js +57 -53
- package/package.json +17 -11
package/dist/mediawiki.d.ts
CHANGED
|
@@ -5,13 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { LanguageSupport } from '@codemirror/language';
|
|
7
7
|
export interface MwConfig {
|
|
8
|
-
urlProtocols: string;
|
|
9
|
-
tags: Record<string, true>;
|
|
10
|
-
tagModes: Record<string, string>;
|
|
11
|
-
functionSynonyms: [Record<string, string
|
|
12
|
-
doubleUnderscore: [Record<string,
|
|
8
|
+
readonly urlProtocols: string;
|
|
9
|
+
readonly tags: Record<string, true>;
|
|
10
|
+
readonly tagModes: Record<string, string>;
|
|
11
|
+
functionSynonyms: [Record<string, string>, Record<string, unknown>];
|
|
12
|
+
doubleUnderscore: [Record<string, unknown>, Record<string, unknown>];
|
|
13
13
|
variants?: string[];
|
|
14
|
-
redirect?: string[];
|
|
15
14
|
img?: Record<string, string>;
|
|
16
15
|
}
|
|
17
16
|
/**
|
package/mediawiki.css
CHANGED
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
color: #84a0a0;
|
|
55
55
|
font-weight: normal;
|
|
56
56
|
}
|
|
57
|
+
.cm-mw-apostrophes,
|
|
57
58
|
.cm-mw-apostrophes-bold,
|
|
58
59
|
.cm-mw-apostrophes-italic {
|
|
59
60
|
color: #08f;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
/* template */
|
|
63
|
-
.cm-mw-template
|
|
64
|
-
.cm-mw-template-name-mnemonic {
|
|
64
|
+
.cm-mw-template {
|
|
65
65
|
font-weight: normal;
|
|
66
66
|
}
|
|
67
67
|
.cm-mw-template-name,
|
|
@@ -105,6 +105,12 @@
|
|
|
105
105
|
.cm-mw-extlink,
|
|
106
106
|
.cm-mw-free-extlink {
|
|
107
107
|
color: #36c;
|
|
108
|
+
}
|
|
109
|
+
.cm-mw-link-pagename:not(.cm-mw-strong),
|
|
110
|
+
.cm-mw-link-bracket,
|
|
111
|
+
.cm-mw-link-delimiter,
|
|
112
|
+
.cm-mw-extlink:not(.cm-mw-strong),
|
|
113
|
+
.cm-mw-free-extlink:not(.cm-mw-strong) {
|
|
108
114
|
font-weight: normal;
|
|
109
115
|
}
|
|
110
116
|
.cm-mw-link,
|
|
@@ -154,8 +160,8 @@
|
|
|
154
160
|
font-weight: bold;
|
|
155
161
|
}
|
|
156
162
|
|
|
157
|
-
/*
|
|
158
|
-
.cm-mw-
|
|
163
|
+
/* HTML entity */
|
|
164
|
+
.cm-mw-html-entity {
|
|
159
165
|
color: #84a0a0;
|
|
160
166
|
}
|
|
161
167
|
|
package/mw/dist/base.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.
|
|
1
|
+
import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.15/dist/main.min.js';
|
|
2
2
|
(() => {
|
|
3
3
|
var _a;
|
|
4
|
-
mw.loader.load('https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.
|
|
4
|
+
mw.loader.load('https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.15/mediawiki.min.css', 'text/css');
|
|
5
5
|
const instances = new WeakMap();
|
|
6
6
|
$.valHooks['textarea'] = {
|
|
7
7
|
get(elem) {
|
|
@@ -12,13 +12,13 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
12
12
|
const cm = instances.get(elem);
|
|
13
13
|
if (cm) {
|
|
14
14
|
cm.view.dispatch({
|
|
15
|
-
changes: { from: 0, to: cm.view.state.doc.length, insert: value }
|
|
15
|
+
changes: { from: 0, to: cm.view.state.doc.length, insert: value },
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
18
|
else {
|
|
19
19
|
elem.value = value;
|
|
20
20
|
}
|
|
21
|
-
}
|
|
21
|
+
},
|
|
22
22
|
};
|
|
23
23
|
function getCaretPosition(option) {
|
|
24
24
|
const { view: { state: { selection: { main } } } } = instances.get(this[0]);
|
|
@@ -31,7 +31,7 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
31
31
|
setContents(content) {
|
|
32
32
|
const { view } = instances.get(this[0]);
|
|
33
33
|
view.dispatch({
|
|
34
|
-
changes: { from: 0, to: view.state.doc.length, insert: content }
|
|
34
|
+
changes: { from: 0, to: view.state.doc.length, insert: content },
|
|
35
35
|
});
|
|
36
36
|
return this;
|
|
37
37
|
},
|
|
@@ -42,7 +42,7 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
42
42
|
setSelection({ start, end }) {
|
|
43
43
|
const { view } = instances.get(this[0]);
|
|
44
44
|
view.dispatch({
|
|
45
|
-
selection: { anchor: start, head: end !== null && end !== void 0 ? end : start }
|
|
45
|
+
selection: { anchor: start, head: end !== null && end !== void 0 ? end : start },
|
|
46
46
|
});
|
|
47
47
|
view.focus();
|
|
48
48
|
return this;
|
|
@@ -56,14 +56,14 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
56
56
|
scrollToCaretPosition() {
|
|
57
57
|
instances.get(this[0]).view.dispatch({ scrollIntoView: true });
|
|
58
58
|
return this;
|
|
59
|
-
}
|
|
59
|
+
},
|
|
60
60
|
};
|
|
61
61
|
const USING_LOCAL = mw.loader.getState('ext.CodeMirror') !== null, DATA_MODULE = mw.loader.getState('ext.CodeMirror.data') ? 'ext.CodeMirror.data' : 'ext.CodeMirror', ALL_SETTINGS_CACHE = (_a = JSON.parse(localStorage.getItem('InPageEditMwConfig'))) !== null && _a !== void 0 ? _a : {}, SITE_ID = `${mw.config.get('wgServerName')}${mw.config.get('wgScriptPath')}`, SITE_SETTINGS = ALL_SETTINGS_CACHE[SITE_ID], EXPIRED = !(SITE_SETTINGS && SITE_SETTINGS.time > Date.now() - 86400 * 1000 * 30);
|
|
62
|
-
const getAliases = (words) => words.flatMap(({ aliases, name }) => aliases.map(
|
|
62
|
+
const getAliases = (words) => words.flatMap(({ aliases, name }) => aliases.map(alias => ({ alias, name })));
|
|
63
63
|
const getConfig = (aliases) => {
|
|
64
64
|
const config = {};
|
|
65
65
|
for (const { alias, name } of aliases) {
|
|
66
|
-
config[alias.replace(
|
|
66
|
+
config[alias.replace(/:$/u, '')] = name;
|
|
67
67
|
}
|
|
68
68
|
return config;
|
|
69
69
|
};
|
|
@@ -77,13 +77,17 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
77
77
|
mw.config.set('extCodeMirrorConfig', config);
|
|
78
78
|
}
|
|
79
79
|
const isIPE = config && Object.values(config.functionSynonyms[0]).includes(true);
|
|
80
|
-
if (config && config.
|
|
80
|
+
if (config && config.img && config.variants && !isIPE) {
|
|
81
81
|
return config;
|
|
82
82
|
}
|
|
83
|
-
const { query: { general: { variants }, magicwords, extensiontags, functionhooks, variables } } = await new mw.Api().get({
|
|
83
|
+
const { query: { general: { variants }, magicwords, extensiontags, functionhooks, variables }, } = await new mw.Api().get({
|
|
84
84
|
meta: 'siteinfo',
|
|
85
|
-
siprop:
|
|
86
|
-
|
|
85
|
+
siprop: [
|
|
86
|
+
'general',
|
|
87
|
+
'magicwords',
|
|
88
|
+
...config && !isIPE ? [] : ['extensiontags', 'functionhooks', 'variables'],
|
|
89
|
+
],
|
|
90
|
+
formatversion: '2',
|
|
87
91
|
});
|
|
88
92
|
const otherMagicwords = new Set(['msg', 'raw', 'msgnw', 'subst', 'safesubst']);
|
|
89
93
|
if (config && !isIPE) {
|
|
@@ -91,34 +95,35 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
91
95
|
if (!('subst' in insensitive)) {
|
|
92
96
|
const aliases = getAliases(magicwords.filter(({ name }) => otherMagicwords.has(name)));
|
|
93
97
|
for (const { alias, name } of aliases) {
|
|
94
|
-
insensitive[alias.replace(
|
|
98
|
+
insensitive[alias.replace(/:$/u, '')] = name;
|
|
95
99
|
}
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
else {
|
|
99
103
|
config = {
|
|
100
104
|
tagModes: {
|
|
101
|
-
|
|
102
|
-
nowiki: 'mw-tag-nowiki',
|
|
103
|
-
ref: 'text/mediawiki'
|
|
105
|
+
ref: 'text/mediawiki',
|
|
104
106
|
},
|
|
105
107
|
tags: {},
|
|
106
|
-
urlProtocols: mw.config.get('wgUrlProtocols')
|
|
108
|
+
urlProtocols: mw.config.get('wgUrlProtocols'),
|
|
107
109
|
};
|
|
108
110
|
for (const tag of extensiontags) {
|
|
109
111
|
config.tags[tag.slice(1, -1)] = true;
|
|
110
112
|
}
|
|
111
|
-
const realMagicwords = new Set([
|
|
113
|
+
const realMagicwords = new Set([
|
|
114
|
+
...functionhooks,
|
|
115
|
+
...variables,
|
|
116
|
+
...otherMagicwords,
|
|
117
|
+
]), allMagicwords = magicwords.filter(({ name, aliases }) => aliases.some(alias => /^__.+__$/u.test(alias)) || realMagicwords.has(name)), sensitive = getAliases(allMagicwords.filter(word => word['case-sensitive'])), insensitive = getAliases(allMagicwords.filter(word => !word['case-sensitive'])).map(({ alias, name }) => ({ alias: alias.toLowerCase(), name }));
|
|
112
118
|
config.doubleUnderscore = [
|
|
113
119
|
getConfig(insensitive.filter(({ alias }) => /^__.+__$/u.test(alias))),
|
|
114
|
-
getConfig(sensitive.filter(({ alias }) => /^__.+__$/u.test(alias)))
|
|
120
|
+
getConfig(sensitive.filter(({ alias }) => /^__.+__$/u.test(alias))),
|
|
115
121
|
];
|
|
116
122
|
config.functionSynonyms = [
|
|
117
123
|
getConfig(insensitive.filter(({ alias }) => !/^__.+__|^#$/u.test(alias))),
|
|
118
|
-
getConfig(sensitive.filter(({ alias }) => !/^__.+__|^#$/u.test(alias)))
|
|
124
|
+
getConfig(sensitive.filter(({ alias }) => !/^__.+__|^#$/u.test(alias))),
|
|
119
125
|
];
|
|
120
126
|
}
|
|
121
|
-
config.redirect = magicwords.find(({ name }) => name === 'redirect').aliases;
|
|
122
127
|
config.img = getConfig(getAliases(magicwords.filter(({ name }) => name.startsWith('img_'))));
|
|
123
128
|
config.variants = variants ? variants.map(({ code }) => code) : [];
|
|
124
129
|
mw.config.set('extCodeMirrorConfig', config);
|
|
@@ -128,22 +133,8 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
128
133
|
};
|
|
129
134
|
const linters = {};
|
|
130
135
|
class CodeMirror extends CodeMirror6 {
|
|
131
|
-
constructor(textarea, lang) {
|
|
132
|
-
|
|
133
|
-
super(textarea, lang === 'mediawiki' ? undefined : lang);
|
|
134
|
-
if (lang === 'mediawiki') {
|
|
135
|
-
(async () => {
|
|
136
|
-
const config = await getMwConfig();
|
|
137
|
-
this.setLanguage('mediawiki', config);
|
|
138
|
-
})();
|
|
139
|
-
}
|
|
140
|
-
this.view.dispatch({
|
|
141
|
-
selection: { anchor: selectionStart, head: selectionEnd }
|
|
142
|
-
});
|
|
143
|
-
this.view.scrollDOM.scrollTop = scrollTop;
|
|
144
|
-
if (hasFocus) {
|
|
145
|
-
this.view.focus();
|
|
146
|
-
}
|
|
136
|
+
constructor(textarea, lang, config) {
|
|
137
|
+
super(textarea, lang, config);
|
|
147
138
|
instances.set(textarea, this);
|
|
148
139
|
if (mw.loader.getState('jquery.textSelection') === 'ready') {
|
|
149
140
|
$(textarea).data('jquery.textSelection', textSelection);
|
|
@@ -157,30 +148,43 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
|
|
|
157
148
|
const { lang } = this;
|
|
158
149
|
if (!(lang in linters)) {
|
|
159
150
|
linters[lang] = await this.getLinter();
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
151
|
+
if (this.lang === 'mediawiki') {
|
|
152
|
+
const mwConfig = await getMwConfig(), config = {
|
|
153
|
+
...await wikiparse.getConfig(),
|
|
154
|
+
ext: Object.keys(mwConfig.tags),
|
|
155
|
+
namespaces: mw.config.get('wgFormattedNamespaces'),
|
|
156
|
+
nsid: mw.config.get('wgNamespaceIds'),
|
|
157
|
+
doubleUnderscore: mwConfig.doubleUnderscore.map(obj => Object.keys(obj).map(s => s.slice(2, -2))),
|
|
158
|
+
variants: mwConfig.variants,
|
|
159
|
+
protocol: mwConfig.urlProtocols,
|
|
160
|
+
};
|
|
161
|
+
[config.parserFunction[0]] = mwConfig.functionSynonyms;
|
|
162
|
+
config.parserFunction[1] = [
|
|
163
|
+
...Object.keys(mwConfig.functionSynonyms[1]),
|
|
164
|
+
'=',
|
|
165
|
+
];
|
|
166
|
+
for (const key of Object.keys(mwConfig.img)) {
|
|
167
|
+
config.img[key] = mwConfig.img[key].slice(4);
|
|
168
|
+
}
|
|
169
|
+
wikiparse.setConfig(config);
|
|
173
170
|
}
|
|
174
|
-
wikiparse.setConfig(config);
|
|
175
171
|
}
|
|
176
172
|
super.lint(linters[lang]);
|
|
177
173
|
}
|
|
174
|
+
static async fromTextArea(textarea, lang) {
|
|
175
|
+
const cm = new CodeMirror(textarea, lang === 'mediawiki' ? undefined : lang);
|
|
176
|
+
if (lang === 'mediawiki') {
|
|
177
|
+
const config = await getMwConfig();
|
|
178
|
+
cm.setLanguage('mediawiki', config);
|
|
179
|
+
}
|
|
180
|
+
return cm;
|
|
181
|
+
}
|
|
178
182
|
}
|
|
179
183
|
$(document.body).click(async (e) => {
|
|
180
184
|
if (e.target instanceof HTMLTextAreaElement && (e.ctrlKey || e.metaKey) && !instances.has(e.target)) {
|
|
181
185
|
e.preventDefault();
|
|
182
186
|
await mw.loader.using('oojs-ui-windows');
|
|
183
|
-
const lang = await OO.ui.prompt('Language:') || undefined, cm =
|
|
187
|
+
const lang = await OO.ui.prompt('Language:') || undefined, cm = await CodeMirror.fromTextArea(e.target, lang === null || lang === void 0 ? void 0 : lang.toLowerCase());
|
|
184
188
|
void cm.defaultLint(true);
|
|
185
189
|
}
|
|
186
190
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bhsd/codemirror-mediawiki",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.15",
|
|
4
4
|
"description": "Modified CodeMirror mode based on wikimedia/mediawiki-extensions-CodeMirror",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -24,14 +24,16 @@
|
|
|
24
24
|
"url": "git+https://github.com/bhsd-harry/codemirror-mediawiki.git"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build:core": "
|
|
27
|
+
"build:core": "esbuild ./src/codemirror.ts --bundle --minify --target=es2018 --format=esm --outfile=dist/main.min.js; tsc --emitDeclarationOnly; rm dist/gh-page.d.ts",
|
|
28
28
|
"build:mw": "bash build.sh mw/base.ts mw/dist/base.js",
|
|
29
29
|
"build:gh-page": "bash build.sh src/gh-page.ts gh-page.js",
|
|
30
30
|
"build": "npm run build:core && npm run build:mw",
|
|
31
31
|
"lint:ts": "tsc --noEmit && tsc --project mw/tsconfig.json --noEmit && eslint --cache .",
|
|
32
32
|
"lint:css": "stylelint *.css",
|
|
33
33
|
"lint": "npm run lint:ts && npm run lint:css",
|
|
34
|
-
"
|
|
34
|
+
"server": "http-server .. -c-1 --cors &",
|
|
35
|
+
"test": "npm run server; open http://127.0.0.1:8080/codemirror-mediawiki/index.html",
|
|
36
|
+
"test:end": "pkill -x http-server"
|
|
35
37
|
},
|
|
36
38
|
"engines": {
|
|
37
39
|
"node": "20.9.0"
|
|
@@ -46,20 +48,24 @@
|
|
|
46
48
|
"@codemirror/state": "^6.3.3",
|
|
47
49
|
"@codemirror/view": "^6.22.2",
|
|
48
50
|
"@lezer/highlight": "^1.2.0",
|
|
51
|
+
"@stylistic/eslint-plugin": "^1.5.3",
|
|
52
|
+
"@stylistic/stylelint-plugin": "^2.0.0",
|
|
49
53
|
"@types/jquery": "^3.5.29",
|
|
50
54
|
"@types/oojs-ui": "^0.47.6",
|
|
51
|
-
"
|
|
52
|
-
"eslint": "^
|
|
55
|
+
"@typescript-eslint/eslint-plugin": "^6.12.0",
|
|
56
|
+
"@typescript-eslint/parser": "^6.12.0",
|
|
57
|
+
"esbuild": "^0.19.7",
|
|
58
|
+
"eslint": "^8.56.0",
|
|
53
59
|
"eslint-plugin-es-x": "^7.3.0",
|
|
60
|
+
"eslint-plugin-eslint-comments": "^3.2.0",
|
|
54
61
|
"eslint-plugin-promise": "^6.1.1",
|
|
55
62
|
"eslint-plugin-regexp": "^2.1.2",
|
|
56
|
-
"eslint-plugin-unicorn": "^
|
|
63
|
+
"eslint-plugin-unicorn": "^50.0.1",
|
|
57
64
|
"http-server": "^14.1.0",
|
|
58
|
-
"stylelint": "^
|
|
59
|
-
"stylelint-config-recommended": "^
|
|
65
|
+
"stylelint": "^16.1.0",
|
|
66
|
+
"stylelint-config-recommended": "^14.0.0",
|
|
60
67
|
"types-mediawiki": "^1.4.0",
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"wikilint": "^2.1.5"
|
|
68
|
+
"typescript": "^5.1.6",
|
|
69
|
+
"wikilint": "^2.3.0"
|
|
64
70
|
}
|
|
65
71
|
}
|