fix: do not auto link url from text if already inside a link (#857)

This commit is contained in:
Daniel Lautzenheiser 2023-08-31 12:34:54 -04:00 committed by GitHub
parent 4325905fc4
commit e0b3aedfff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 14 deletions

View File

@ -16,7 +16,21 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
});
it('does not convert url to anchor node if inside link', () => {
const nodes: MdastNode[] = [
{ type: 'text', value: 'https://www.youtube.com/watch?v=p6h-rYSVX90' },
];
const output: MdastNode[] = [
{
type: 'text',
value: 'https://www.youtube.com/watch?v=p6h-rYSVX90',
},
];
expect(autoLinkToSlate(nodes, true)).toEqual(output);
}); });
it('does not convert url in shortcode node', () => { it('does not convert url in shortcode node', () => {
@ -43,7 +57,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
it('converts url with text before', () => { it('converts url with text before', () => {
@ -62,7 +76,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
it('converts url with text after', () => { it('converts url with text after', () => {
@ -81,7 +95,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
it('converts url with text before and after', () => { it('converts url with text before and after', () => {
@ -107,7 +121,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
it('converts multiple urls', () => { it('converts multiple urls', () => {
@ -143,7 +157,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
it('does not convert plain text', () => { it('does not convert plain text', () => {
@ -160,7 +174,7 @@ describe('processShortcodeConfig', () => {
}, },
]; ];
expect(autoLinkToSlate(nodes)).toEqual(slate); expect(autoLinkToSlate(nodes, false)).toEqual(slate);
}); });
}); });
}); });

View File

@ -1,15 +1,14 @@
/* eslint-disable import/prefer-default-export */ /* eslint-disable import/prefer-default-export */
import { isNotEmpty } from '@staticcms/core/lib/util/string.util'; import { isNotEmpty } from '@staticcms/core/lib/util/string.util';
import { NodeTypes } from './ast-types'; import { NodeTypes } from './ast-types';
import type { BaseMdastNode, MdastNode } from './ast-types'; import type { BaseMdastNode, MdastNode } from './ast-types';
export function autoLinkToSlate(nodes: BaseMdastNode[]) { export function autoLinkToSlate(nodes: BaseMdastNode[], isInLink: boolean) {
const output: MdastNode[] = []; const output: MdastNode[] = [];
for (const node of nodes) { for (const node of nodes) {
if (node.type === 'text' && node.value) { if (node.type === 'text' && node.value && !isInLink) {
const regex = const regex =
/([\w\W]*?)((?:http(?:s)?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_+.~#?&//=]*))([\w\W]*)/g; /([\w\W]*?)((?:http(?:s)?:\/\/.)?(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,6}\b(?:[-a-zA-Z0-9@:%_+.~#?&//=]*))([\w\W]*)/g;
let matches: RegExpExecArray | null; let matches: RegExpExecArray | null;

View File

@ -90,6 +90,7 @@ function parseStyleAttribute(node: MdxTextMdastNode, allowedStyles: Record<strin
export interface Options { export interface Options {
isInTable?: boolean; isInTable?: boolean;
isInLink?: boolean;
isInTableHeaderRow?: boolean; isInTableHeaderRow?: boolean;
tableAlign?: (string | null)[]; tableAlign?: (string | null)[];
useMdx: boolean; useMdx: boolean;
@ -102,6 +103,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
const { const {
isInTable = false, isInTable = false,
isInLink = false,
isInTableHeaderRow = false, isInTableHeaderRow = false,
tableAlign, tableAlign,
useMdx, useMdx,
@ -110,6 +112,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
} = options ?? {}; } = options ?? {};
const selfIsTable = node.type === 'table'; const selfIsTable = node.type === 'table';
const selfIsLink = node.type === 'link';
const selfIsTableHeaderRow = node.type === 'tableRow' && index === 0; const selfIsTableHeaderRow = node.type === 'tableRow' && index === 0;
const nodeChildren = node.children; const nodeChildren = node.children;
@ -123,6 +126,7 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
}, },
{ {
isInTable: selfIsTable || isInTable, isInTable: selfIsTable || isInTable,
isInLink: selfIsLink || isInLink,
isInTableHeaderRow: selfIsTableHeaderRow || isInTableHeaderRow, isInTableHeaderRow: selfIsTableHeaderRow || isInTableHeaderRow,
useMdx, useMdx,
shortcodeConfigs, shortcodeConfigs,
@ -351,7 +355,10 @@ export default function deserializeMarkdown(node: MdastNode, options: Options) {
return { text: '' }; return { text: '' };
} }
const nodes = autoLinkToSlate(processShortcodeConfigsToSlate(shortcodeConfigs, [node])); const nodes = autoLinkToSlate(
processShortcodeConfigsToSlate(shortcodeConfigs, [node]),
isInLink,
);
return nodes.map(node => (node.type === 'text' ? { text: node.value ?? '' } : node)); return nodes.map(node => (node.type === 'text' ? { text: node.value ?? '' } : node));

View File

@ -201,7 +201,6 @@ const RelationControl: FC<WidgetControlProps<string | string[], RelationField>>
searchFields, searchFields,
inputValue, inputValue,
); );
console.log('file', file, 'hits', hits);
} else { } else {
const expandedEntries = expandSearchEntries(entries, searchFields); const expandedEntries = expandSearchEntries(entries, searchFields);
hits = mergeExpandedEntries( hits = mergeExpandedEntries(
@ -325,8 +324,6 @@ const RelationControl: FC<WidgetControlProps<string | string[], RelationField>>
const isRequired = useMemo(() => field.required ?? true, [field.required]); const isRequired = useMemo(() => field.required ?? true, [field.required]);
console.log('field.required', field.required);
return ( return (
<Field <Field
inputRef={ref} inputRef={ref}