@bhsd/codemirror-mediawiki 3.11.0 → 3.11.2

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.
@@ -2,7 +2,7 @@ import { EditorView, lineNumbers, keymap, highlightActiveLineGutter } from '@cod
2
2
  import { EditorSelection, Compartment, EditorState, SelectionRange, } from '@codemirror/state';
3
3
  import { syntaxHighlighting, defaultHighlightStyle, indentOnInput, indentUnit, ensureSyntaxTree, syntaxTree, } from '@codemirror/language';
4
4
  import { defaultKeymap, historyKeymap, history, redo, indentWithTab, insertNewlineKeepIndent, deleteCharBackwardStrict, } from '@codemirror/commands';
5
- import { search, searchKeymap } from '@codemirror/search';
5
+ import { searchKeymap } from '@codemirror/search';
6
6
  import { linter, lintGutter, nextDiagnostic } from '@codemirror/lint';
7
7
  import elt from 'crelt';
8
8
  import { base, panelSelector, panelsSelector, diagnosticSelector, noDetectionLangs } from './constants.js';
@@ -155,13 +155,6 @@ export class CodeMirror6 {
155
155
  EditorView.editorAttributes.of({ lang: l }),
156
156
  lineNumbers(),
157
157
  highlightActiveLineGutter(),
158
- search({
159
- scrollToMatch(range, view) {
160
- const scrollRect = view.scrollDOM.getBoundingClientRect(), startCoords = view.coordsAtPos(range.from), endCoords = view.coordsAtPos(range.to), isInViewport = startCoords && startCoords.top >= scrollRect.top
161
- && endCoords && endCoords.bottom <= scrollRect.bottom;
162
- return EditorView.scrollIntoView(range, { y: isInViewport ? 'nearest' : 'center' });
163
- },
164
- }),
165
158
  keymap.of([
166
159
  ...defaultKeymap,
167
160
  ...searchKeymap,
@@ -260,10 +253,6 @@ export class CodeMirror6 {
260
253
  #minHeight(linting) {
261
254
  this.#view.dom.style.minHeight = linting ? 'calc(100px + 2em)' : '2em';
262
255
  }
263
- /** 获取语法检查扩展 */
264
- #getLintExtension() {
265
- return this.#linter.get(this.#view.state)[0];
266
- }
267
256
  /**
268
257
  * Set language
269
258
  * @param lang language
@@ -332,7 +321,7 @@ export class CodeMirror6 {
332
321
  /** Update syntax checking immediately */
333
322
  update() {
334
323
  if (this.#view) {
335
- const extension = this.#getLintExtension();
324
+ const [extension] = this.#linter.get(this.#view.state);
336
325
  if (extension) {
337
326
  const plugin = this.#view.plugin(extension[1]);
338
327
  plugin.set = true;
@@ -0,0 +1 @@
1
+ export { builtin, vue } from 'globals';
@@ -0,0 +1,78 @@
1
+ // ../node_modules/globals/globals.json
2
+ var builtin = {
3
+ AggregateError: false,
4
+ Array: false,
5
+ ArrayBuffer: false,
6
+ Atomics: false,
7
+ BigInt: false,
8
+ BigInt64Array: false,
9
+ BigUint64Array: false,
10
+ Boolean: false,
11
+ DataView: false,
12
+ Date: false,
13
+ decodeURI: false,
14
+ decodeURIComponent: false,
15
+ encodeURI: false,
16
+ encodeURIComponent: false,
17
+ Error: false,
18
+ escape: false,
19
+ eval: false,
20
+ EvalError: false,
21
+ FinalizationRegistry: false,
22
+ Float16Array: false,
23
+ Float32Array: false,
24
+ Float64Array: false,
25
+ Function: false,
26
+ globalThis: false,
27
+ Infinity: false,
28
+ Int16Array: false,
29
+ Int32Array: false,
30
+ Int8Array: false,
31
+ Intl: false,
32
+ isFinite: false,
33
+ isNaN: false,
34
+ Iterator: false,
35
+ JSON: false,
36
+ Map: false,
37
+ Math: false,
38
+ NaN: false,
39
+ Number: false,
40
+ Object: false,
41
+ parseFloat: false,
42
+ parseInt: false,
43
+ Promise: false,
44
+ Proxy: false,
45
+ RangeError: false,
46
+ ReferenceError: false,
47
+ Reflect: false,
48
+ RegExp: false,
49
+ Set: false,
50
+ SharedArrayBuffer: false,
51
+ String: false,
52
+ Symbol: false,
53
+ SyntaxError: false,
54
+ TypeError: false,
55
+ Uint16Array: false,
56
+ Uint32Array: false,
57
+ Uint8Array: false,
58
+ Uint8ClampedArray: false,
59
+ undefined: false,
60
+ unescape: false,
61
+ URIError: false,
62
+ WeakMap: false,
63
+ WeakRef: false,
64
+ WeakSet: false
65
+ };
66
+ var vue = {
67
+ defineEmits: false,
68
+ defineExpose: false,
69
+ defineModel: false,
70
+ defineOptions: false,
71
+ defineProps: false,
72
+ defineSlots: false,
73
+ withDefaults: false
74
+ };
75
+ export {
76
+ builtin,
77
+ vue
78
+ };
@@ -2,9 +2,9 @@ import { javascript as js, javascriptLanguage, scopeCompletionSource, localCompl
2
2
  import { ViewPlugin, Decoration } from '@codemirror/view';
3
3
  import { syntaxTree } from '@codemirror/language';
4
4
  import { setDiagnosticsEffect } from '@codemirror/lint';
5
- import { builtin } from 'globals/globals.json';
5
+ import { builtin } from './javascript-globals.js';
6
6
  export const jsCompletion = javascriptLanguage.data.of({ autocomplete: scopeCompletionSource(globalThis) });
7
- const globals = Decoration.mark({ class: 'cm-globals' }), builtinGlobals = new Set(Object.keys(builtin));
7
+ const globalsMark = Decoration.mark({ class: 'cm-globals' }), builtinGlobals = new Set(Object.keys(builtin));
8
8
  /**
9
9
  * 高亮显示全局变量
10
10
  * @ignore
@@ -14,17 +14,25 @@ export const markGlobals = (tree, visibleRanges, state, cm) => {
14
14
  const decorations = [];
15
15
  let allGlobals = builtinGlobals;
16
16
  if (cm?.lintSources.length && typeof eslint === 'object' && 'environments' in eslint) {
17
- const env = cm.lintSources[0]?.config?.env;
18
- if (env) {
17
+ const { env, globals } = cm.lintSources[0]?.config ?? {};
18
+ if (env || globals) {
19
19
  allGlobals = new Set(builtinGlobals);
20
- for (const key of Object.keys(env)) {
21
- const obj = eslint.environments.get(key)?.globals;
22
- if (obj) {
23
- for (const k of Object.keys(obj)) {
24
- allGlobals.add(k);
20
+ if (env) {
21
+ for (const key of Object.keys(env)) {
22
+ const obj = eslint.environments.get(key)
23
+ ?.globals;
24
+ if (obj) {
25
+ for (const k of Object.keys(obj)) {
26
+ allGlobals.add(k);
27
+ }
25
28
  }
26
29
  }
27
30
  }
31
+ if (globals) {
32
+ for (const k of Object.keys(globals)) {
33
+ allGlobals.add(k);
34
+ }
35
+ }
28
36
  }
29
37
  }
30
38
  for (const { from, to } of visibleRanges) {
@@ -36,7 +44,7 @@ export const markGlobals = (tree, visibleRanges, state, cm) => {
36
44
  if (type.is('VariableName') && javascriptLanguage.isActiveAt(state, f) && allGlobals.has(name)) {
37
45
  const completions = localCompletionSource({ state, pos: t, explicit: true });
38
46
  if (!completions?.options.some(({ label }) => label === name)) {
39
- decorations.push(globals.range(f, t));
47
+ decorations.push(globalsMark.range(f, t));
40
48
  }
41
49
  }
42
50
  },
package/dist/linter.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { Diagnostic as DiagnosticBase, Range, Position } from 'vscode-languageserver-types';
2
2
  import type { Linter } from 'eslint';
3
- import type { Warning } from 'stylelint/types/stylelint';
3
+ import type { Warning, Config } from 'stylelint/types/stylelint';
4
4
  import type { Diagnostic } from 'luacheck-browserify';
5
5
  import type { AST } from 'wikiparser-node';
6
6
  export type Option = Record<string, unknown> | null | undefined;
@@ -45,6 +45,11 @@ export declare const getPrefix: ({ type, tag }: AST, i: number) => string;
45
45
  * @test
46
46
  */
47
47
  export declare const indexToPos: (code: string, index: number) => Position;
48
+ /**
49
+ * 判断是否为 Stylelint 设置
50
+ * @param config 设置
51
+ */
52
+ export declare const isStylelintConfig: (config?: Config | Config["rules"]) => config is Config;
48
53
  /**
49
54
  * 获取 Wikitext LSP
50
55
  * @param opt 选项
package/dist/linter.js CHANGED
@@ -42,7 +42,7 @@ export const indexToPos = (code, index) => {
42
42
  * 判断是否为 Stylelint 设置
43
43
  * @param config 设置
44
44
  */
45
- const isStylelintConfig = (config) => Boolean(config && ('extends' in config || 'rules' in config));
45
+ export const isStylelintConfig = (config) => Boolean(config && ('extends' in config || 'rules' in config));
46
46
  /**
47
47
  * 获取 Wikitext LSP
48
48
  * @param opt 选项
@@ -108,8 +108,10 @@ export const getWikiLinter = async (opt, obj) => {
108
108
  }
109
109
  return linter;
110
110
  };
111
+ // eslint-disable-next-line unicorn/no-unreadable-iife
112
+ const jsEnv = /* #__PURE__ */ (() => ({ browser: true, es2024: true }))();
111
113
  export const jsConfig = /* #__PURE__ */ (() => ({
112
- env: { browser: true, es2024: true, jquery: true },
114
+ env: { ...jsEnv, jquery: true },
113
115
  globals: {
114
116
  mw: 'readonly',
115
117
  mediaWiki: 'readonly',
@@ -130,7 +132,7 @@ export const getJsLinter = async (cdn = eslintRepo) => {
130
132
  await loadScript(cdn, 'eslint');
131
133
  /** @see https://www.npmjs.com/package/@codemirror/lang-javascript */
132
134
  const esLinter = new eslint.Linter(), conf = {
133
- env: { browser: true, es2024: true },
135
+ env: jsEnv,
134
136
  parserOptions: { ecmaVersion: 15, sourceType: 'module' },
135
137
  }, recommended = {};
136
138
  for (const [name, { meta }] of esLinter.getRules()) {
@@ -2,9 +2,10 @@ import { ensureSyntaxTree } from '@codemirror/language';
2
2
  import { cssLanguage } from '@codemirror/lang-css';
3
3
  import { javascriptLanguage } from '@codemirror/lang-javascript';
4
4
  import { sanitizeInlineStyle, lintJSON } from '@bhsd/common';
5
- import { getWikiLinter, getJsLinter, getCssLinter, getLuaLinter, stylelintRepo, eslintRepo, luacheckRepo, } from './linter.js';
5
+ import { getWikiLinter, getJsLinter, getCssLinter, getLuaLinter, stylelintRepo, eslintRepo, luacheckRepo, isStylelintConfig, } from './linter.js';
6
6
  import { posToIndex, toConfigGetter, } from './util.js';
7
7
  import { base } from './constants.js';
8
+ import { vue } from './javascript-globals.js';
8
9
  /**
9
10
  * 获取Linter选项
10
11
  * @param opt Linter选项
@@ -166,13 +167,34 @@ export const getCssLintSource = async (opt) => {
166
167
  return lintSource;
167
168
  };
168
169
  /**
169
- * @implements
170
- * @test
170
+ * @author Yosuke Ota and others
171
+ * @license MIT
172
+ * @see https://github.com/ota-meshi/stylelint-config-recommended-vue/blob/main/lib/vue-specific-rules.js
171
173
  */
172
- export const getVueLintSource = async (opt) => {
174
+ // eslint-disable-next-line unicorn/no-unreadable-iife
175
+ const stylelintConfigVue = /* #__PURE__ */ (() => ({
176
+ 'selector-pseudo-class-no-unknown': [true, { ignorePseudoClasses: ['deep', 'global', 'slotted'] }],
177
+ 'selector-pseudo-element-no-unknown': [true, { ignorePseudoElements: ['v-deep', 'v-global', 'v-slotted'] }],
178
+ 'declaration-property-value-no-unknown': [true, { ignoreProperties: { '/.*/': String.raw `/v-bind\(.+\)/` } }],
179
+ 'function-no-unknown': [true, { ignoreFunctions: ['v-bind'] }],
180
+ }))();
181
+ /** @implements */
182
+ const getVueOrHtmlLintSource = (rules, globals) => async (opt) => {
173
183
  const { CDN } = base, styleLint = await getCssLinter(CDN && `${CDN}/${stylelintRepo}`), esLint = await getJsLinter(CDN && `${CDN}/${eslintRepo}`);
174
184
  const lintSource = async (state) => {
175
- const { doc } = state, option = await getOpt(opt, true) ?? {}, js = option['js'], css = option['css'];
185
+ const { doc } = state, option = await getOpt(opt, true) ?? {};
186
+ let js = option['js'], css = option['css'];
187
+ if (rules) {
188
+ css = isStylelintConfig(css)
189
+ ? {
190
+ ...css,
191
+ rules: { ...rules, ...css.rules },
192
+ }
193
+ : { ...rules, ...css };
194
+ }
195
+ if (globals) {
196
+ js = { ...js, globals: { ...globals, ...js?.globals } };
197
+ }
176
198
  return [
177
199
  ...(await Promise.all(cssLanguage.findRegions(state).map(async ({ from, to }) => {
178
200
  const node = ensureSyntaxTree(state, from)?.resolve(from, 1);
@@ -186,8 +208,7 @@ export const getVueLintSource = async (opt) => {
186
208
  }
187
209
  return node ? cssLintSource(styleLint, state.sliceDoc(from, to), css, doc, from, to) : [];
188
210
  }))).flat(),
189
- ...javascriptLanguage.findRegions(state)
190
- .flatMap(({ from, to }) => jsLintSource(esLint, state.sliceDoc(from, to), js, doc, from, to)),
211
+ ...javascriptLanguage.findRegions(state).flatMap(({ from, to }) => jsLintSource(esLint, state.sliceDoc(from, to), js, doc, from, to)),
191
212
  ];
192
213
  };
193
214
  Object.defineProperty(lintSource, 'config', {
@@ -197,12 +218,17 @@ export const getVueLintSource = async (opt) => {
197
218
  });
198
219
  return lintSource;
199
220
  };
221
+ /**
222
+ * @implements
223
+ * @test
224
+ */
225
+ export const getVueLintSource = /* #__PURE__ */ getVueOrHtmlLintSource(stylelintConfigVue, vue);
200
226
  /**
201
227
  * @implements
202
228
  * @test
203
229
  */
204
230
  export const getHTMLLintSource = async (opt, view, language) => {
205
- const vueLintSource = await getVueLintSource(opt), wikiLint = await getWikiLinter({ include: false, ...await getOpt(opt), cdn: base.CDN }, view);
231
+ const vueLintSource = await getVueOrHtmlLintSource()(opt), wikiLint = await getWikiLinter({ include: false, ...await getOpt(opt), cdn: base.CDN }, view);
206
232
  const lintSource = async (state) => {
207
233
  const { doc } = state, option = await getOpt(opt, true) ?? {}, wiki = option['wiki'];
208
234
  return [