mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-25 05:02:57 +01:00
Account for terminal punctuation right after a pasted URL within text
This commit is contained in:
parent
b31319934a
commit
6b04961654
@ -144,7 +144,14 @@ const insertContentWithLinks = (editorState, htmlOrText) => {
|
||||
const pattern = new RegExp(linkPatternSource, 'ig');
|
||||
// Find matches in the block, confirm the URL, create the entity, store the range.
|
||||
const matches = Array.from(blockText.matchAll(pattern), (match) => {
|
||||
const url = getValidLinkURL(match[1]);
|
||||
// Account for punctuation chars valid in URLs but unlikely to be intended.
|
||||
// For example "Go to https://example.com."
|
||||
// Terminal Punctuation class: see https://www.unicode.org/review/pr-23.html.
|
||||
const cleanURLPattern = match[1].replace(
|
||||
/\p{Terminal_Punctuation}$/u,
|
||||
'',
|
||||
);
|
||||
const url = getValidLinkURL(cleanURLPattern);
|
||||
|
||||
if (!url) return {};
|
||||
|
||||
@ -152,7 +159,7 @@ const insertContentWithLinks = (editorState, htmlOrText) => {
|
||||
|
||||
return {
|
||||
start: match.index,
|
||||
end: match.index + match[1].length,
|
||||
end: match.index + cleanURLPattern.length,
|
||||
key: content.getLastCreatedEntityKey(),
|
||||
};
|
||||
});
|
||||
|
@ -276,4 +276,45 @@ describe('onPasteLink', () => {
|
||||
1: { data: { url: 'http://test.co/' } },
|
||||
});
|
||||
});
|
||||
|
||||
it('skips linking punctuation chars', () => {
|
||||
const punctuation = {
|
||||
// Characters that will be removed.
|
||||
'.': '',
|
||||
'?': '',
|
||||
'!': '',
|
||||
':': '',
|
||||
';': '',
|
||||
',': '',
|
||||
// Syriac Harklean Metobelus
|
||||
'܌': '',
|
||||
'؟': '',
|
||||
'،': '',
|
||||
'‼': '',
|
||||
'﹒': '',
|
||||
// Characters that will be preserved.
|
||||
'…': '…',
|
||||
'-': '-',
|
||||
'_': '_',
|
||||
'–': '–',
|
||||
'+': '+',
|
||||
'=': '=',
|
||||
};
|
||||
const input = Object.keys(punctuation)
|
||||
.map((punc) => `<p><span>http://a.co/t${punc}/${punc}</span></p>`)
|
||||
.join(' ');
|
||||
const raw = testOnPasteOutput(input.replace(/<[^>]+/g), input);
|
||||
|
||||
expect(raw.blocks.map(({ text }) => text)).toMatchSnapshot();
|
||||
expect(
|
||||
Object.values(raw.entityMap).map((entity) => entity.data.url),
|
||||
).toMatchSnapshot();
|
||||
|
||||
const expectedLength = Object.keys(punctuation).map(
|
||||
(punc) => `http://a.co/t${punc}/`.length + punctuation[punc].length,
|
||||
);
|
||||
expect(
|
||||
raw.blocks.map(({ entityRanges }) => entityRanges[0].length),
|
||||
).toEqual(expectedLength);
|
||||
});
|
||||
});
|
||||
|
@ -67,3 +67,47 @@ exports[`Link works 1`] = `
|
||||
test
|
||||
</TooltipEntity>
|
||||
`;
|
||||
|
||||
exports[`onPasteLink skips linking punctuation chars 1`] = `
|
||||
[
|
||||
"http://a.co/t./.",
|
||||
"http://a.co/t?/?",
|
||||
"http://a.co/t!/!",
|
||||
"http://a.co/t:/:",
|
||||
"http://a.co/t;/;",
|
||||
"http://a.co/t,/,",
|
||||
"http://a.co/t܌/܌",
|
||||
"http://a.co/t؟/؟",
|
||||
"http://a.co/t،/،",
|
||||
"http://a.co/t‼/‼",
|
||||
"http://a.co/t﹒/﹒",
|
||||
"http://a.co/t…/…",
|
||||
"http://a.co/t-/-",
|
||||
"http://a.co/t_/_",
|
||||
"http://a.co/t–/–",
|
||||
"http://a.co/t+/+",
|
||||
"http://a.co/t=/=hello",
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`onPasteLink skips linking punctuation chars 2`] = `
|
||||
[
|
||||
"http://a.co/t./",
|
||||
"http://a.co/t?/",
|
||||
"http://a.co/t!/",
|
||||
"http://a.co/t:/",
|
||||
"http://a.co/t;/",
|
||||
"http://a.co/t,/",
|
||||
"http://a.co/t܌/",
|
||||
"http://a.co/t؟/",
|
||||
"http://a.co/t،/",
|
||||
"http://a.co/t‼/",
|
||||
"http://a.co/t﹒/",
|
||||
"http://a.co/t…/…",
|
||||
"http://a.co/t-/-",
|
||||
"http://a.co/t_/_",
|
||||
"http://a.co/t–/–",
|
||||
"http://a.co/t+/+",
|
||||
"http://a.co/t=/=",
|
||||
]
|
||||
`;
|
||||
|
Loading…
Reference in New Issue
Block a user