0
Fork 0
mirror of https://github.com/fastmail/Squire.git synced 2024-12-22 07:13:08 -05:00

Improve linkRegExp

Solves/improves the following:
- Setting a custom linkRegExp messes with the logic for adding
  protocol or mailto. Use named capture groups in the regex, and
  add a case in the href generation that just uses the match
  directly if neither the url nor the email regex matches, which
  would mean that the user's custom regex matched instead.
- Make https the default protocol instead of http
- Use a more general regex for matching the protocol.

Signed-off-by: Øyvind Rønningstad <ronningstad@gmail.com>
This commit is contained in:
Øyvind Rønningstad 2024-01-13 21:06:44 +01:00
parent 8bee51683b
commit 2e97618f17
3 changed files with 16 additions and 13 deletions

View file

@ -475,4 +475,4 @@ This is useful when the document needs to be changed programmatically, but those
### linkRegExp
This is the regular expression used to automatically mark up links when inserting HTML or after pressing space. You can change it if you want to use a custom regular expression for detecting links, or set to `/[]/` to turn off link detection.
This is the regular expression used to automatically mark up links when inserting HTML or after pressing space. You can change it if you want to use a custom regular expression for detecting links, or set to `/[]/` to turn off link detection. To append to the existing regex, set it to `linkRegExp.source + '|' + newLinkRegExp`.

View file

@ -1741,7 +1741,7 @@ class Squire {
// Only look on boundaries
'\\b(?:' +
// Capture group 1: URLs
'(' +
'(?<url>' +
// Add links to URLS
// Starts with:
'(?:' +
@ -1775,7 +1775,7 @@ class Squire {
'\\([^\\s()<>]+\\)' +
')' +
// Capture group 2: Emails
')|(' +
')|(?<email>' +
// Add links to emails
'[\\w\\-.%+]+@(?:[\\w\\-]+\\.)+[a-z]{2,}\\b' +
// Allow query parameters in the mailto: style
@ -1788,8 +1788,8 @@ class Squire {
);
*/
linkRegExp =
/\b(?:((?:(?:ht|f)tps?:\/\/|www\d{0,3}[.]|[a-z0-9][a-z0-9.\-]*[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:[^\s?&`!()\[\]{};:'".,<>«»“”‘’]|\([^\s()<>]+\)))|([\w\-.%+]+@(?:[\w\-]+\.)+[a-z]{2,}\b(?:[?][^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+(?:&[^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+)*)?))/i;
/\b(?:(?<url>(?:(?:[a-z+]+:)?\/\/|www\d{0,3}[.]|[a-z0-9][a-z0-9.\-]*[.][a-z]{2,}\/)(?:[^\s()<>]+|\([^\s()<>]+\))+(?:[^\s?&`!()\[\]{};:'".,<>«»“”‘’]|\([^\s()<>]+\)))|(?<email>[\w\-.%+]+@(?:[\w\-]+\.)+[a-z]{2,}\b(?:[?][^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+(?:&[^&?\s]+=[^\s?&`!()\[\]{};:'".,<>«»“”‘’]+)*)?))/i;
linkRegExpHandlers = {}
addDetectedLinks(
searchInNode: DocumentFragment | Node,
root?: DocumentFragment | HTMLElement,
@ -1819,11 +1819,13 @@ class Squire {
'A',
Object.assign(
{
href: match[1]
? /^(?:ht|f)tps?:/i.test(match[1])
? match[1]
: 'http://' + match[1]
: 'mailto:' + match[0],
href: match.groups['url']
? /^(?:[a-z+]+:)?\/\//i.test(match[0])
? match[0]
: 'https://' + match[0]
: match.groups['email']
? 'mailto:' + match[0]
: match[0],
},
defaultAttributes,
),

View file

@ -472,9 +472,9 @@ describe('Squire RTE', () => {
'https://google.com': 'https://google.com/',
'https://www.google.com': 'https://www.google.com/',
'https://www.google.com/': 'https://www.google.com/',
'https://google.com/?': 'https://google.com/',
'https://google.com?': 'https://google.com/',
'https://google.com?a': 'https://google.com/?a',
'HTTPS://google.com/?': 'https://google.com/', // Test protocol matching
'ftp://google.com?': 'ftp://google.com/', // Test protocol matching
'redis://google.com?a': 'redis://google.com?a', // Test protocol matching
'https://google.com?a=': 'https://google.com/?a=',
'https://google.com?a=b': 'https://google.com/?a=b',
'https://google.com?a=b?': 'https://google.com/?a=b',
@ -486,6 +486,7 @@ describe('Squire RTE', () => {
'https://google.com?a=b&c=d&': 'https://google.com/?a=b&c=d',
'https://google.com?a=b&c=d&e=': 'https://google.com/?a=b&c=d&e=',
'https://google.com?a=b&c=d&e=f': 'https://google.com/?a=b&c=d&e=f',
'www.google.com': 'https://www.google.com/', // Test prepending protocol
};
Object.keys(LINK_MAP).forEach((input) => {