@bhsd/codemirror-mediawiki 2.0.12 → 2.0.14
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 +33 -3
- package/dist/codemirror.d.ts +6 -1
- package/dist/main.min.js +1 -1
- package/dist/mediawiki.d.ts +5 -2
- package/mediawiki.css +1 -1
- package/mw/dist/base.js +182 -0
- package/package.json +20 -7
package/dist/mediawiki.d.ts
CHANGED
|
@@ -8,8 +8,11 @@ export interface MwConfig {
|
|
|
8
8
|
urlProtocols: string;
|
|
9
9
|
tags: Record<string, true>;
|
|
10
10
|
tagModes: Record<string, string>;
|
|
11
|
-
functionSynonyms: [Record<string, string>, Record<string, string>];
|
|
12
|
-
doubleUnderscore: [Record<string, string>, Record<string, string>];
|
|
11
|
+
functionSynonyms: [Record<string, string | true>, Record<string, string | true>];
|
|
12
|
+
doubleUnderscore: [Record<string, string | true>, Record<string, string | true>];
|
|
13
|
+
variants?: string[];
|
|
14
|
+
redirect?: string[];
|
|
15
|
+
img?: Record<string, string>;
|
|
13
16
|
}
|
|
14
17
|
/**
|
|
15
18
|
* Gets a LanguageSupport instance for the MediaWiki mode.
|
package/mediawiki.css
CHANGED
package/mw/dist/base.js
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.14/dist/main.min.js';
|
|
2
|
+
(() => {
|
|
3
|
+
var _a;
|
|
4
|
+
mw.loader.load('https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.0.14/mediawiki.min.css', 'text/css');
|
|
5
|
+
const instances = new WeakMap();
|
|
6
|
+
$.valHooks['textarea'] = {
|
|
7
|
+
get(elem) {
|
|
8
|
+
const cm = instances.get(elem);
|
|
9
|
+
return cm ? cm.view.state.doc.toString() : elem.value;
|
|
10
|
+
},
|
|
11
|
+
set(elem, value) {
|
|
12
|
+
const cm = instances.get(elem);
|
|
13
|
+
if (cm) {
|
|
14
|
+
cm.view.dispatch({
|
|
15
|
+
changes: { from: 0, to: cm.view.state.doc.length, insert: value }
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
elem.value = value;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
function getCaretPosition(option) {
|
|
24
|
+
const { view: { state: { selection: { main } } } } = instances.get(this[0]);
|
|
25
|
+
return (option === null || option === void 0 ? void 0 : option.startAndEnd) ? [main.from, main.to] : main.head;
|
|
26
|
+
}
|
|
27
|
+
const textSelection = {
|
|
28
|
+
getContents() {
|
|
29
|
+
return instances.get(this[0]).view.state.doc.toString();
|
|
30
|
+
},
|
|
31
|
+
setContents(content) {
|
|
32
|
+
const { view } = instances.get(this[0]);
|
|
33
|
+
view.dispatch({
|
|
34
|
+
changes: { from: 0, to: view.state.doc.length, insert: content }
|
|
35
|
+
});
|
|
36
|
+
return this;
|
|
37
|
+
},
|
|
38
|
+
getSelection() {
|
|
39
|
+
const { view: { state } } = instances.get(this[0]);
|
|
40
|
+
return state.sliceDoc(state.selection.main.from, state.selection.main.to);
|
|
41
|
+
},
|
|
42
|
+
setSelection({ start, end }) {
|
|
43
|
+
const { view } = instances.get(this[0]);
|
|
44
|
+
view.dispatch({
|
|
45
|
+
selection: { anchor: start, head: end !== null && end !== void 0 ? end : start }
|
|
46
|
+
});
|
|
47
|
+
view.focus();
|
|
48
|
+
return this;
|
|
49
|
+
},
|
|
50
|
+
replaceSelection(value) {
|
|
51
|
+
const { view } = instances.get(this[0]);
|
|
52
|
+
view.dispatch(view.state.replaceSelection(value));
|
|
53
|
+
return this;
|
|
54
|
+
},
|
|
55
|
+
getCaretPosition,
|
|
56
|
+
scrollToCaretPosition() {
|
|
57
|
+
instances.get(this[0]).view.dispatch({ scrollIntoView: true });
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
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((alias) => ({ alias, name })));
|
|
63
|
+
const getConfig = (aliases) => {
|
|
64
|
+
const config = {};
|
|
65
|
+
for (const { alias, name } of aliases) {
|
|
66
|
+
config[alias.replace(/:$/, '')] = name;
|
|
67
|
+
}
|
|
68
|
+
return config;
|
|
69
|
+
};
|
|
70
|
+
const getMwConfig = async () => {
|
|
71
|
+
if (USING_LOCAL && EXPIRED) {
|
|
72
|
+
await mw.loader.using(DATA_MODULE);
|
|
73
|
+
}
|
|
74
|
+
let config = mw.config.get('extCodeMirrorConfig');
|
|
75
|
+
if (!config && !EXPIRED) {
|
|
76
|
+
({ config } = SITE_SETTINGS);
|
|
77
|
+
mw.config.set('extCodeMirrorConfig', config);
|
|
78
|
+
}
|
|
79
|
+
const isIPE = config && Object.values(config.functionSynonyms[0]).includes(true);
|
|
80
|
+
if (config && config.redirect && config.img && config.variants && !isIPE) {
|
|
81
|
+
return config;
|
|
82
|
+
}
|
|
83
|
+
const { query: { general: { variants }, magicwords, extensiontags, functionhooks, variables } } = await new mw.Api().get({
|
|
84
|
+
meta: 'siteinfo',
|
|
85
|
+
siprop: `general|magicwords${config && !isIPE ? '' : '|extensiontags|functionhooks|variables'}`,
|
|
86
|
+
formatversion: 2
|
|
87
|
+
});
|
|
88
|
+
const otherMagicwords = new Set(['msg', 'raw', 'msgnw', 'subst', 'safesubst']);
|
|
89
|
+
if (config && !isIPE) {
|
|
90
|
+
const { functionSynonyms: [insensitive] } = config;
|
|
91
|
+
if (!('subst' in insensitive)) {
|
|
92
|
+
const aliases = getAliases(magicwords.filter(({ name }) => otherMagicwords.has(name)));
|
|
93
|
+
for (const { alias, name } of aliases) {
|
|
94
|
+
insensitive[alias.replace(/:$/, '')] = name;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
config = {
|
|
100
|
+
tagModes: {
|
|
101
|
+
pre: 'mw-tag-pre',
|
|
102
|
+
nowiki: 'mw-tag-nowiki',
|
|
103
|
+
ref: 'text/mediawiki'
|
|
104
|
+
},
|
|
105
|
+
tags: {},
|
|
106
|
+
urlProtocols: mw.config.get('wgUrlProtocols')
|
|
107
|
+
};
|
|
108
|
+
for (const tag of extensiontags) {
|
|
109
|
+
config.tags[tag.slice(1, -1)] = true;
|
|
110
|
+
}
|
|
111
|
+
const realMagicwords = new Set([...functionhooks, ...variables, ...otherMagicwords]), allMagicwords = magicwords.filter(({ name, aliases }) => aliases.some((alias) => /^__.+__$/.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
|
+
config.doubleUnderscore = [
|
|
113
|
+
getConfig(insensitive.filter(({ alias }) => /^__.+__$/u.test(alias))),
|
|
114
|
+
getConfig(sensitive.filter(({ alias }) => /^__.+__$/u.test(alias)))
|
|
115
|
+
];
|
|
116
|
+
config.functionSynonyms = [
|
|
117
|
+
getConfig(insensitive.filter(({ alias }) => !/^__.+__|^#$/u.test(alias))),
|
|
118
|
+
getConfig(sensitive.filter(({ alias }) => !/^__.+__|^#$/u.test(alias)))
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
config.redirect = magicwords.find(({ name }) => name === 'redirect').aliases;
|
|
122
|
+
config.img = getConfig(getAliases(magicwords.filter(({ name }) => name.startsWith('img_'))));
|
|
123
|
+
config.variants = variants ? variants.map(({ code }) => code) : [];
|
|
124
|
+
mw.config.set('extCodeMirrorConfig', config);
|
|
125
|
+
ALL_SETTINGS_CACHE[SITE_ID] = { config: config, time: Date.now() };
|
|
126
|
+
localStorage.setItem('InPageEditMwConfig', JSON.stringify(ALL_SETTINGS_CACHE));
|
|
127
|
+
return config;
|
|
128
|
+
};
|
|
129
|
+
const linters = {};
|
|
130
|
+
class CodeMirror extends CodeMirror6 {
|
|
131
|
+
constructor(textarea, lang, config) {
|
|
132
|
+
super(textarea, lang, config);
|
|
133
|
+
instances.set(textarea, this);
|
|
134
|
+
if (mw.loader.getState('jquery.textSelection') === 'ready') {
|
|
135
|
+
$(textarea).data('jquery.textSelection', textSelection);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
async defaultLint(on) {
|
|
139
|
+
if (!on) {
|
|
140
|
+
super.lint();
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const { lang } = this;
|
|
144
|
+
if (!(lang in linters)) {
|
|
145
|
+
linters[lang] = await this.getLinter();
|
|
146
|
+
if (this.lang === 'mediawiki') {
|
|
147
|
+
const mwConfig = await getMwConfig(), config = await wikiparse.getConfig();
|
|
148
|
+
config.ext = Object.keys(mwConfig.tags);
|
|
149
|
+
config.namespaces = mw.config.get('wgFormattedNamespaces');
|
|
150
|
+
config.nsid = mw.config.get('wgNamespaceIds');
|
|
151
|
+
config.parserFunction[0] = mwConfig.functionSynonyms[0];
|
|
152
|
+
config.parserFunction[1] = [...Object.keys(mwConfig.functionSynonyms[1]), '='];
|
|
153
|
+
config.doubleUnderscore = mwConfig.doubleUnderscore.map(Object.keys);
|
|
154
|
+
config.variants = mwConfig.variants;
|
|
155
|
+
config.img = mwConfig.img;
|
|
156
|
+
for (const key of Object.keys(config.img)) {
|
|
157
|
+
config.img[key] = config.img[key].slice(4);
|
|
158
|
+
}
|
|
159
|
+
wikiparse.setConfig(config);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
super.lint(linters[lang]);
|
|
163
|
+
}
|
|
164
|
+
static async fromTextArea(textarea, lang) {
|
|
165
|
+
const cm = new CodeMirror(textarea, lang === 'mediawiki' ? undefined : lang);
|
|
166
|
+
if (lang === 'mediawiki') {
|
|
167
|
+
const config = await getMwConfig();
|
|
168
|
+
cm.setLanguage('mediawiki', config);
|
|
169
|
+
}
|
|
170
|
+
return cm;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
$(document.body).click(async (e) => {
|
|
174
|
+
if (e.target instanceof HTMLTextAreaElement && (e.ctrlKey || e.metaKey) && !instances.has(e.target)) {
|
|
175
|
+
e.preventDefault();
|
|
176
|
+
await mw.loader.using('oojs-ui-windows');
|
|
177
|
+
const lang = await OO.ui.prompt('Language:') || undefined, cm = await CodeMirror.fromTextArea(e.target, lang);
|
|
178
|
+
void cm.defaultLint(true);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
Object.assign(window, { CodeMirror });
|
|
182
|
+
})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bhsd/codemirror-mediawiki",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.14",
|
|
4
4
|
"description": "Modified CodeMirror mode based on wikimedia/mediawiki-extensions-CodeMirror",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mediawiki",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"license": "GPL-2.0",
|
|
14
14
|
"files":[
|
|
15
15
|
"/dist/*.[jt]s",
|
|
16
|
-
"/mediawiki.css"
|
|
16
|
+
"/mediawiki.css",
|
|
17
|
+
"/mw/dist/*.js"
|
|
17
18
|
],
|
|
18
19
|
"browser": "dist/main.min.js",
|
|
19
20
|
"main": "./dist/main.min.js",
|
|
@@ -23,10 +24,16 @@
|
|
|
23
24
|
"url": "git+https://github.com/bhsd-harry/codemirror-mediawiki.git"
|
|
24
25
|
},
|
|
25
26
|
"scripts": {
|
|
26
|
-
"
|
|
27
|
-
"build": "
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
"build:core": "webpack --mode production; tsc --emitDeclarationOnly; rm dist/gh-page.d.ts",
|
|
28
|
+
"build:mw": "bash build.sh mw/base.ts mw/dist/base.js",
|
|
29
|
+
"build:gh-page": "bash build.sh src/gh-page.ts gh-page.js",
|
|
30
|
+
"build": "npm run build:core && npm run build:mw",
|
|
31
|
+
"lint:ts": "tsc --noEmit && tsc --project mw/tsconfig.json --noEmit && eslint --cache .",
|
|
32
|
+
"lint:css": "stylelint *.css",
|
|
33
|
+
"lint": "npm run lint:ts && npm run lint:css",
|
|
34
|
+
"server": "http-server -c-1 --cors &",
|
|
35
|
+
"test": "npm run server; open http://127.0.0.1:8080/index.html",
|
|
36
|
+
"test:end": "pkill -x http-server"
|
|
30
37
|
},
|
|
31
38
|
"engines": {
|
|
32
39
|
"node": "20.9.0"
|
|
@@ -41,6 +48,8 @@
|
|
|
41
48
|
"@codemirror/state": "^6.3.3",
|
|
42
49
|
"@codemirror/view": "^6.22.2",
|
|
43
50
|
"@lezer/highlight": "^1.2.0",
|
|
51
|
+
"@types/jquery": "^3.5.29",
|
|
52
|
+
"@types/oojs-ui": "^0.47.6",
|
|
44
53
|
"esbuild-loader": "^4.0.2",
|
|
45
54
|
"eslint": "^8.53.0",
|
|
46
55
|
"eslint-plugin-es-x": "^7.3.0",
|
|
@@ -48,7 +57,11 @@
|
|
|
48
57
|
"eslint-plugin-regexp": "^2.1.2",
|
|
49
58
|
"eslint-plugin-unicorn": "^49.0.0",
|
|
50
59
|
"http-server": "^14.1.0",
|
|
60
|
+
"stylelint": "^15.11.0",
|
|
61
|
+
"stylelint-config-recommended": "^13.0.0",
|
|
62
|
+
"types-mediawiki": "^1.4.0",
|
|
51
63
|
"webpack": "^5.89.0",
|
|
52
|
-
"webpack-cli": "^5.1.4"
|
|
64
|
+
"webpack-cli": "^5.1.4",
|
|
65
|
+
"wikilint": "^2.1.5"
|
|
53
66
|
}
|
|
54
67
|
}
|