Skip to content

Commit

Permalink
refactor: reduce number of exports
Browse files Browse the repository at this point in the history
  • Loading branch information
bhsd-harry committed Aug 17, 2024
1 parent 656a2c2 commit 07fcd1a
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 83 deletions.
26 changes: 13 additions & 13 deletions dist/main.min.js

Large diffs are not rendered by default.

46 changes: 6 additions & 40 deletions mw/base.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {CDN} from '@bhsd/common';
import {CodeMirror6} from '../src/codemirror';
import {getMwConfig, getParserConfig} from './config';
import {openLinks, linkProvider} from './openLinks';
import {refDefinitionProvider, refReferenceProvider, refListener} from './ref';
import openLinks from './openLinks';
import refHover from './ref';
import {instances, textSelection, monacoTextSelection} from './textSelection';
import {openPreference, prefs, useMonaco, indentKey, wikilint, codeConfigs, loadJSON} from './preference';
import {msg, setI18N, welcome, REPO_CDN, curVersion, localize, languages} from './msg';
import {getEscapeActions} from './escape';
import escape from './escape';
import wikiEditor from './wikiEditor';
import type {Diagnostic} from '@codemirror/lint';
import type {LintError} from 'wikiparser-node';
Expand Down Expand Up @@ -79,10 +79,6 @@ const linters: Record<string, LintSource | undefined> = {},
['highlightWhitespace', 'renderWhitespace', 'selection', 'all'],
['scrollPastEnd', 'scrollBeyondLastLine', false, true],
];
let escapeActions: readonly [Monaco.editor.IActionDescriptor, Monaco.editor.IActionDescriptor] | undefined,
wikilinkProvider: Monaco.IDisposable | undefined,
refProvider: Monaco.IDisposable | undefined,
refProvider2: Monaco.IDisposable | undefined;

/**
* 判断是否为普通编辑器
Expand Down Expand Up @@ -176,8 +172,6 @@ export class CodeMirror extends CodeMirror6 {
#editor: Monaco.editor.IStandaloneCodeEditor | undefined;
#init;
#indentStr = '\t';
#escapeActions: Monaco.IDisposable[] = [];
#refListener: Monaco.IDisposable | undefined;

override get visible(): boolean {
return this.#visible;
Expand Down Expand Up @@ -413,50 +407,22 @@ export class CodeMirror extends CodeMirror6 {
? (ext: string): boolean => extensions.includes(ext)
: (ext: string): boolean | undefined => extensions[ext];
const hasLint = hasExtension('lint'),
hasOpenLinks = hasExtension('openLinks'),
hasRefHover = hasExtension('refHover'),
isWiki = this.lang === 'mediawiki';
openLinks(this, hasExtension('openLinks'), isWiki);
if (this.view) {
super.prefer(extensions);
if (hasLint !== undefined) {
void this.defaultLint(hasLint);
}
openLinks(this, isWiki && hasOpenLinks);
return;
} else if (!this.#editor || !this.#model) {
throw new Error('The editor is not initialized!');
} else if (hasLint !== undefined && this.#model.lint) {
this.#model.lint(hasLint);
}
if (isWiki) {
const hasEscape = hasExtension('escape');
if (hasEscape === false) {
let action = this.#escapeActions.pop();
while (action) {
action.dispose();
action = this.#escapeActions.pop();
}
} else if (hasEscape && this.#escapeActions.length === 0) {
escapeActions ??= getEscapeActions();
this.#escapeActions.push(
this.#editor.addAction(escapeActions[0]),
this.#editor.addAction(escapeActions[1]),
);
}
if (hasOpenLinks === false) {
wikilinkProvider?.dispose();
} else if (hasOpenLinks) {
wikilinkProvider ??= monaco.languages.registerLinkProvider('wikitext', linkProvider);
}
if (hasRefHover === false) {
refProvider?.dispose();
refProvider2?.dispose();
this.#refListener?.dispose();
} else if (hasRefHover) {
refProvider ??= monaco.languages.registerDefinitionProvider('wikitext', refDefinitionProvider);
refProvider2 ??= monaco.languages.registerReferenceProvider('wikitext', refReferenceProvider);
this.#refListener ??= refListener(this.#model);
}
escape(this.#editor, hasExtension('escape'));
refHover(this.#model, hasExtension('refHover'));
}
const options: Record<string, unknown> = {};
for (const [key, opts, off, on] of avail) {
Expand Down
28 changes: 24 additions & 4 deletions mw/escape.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {escapeHTML, escapeURI} from '../src/escape';
import type {editor, KeyCode} from 'monaco-editor';
import type {editor, KeyCode, IDisposable} from 'monaco-editor';

/**
* 创建单个Monaco编辑器动作
Expand Down Expand Up @@ -35,8 +35,28 @@ const createAction = (
},
});

/** 创建Monaco编辑器的转义动作 */
export const getEscapeActions = () => [
/** 创建Monaco编辑器的转义动作,需要等待Monaco加载 */
const getEscapeActions = (): editor.IActionDescriptor[] => [
createAction('escape.html', 'Escape HTML Entity', 'BracketLeft', 'editor.action.indentLines', escapeHTML),
createAction('escape.uri', 'URI Encode/Decode', 'BracketRight', 'editor.action.outdentLines', escapeURI),
] as const;
];

const actionMap = new WeakMap<editor.IStandaloneCodeEditor, IDisposable[]>();
let actions: editor.IActionDescriptor[] | undefined;

/**
* 添加或移除转义动作
* @param editor
* @param on 是否添加
*/
export default (editor: editor.IStandaloneCodeEditor, on: boolean | undefined): void => {
if (on && !actionMap.has(editor)) {
actions ??= getEscapeActions();
actionMap.set(editor, actions.map(action => editor.addAction(action)));
} else if (on === false && actionMap.has(editor)) {
for (const disposable of actionMap.get(editor)!) {
disposable.dispose();
}
actionMap.delete(editor);
}
};
59 changes: 36 additions & 23 deletions mw/openLinks.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import {isMac} from './msg';
import {tokens} from '../src/config';
import type {SyntaxNode} from '@lezer/common';
import type {languages, editor} from 'monaco-editor';
import type {languages, editor, IDisposable} from 'monaco-editor';
import type {AST, TokenTypes} from 'wikiparser-node/base';
import type {CodeMirror} from './base';

declare type MouseEventListener = (e: MouseEvent) => void;

const modKey = isMac ? 'metaKey' : 'ctrlKey',
handlers = new WeakMap<CodeMirror, MouseEventListener>();
handlers = new WeakMap<CodeMirror, MouseEventListener>(),
linkTypes = new Set<TokenTypes | undefined>(['link-target', 'template-name', 'invoke-module', 'magic-link']);

/**
* 获取节点的名称
Expand Down Expand Up @@ -111,26 +112,6 @@ const getHandler = (cm: CodeMirror): MouseEventListener => {
return handler;
};

/**
* 添加或移除打开链接的事件
* @param cm
* @param on 是否添加
*/
export const openLinks = (cm: CodeMirror, on?: boolean): void => {
const {scrollDOM} = cm.view!,
handler = getHandler(cm);
if (on) {
mw.loader.load('mediawiki.Title');
scrollDOM.addEventListener('mousedown', handler, {capture: true});
scrollDOM.style.setProperty('--codemirror-cursor', 'pointer');
} else if (on === false) {
scrollDOM.removeEventListener('mousedown', handler, {capture: true});
scrollDOM.style.removeProperty('--codemirror-cursor');
}
};

const linkTypes = new Set<TokenTypes | undefined>(['link-target', 'template-name', 'invoke-module', 'magic-link']);

/**
* 生成Monaco编辑器的链接
* @param model
Expand Down Expand Up @@ -180,7 +161,7 @@ const generateLinks = (model: editor.ITextModel, tree: AST, parent?: AST, grandp
return childNodes?.flatMap(node => generateLinks(model, node, tree, parent)) ?? [];
};

export const linkProvider: languages.LinkProvider = {
const linkProvider: languages.LinkProvider = {
async provideLinks(model) {
return {
links: 'wikiparse' in window
Expand All @@ -189,3 +170,35 @@ export const linkProvider: languages.LinkProvider = {
};
},
};

let disposable: IDisposable | undefined;

/**
* 添加或移除打开链接的事件
* @param cm
* @param on 是否添加
* @param isWiki 是否为Wikitext
*/
export default (cm: CodeMirror, on: boolean | undefined, isWiki: boolean): void => {
const {view, model} = cm;
if (view) {
on = isWiki && on; // eslint-disable-line no-param-reassign
const {scrollDOM} = view,
handler = getHandler(cm);
if (on) {
mw.loader.load('mediawiki.Title');
scrollDOM.addEventListener('mousedown', handler, {capture: true});
scrollDOM.style.setProperty('--codemirror-cursor', 'pointer');
} else if (on === false) {
scrollDOM.removeEventListener('mousedown', handler, {capture: true});
scrollDOM.style.removeProperty('--codemirror-cursor');
}
} else if (!isWiki || !model) {
// pass
} else if (on) {
disposable ??= monaco.languages.registerLinkProvider('wikitext', linkProvider);
} else if (on === false) {
disposable?.dispose();
disposable = undefined;
}
};
32 changes: 29 additions & 3 deletions mw/ref.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,47 @@ const provideRef = async (
}));
};

export const refDefinitionProvider: languages.DefinitionProvider = {
const refDefinitionProvider: languages.DefinitionProvider = {
async provideDefinition(model, pos) {
return (await provideRef(model, pos))?.[0];
},
};

export const refReferenceProvider: languages.ReferenceProvider = {
const refReferenceProvider: languages.ReferenceProvider = {
async provideReferences(model, pos) {
return provideRef(model, pos, true);
},
};

export const refListener = (model: editor.ITextModel): IDisposable => model.onDidChangeContent(() => {
const refListener = (model: editor.ITextModel): IDisposable => model.onDidChangeContent(() => {
const tree = trees.get(model);
if (tree) {
tree.docChanged = true;
}
});

const map = new WeakMap<editor.ITextModel, IDisposable>();
let definition: IDisposable | undefined,
reference: IDisposable | undefined;

/**
* 添加或移除注释服务
* @param model
* @param on 是否添加
*/
export default (model: editor.ITextModel, on: boolean | undefined): void => {
if (on) {
definition ??= monaco.languages.registerDefinitionProvider('wikitext', refDefinitionProvider);
reference ??= monaco.languages.registerReferenceProvider('wikitext', refReferenceProvider);
if (!map.has(model)) {
map.set(model, refListener(model));
}
} else if (on === false) {
definition?.dispose();
definition = undefined;
reference?.dispose();
reference = undefined;
map.get(model)?.dispose();
map.delete(model);
}
};

0 comments on commit 07fcd1a

Please sign in to comment.