Files

62 lines
1.8 KiB
TypeScript

import makeInlineReplaceExtension from './utils/makeInlineReplaceExtension';
import { SyntaxNodeRef } from '@lezer/common';
import { EditorState } from '@codemirror/state';
import referenceLinkStateField, { isReferenceLink, resolveReferenceFromLink } from '../links/referenceLinksStateField';
import { Decoration } from '@codemirror/view';
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 hideDecoration = Decoration.replace({});
const replaceLinks = [
// Dependency
referenceLinkStateField,
makeInlineReplaceExtension({
getRevealStrategy: () => 'active',
createDecoration: (node, state) => {
if (shouldFullReplace(node, state)) {
return hideDecoration;
}
return null;
},
}),
];
export default replaceLinks;