@bhsd/codemirror-mediawiki 2.6.1 → 2.6.3

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/preference.ts CHANGED
@@ -1,23 +1,26 @@
1
1
  import {rules} from 'wikiparser-node/dist/base';
2
+ import {CodeMirror} from './base';
2
3
  import {msg, i18n, setObject, getObject} from './msg';
3
- import type {CodeMirror} from './base';
4
+ import {instances} from './textSelection';
4
5
 
5
6
  const storageKey = 'codemirror-mediawiki-addons',
6
- wikilintKey = 'codemirror-mediawiki-wikilint';
7
+ wikilintKey = 'codemirror-mediawiki-wikilint',
8
+ codeKeys = ['ESLint', 'Stylelint'] as const;
9
+
10
+ declare type codeKey = typeof codeKeys[number];
11
+
7
12
  export const indentKey = 'codemirror-mediawiki-indent',
8
13
  prefs = new Set<string>(getObject(storageKey) as string[] | null),
9
- wikilintConfig = (getObject(wikilintKey) || {}) as Record<Rule, RuleState | undefined>;
14
+ wikilintConfig = (getObject(wikilintKey) || {}) as Record<Rule, RuleState | undefined>,
15
+ codeConfigs = new Map(codeKeys.map(k => [k, getObject(`codemirror-mediawiki-${k}`)]));
10
16
 
11
17
  // OOUI组件
12
18
  let dialog: OO.ui.MessageDialog | undefined,
13
- layout: OO.ui.IndexLayout | undefined,
14
- panelMain: OO.ui.TabPanelLayout | undefined,
15
- panelWikilint: OO.ui.TabPanelLayout | undefined,
19
+ layout: OO.ui.IndexLayout,
16
20
  widget: OO.ui.CheckboxMultiselectInputWidget,
17
21
  indentWidget: OO.ui.TextInputWidget,
18
- field: OO.ui.FieldLayout,
19
- indentField: OO.ui.FieldLayout,
20
22
  indent = localStorage.getItem(indentKey) || '';
23
+ const widgets: Partial<Record<codeKey, OO.ui.MultilineTextInputWidget>> = {};
21
24
 
22
25
  const enum RuleState {
23
26
  off = '0',
@@ -28,7 +31,8 @@ const enum RuleState {
28
31
  const wikilintWidgets = new Map<Rule, OO.ui.DropdownInputWidget>();
29
32
 
30
33
  mw.loader.addStyleTag(`#cm-preference>.oo-ui-window-frame{height:100%!important}
31
- #cm-preference .oo-ui-panelLayout{overflow:visible}`);
34
+ #cm-preference .oo-ui-panelLayout{overflow:visible}
35
+ #cm-preference .cm-editor{border:1.5px solid #dedede;border-radius:.3em}`);
32
36
 
33
37
  /**
34
38
  * 打开设置对话框
@@ -45,9 +49,25 @@ export const openPreference = async (editors: (CodeMirror | undefined)[]): Promi
45
49
  windowManager.$element.appendTo(document.body);
46
50
  windowManager.addWindows([dialog]);
47
51
  layout = new OO.ui.IndexLayout();
48
- panelMain = new OO.ui.TabPanelLayout('main', {label: msg('title')});
49
- panelWikilint = new OO.ui.TabPanelLayout('eslint', {label: msg('wikilint')});
50
- layout.addTabPanels([panelMain, panelWikilint], 0);
52
+ const panelMain = new OO.ui.TabPanelLayout('main', {label: msg('title')}),
53
+ panelWikilint = new OO.ui.TabPanelLayout('wikilint', {label: 'WikiLint'}),
54
+ panels: Partial<Record<codeKey, OO.ui.TabPanelLayout>> = {};
55
+ for (const key of codeKeys) {
56
+ const c = codeConfigs.get(key);
57
+ widgets[key] = new OO.ui.MultilineTextInputWidget({
58
+ value: c ? JSON.stringify(c, null, indent || '\t') : '',
59
+ });
60
+ const codeField = new OO.ui.FieldLayout(widgets[key]!, {label: msg(`${key}-config`), align: 'top'}),
61
+ panel = new OO.ui.TabPanelLayout(key, {label: key, $content: codeField.$element});
62
+ panel.on('active', active => {
63
+ const [textarea] = panel.$element.find('textarea') as unknown as [HTMLTextAreaElement];
64
+ if (active && !instances.has(textarea)) {
65
+ void CodeMirror.fromTextArea(textarea, 'json');
66
+ }
67
+ });
68
+ panels[key] = panel;
69
+ }
70
+ layout.addTabPanels([panelMain, panelWikilint, ...Object.values(panels)], 0);
51
71
  widget = new OO.ui.CheckboxMultiselectInputWidget({
52
72
  options: Object.keys(i18n)
53
73
  .filter(k => k !== 'addon-indent' && k.startsWith('addon-') && !k.endsWith('-mac'))
@@ -58,12 +78,12 @@ export const openPreference = async (editors: (CodeMirror | undefined)[]): Promi
58
78
  })),
59
79
  value: [...prefs] as unknown as string,
60
80
  });
61
- field = new OO.ui.FieldLayout(widget, {
62
- label: msg('label'),
63
- align: 'top',
64
- });
65
81
  indentWidget = new OO.ui.TextInputWidget({value: indent, placeholder: '\\t'});
66
- indentField = new OO.ui.FieldLayout(indentWidget, {label: msg('addon-indent')});
82
+ const field = new OO.ui.FieldLayout(widget, {
83
+ label: msg('label'),
84
+ align: 'top',
85
+ }),
86
+ indentField = new OO.ui.FieldLayout(indentWidget, {label: msg('addon-indent')});
67
87
  panelMain.$element.append(
68
88
  field.$element,
69
89
  indentField.$element,
@@ -98,6 +118,19 @@ export const openPreference = async (editors: (CodeMirror | undefined)[]): Promi
98
118
  size: 'medium',
99
119
  }).closing as unknown as Promise<{action?: unknown} | undefined>);
100
120
  if (typeof data === 'object' && data.action === 'accept') {
121
+ const jsonErrors: string[] = [];
122
+ for (const key of codeKeys) {
123
+ try {
124
+ const config = JSON.parse(widgets[key]!.getValue().trim() || 'null');
125
+ codeConfigs.set(key, config);
126
+ setObject(`codemirror-mediawiki-${key}`, config);
127
+ } catch {
128
+ jsonErrors.push(key);
129
+ }
130
+ }
131
+ if (jsonErrors.length > 0) {
132
+ void OO.ui.alert(msg('json-error', jsonErrors.join(msg('and'))));
133
+ }
101
134
  for (const [rule, dropdown] of wikilintWidgets) {
102
135
  wikilintConfig[rule] = dropdown.getValue() as RuleState;
103
136
  }
@@ -17,37 +17,40 @@ export const textSelection = {
17
17
  return getInstance(this).view.state.doc.toString();
18
18
  },
19
19
  setContents(this: JQuery<HTMLTextAreaElement>, content: string): JQuery<HTMLTextAreaElement> {
20
- getInstance(this).setContent(content);
20
+ const cm = getInstance(this),
21
+ {view: {scrollDOM}} = cm,
22
+ {scrollTop} = scrollDOM;
23
+ cm.setContent(content);
24
+ scrollDOM.scrollTop = scrollTop;
21
25
  return this;
22
26
  },
23
27
  getSelection(this: JQuery<HTMLTextAreaElement>): string {
24
- const {view: {state}} = getInstance(this);
25
- return state.sliceDoc(state.selection.main.from, state.selection.main.to);
28
+ const {view: {state}} = getInstance(this),
29
+ {selection: {main: {from, to}}} = state;
30
+ return state.sliceDoc(from, to);
26
31
  },
27
32
  setSelection(
28
33
  this: JQuery<HTMLTextAreaElement>,
29
- {start, end}: {start: number, end?: number},
34
+ {start, end = start}: {start: number, end?: number},
30
35
  ): JQuery<HTMLTextAreaElement> {
31
- const {view} = getInstance(this);
32
- view.dispatch({
33
- selection: {anchor: start, head: end ?? start},
36
+ getInstance(this).view.dispatch({
37
+ selection: {anchor: start, head: end},
34
38
  });
35
- view.focus();
36
39
  return this;
37
40
  },
38
41
  replaceSelection(this: JQuery<HTMLTextAreaElement>, value: string): JQuery<HTMLTextAreaElement> {
39
- const {view} = getInstance(this),
40
- {state: {selection: {main: {from, to}}}} = view;
41
- view.dispatch({selection: {anchor: from, head: to}});
42
+ const {view} = getInstance(this);
43
+ view.dispatch({selection: view.state.selection.asSingle()});
42
44
  view.dispatch(view.state.replaceSelection(value));
43
45
  return this;
44
46
  },
45
47
  getCaretPosition(this: JQuery<HTMLTextAreaElement>, option?: {startAndEnd?: boolean}): [number, number] | number {
46
- const {view: {state: {selection: {main}}}} = getInstance(this);
47
- return option?.startAndEnd ? [main.from, main.to] : main.head;
48
+ const {view: {state: {selection: {main: {from, to, head}}}}} = getInstance(this);
49
+ return option?.startAndEnd ? [from, to] : head;
48
50
  },
49
51
  scrollToCaretPosition(this: JQuery<HTMLTextAreaElement>): JQuery<HTMLTextAreaElement> {
50
- getInstance(this).view.dispatch({scrollIntoView: true});
52
+ const cm = getInstance(this);
53
+ cm.scrollTo();
51
54
  return this;
52
55
  },
53
56
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bhsd/codemirror-mediawiki",
3
- "version": "2.6.1",
3
+ "version": "2.6.3",
4
4
  "description": "Modified CodeMirror mode based on wikimedia/mediawiki-extensions-CodeMirror",
5
5
  "keywords": [
6
6
  "mediawiki",