@bhsd/codemirror-mediawiki 3.9.1 → 3.10.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.
Files changed (51) hide show
  1. package/README.md +71 -11
  2. package/dist/bidi.d.ts +4 -8
  3. package/dist/bidi.js +33 -23
  4. package/dist/codemirror.js +15 -9
  5. package/dist/color.d.ts +1 -1
  6. package/dist/color.js +1 -1
  7. package/dist/config.d.ts +1 -0
  8. package/dist/config.js +1 -0
  9. package/dist/constants.d.ts +3 -2
  10. package/dist/constants.js +3 -2
  11. package/dist/css.js +9 -6
  12. package/dist/escape.d.ts +1 -1
  13. package/dist/escape.js +4 -3
  14. package/dist/fold.d.ts +2 -2
  15. package/dist/fold.js +113 -40
  16. package/dist/hover.d.ts +2 -2
  17. package/dist/hover.js +74 -62
  18. package/dist/index.d.ts +54 -16
  19. package/dist/index.js +91 -38
  20. package/dist/inlay.d.ts +1 -1
  21. package/dist/inlay.js +26 -25
  22. package/dist/javascript.js +45 -2
  23. package/dist/linter.d.ts +15 -2
  24. package/dist/linter.js +2 -2
  25. package/dist/lintsource.d.ts +15 -3
  26. package/dist/lintsource.js +13 -7
  27. package/dist/lua.d.ts +0 -2
  28. package/dist/lua.js +32 -26
  29. package/dist/main.min.js +31 -29
  30. package/dist/matchTag.js +4 -3
  31. package/dist/mediawiki.d.ts +4 -2
  32. package/dist/mediawiki.js +56 -44
  33. package/dist/mw.min.js +33 -37
  34. package/dist/mwConfig.js +2 -2
  35. package/dist/openLinks.d.ts +4 -2
  36. package/dist/openLinks.js +56 -54
  37. package/dist/ref.d.ts +1 -1
  38. package/dist/ref.js +92 -93
  39. package/dist/signature.d.ts +1 -1
  40. package/dist/signature.js +50 -49
  41. package/dist/statusBar.js +31 -9
  42. package/dist/theme.js +10 -23
  43. package/dist/token.d.ts +20 -6
  44. package/dist/token.js +26 -17
  45. package/dist/util.d.ts +17 -2
  46. package/dist/util.js +39 -1
  47. package/dist/wiki.min.js +32 -36
  48. package/i18n/en.json +2 -2
  49. package/i18n/zh-hans.json +2 -2
  50. package/i18n/zh-hant.json +2 -2
  51. package/package.json +14 -12
package/dist/mwConfig.js CHANGED
@@ -149,7 +149,7 @@ var getMwConfig = async (modes) => {
149
149
  config = getStaticMwConfig(parserConfig, modes);
150
150
  } else {
151
151
  await mw.loader.using("mediawiki.api");
152
- const { query: { general: { variants }, magicwords, extensiontags, functionhooks, variables } } = await new mw.Api().get({
152
+ const { query: { general: { variants, langconversion }, magicwords, extensiontags, functionhooks, variables } } = await new mw.Api().get({
153
153
  meta: "siteinfo",
154
154
  siprop: [
155
155
  "general",
@@ -185,7 +185,7 @@ var getMwConfig = async (modes) => {
185
185
  Object.assign(config, {
186
186
  ...getKeywords(magicwords, true),
187
187
  tagModes: modes,
188
- variants: getVariants(variants),
188
+ variants: langconversion ? getVariants(variants) : [],
189
189
  urlProtocols: mw.config.get("wgUrlProtocols").replace(/\\:/gu, ":")
190
190
  });
191
191
  (_b = config.variableIDs) != null ? _b : config.variableIDs = variables;
@@ -2,6 +2,8 @@ import { EditorView } from '@codemirror/view';
2
2
  import type { Extension } from '@codemirror/state';
3
3
  import type { CodeMirror6 } from './codemirror';
4
4
  import type { MwConfig } from './token';
5
- export declare const mouseEventListener: (e: MouseEvent, view: EditorView, langConfig: MwConfig | undefined) => string | undefined;
6
- declare const _default: ({ langConfig }: CodeMirror6) => Extension;
5
+ declare type ISBNParser = (link: string) => string;
6
+ export declare const getISBNParser: (articlePath?: string) => ISBNParser | undefined;
7
+ export declare const mouseEventListener: (e: MouseEvent, view: EditorView, isbnParser?: ISBNParser, titleParser?: MwConfig["titleParser"]) => string | undefined;
8
+ declare const _default: (articlePath?: string) => ({ langConfig }: CodeMirror6) => Extension;
7
9
  export default _default;
package/dist/openLinks.js CHANGED
@@ -3,42 +3,27 @@ import { ensureSyntaxTree } from '@codemirror/language';
3
3
  import { tokens } from './config.js';
4
4
  import { isMac } from './constants.js';
5
5
  import { hasTag } from './util.js';
6
- const modKey = isMac ? 'metaKey' : 'ctrlKey', key = isMac ? 'Meta' : 'Control', tags = ['extLinkProtocol', 'extLink', 'freeExtLinkProtocol', 'freeExtLink', 'magicLink', 'pageName'], links = ['extlink-protocol', 'extlink', 'free-extlink-protocol', 'free-extlink', 'magic-link'], pagename = '.cm-mw-pagename', wikiLinks = [
6
+ const tags = ['extLinkProtocol', 'extLink', 'freeExtLinkProtocol', 'freeExtLink', 'magicLink', 'pageName'], links = ['extlink-protocol', 'extlink', 'free-extlink-protocol', 'free-extlink', 'magic-link'], pagename = '.cm-mw-pagename', wikiLinks = [
7
7
  'template-name',
8
8
  'link-pagename',
9
9
  `parserfunction${pagename}`,
10
10
  `exttag-attribute-value${pagename}`,
11
11
  `file-text${pagename}`,
12
- ];
13
- const toggleOpenLinks = (toggle) => {
14
- for (const ele of document.querySelectorAll('.cm-content')) {
15
- if (toggle) {
16
- ele.style.setProperty('--codemirror-cursor', 'pointer');
17
- }
18
- else {
19
- ele.style.removeProperty('--codemirror-cursor');
20
- }
21
- }
12
+ ], modKey = isMac ? 'metaKey' : 'ctrlKey', key = isMac ? 'Meta' : 'Control';
13
+ const toggleOpenLinks = ({ contentDOM }, toggle) => {
14
+ contentDOM.style[toggle ? 'setProperty' : 'removeProperty']('--codemirror-cursor', 'pointer');
22
15
  };
23
- /* eslint-disable @typescript-eslint/no-unnecessary-condition */
24
- globalThis.document?.addEventListener('keydown', e => {
25
- if (e.key === key) {
26
- toggleOpenLinks(true);
27
- }
28
- });
29
- globalThis.document?.addEventListener('keyup', e => {
30
- if (e.key === key) {
31
- toggleOpenLinks();
32
- }
33
- });
34
- globalThis.document?.addEventListener('visibilitychange', () => {
35
- if (document.hidden) {
36
- toggleOpenLinks();
37
- }
38
- });
39
- /* eslint-enable @typescript-eslint/no-unnecessary-condition */
40
16
  const wrapURL = (url) => url.startsWith('//') ? location.protocol + url : url;
41
- export const mouseEventListener = (e, view, langConfig) => {
17
+ export const getISBNParser = (articlePath) => articlePath
18
+ ? (link) => {
19
+ const page = `Special:Booksources/${link.slice(4).replace(/[\p{Zs}\t-]/gu, '')
20
+ .replace(/x$/u, 'X')}`;
21
+ return articlePath.includes('$1')
22
+ ? articlePath.replace('$1', page)
23
+ : articlePath + (articlePath.endsWith('/') ? '' : '/') + page;
24
+ }
25
+ : undefined;
26
+ export const mouseEventListener = (e, view, isbnParser, titleParser) => {
42
27
  if (!e[modKey]
43
28
  || !(e.target instanceof Element && getComputedStyle(e.target).textDecorationLine === 'underline')) {
44
29
  return undefined;
@@ -62,8 +47,8 @@ export const mouseEventListener = (e, view, langConfig) => {
62
47
  if (name.includes('-extlink-protocol')) {
63
48
  return wrapURL(state.sliceDoc(from, node.nextSibling.to));
64
49
  }
65
- else if (name.includes(tokens.pageName) && typeof langConfig?.titleParser === 'function') {
66
- return langConfig.titleParser(state, node);
50
+ else if (name.includes(tokens.pageName) && typeof titleParser === 'function') {
51
+ return titleParser(state, node);
67
52
  }
68
53
  else if (/-extlink(?:_|$)/u.test(name)) {
69
54
  return wrapURL(state.sliceDoc(node.prevSibling.from, to));
@@ -76,30 +61,47 @@ export const mouseEventListener = (e, view, langConfig) => {
76
61
  else if (link.startsWith('PMID')) {
77
62
  return `https://pubmed.ncbi.nlm.nih.gov/${link.slice(4).trim()}`;
78
63
  }
79
- else if (typeof langConfig?.isbnParser === 'function') {
80
- return langConfig.isbnParser(link);
81
- }
64
+ return isbnParser?.(link);
82
65
  }
83
66
  return undefined;
84
67
  };
85
- export default ({ langConfig }) => [
86
- EditorView.domEventHandlers({
87
- mousedown(e, view) {
88
- if (e.button !== 0) {
68
+ export default (articlePath) => ({ langConfig }) => {
69
+ const isbnParser = getISBNParser(articlePath || langConfig?.articlePath);
70
+ return [
71
+ EditorView.domEventHandlers({
72
+ mousedown(e, view) {
73
+ if (e.button !== 0) {
74
+ return undefined;
75
+ }
76
+ const url = mouseEventListener(e, view, isbnParser, langConfig?.titleParser);
77
+ if (url) {
78
+ open(url, '_blank', 'noreferrer');
79
+ return true;
80
+ }
89
81
  return undefined;
90
- }
91
- const url = mouseEventListener(e, view, langConfig);
92
- if (url) {
93
- open(url, '_blank', 'noopener noreferrer');
94
- return true;
95
- }
96
- return undefined;
97
- },
98
- }),
99
- EditorView.theme({
100
- [[...links, ...langConfig?.titleParser ? wikiLinks : []]
101
- .map(type => `.cm-mw-${type}`).join()]: {
102
- cursor: 'var(--codemirror-cursor)',
103
- },
104
- }),
105
- ];
82
+ },
83
+ keydown(e, view) {
84
+ if (e.key === key) {
85
+ toggleOpenLinks(view, true);
86
+ }
87
+ },
88
+ keyup(e, view) {
89
+ if (e.key === key) {
90
+ toggleOpenLinks(view);
91
+ }
92
+ },
93
+ mousemove(e, view) {
94
+ toggleOpenLinks(view, e[modKey]);
95
+ },
96
+ }),
97
+ EditorView.theme({
98
+ [[
99
+ ...links,
100
+ ...langConfig?.titleParser ? wikiLinks : [],
101
+ ]
102
+ .map(type => `.cm-mw-${type}`).join()]: {
103
+ cursor: 'var(--codemirror-cursor)',
104
+ },
105
+ }),
106
+ ];
107
+ };
package/dist/ref.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  import type { Extension } from '@codemirror/state';
2
2
  import type { CodeMirror6 } from './codemirror';
3
- declare const _default: (cm: CodeMirror6) => Extension;
3
+ declare const _default: (articlePath?: string) => (cm: CodeMirror6) => Extension;
4
4
  export default _default;
package/dist/ref.js CHANGED
@@ -6,109 +6,108 @@ import elt from 'crelt';
6
6
  import { base } from './constants.js';
7
7
  import { tokens } from './config.js';
8
8
  import { getTag } from './matchTag.js';
9
- import { indexToPos, posToIndex, escHTML, } from './util.js';
9
+ import { sliceDoc, indexToPos, posToIndex, escHTML, toConfigGetter, } from './util.js';
10
10
  const trees = new WeakMap(), selector = '.cm-tooltip-ref', noDef = '.cm-tooltip-no-def';
11
11
  /**
12
12
  * 获取节点内容
13
13
  * @param state
14
14
  * @param node 语法树节点
15
- * @param node.from 起始位置
16
- * @param node.to 结束位置
17
15
  */
18
- const getName = (state, { from, to }) => state.sliceDoc(from, to).trim();
19
- export default (cm) => [
20
- hoverTooltip(async (view, pos, side) => {
21
- const { state } = view, node = ensureSyntaxTree(state, pos)?.resolve(pos, side);
22
- if (node && /-exttag-(?!bracket)/u.test(node.name)) {
23
- const tag = getTag(state, node);
24
- if (!tag) {
25
- return null;
26
- }
27
- const { name, selfClosing, first, last, to } = tag;
28
- if (name === 'ref' && selfClosing) {
29
- let prevSibling = last, nextSibling = null;
30
- while (prevSibling && prevSibling.from > first.to) {
31
- const key = getName(state, prevSibling);
32
- if (prevSibling.name.split('_').includes(tokens.extTagAttribute)
33
- && /(?:^|\s)name(?:$|[\s=])/iu.test(key)) {
34
- if (/(?:^|\s)name\s*=/iu.test(key)) {
35
- ({ nextSibling } = prevSibling);
36
- }
37
- break;
38
- }
39
- ({ prevSibling } = prevSibling);
16
+ const getName = (state, node) => sliceDoc(state, node).trim();
17
+ export default (articlePath) => (cm) => {
18
+ return [
19
+ hoverTooltip(async (view, pos, side) => {
20
+ const { state } = view, node = ensureSyntaxTree(state, pos)?.resolve(pos, side);
21
+ if (node && /-exttag-(?!bracket)/u.test(node.name)) {
22
+ const tag = getTag(state, node);
23
+ if (!tag) {
24
+ return null;
40
25
  }
41
- if (nextSibling?.name.includes(tokens.extTagAttributeValue)) {
42
- let target = getName(state, nextSibling);
43
- const quote = target.charAt(0);
44
- if (quote === '"' || quote === "'") {
45
- target = target.slice(1, target.slice(-1) === quote ? -1 : undefined).trim();
26
+ const { name, selfClosing, first, last, to } = tag;
27
+ if (name === 'ref' && selfClosing) {
28
+ let prevSibling = last, nextSibling = null;
29
+ while (prevSibling && prevSibling.from > first.to) {
30
+ const key = getName(state, prevSibling);
31
+ if (prevSibling.name.split('_').includes(tokens.extTagAttribute)
32
+ && /(?:^|\s)name(?:$|[\s=])/iu.test(key)) {
33
+ if (/(?:^|\s)name\s*=/iu.test(key)) {
34
+ ({ nextSibling } = prevSibling);
35
+ }
36
+ break;
37
+ }
38
+ ({ prevSibling } = prevSibling);
46
39
  }
47
- if (target) {
48
- const { doc } = state, ref = await getLSP(view, false, cm.getWikiConfig, base.CDN)
49
- ?.provideDefinition(doc.toString(), indexToPos(doc, first.to));
50
- return {
51
- pos,
52
- end: to,
53
- above: true,
54
- create() {
55
- const dom = elt('div', { class: selector.slice(1) });
56
- dom.style.font = getComputedStyle(view.contentDOM).font;
57
- if (ref) {
58
- const { range: { start, end } } = ref[0], anchor = posToIndex(doc, start), head = posToIndex(doc, end), text = state.sliceDoc(anchor, head);
59
- let result = '';
60
- highlightCode(text, state.facet(language).parser.parse(text), {
61
- style(tags) {
62
- return highlightingFor(state, tags);
63
- },
64
- }, (code, classes) => {
65
- const escaped = escHTML(code);
66
- result += classes
67
- ? `<span class="${classes}">${escaped}</span>`
68
- : escaped;
69
- }, () => {
70
- result += '<br>';
71
- });
72
- dom.innerHTML = result;
73
- dom.addEventListener('click', () => {
74
- view.dispatch({
75
- selection: { anchor, head },
76
- scrollIntoView: true,
40
+ if (nextSibling?.name.includes(tokens.extTagAttributeValue)) {
41
+ let target = getName(state, nextSibling);
42
+ const quote = target.charAt(0);
43
+ if (quote === '"' || quote === "'") {
44
+ target = target.slice(1, target.slice(-1) === quote ? -1 : undefined).trim();
45
+ }
46
+ if (target) {
47
+ const { doc } = state, ref = await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideDefinition(doc.toString(), indexToPos(doc, first.to));
48
+ return {
49
+ pos,
50
+ end: to,
51
+ above: true,
52
+ create() {
53
+ const dom = elt('div', { class: selector.slice(1) });
54
+ dom.style.font = getComputedStyle(view.contentDOM).font;
55
+ if (ref) {
56
+ const { range: { start, end } } = ref[0], anchor = posToIndex(doc, start), head = posToIndex(doc, end), text = state.sliceDoc(anchor, head);
57
+ let result = '';
58
+ highlightCode(text, state.facet(language).parser.parse(text), {
59
+ style(tags) {
60
+ return highlightingFor(state, tags);
61
+ },
62
+ }, (code, classes) => {
63
+ const escaped = escHTML(code);
64
+ result += classes
65
+ ? `<span class="${classes}">${escaped}</span>`
66
+ : escaped;
67
+ }, () => {
68
+ result += '<br>';
69
+ });
70
+ dom.innerHTML = result;
71
+ dom.addEventListener('click', () => {
72
+ view.dispatch({
73
+ selection: { anchor, head },
74
+ scrollIntoView: true,
75
+ });
76
+ view.focus();
77
77
  });
78
- view.focus();
79
- });
80
- }
81
- else {
82
- dom.textContent = state.phrase('No definition found');
83
- dom.classList.add(noDef.slice(1));
84
- }
85
- return { dom };
86
- },
87
- };
78
+ }
79
+ else {
80
+ dom.textContent = state.phrase('No definition found');
81
+ dom.classList.add(noDef.slice(1));
82
+ }
83
+ return { dom };
84
+ },
85
+ };
86
+ }
88
87
  }
89
88
  }
90
89
  }
91
- }
92
- return null;
93
- }),
94
- EditorView.updateListener.of(({ view, docChanged }) => {
95
- if (docChanged) {
96
- const tree = trees.get(view);
97
- if (tree) {
98
- tree.docChanged = true;
90
+ return null;
91
+ }),
92
+ EditorView.updateListener.of(({ view, docChanged }) => {
93
+ if (docChanged) {
94
+ const tree = trees.get(view);
95
+ if (tree) {
96
+ tree.docChanged = true;
97
+ }
99
98
  }
100
- }
101
- }),
102
- EditorView.theme({
103
- [selector]: {
104
- padding: '2px 5px',
105
- width: 'max-content',
106
- maxWidth: '60vw',
107
- cursor: 'pointer',
108
- whiteSpace: 'pre-wrap',
109
- },
110
- [noDef]: {
111
- color: 'var(--cm-comment)',
112
- },
113
- }),
114
- ];
99
+ }),
100
+ EditorView.theme({
101
+ [selector]: {
102
+ padding: '2px 5px',
103
+ width: 'max-content',
104
+ maxWidth: '60vw',
105
+ cursor: 'pointer',
106
+ whiteSpace: 'pre-wrap',
107
+ },
108
+ [noDef]: {
109
+ color: 'var(--cm-comment)',
110
+ },
111
+ }),
112
+ ];
113
+ };
@@ -1,4 +1,4 @@
1
1
  import type { Extension } from '@codemirror/state';
2
2
  import type { CodeMirror6 } from './codemirror';
3
- declare const _default: (cm: CodeMirror6) => Extension;
3
+ declare const _default: (articlePath?: string) => (cm: CodeMirror6) => Extension;
4
4
  export default _default;
package/dist/signature.js CHANGED
@@ -2,7 +2,7 @@ import { EditorView, showTooltip } from '@codemirror/view';
2
2
  import { StateField, StateEffect } from '@codemirror/state';
3
3
  import { getLSP } from '@bhsd/browser';
4
4
  import { base } from './constants.js';
5
- import { createTooltipView, indexToPos, escHTML, } from './util.js';
5
+ import { createTooltipView, indexToPos, escHTML, toConfigGetter, } from './util.js';
6
6
  const stateEffect = StateEffect.define(), field = StateField.define({
7
7
  create() {
8
8
  return undefined;
@@ -20,52 +20,53 @@ const stateEffect = StateEffect.define(), field = StateField.define({
20
20
  return oldValue;
21
21
  },
22
22
  });
23
- export default (cm) => [
24
- field,
25
- EditorView.updateListener.of(({ view, state, docChanged, selectionSet }) => {
26
- if (docChanged || selectionSet && state.field(field)?.signatureHelp?.signatures.length) {
27
- const { doc, selection: { main } } = state, { head: cursor } = main, text = doc.toString();
28
- if (!main.empty) {
29
- view.dispatch({
30
- effects: stateEffect.of({ text, cursor }),
31
- });
32
- return;
23
+ export default (articlePath) => (cm) => {
24
+ return [
25
+ field,
26
+ EditorView.updateListener.of(({ view, state, docChanged, selectionSet }) => {
27
+ if (docChanged || selectionSet && state.field(field)?.signatureHelp?.signatures.length) {
28
+ const { doc, selection: { main } } = state, { head: cursor } = main, text = doc.toString();
29
+ if (!main.empty) {
30
+ view.dispatch({
31
+ effects: stateEffect.of({ text, cursor }),
32
+ });
33
+ return;
34
+ }
35
+ (async () => {
36
+ view.dispatch({
37
+ effects: stateEffect.of({
38
+ text,
39
+ cursor,
40
+ signatureHelp: await getLSP(view, false, toConfigGetter(cm.getWikiConfig, articlePath), base.CDN)?.provideSignatureHelp(text, indexToPos(doc, cursor)),
41
+ }),
42
+ });
43
+ })();
33
44
  }
34
- (async () => {
35
- view.dispatch({
36
- effects: stateEffect.of({
37
- text,
38
- cursor,
39
- signatureHelp: await getLSP(view, false, cm.getWikiConfig, base.CDN)
40
- ?.provideSignatureHelp(text, indexToPos(doc, cursor)),
41
- }),
42
- });
43
- })();
44
- }
45
- }),
46
- showTooltip.from(field, (value) => {
47
- if (!value) {
48
- return null;
49
- }
50
- const { cursor, signatureHelp } = value;
51
- if (!signatureHelp || signatureHelp.signatures.length === 0) {
52
- return null;
53
- }
54
- const { signatures, activeParameter: active } = signatureHelp;
55
- return {
56
- pos: cursor,
57
- above: true,
58
- create(view) {
59
- return createTooltipView(view, signatures.map(({ label, parameters, activeParameter = active }) => {
60
- const safeLabel = escHTML(label);
61
- if (activeParameter < 0 || activeParameter >= parameters.length) {
62
- return safeLabel;
63
- }
64
- const colon = safeLabel.indexOf(':'), parts = safeLabel.slice(colon + 1, -2).split('|');
65
- parts[activeParameter] = `<b>${parts[activeParameter]}</b>`;
66
- return `${safeLabel.slice(0, colon)}:${parts.join('|')}}}`;
67
- }).join('<br>'));
68
- },
69
- };
70
- }),
71
- ];
45
+ }),
46
+ showTooltip.from(field, (value) => {
47
+ if (!value) {
48
+ return null;
49
+ }
50
+ const { cursor, signatureHelp } = value;
51
+ if (!signatureHelp || signatureHelp.signatures.length === 0) {
52
+ return null;
53
+ }
54
+ const { signatures, activeParameter: active } = signatureHelp;
55
+ return {
56
+ pos: cursor,
57
+ above: true,
58
+ create(view) {
59
+ return createTooltipView(view, signatures.map(({ label, parameters, activeParameter = active }) => {
60
+ const safeLabel = escHTML(label);
61
+ if (activeParameter < 0 || activeParameter >= parameters.length) {
62
+ return safeLabel;
63
+ }
64
+ const colon = safeLabel.indexOf(':'), parts = safeLabel.slice(colon + 1, -2).split('|');
65
+ parts[activeParameter] = `<b>${parts[activeParameter]}</b>`;
66
+ return `${safeLabel.slice(0, colon)}:${parts.join('|')}}}`;
67
+ }).join('<br>'));
68
+ },
69
+ };
70
+ }),
71
+ ];
72
+ };
package/dist/statusBar.js CHANGED
@@ -3,8 +3,8 @@ import { nextDiagnostic, setDiagnosticsEffect } from '@codemirror/lint';
3
3
  import { gotoLine } from '@codemirror/search';
4
4
  import elt from 'crelt';
5
5
  import { menuRegistry } from './codemirror.js';
6
- import { panelSelector, diagnosticSelector, menuSelector, messageSelector, actionSelector } from './constants.js';
7
- const statusSelector = '.cm-panel-status', workerSelector = '.cm-status-worker', errorSelector = '.cm-status-error', warningSelector = '.cm-status-warning', enabledSelector = '.cm-status-fix-enabled', disabledSelector = '.cm-status-fix-disabled', workerCls = 'cm-status-worker-enabled', lineCls = 'cm-status-line';
6
+ import { panelSelector, diagnosticSelector, actionSelector, bgDark, } from './constants.js';
7
+ const statusSelector = '.cm-panel-status', workerSelector = '.cm-status-worker', errorSelector = '.cm-status-error', warningSelector = '.cm-status-warning', enabledSelector = '.cm-status-fix-enabled', disabledSelector = '.cm-status-fix-disabled', menuSelector = '.cm-status-fix-menu', menuHover = `${menuSelector}>div:hover`, messageSelector = '.cm-status-message', workerCls = 'cm-status-worker-enabled', lineCls = 'cm-status-line';
8
8
  function getLintMarker(view, severity, menu) {
9
9
  const marker = elt('div', { class: `cm-status-${severity}` }), icon = elt('div');
10
10
  if (severity === 'fix') {
@@ -43,13 +43,13 @@ const toggleClass = (classList, enabled) => {
43
43
  classList.toggle(disabledSelector.slice(1), !enabled);
44
44
  };
45
45
  const getDiagnostics = (all, main) => all.filter(({ from, to }) => from <= main.to && to >= main.from);
46
- const updateDiagnosticMessage = (cm, allDiagnostics, main, msg) => {
46
+ const updateDiagnosticMessage = (view, allDiagnostics, main, msg) => {
47
47
  const diagnostics = getDiagnostics(allDiagnostics, main);
48
48
  if (diagnostics.length === 0) {
49
49
  msg.textContent = '';
50
50
  }
51
51
  else {
52
- const diagnostic = diagnostics.find(({ from, to }) => from <= main.head && to >= main.head) ?? diagnostics[0], view = cm.view;
52
+ const diagnostic = diagnostics.find(({ from, to }) => from <= main.head && to >= main.head) ?? diagnostics[0];
53
53
  if (diagnostic.renderMessage) {
54
54
  msg.replaceChildren(diagnostic.renderMessage(view));
55
55
  }
@@ -94,7 +94,8 @@ const updateMenu = (cm, allDiagnostics, main, classList, optionAll, menu, fixer)
94
94
  };
95
95
  export default (cm, fixer) => [
96
96
  showPanel.of(view => {
97
- let diagnostics = [], menu;
97
+ let diagnostics = [];
98
+ let menu;
98
99
  if (!view.state.readOnly && (fixer || menuRegistry.length > 0)) {
99
100
  menu = elt('div', { class: menuSelector.slice(1), tabIndex: -1 });
100
101
  if (fixer) {
@@ -118,7 +119,7 @@ export default (cm, fixer) => [
118
119
  });
119
120
  view.dom.append(menu);
120
121
  }
121
- const error = getLintMarker(view, 'error'), warning = getLintMarker(view, 'warning'), fix = getLintMarker(view, 'fix', menu), optionAll = elt('div', 'Fix all auto-fixable problems'), worker = elt('div', { class: workerSelector.slice(1) }, error, warning, fix), message = elt('div', { class: messageSelector.slice(1) }), position = elt('div', { class: lineCls }, '0:0'), dom = elt('div', { class: `${panelSelector.slice(1)} ${statusSelector.slice(1)}` }, worker, message, position), { classList } = fix.firstChild;
122
+ const error = getLintMarker(view, 'error'), warning = getLintMarker(view, 'warning'), fix = getLintMarker(view, 'fix', menu), { classList } = fix.firstChild, optionAll = elt('div', 'Fix all auto-fixable problems'), worker = elt('div', { class: workerSelector.slice(1) }, error, warning, fix), message = elt('div', { class: messageSelector.slice(1) }), position = elt('div', { class: lineCls }, '0:0'), dom = elt('div', { class: `${panelSelector.slice(1)} ${statusSelector.slice(1)}` }, worker, message, position);
122
123
  position.addEventListener('click', () => {
123
124
  gotoLine(view);
124
125
  });
@@ -132,13 +133,13 @@ export default (cm, fixer) => [
132
133
  worker.classList.toggle(workerCls, diagnostics.length > 0);
133
134
  updateDiagnosticsCount(diagnostics, 'error', error);
134
135
  updateDiagnosticsCount(diagnostics, 'warning', warning);
135
- updateDiagnosticMessage(cm, diagnostics, main, message);
136
+ updateDiagnosticMessage(view, diagnostics, main, message);
136
137
  updateMenu(cm, diagnostics, main, classList, optionAll, menu, fixer);
137
138
  }
138
139
  }
139
140
  }
140
141
  if (docChanged || selectionSet) {
141
- updateDiagnosticMessage(cm, diagnostics, main, message);
142
+ updateDiagnosticMessage(view, diagnostics, main, message);
142
143
  updateMenu(cm, diagnostics, main, classList, optionAll, menu, fixer);
143
144
  const { number, from } = doc.lineAt(main.head);
144
145
  position.textContent = `${number}:${main.head - from}`;
@@ -174,7 +175,7 @@ export default (cm, fixer) => [
174
175
  [`${errorSelector},${warningSelector}`]: {
175
176
  paddingRight: '8px',
176
177
  },
177
- [`.${workerCls} ${errorSelector},.${workerCls} ${warningSelector}`]: {
178
+ [`.${workerCls} ${errorSelector}, .${workerCls} ${warningSelector}`]: {
178
179
  cursor: 'pointer',
179
180
  },
180
181
  [`${workerSelector}>*>div`]: {
@@ -233,4 +234,25 @@ export default (cm, fixer) => [
233
234
  cursor: 'pointer',
234
235
  },
235
236
  }),
237
+ EditorView.baseTheme({
238
+ [`&light ${menuSelector}`]: {
239
+ backgroundColor: '#f5f5f5',
240
+ boxShadow: '0 2px 2px 0 rgb(0,0,0,.25)',
241
+ },
242
+ [`&light ${menuHover}`]: {
243
+ backgroundColor: '#e2f2ff',
244
+ },
245
+ [`&light ${messageSelector}`]: {
246
+ borderColor: '#c8ccd1',
247
+ },
248
+ [`&dark ${menuSelector}`]: {
249
+ backgroundColor: '#252a33',
250
+ },
251
+ [`&dark ${menuHover}`]: {
252
+ backgroundColor: bgDark,
253
+ },
254
+ [`&dark ${messageSelector}`]: {
255
+ borderColor: '#000',
256
+ },
257
+ }),
236
258
  ];