一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
62 行
1.9 KiB
TypeScript
62 行
1.9 KiB
TypeScript
import { SyntaxNodeRef } from '@lezer/common';
|
|
import { EditorState } from '@codemirror/state';
|
|
import referenceLinkStateField, { isReferenceLink, resolveReferenceFromLink } from '../links/referenceLinksStateField';
|
|
import makeHideReplaceExtension from './utils/makeHideReplaceExtension';
|
|
|
|
const shouldFullReplace = (node: SyntaxNodeRef, state: EditorState) => {
|
|
const isUrl = node.name === 'URL';
|
|
const isLinkMark = node.name === 'LinkMark';
|
|
if (!isUrl && !isLinkMark) return false;
|
|
|
|
const parent = node.node.parent;
|
|
if (parent?.name !== 'Link') return false;
|
|
|
|
const parentContent = state.sliceDoc(parent.from, parent.to);
|
|
if (isLinkMark && isReferenceLink(parentContent)) {
|
|
return !!resolveReferenceFromLink(parentContent, state);
|
|
}
|
|
|
|
// Find all closing link marks
|
|
const closingBracketNodes = parent.getChildren('LinkMark').filter(mark => {
|
|
const isClosingBracket = state.sliceDoc(mark.from, mark.to) === ']';
|
|
return isClosingBracket;
|
|
});
|
|
|
|
// URLs can only be hidden if after the last ].
|
|
const lastClosingBracketIdx = closingBracketNodes.length > 0 ? closingBracketNodes[closingBracketNodes.length - 1].from : null;
|
|
if (!lastClosingBracketIdx || isUrl && node.from < lastClosingBracketIdx) {
|
|
return false;
|
|
}
|
|
|
|
const label = state.sliceDoc(
|
|
parent.from, lastClosingBracketIdx,
|
|
).replace(/^\[/, '');
|
|
|
|
// Links with an empty label shouldn't be hidden
|
|
if (label.trim() === '') {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
const replaceLinks = [
|
|
// Dependency
|
|
referenceLinkStateField,
|
|
|
|
makeHideReplaceExtension({
|
|
getRevealStrategy: () => 'active',
|
|
shouldHide: (node, state) => {
|
|
return shouldFullReplace(node, state);
|
|
},
|
|
getDecorationRange: (node, state) => {
|
|
const previous = node.name === 'URL' ? node.node.prevSibling : null;
|
|
if (previous?.name !== 'LinkMark') return null;
|
|
if (state.sliceDoc(previous.from, previous.to) !== '(') return null;
|
|
return [previous.to, node.to];
|
|
},
|
|
}),
|
|
];
|
|
|
|
export default replaceLinks;
|