@bhsd/codemirror-mediawiki 3.5.1 → 3.6.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 +1 -1
- package/dist/bidi.js +5 -4
- package/dist/codemirror.d.ts +3 -3
- package/dist/codemirror.js +22 -7
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +9 -0
- package/dist/escape.js +3 -5
- package/dist/fold.d.ts +0 -6
- package/dist/fold.js +17 -28
- package/dist/hover.d.ts +1 -22
- package/dist/hover.js +32 -39
- package/dist/html.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +11 -11
- package/dist/inlay.js +5 -6
- package/dist/lintsource.js +4 -2
- package/dist/lua.js +4 -0
- package/dist/main.min.js +28 -27
- package/dist/matchTag.js +2 -1
- package/dist/mediawiki.d.ts +0 -7
- package/dist/mediawiki.js +11 -18
- package/dist/mw.min.js +31 -30
- package/dist/mwConfig.js +22 -4
- package/dist/openLinks.d.ts +0 -1
- package/dist/openLinks.js +6 -10
- package/dist/ref.js +26 -9
- package/dist/signature.js +1 -1
- package/dist/static.js +3 -2
- package/dist/statusBar.js +26 -42
- package/dist/theme.js +51 -52
- package/dist/token.d.ts +6 -4
- package/dist/token.js +18 -13
- package/dist/util.d.ts +39 -0
- package/dist/util.js +53 -0
- package/dist/vue.js +1 -1
- package/dist/wiki.min.js +30 -29
- package/i18n/en.json +2 -2
- package/i18n/zh-hans.json +2 -2
- package/i18n/zh-hant.json +2 -2
- package/package.json +8 -11
package/README.md
CHANGED
|
@@ -1111,7 +1111,7 @@ registerHighlightWhitespace();
|
|
|
1111
1111
|
|
|
1112
1112
|
*version added: 2.21.1*
|
|
1113
1113
|
|
|
1114
|
-
Show the help information of a magic word when hovering.
|
|
1114
|
+
Show the help information of a magic word or a template name when hovering.
|
|
1115
1115
|
|
|
1116
1116
|
For granular control over the bundled extensions, you can import the `registerHover` function:
|
|
1117
1117
|
|
package/dist/bidi.js
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
import { EditorView, Direction, ViewPlugin, Decoration } from '@codemirror/view';
|
|
7
7
|
import { Prec, RangeSetBuilder } from '@codemirror/state';
|
|
8
8
|
import { syntaxTree } from '@codemirror/language';
|
|
9
|
-
import { getTag } from './matchTag';
|
|
10
9
|
import { tokens } from './config';
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import { isolateSelector, ltrSelector } from './constants';
|
|
11
|
+
import { getTag } from './matchTag';
|
|
12
|
+
const cls = isolateSelector.slice(1), isolateLTR = Decoration.mark({
|
|
13
|
+
class: `${cls} ${ltrSelector.slice(1)}`,
|
|
13
14
|
bidiIsolate: Direction.LTR,
|
|
14
|
-
}), isolate = Decoration.mark({ class:
|
|
15
|
+
}), isolate = Decoration.mark({ class: cls });
|
|
15
16
|
export const computeIsolates = ({ visibleRanges, state, textDirection }) => {
|
|
16
17
|
const set = new RangeSetBuilder();
|
|
17
18
|
if (textDirection === Direction.RTL) {
|
package/dist/codemirror.d.ts
CHANGED
|
@@ -3,19 +3,19 @@ import type { KeyBinding } from '@codemirror/view';
|
|
|
3
3
|
import type { Extension } from '@codemirror/state';
|
|
4
4
|
import type { SyntaxNode } from '@lezer/common';
|
|
5
5
|
import type { ConfigData } from 'wikiparser-node';
|
|
6
|
-
import type { MwConfig } from './token';
|
|
7
6
|
import type { DocRange, foldHandler } from './fold';
|
|
7
|
+
import type { detectIndent } from './indent';
|
|
8
8
|
import type { Option, LiveOption } from './linter';
|
|
9
9
|
import type { LintSource, LintSources, LintSourceGetter } from './lintsource';
|
|
10
|
-
import type { detectIndent } from './indent';
|
|
11
10
|
import type statusBar from './statusBar';
|
|
11
|
+
import type { MwConfig } from './token';
|
|
12
12
|
export type AddonMain<T> = (config?: T, cm?: CodeMirror6) => Extension;
|
|
13
13
|
export type Addon<T> = [AddonMain<T>, Record<string, T>?];
|
|
14
14
|
export type Dialect = 'sanitized-css' | undefined;
|
|
15
15
|
declare interface MenuItem {
|
|
16
16
|
name: string;
|
|
17
17
|
isActionable(this: void, cm: CodeMirror6): boolean;
|
|
18
|
-
getItems(this: void, cm: CodeMirror6):
|
|
18
|
+
getItems(this: void, cm: CodeMirror6): HTMLElement[];
|
|
19
19
|
}
|
|
20
20
|
declare interface OptionalFunctions {
|
|
21
21
|
statusBar: typeof statusBar;
|
package/dist/codemirror.js
CHANGED
|
@@ -4,6 +4,8 @@ import { syntaxHighlighting, defaultHighlightStyle, indentOnInput, indentUnit, e
|
|
|
4
4
|
import { defaultKeymap, historyKeymap, history, redo, indentWithTab } from '@codemirror/commands';
|
|
5
5
|
import { searchKeymap } from '@codemirror/search';
|
|
6
6
|
import { linter, lintGutter, lintKeymap } from '@codemirror/lint';
|
|
7
|
+
import elt from 'crelt';
|
|
8
|
+
import { panelSelector, panelsSelector, diagnosticSelector } from './constants';
|
|
7
9
|
import { light } from './theme';
|
|
8
10
|
export const plain = () => EditorView.contentAttributes.of({ spellcheck: 'true' });
|
|
9
11
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -82,6 +84,9 @@ export class CodeMirror6 {
|
|
|
82
84
|
#getLanguage(config) {
|
|
83
85
|
const lang = (languages[this.#lang] ?? plain)(config);
|
|
84
86
|
this.#nestedMWLanguage = lang.nestedMWLanguage;
|
|
87
|
+
if (this.#lang === 'mediawiki') {
|
|
88
|
+
this.langConfig = config;
|
|
89
|
+
}
|
|
85
90
|
return lang;
|
|
86
91
|
}
|
|
87
92
|
/**
|
|
@@ -121,16 +126,16 @@ export class CodeMirror6 {
|
|
|
121
126
|
},
|
|
122
127
|
]),
|
|
123
128
|
EditorView.theme({
|
|
124
|
-
|
|
129
|
+
[panelsSelector]: {
|
|
125
130
|
direction: document.dir,
|
|
126
131
|
},
|
|
127
132
|
'& .cm-lineNumbers .cm-gutterElement': {
|
|
128
133
|
textAlign: 'end',
|
|
129
134
|
},
|
|
130
|
-
|
|
135
|
+
[`.cm-textfield,.cm-button,${panelSelector}.cm-search label,${panelSelector}.cm-gotoLine label`]: {
|
|
131
136
|
fontSize: 'inherit',
|
|
132
137
|
},
|
|
133
|
-
|
|
138
|
+
[`${panelSelector} [name="close"]`]: {
|
|
134
139
|
color: 'inherit',
|
|
135
140
|
},
|
|
136
141
|
}),
|
|
@@ -229,7 +234,19 @@ export class CodeMirror6 {
|
|
|
229
234
|
const linterExtension = lintSources
|
|
230
235
|
? [
|
|
231
236
|
...lintSources.map(source => linter(async ({ state }) => {
|
|
232
|
-
const diagnostics = await source(state)
|
|
237
|
+
const diagnostics = (await source(state)).map((diagnostic) => ({
|
|
238
|
+
...diagnostic,
|
|
239
|
+
renderMessage(view) {
|
|
240
|
+
const span = elt('span', { class: diagnosticSelector.slice(1) }, diagnostic.message);
|
|
241
|
+
span.addEventListener('click', () => {
|
|
242
|
+
view.dispatch({
|
|
243
|
+
selection: { anchor: diagnostic.from, head: diagnostic.to },
|
|
244
|
+
});
|
|
245
|
+
view.focus();
|
|
246
|
+
});
|
|
247
|
+
return span;
|
|
248
|
+
},
|
|
249
|
+
}));
|
|
233
250
|
if (state.readOnly) {
|
|
234
251
|
for (const diagnostic of diagnostics) {
|
|
235
252
|
delete diagnostic.actions;
|
|
@@ -436,9 +453,7 @@ export class CodeMirror6 {
|
|
|
436
453
|
*/
|
|
437
454
|
setTheme(theme) {
|
|
438
455
|
if (theme in themes) {
|
|
439
|
-
this.#view?.dispatch({
|
|
440
|
-
effects: this.#theme.reconfigure(themes[theme]),
|
|
441
|
-
});
|
|
456
|
+
this.#view?.dispatch({ effects: this.#theme.reconfigure(themes[theme]) });
|
|
442
457
|
}
|
|
443
458
|
}
|
|
444
459
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const panelSelector = ".cm-panel", panelsSelector = ".cm-panels", diagnosticSelector = ".cm-diagnosticText-clickable", foldSelector = ".cm-tooltip-fold", hoverSelector = ".cm-tooltip-hover", matchingCls = "cm-matchingTag", nonmatchingCls = "cm-nonmatchingTag", isolateSelector = ".cm-bidi-isolate", ltrSelector = ".cm-bidi-ltr", menuSelector = ".cm-status-fix-menu", messageSelector = ".cm-status-message", actionSelector = ".cm-diagnosticAction", isWMF: boolean, isMac: boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { wmf } from '@bhsd/common';
|
|
2
|
+
export const panelSelector = '.cm-panel', panelsSelector = '.cm-panels', diagnosticSelector = '.cm-diagnosticText-clickable', foldSelector = '.cm-tooltip-fold', hoverSelector = '.cm-tooltip-hover', matchingCls = 'cm-matchingTag', nonmatchingCls = 'cm-nonmatchingTag', isolateSelector = '.cm-bidi-isolate', ltrSelector = '.cm-bidi-ltr', menuSelector = '.cm-status-fix-menu', messageSelector = '.cm-status-message', actionSelector = '.cm-diagnosticAction', isWMF = /* @__PURE__ */ (() => typeof location === 'object'
|
|
3
|
+
&& new RegExp(String.raw `\.(?:${wmf})\.org$`, 'u').test(location.hostname))(), isMac = /* @__PURE__ */ (() => {
|
|
4
|
+
const { vendor, userAgent, maxTouchPoints, platform } = navigator;
|
|
5
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
6
|
+
return vendor?.includes('Apple Computer')
|
|
7
|
+
&& (userAgent.includes('Mobile/') || maxTouchPoints > 2)
|
|
8
|
+
|| platform.includes('Mac');
|
|
9
|
+
})();
|
package/dist/escape.js
CHANGED
|
@@ -2,6 +2,7 @@ import { keymap } from '@codemirror/view';
|
|
|
2
2
|
import { EditorSelection } from '@codemirror/state';
|
|
3
3
|
import { indentMore, indentLess } from '@codemirror/commands';
|
|
4
4
|
import { getLSP } from '@bhsd/browser';
|
|
5
|
+
import elt from 'crelt';
|
|
5
6
|
import { CodeMirror6, menuRegistry } from './codemirror';
|
|
6
7
|
const entity = { '"': 'quot', "'": 'apos', '<': 'lt', '>': 'gt', '&': 'amp', ' ': 'nbsp' };
|
|
7
8
|
/**
|
|
@@ -69,13 +70,11 @@ menuRegistry.push({
|
|
|
69
70
|
},
|
|
70
71
|
getItems(cm) {
|
|
71
72
|
if (!items) {
|
|
72
|
-
const view = cm.view, btnHTML =
|
|
73
|
-
btnHTML.textContent = 'HTML escape';
|
|
73
|
+
const view = cm.view, btnHTML = elt('div', 'HTML escape'), btnURI = elt('div', 'URI encode/decode');
|
|
74
74
|
btnHTML.addEventListener('click', e => {
|
|
75
75
|
CodeMirror6.replaceSelections(view, escapeHTML);
|
|
76
76
|
handlerBase(view, e);
|
|
77
77
|
});
|
|
78
|
-
btnURI.textContent = 'URI encode/decode';
|
|
79
78
|
btnURI.addEventListener('click', e => {
|
|
80
79
|
CodeMirror6.replaceSelections(view, escapeURI);
|
|
81
80
|
handlerBase(view, e);
|
|
@@ -83,8 +82,7 @@ menuRegistry.push({
|
|
|
83
82
|
items = [btnHTML, btnURI];
|
|
84
83
|
const lsp = getLSP(view, false, cm.getWikiConfig);
|
|
85
84
|
if (lsp && 'provideRefactoringAction' in lsp) {
|
|
86
|
-
const btnWiki =
|
|
87
|
-
btnWiki.textContent = 'Escape with magic words';
|
|
85
|
+
const btnWiki = elt('div', 'Escape with magic words');
|
|
88
86
|
btnWiki.addEventListener('click', e => {
|
|
89
87
|
escapeWiki(cm);
|
|
90
88
|
handlerBase(view, e);
|
package/dist/fold.d.ts
CHANGED
|
@@ -6,12 +6,6 @@ export interface DocRange {
|
|
|
6
6
|
from: number;
|
|
7
7
|
to: number;
|
|
8
8
|
}
|
|
9
|
-
/**
|
|
10
|
-
* Update the stack of opening (+) or closing (-) brackets
|
|
11
|
-
* @param state
|
|
12
|
-
* @param node 语法树节点
|
|
13
|
-
*/
|
|
14
|
-
export declare const braceStackUpdate: (state: EditorState, node: SyntaxNode) => [number, number];
|
|
15
9
|
/**
|
|
16
10
|
* 寻找可折叠的范围
|
|
17
11
|
* @param state
|
package/dist/fold.js
CHANGED
|
@@ -2,8 +2,11 @@ import { showTooltip, keymap, GutterMarker, gutter, ViewPlugin, EditorView } fro
|
|
|
2
2
|
import { StateField, RangeSetBuilder, RangeSet } from '@codemirror/state';
|
|
3
3
|
import { syntaxTree, ensureSyntaxTree, foldEffect, unfoldEffect, foldedRanges, unfoldAll, codeFolding, foldGutter, foldKeymap, foldState, language, } from '@codemirror/language';
|
|
4
4
|
import { getRegex } from '@bhsd/common';
|
|
5
|
+
import elt from 'crelt';
|
|
5
6
|
import { tokens } from './config';
|
|
7
|
+
import { foldSelector } from './constants';
|
|
6
8
|
import { matchTag, getTag } from './matchTag';
|
|
9
|
+
import { braceStackUpdate } from './util';
|
|
7
10
|
const getExtRegex = /* @__PURE__ */ getRegex(tag => new RegExp(`mw-tag-${tag}(?![a-z])`, 'u'));
|
|
8
11
|
const updateSelection = (pos, { to }) => Math.max(pos, to), updateAll = (pos, { from, to }) => from <= pos && to > pos ? to : pos;
|
|
9
12
|
/**
|
|
@@ -35,15 +38,6 @@ isExtBracket = /* @__PURE__ */ isComponent(['extTagBracket']),
|
|
|
35
38
|
* @param refOnly 是否仅检查`<ref>`标签
|
|
36
39
|
*/
|
|
37
40
|
isExt = (node, refOnly) => node.name.includes(`mw-tag-${refOnly ? 'ref' : ''}`);
|
|
38
|
-
/**
|
|
39
|
-
* Update the stack of opening (+) or closing (-) brackets
|
|
40
|
-
* @param state
|
|
41
|
-
* @param node 语法树节点
|
|
42
|
-
*/
|
|
43
|
-
export const braceStackUpdate = (state, node) => {
|
|
44
|
-
const brackets = state.sliceDoc(node.from, node.to);
|
|
45
|
-
return [brackets.split('{{').length - 1, 1 - brackets.split('}}').length];
|
|
46
|
-
};
|
|
47
41
|
const refNames = new Set(['ref', 'references']);
|
|
48
42
|
/**
|
|
49
43
|
* 寻找可折叠的范围
|
|
@@ -160,10 +154,10 @@ const create = (state) => {
|
|
|
160
154
|
pos: head,
|
|
161
155
|
above: true,
|
|
162
156
|
create() {
|
|
163
|
-
const dom =
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
157
|
+
const dom = elt('div', {
|
|
158
|
+
class: foldSelector.slice(1),
|
|
159
|
+
title: state.phrase('Fold template or extension tag'),
|
|
160
|
+
}, '\uff0d');
|
|
167
161
|
dom.dataset['from'] = String(from);
|
|
168
162
|
dom.dataset['to'] = String(to);
|
|
169
163
|
return { dom };
|
|
@@ -180,9 +174,12 @@ const create = (state) => {
|
|
|
180
174
|
*/
|
|
181
175
|
const execute = (view, effects, anchor) => {
|
|
182
176
|
if (effects.length > 0) {
|
|
183
|
-
view.dom.querySelector(
|
|
177
|
+
view.dom.querySelector(foldSelector)?.remove();
|
|
184
178
|
// Fold the template(s) and update the cursor position
|
|
185
|
-
view.dispatch({
|
|
179
|
+
view.dispatch({
|
|
180
|
+
effects,
|
|
181
|
+
selection: { anchor },
|
|
182
|
+
});
|
|
186
183
|
return true;
|
|
187
184
|
}
|
|
188
185
|
return false;
|
|
@@ -228,10 +225,7 @@ class FoldMarker extends GutterMarker {
|
|
|
228
225
|
return this.open === other.open;
|
|
229
226
|
}
|
|
230
227
|
toDOM({ state }) {
|
|
231
|
-
|
|
232
|
-
span.textContent = this.open ? '⌄' : '›';
|
|
233
|
-
span.title = state.phrase(this.open ? 'Fold line' : 'Unfold line');
|
|
234
|
-
return span;
|
|
228
|
+
return elt('span', { title: state.phrase(this.open ? 'Fold line' : 'Unfold line') }, this.open ? '⌄' : '›');
|
|
235
229
|
}
|
|
236
230
|
}
|
|
237
231
|
const canFold = /* @__PURE__ */ new FoldMarker(true), canUnfold = /* @__PURE__ */ new FoldMarker(false);
|
|
@@ -334,15 +328,10 @@ const foldCommand = (refOnly) => view => {
|
|
|
334
328
|
};
|
|
335
329
|
export const foldRef = /* @__PURE__ */ foldCommand(true);
|
|
336
330
|
export default ((e = defaultFoldExtension) => e);
|
|
337
|
-
const selector = '.cm-tooltip-fold';
|
|
338
331
|
export const mediaWikiFold = /* @__PURE__ */ (() => [
|
|
339
332
|
codeFolding({
|
|
340
333
|
placeholderDOM(view) {
|
|
341
|
-
const element =
|
|
342
|
-
element.textContent = '…';
|
|
343
|
-
element.setAttribute('aria-label', 'folded code');
|
|
344
|
-
element.title = view.state.phrase('unfold');
|
|
345
|
-
element.className = 'cm-foldPlaceholder';
|
|
334
|
+
const element = elt('span', { 'aria-label': 'folded code', title: view.state.phrase('unfold'), class: 'cm-foldPlaceholder' }, '…');
|
|
346
335
|
element.addEventListener('click', ({ target }) => {
|
|
347
336
|
const pos = view.posAtDOM(target), { state } = view, { selection } = state;
|
|
348
337
|
foldedRanges(state).between(pos, pos, (from, to) => {
|
|
@@ -448,13 +437,13 @@ export const mediaWikiFold = /* @__PURE__ */ (() => [
|
|
|
448
437
|
},
|
|
449
438
|
}),
|
|
450
439
|
EditorView.theme({
|
|
451
|
-
[
|
|
440
|
+
[foldSelector]: {
|
|
452
441
|
cursor: 'pointer',
|
|
453
442
|
lineHeight: 1.2,
|
|
454
443
|
padding: '0 1px',
|
|
455
444
|
opacity: 0.6,
|
|
456
445
|
},
|
|
457
|
-
[`${
|
|
446
|
+
[`${foldSelector}:hover`]: {
|
|
458
447
|
opacity: 1,
|
|
459
448
|
},
|
|
460
449
|
}),
|
|
@@ -464,7 +453,7 @@ export const mediaWikiFold = /* @__PURE__ */ (() => [
|
|
|
464
453
|
* @param view
|
|
465
454
|
*/
|
|
466
455
|
export const foldHandler = (view) => (e) => {
|
|
467
|
-
const dom = e.target.closest(
|
|
456
|
+
const dom = e.target.closest(foldSelector);
|
|
468
457
|
if (dom) {
|
|
469
458
|
e.preventDefault();
|
|
470
459
|
const { dataset } = dom, from = Number(dataset['from']), to = Number(dataset['to']);
|
package/dist/hover.d.ts
CHANGED
|
@@ -1,25 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { TooltipView } from '@codemirror/view';
|
|
3
|
-
import type { Text, Extension } from '@codemirror/state';
|
|
4
|
-
import type { Position } from 'vscode-languageserver-types';
|
|
1
|
+
import type { Extension } from '@codemirror/state';
|
|
5
2
|
import type { CodeMirror6 } from './codemirror';
|
|
6
|
-
/**
|
|
7
|
-
* 将索引转换为位置
|
|
8
|
-
* @param doc Text 实例
|
|
9
|
-
* @param index 索引
|
|
10
|
-
*/
|
|
11
|
-
export declare const indexToPos: (doc: Text, index: number) => Position;
|
|
12
|
-
/**
|
|
13
|
-
* 将位置转换为索引
|
|
14
|
-
* @param doc Text 实例
|
|
15
|
-
* @param pos 位置
|
|
16
|
-
*/
|
|
17
|
-
export declare const posToIndex: (doc: Text, pos: Position) => number;
|
|
18
|
-
/**
|
|
19
|
-
* 创建 TooltipView
|
|
20
|
-
* @param view EditorView 实例
|
|
21
|
-
* @param innerHTML 提示内容
|
|
22
|
-
*/
|
|
23
|
-
export declare const createTooltipView: (view: EditorView, innerHTML: string) => TooltipView;
|
|
24
3
|
declare const _default: (cm: CodeMirror6) => Extension;
|
|
25
4
|
export default _default;
|
package/dist/hover.js
CHANGED
|
@@ -1,41 +1,32 @@
|
|
|
1
1
|
import { hoverTooltip, EditorView } from '@codemirror/view';
|
|
2
|
+
import { ensureSyntaxTree } from '@codemirror/language';
|
|
2
3
|
import { loadScript, getLSP } from '@bhsd/browser';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* @param index 索引
|
|
7
|
-
*/
|
|
8
|
-
export const indexToPos = (doc, index) => {
|
|
9
|
-
const line = doc.lineAt(index);
|
|
10
|
-
return { line: line.number - 1, character: index - line.from };
|
|
11
|
-
};
|
|
12
|
-
/**
|
|
13
|
-
* 将位置转换为索引
|
|
14
|
-
* @param doc Text 实例
|
|
15
|
-
* @param pos 位置
|
|
16
|
-
*/
|
|
17
|
-
export const posToIndex = (doc, pos) => {
|
|
18
|
-
const line = doc.line(pos.line + 1);
|
|
19
|
-
return Math.min(line.from + pos.character, line.to);
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* 创建 TooltipView
|
|
23
|
-
* @param view EditorView 实例
|
|
24
|
-
* @param innerHTML 提示内容
|
|
25
|
-
*/
|
|
26
|
-
export const createTooltipView = (view, innerHTML) => {
|
|
27
|
-
const dom = document.createElement('div'), inner = document.createElement('div');
|
|
28
|
-
dom.append(inner);
|
|
29
|
-
dom.className = 'cm-tooltip-hover';
|
|
30
|
-
dom.style.font = getComputedStyle(view.contentDOM).font;
|
|
31
|
-
inner.innerHTML = innerHTML;
|
|
32
|
-
return { dom };
|
|
33
|
-
};
|
|
34
|
-
const selector = '.cm-tooltip-hover';
|
|
4
|
+
import { tokens } from './config';
|
|
5
|
+
import { hoverSelector } from './constants';
|
|
6
|
+
import { escHTML, indexToPos, posToIndex, createTooltipView } from './util';
|
|
35
7
|
export default (cm) => [
|
|
36
|
-
hoverTooltip(async (view, pos) => {
|
|
37
|
-
const { state
|
|
8
|
+
hoverTooltip(async (view, pos, side) => {
|
|
9
|
+
const { state } = view, { doc } = state, { paramSuggest, tags } = cm.langConfig;
|
|
10
|
+
let hover = await getLSP(view, false, cm.getWikiConfig)
|
|
38
11
|
?.provideHover(doc.toString(), indexToPos(doc, pos));
|
|
12
|
+
if (!hover && paramSuggest && 'templatedata' in tags) {
|
|
13
|
+
const node = ensureSyntaxTree(state, pos + Math.max(side, 0))?.resolve(pos, side);
|
|
14
|
+
if (node?.name.includes(tokens.templateName)) {
|
|
15
|
+
const result = await paramSuggest(state.sliceDoc(node.from, node.to), false), { description, length } = result;
|
|
16
|
+
if (description || length > 0) {
|
|
17
|
+
// eslint-disable-next-line require-atomic-updates
|
|
18
|
+
hover = {
|
|
19
|
+
contents: {
|
|
20
|
+
kind: 'plaintext',
|
|
21
|
+
value: (description ? `<p>${escHTML(description)}</p>` : '') + (length === 0
|
|
22
|
+
? ''
|
|
23
|
+
: `<ul>${result.map(([key, details]) => `<li><code>${escHTML(key)}</code>${details ? ` — ${escHTML(details)}` : ''}</li>`).join('')}</ul>`),
|
|
24
|
+
},
|
|
25
|
+
range: { start: indexToPos(doc, node.from), end: indexToPos(doc, node.to) },
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
39
30
|
if (hover) {
|
|
40
31
|
await loadScript('npm/marked/lib/marked.umd.js', 'marked', true);
|
|
41
32
|
const { end } = hover.range;
|
|
@@ -44,27 +35,29 @@ export default (cm) => [
|
|
|
44
35
|
end: posToIndex(doc, end),
|
|
45
36
|
above: true,
|
|
46
37
|
create() {
|
|
47
|
-
|
|
38
|
+
const { kind, value } = hover.contents;
|
|
39
|
+
return createTooltipView(view, kind === 'plaintext' ? value : marked.parse(value));
|
|
48
40
|
},
|
|
49
41
|
};
|
|
50
42
|
}
|
|
51
43
|
return null;
|
|
52
44
|
}),
|
|
53
45
|
EditorView.theme({
|
|
54
|
-
[
|
|
46
|
+
[hoverSelector]: {
|
|
55
47
|
padding: '2px 5px',
|
|
56
48
|
width: 'max-content',
|
|
57
49
|
maxWidth: '60vw',
|
|
50
|
+
overflowY: 'auto',
|
|
58
51
|
},
|
|
59
|
-
[`${
|
|
52
|
+
[`${hoverSelector} *`]: {
|
|
60
53
|
marginTop: '0!important',
|
|
61
54
|
marginBottom: '0!important',
|
|
62
55
|
},
|
|
63
|
-
[`${
|
|
56
|
+
[`${hoverSelector}>div`]: {
|
|
64
57
|
fontSize: '90%',
|
|
65
58
|
lineHeight: 1.4,
|
|
66
59
|
},
|
|
67
|
-
[`${
|
|
60
|
+
[`${hoverSelector} code`]: {
|
|
68
61
|
padding: '.1em .4em',
|
|
69
62
|
borderRadius: '.4em',
|
|
70
63
|
},
|
package/dist/html.js
CHANGED
|
@@ -3,9 +3,9 @@ import { htmlLanguage, htmlCompletionSourceWith } from '@codemirror/lang-html';
|
|
|
3
3
|
import { javascript, javascriptLanguage } from '@codemirror/lang-javascript';
|
|
4
4
|
import { cssLanguage } from '@codemirror/lang-css';
|
|
5
5
|
import { LanguageSupport } from '@codemirror/language';
|
|
6
|
+
import { cssCompletion } from './css';
|
|
6
7
|
import { jsCompletion } from './javascript';
|
|
7
8
|
import { mediawiki } from './mediawiki';
|
|
8
|
-
import { cssCompletion } from './css';
|
|
9
9
|
export default (config) => {
|
|
10
10
|
const { language, support } = mediawiki(config), lang = new LanguageSupport(htmlLanguage.configure({
|
|
11
11
|
wrap: configureNesting([
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { CodeMirror6 } from './codemirror';
|
|
2
2
|
import type { Extension } from '@codemirror/state';
|
|
3
3
|
import type { LanguageSupport } from '@codemirror/language';
|
|
4
|
-
import type { MwConfig } from './token';
|
|
5
4
|
import type { LintSourceGetter } from './lintsource';
|
|
5
|
+
import type { MwConfig } from './token';
|
|
6
6
|
export type { MwConfig };
|
|
7
7
|
export { CodeMirror6 };
|
|
8
8
|
/** Register the `highlightSpecialChars` extension */
|
package/dist/index.js
CHANGED
|
@@ -6,29 +6,29 @@ import { json } from '@codemirror/lang-json';
|
|
|
6
6
|
import { autoCloseTags } from '@codemirror/lang-html';
|
|
7
7
|
import { getLSP } from '@bhsd/browser';
|
|
8
8
|
import { colorPicker as cssColorPicker, colorPickerTheme, makeColorPicker } from '@bhsd/codemirror-css-color-picker';
|
|
9
|
+
import bidiIsolation from './bidi';
|
|
10
|
+
import { CodeMirror6, avail, languages, linterRegistry, destroyListeners, plain, optionalFunctions, themes, } from './codemirror';
|
|
9
11
|
import colorPicker, { discoverColors } from './color';
|
|
10
|
-
import { mediawiki } from './mediawiki';
|
|
11
12
|
import escape from './escape';
|
|
12
13
|
import codeFolding, { mediaWikiFold, foldHandler } from './fold';
|
|
13
|
-
import tagMatchingState from './matchTag';
|
|
14
|
-
import refHover from './ref';
|
|
15
14
|
import magicWordHover from './hover';
|
|
16
|
-
import
|
|
15
|
+
import { detectIndent } from './indent';
|
|
17
16
|
import inlayHints from './inlay';
|
|
17
|
+
import toolKeymap from './keymap';
|
|
18
18
|
import { getWikiLintSource, getJsLintSource, getCssLintSource, getJsonLintSource, getLuaLintSource, getVueLintSource, getHTMLLintSource, } from './lintsource';
|
|
19
|
+
import bracketMatching from './matchBrackets';
|
|
20
|
+
import tagMatchingState from './matchTag';
|
|
21
|
+
import { mediawiki } from './mediawiki';
|
|
19
22
|
import openLinks from './openLinks';
|
|
23
|
+
import refHover from './ref';
|
|
24
|
+
import signatureHelp from './signature';
|
|
20
25
|
import { tagModes, getStaticMwConfig } from './static';
|
|
21
|
-
import bidiIsolation from './bidi';
|
|
22
|
-
import toolKeymap from './keymap';
|
|
23
|
-
import bracketMatching from './matchBrackets';
|
|
24
26
|
import statusBar from './statusBar';
|
|
25
|
-
import { detectIndent } from './indent';
|
|
26
|
-
import javascript from './javascript';
|
|
27
27
|
import css from './css';
|
|
28
|
+
import html from './html';
|
|
29
|
+
import javascript from './javascript';
|
|
28
30
|
import lua from './lua';
|
|
29
31
|
import vue from './vue';
|
|
30
|
-
import html from './html';
|
|
31
|
-
import { CodeMirror6, avail, languages, linterRegistry, destroyListeners, plain, optionalFunctions, themes, } from './codemirror';
|
|
32
32
|
export { CodeMirror6 };
|
|
33
33
|
/**
|
|
34
34
|
* 注册通用扩展
|
package/dist/inlay.js
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { StateField, StateEffect } from '@codemirror/state';
|
|
2
2
|
import { Decoration, EditorView, WidgetType, ViewPlugin } from '@codemirror/view';
|
|
3
3
|
import { getLSP } from '@bhsd/browser';
|
|
4
|
-
import
|
|
4
|
+
import elt from 'crelt';
|
|
5
|
+
import { posToIndex } from './util';
|
|
6
|
+
const cls = 'cm-inlay-hint';
|
|
5
7
|
class InlayHintWidget extends WidgetType {
|
|
6
8
|
constructor(label) {
|
|
7
9
|
super();
|
|
8
10
|
this.label = label;
|
|
9
11
|
}
|
|
10
12
|
toDOM() {
|
|
11
|
-
|
|
12
|
-
element.textContent = this.label;
|
|
13
|
-
element.className = 'cm-inlay-hint';
|
|
14
|
-
return element;
|
|
13
|
+
return elt('span', { class: cls }, this.label);
|
|
15
14
|
}
|
|
16
15
|
}
|
|
17
16
|
const stateEffect = StateEffect.define(), field = StateField.define({
|
|
@@ -66,7 +65,7 @@ export default (cm) => [
|
|
|
66
65
|
}
|
|
67
66
|
}),
|
|
68
67
|
EditorView.theme({
|
|
69
|
-
|
|
68
|
+
[`.${cls}`]: {
|
|
70
69
|
color: '#969696',
|
|
71
70
|
fontStyle: 'italic',
|
|
72
71
|
'-webkitUserSelect': 'none',
|
package/dist/lintsource.js
CHANGED
|
@@ -3,7 +3,7 @@ import { cssLanguage } from '@codemirror/lang-css';
|
|
|
3
3
|
import { javascriptLanguage } from '@codemirror/lang-javascript';
|
|
4
4
|
import { sanitizeInlineStyle } from '@bhsd/common';
|
|
5
5
|
import { getWikiLinter, getJsLinter, getCssLinter, getJsonLinter, getLuaLinter } from './linter';
|
|
6
|
-
import { posToIndex } from './
|
|
6
|
+
import { posToIndex } from './util';
|
|
7
7
|
/**
|
|
8
8
|
* 获取Linter选项
|
|
9
9
|
* @param opt Linter选项
|
|
@@ -78,7 +78,9 @@ const jsLintSource = (esLint, code, opt, doc, f = 0, t) => esLint(code, opt)
|
|
|
78
78
|
].map(({ name, fix: { range: [from, to], text } }) => ({
|
|
79
79
|
name,
|
|
80
80
|
apply(view) {
|
|
81
|
-
view.dispatch({
|
|
81
|
+
view.dispatch({
|
|
82
|
+
changes: { from: from + f, to: to + f, insert: text },
|
|
83
|
+
});
|
|
82
84
|
},
|
|
83
85
|
}));
|
|
84
86
|
}
|
package/dist/lua.js
CHANGED
|
@@ -140,6 +140,9 @@ const map = {
|
|
|
140
140
|
interwikiMap: 2,
|
|
141
141
|
},
|
|
142
142
|
},
|
|
143
|
+
svg: {
|
|
144
|
+
new: 2,
|
|
145
|
+
},
|
|
143
146
|
text: {
|
|
144
147
|
decode: 2,
|
|
145
148
|
encode: 2,
|
|
@@ -164,6 +167,7 @@ const map = {
|
|
|
164
167
|
compare: 2,
|
|
165
168
|
getCurrentTitle: 2,
|
|
166
169
|
new: 2,
|
|
170
|
+
newBatch: 2,
|
|
167
171
|
makeTitle: 2,
|
|
168
172
|
},
|
|
169
173
|
uri: {
|