1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-04-24 19:55:13 +02:00
Files

94 lines
2.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 getParentName = () => node.node.parent?.name;
const getNodeStartLine = () => state.doc.lineAt(node.from);
if (['HeaderMark', 'CodeMark', 'EmphasisMark', 'StrikethroughMark', 'HighlightMarker', 'InsertMarker'].includes(node.name)) {
return true;
}
if ((node.name === 'URL' || node.name === 'LinkMark') && getParentName() === 'Link') {
const parent = node.node.parent!;
const parentContent = state.sliceDoc(parent.from, parent.to);
if (node.name === 'LinkMark') {
if (isReferenceLink(parentContent)) {
return !!resolveReferenceFromLink(parentContent, state);
}
} else if (node.name === 'URL') {
// 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 || node.from < lastClosingBracketIdx) {
return false;
}
}
return true;
}
if (node.name === 'QuoteMark' && node.from === getNodeStartLine().from) {
return true;
}
return false;
};
const hideDecoration = Decoration.replace({});
const replaceFormatCharacters = [
// Dependency
referenceLinkStateField,
makeInlineReplaceExtension({
getRevealStrategy: (node) => {
if (node.name === 'QuoteMark') {
return 'line';
}
if (node.name === 'CodeMark') {
if (node.node.parent?.name === 'FencedCode') {
return 'line';
}
}
return 'active';
},
createDecoration: (node, state) => {
if (shouldFullReplace(node, state)) {
return hideDecoration;
}
return null;
},
getDecorationRange: (node, state) => {
// Headers in the form "## Header" should have the "##"s and the
// space immediately after hidden
if (node.name === 'HeaderMark') {
const markerLine = state.doc.lineAt(node.from);
// Certain header styles DON'T have a space after the header mark:
const hasRoomForSpace = node.to + 1 >= markerLine.to;
if (hasRoomForSpace) {
return null;
}
// Include the space in the hidden region, if it's available
if (state.doc.sliceString(node.to, node.to + 1) === ' ') {
return [node.from, node.to + 1];
}
}
return null;
},
}),
];
export default replaceFormatCharacters;