@bhsd/codemirror-mediawiki 2.1.8 → 2.1.9

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/mw/dist/base.js CHANGED
@@ -1,7 +1,8 @@
1
- import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.1.8/dist/main.min.js';
1
+ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.1.9/dist/main.min.js';
2
2
  (() => {
3
3
  var _a;
4
- mw.loader.load('https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.1.8/mediawiki.min.css', 'text/css');
4
+ mw.loader.load('https://testingcf.jsdelivr.net/npm/@bhsd/codemirror-mediawiki@2.1.9/mediawiki.min.css', 'text/css');
5
+ mw.loader.addStyleTag('.wikiEditor-ui-toolbar{z-index:7}');
5
6
  const instances = new WeakMap();
6
7
  const getInstance = ($ele) => instances.get($ele[0]);
7
8
  $.valHooks['textarea'] = {
@@ -157,12 +158,27 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
157
158
  linters[this.lang] = linter;
158
159
  return linter;
159
160
  }
160
- async defaultLint(on, opt) {
161
+ async defaultLint(on, optOrNs) {
161
162
  if (!on) {
162
163
  this.lint();
163
164
  return;
164
165
  }
165
166
  const { lang } = this;
167
+ let opt;
168
+ if (typeof optOrNs === 'number') {
169
+ if (lang === 'mediawiki' && (optOrNs === 10 || optOrNs === 828)) {
170
+ opt = { include: true };
171
+ }
172
+ else if (lang === 'javascript' && (optOrNs === 8 || optOrNs === 2300)) {
173
+ opt = {
174
+ env: { browser: true, es6: true },
175
+ parserOptions: { ecmaVersion: 6 },
176
+ };
177
+ }
178
+ }
179
+ else {
180
+ opt = optOrNs;
181
+ }
166
182
  if (!(lang in linters)) {
167
183
  await this.getLinter(opt);
168
184
  if (lang === 'mediawiki') {
@@ -241,17 +257,7 @@ import { CodeMirror6 } from 'https://testingcf.jsdelivr.net/npm/@bhsd/codemirror
241
257
  }
242
258
  }
243
259
  const cm = await CodeMirror.fromTextArea(e.target, lang);
244
- let opt;
245
- if (lang === 'mediawiki' && wgNamespaceNumber === 10) {
246
- opt = { include: true };
247
- }
248
- else if (lang === 'javascript' && (wgNamespaceNumber === 8 || wgNamespaceNumber === 2300)) {
249
- opt = {
250
- env: { browser: true, es6: true },
251
- parserOptions: { ecmaVersion: 6 },
252
- };
253
- }
254
- await cm.defaultLint(true, opt);
260
+ void cm.defaultLint(true, wgNamespaceNumber);
255
261
  })();
256
262
  }
257
263
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bhsd/codemirror-mediawiki",
3
- "version": "2.1.8",
3
+ "version": "2.1.9",
4
4
  "description": "Modified CodeMirror mode based on wikimedia/mediawiki-extensions-CodeMirror",
5
5
  "keywords": [
6
6
  "mediawiki",
@@ -35,8 +35,7 @@
35
35
  "lint:ts": "tsc --noEmit && tsc --project mw/tsconfig.json --noEmit && eslint --cache .",
36
36
  "lint:css": "stylelint *.css",
37
37
  "lint": "npm run lint:ts && npm run lint:css",
38
- "server": "http-server .. -c-1 --cors &",
39
- "test": "npm run server; open http://127.0.0.1:8080/codemirror-mediawiki/index.html",
38
+ "test": "http-server .. -c-1 --cors &",
40
39
  "test:end": "pkill -x http-server"
41
40
  },
42
41
  "engines": {
package/src/codemirror.ts CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  } from '@codemirror/language';
20
20
  import {defaultKeymap, historyKeymap, history} from '@codemirror/commands';
21
21
  import {searchKeymap} from '@codemirror/search';
22
- import {linter, lintGutter, openLintPanel, closeLintPanel} from '@codemirror/lint';
22
+ import {linter, lintGutter, openLintPanel, closeLintPanel, lintKeymap} from '@codemirror/lint';
23
23
  import {closeBrackets} from '@codemirror/autocomplete';
24
24
  import {mediawiki, html} from './mediawiki';
25
25
  import * as plugins from './plugins';
@@ -32,6 +32,8 @@ import type {Linter} from 'eslint';
32
32
  export type {MwConfig} from './mediawiki';
33
33
  export type LintSource = (doc: Text) => Diagnostic[] | Promise<Diagnostic[]>;
34
34
 
35
+ declare type LintExtension = [unknown, ViewPlugin<{set: boolean, force(): void}>];
36
+
35
37
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
36
38
  const languages: Record<string, (config?: any) => LanguageSupport | []> = {
37
39
  plain: () => [],
@@ -43,7 +45,7 @@ for (const [language, parser] of Object.entries(plugins)) {
43
45
  }
44
46
  const linters: Record<string, Extension> = {};
45
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
- const avail: Record<string, [ (config?: any) => Extension, Record<string, unknown> ]> = {
48
+ const avail: Record<string, [(config?: any) => Extension, Record<string, unknown>]> = {
47
49
  highlightSpecialChars: [highlightSpecialChars, {}],
48
50
  highlightActiveLine: [highlightActiveLine, {}],
49
51
  highlightWhitespace: [highlightWhitespace, {}],
@@ -137,6 +139,7 @@ export class CodeMirror6 {
137
139
  ...defaultKeymap,
138
140
  ...historyKeymap,
139
141
  ...searchKeymap,
142
+ ...lintKeymap,
140
143
  ]),
141
144
  EditorView.updateListener.of(({state: {doc}, docChanged}) => {
142
145
  if (docChanged) {
@@ -186,6 +189,21 @@ export class CodeMirror6 {
186
189
  this.#view.dom.style.minHeight = linting ? 'calc(100px + 2em)' : '2em';
187
190
  }
188
191
 
192
+ /**
193
+ * 开关语法检查面板
194
+ * @param show 是否显示
195
+ */
196
+ #toggleLintPanel(show: boolean): void {
197
+ (show ? openLintPanel : closeLintPanel)(this.#view);
198
+ document.querySelector<HTMLUListElement>('.cm-panel-lint ul')?.blur();
199
+ this.#minHeight(show);
200
+ }
201
+
202
+ /** 获取语法检查扩展 */
203
+ #getLintExtension(): LintExtension | undefined {
204
+ return (this.#linter.get(this.#view.state) as LintExtension[])[0];
205
+ }
206
+
189
207
  /**
190
208
  * 设置语言
191
209
  * @param lang 语言
@@ -199,7 +217,7 @@ export class CodeMirror6 {
199
217
  ],
200
218
  });
201
219
  this.#lang = lang;
202
- (linters[lang] ? openLintPanel : closeLintPanel)(this.#view);
220
+ this.#toggleLintPanel(Boolean(linters[lang]));
203
221
  }
204
222
 
205
223
  /**
@@ -215,25 +233,20 @@ export class CodeMirror6 {
215
233
  : [];
216
234
  if (lintSource) {
217
235
  linters[this.#lang] = linterExtension;
218
- this.#minHeight(true);
219
236
  } else {
220
237
  delete linters[this.#lang];
221
- this.#minHeight();
222
238
  }
223
239
  this.#view.dispatch({
224
240
  effects: [this.#linter.reconfigure(linterExtension)],
225
241
  });
226
- (lintSource ? openLintPanel : closeLintPanel)(this.#view);
242
+ this.#toggleLintPanel(Boolean(lintSource));
227
243
  }
228
244
 
229
245
  /** 立即更新语法检查 */
230
246
  update(): void {
231
- const extension = this.#linter.get(this.#view.state) as [[ unknown, ViewPlugin<{
232
- set: boolean;
233
- force(): void;
234
- }> ]] | [];
235
- if (extension.length > 0) {
236
- const plugin = this.#view.plugin(extension[0]![1])!;
247
+ const extension = this.#getLintExtension();
248
+ if (extension) {
249
+ const plugin = this.#view.plugin(extension[1])!;
237
250
  plugin.set = true;
238
251
  plugin.force();
239
252
  }
@@ -281,10 +294,10 @@ export class CodeMirror6 {
281
294
  conf: Linter.Config = {
282
295
  env: {
283
296
  browser: true,
284
- es2018: true,
297
+ es2024: true,
285
298
  },
286
299
  parserOptions: {
287
- ecmaVersion: 9,
300
+ ecmaVersion: 15,
288
301
  sourceType: 'module',
289
302
  },
290
303
  rules: {},
package/src/mediawiki.ts CHANGED
@@ -556,7 +556,7 @@ class MediaWiki {
556
556
 
557
557
  inHtmlTagAttribute(name: string): Tokenizer {
558
558
  return (stream, state) => {
559
- if (stream.match(/^[^>/<{]+/u)) {
559
+ if (stream.match(/^(?:"[^<">]*"|'[^<'>]*'[^>/<{])+/u)) {
560
560
  return this.makeLocalStyle(modeConfig.tags.htmlTagAttribute, state);
561
561
  } else if (stream.match(/^\/?>/u)) {
562
562
  if (!this.implicitlyClosedHtmlTags.has(name)) {
@@ -582,7 +582,7 @@ class MediaWiki {
582
582
 
583
583
  inExtTagAttribute(name: string): Tokenizer {
584
584
  return (stream, state) => {
585
- if (stream.match(/^[^>/]+/u)) {
585
+ if (stream.match(/^(?:"[^">]*"|'[^'>]*'|[^>/])+/u)) {
586
586
  return this.makeLocalStyle(modeConfig.tags.extTagAttribute, state);
587
587
  } else if (stream.eat('>')) {
588
588
  state.extName = name;