From a0faca0997d4e4680f54bd0c043cc6c360ecf3b3 Mon Sep 17 00:00:00 2001 From: Laurent Cozic Date: Sat, 27 Apr 2024 11:22:36 +0100 Subject: [PATCH] Chore: Improve link detection function --- .../NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx | 4 +- packages/utils/url.test.ts | 38 ++++++++++++++++++- packages/utils/url.ts | 14 ++++--- 3 files changed, 48 insertions(+), 8 deletions(-) diff --git a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx index 566ffa3a3..6a233248f 100644 --- a/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx +++ b/packages/app-desktop/gui/NoteEditor/NoteBody/TinyMCE/TinyMCE.tsx @@ -36,7 +36,7 @@ import { focus } from '@joplin/lib/utils/focusHandler'; const md5 = require('md5'); const { clipboard } = require('electron'); const supportedLocales = require('./supportedLocales'); -import { isLink } from '@joplin/utils/url'; +import { hasProtocol } from '@joplin/utils/url'; const logger = Logger.create('TinyMCE'); @@ -1195,7 +1195,7 @@ const TinyMCE = (props: NoteBodyEditorProps, ref: any) => { editor.insertContent(result.html); } } else { - if (BaseItem.isMarkdownTag(pastedText) || isLink(pastedText)) { // Paste a link to a note + if (BaseItem.isMarkdownTag(pastedText) || hasProtocol(pastedText, ['https', 'joplin', 'file'])) { // Paste a link to a note logger.info('onPaste: pasting as a Markdown tag'); const result = await markupToHtml.current(MarkupToHtml.MARKUP_LANGUAGE_MARKDOWN, pastedText, markupRenderOptions({ bodyOnly: true })); editor.insertContent(result.html); diff --git a/packages/utils/url.test.ts b/packages/utils/url.test.ts index cec4d73db..6538e6f97 100644 --- a/packages/utils/url.test.ts +++ b/packages/utils/url.test.ts @@ -1,4 +1,4 @@ -import { fileUriToPath } from './url'; +import { fileUriToPath, hasProtocol } from './url'; describe('utils/url', () => { @@ -28,4 +28,40 @@ describe('utils/url', () => { expect(fileUriToPath('file:///c:/AUTOEXEC.BAT', 'win32')).toBe('c:\\AUTOEXEC.BAT'); })); + test.each([ + [ + 'https://joplinapp.org', + 'https', + true, + ], + [ + 'https://joplinapp.org', + 'http', + false, + ], + [ + 'https://joplinapp.org', + ['http', 'https'], + true, + ], + [ + 'https://joplinapp.org', + [], + false, + ], + [ + '', + [], + false, + ], + [ + 'joplin://openNote?id=ABCD', + ['http', 'https', 'joplin'], + true, + ], + ])('should tell if a URL has a particular protocol', (url, protocol, expected) => { + const actual = hasProtocol(url, protocol); + expect(actual).toBe(expected); + }); + }); diff --git a/packages/utils/url.ts b/packages/utils/url.ts index f67bb0aa5..52987b4aa 100644 --- a/packages/utils/url.ts +++ b/packages/utils/url.ts @@ -101,9 +101,13 @@ export const isDataUrl = (path: string) => { return path.startsWith('data:'); }; -export const isLink = (text: string) => { - if (!text) return false; - const linkRegex = /^(https?|file|joplin):\/\/[^)\s]+$/; - return !!text.match(linkRegex); -}; +export const hasProtocol = (url: string, protocol: string | string[]) => { + if (!url) return false; + const protocols = typeof protocol === 'string' ? [protocol] : protocol; + url = url.toLowerCase(); + for (const p of protocols) { + if (url.startsWith(`${p.toLowerCase()}://`)) return true; + } + return false; +};