mirror of
https://github.com/fastmail/Squire.git
synced 2024-12-22 15:23:29 -05:00
Introduce linkRegExpHandlers
A map of capture groups to functions for producing the href of a link. By default, it is e.g. used to prepend https:// to links matching on www. so they are not interpreted as relative. The user can add their own handlers if modifying linkRegExp. Signed-off-by: Øyvind Rønningstad <ronningstad@gmail.com>
This commit is contained in:
parent
2e97618f17
commit
ec0c3e612a
3 changed files with 18 additions and 9 deletions
|
@ -475,4 +475,8 @@ This is useful when the document needs to be changed programmatically, but those
|
||||||
|
|
||||||
### linkRegExp
|
### 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. To append to the existing regex, set it to `linkRegExp.source + '|' + newLinkRegExp`.
|
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`. For compatibility with linkRegExpHandlers use named capture groups (`?<name>`).
|
||||||
|
|
||||||
|
### linkRegExpHandlers
|
||||||
|
|
||||||
|
This is a map of handlers for different types of matches in linkRegExp. For example, linkRegExp has a named group 'url' that matches urls, and a named group 'email' that matches emails. linkRegExpHandler['url'] and linkRegExpHandler['email'] are functions that take in the matching string and returns what the link should have in its 'href'.
|
||||||
|
|
|
@ -1789,7 +1789,11 @@ class Squire {
|
||||||
*/
|
*/
|
||||||
linkRegExp =
|
linkRegExp =
|
||||||
/\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;
|
/\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 = {}
|
linkRegExpHandlers = {
|
||||||
|
'url': (m) => {return /^(?:[a-z+]+:)?\/\//i.test(m)
|
||||||
|
? m : 'https://' + m},
|
||||||
|
'email': (m) => {return 'mailto:' + m},
|
||||||
|
'default': (m) => {return m}};
|
||||||
addDetectedLinks(
|
addDetectedLinks(
|
||||||
searchInNode: DocumentFragment | Node,
|
searchInNode: DocumentFragment | Node,
|
||||||
root?: DocumentFragment | HTMLElement,
|
root?: DocumentFragment | HTMLElement,
|
||||||
|
@ -1815,17 +1819,14 @@ class Squire {
|
||||||
node,
|
node,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
let handler = Object.keys(this.linkRegExpHandlers).filter(
|
||||||
|
key => Object.keys(match.groups).includes(key) && match.groups[key])[0]
|
||||||
|
|| 'default';
|
||||||
const child = createElement(
|
const child = createElement(
|
||||||
'A',
|
'A',
|
||||||
Object.assign(
|
Object.assign(
|
||||||
{
|
{
|
||||||
href: match.groups['url']
|
href: this.linkRegExpHandlers[handler](match[0])
|
||||||
? /^(?:[a-z+]+:)?\/\//i.test(match[0])
|
|
||||||
? match[0]
|
|
||||||
: 'https://' + match[0]
|
|
||||||
: match.groups['email']
|
|
||||||
? 'mailto:' + match[0]
|
|
||||||
: match[0],
|
|
||||||
},
|
},
|
||||||
defaultAttributes,
|
defaultAttributes,
|
||||||
),
|
),
|
||||||
|
|
|
@ -487,10 +487,14 @@ describe('Squire RTE', () => {
|
||||||
'https://google.com?a=b&c=d&e=': 'https://google.com/?a=b&c=d&e=',
|
'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',
|
'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
|
'www.google.com': 'https://www.google.com/', // Test prepending protocol
|
||||||
|
'foobar': 'http://localhost/foobar', // Test default handler
|
||||||
|
'search': 'http://localhost/replace', // Test custom handler
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(LINK_MAP).forEach((input) => {
|
Object.keys(LINK_MAP).forEach((input) => {
|
||||||
it('should auto convert links to anchor: ' + input, () => {
|
it('should auto convert links to anchor: ' + input, () => {
|
||||||
|
editor.linkRegExp = new RegExp(editor.linkRegExp.source + "|(foobar)|(?<extra>search)", editor.linkRegExp.flags);
|
||||||
|
editor.linkRegExpHandlers['extra'] = (m) => {return 'replace'};
|
||||||
editor.insertHTML(input);
|
editor.insertHTML(input);
|
||||||
const link = document.querySelector('a')!;
|
const link = document.querySelector('a')!;
|
||||||
expect(link.href).toBe(LINK_MAP[input]);
|
expect(link.href).toBe(LINK_MAP[input]);
|
||||||
|
|
Loading…
Reference in a new issue