From dd14385cb439fad5f4a8aaa596a91037764a751d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20H=C3=A4usler?= Date: Sun, 20 Feb 2022 13:52:37 +0100 Subject: [PATCH] fix clickable HTML links on Windows (#3015) (#3033) --- src/main/menu/actions/file.js | 14 ++++++++++---- src/muya/lib/utils/markdownFile.js | 24 ++++++++++++++++++++++++ src/muya/lib/utils/url.js | 18 ++++++++++++++++-- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100755 src/muya/lib/utils/markdownFile.js diff --git a/src/main/menu/actions/file.js b/src/main/menu/actions/file.js index ff44b711..4197d811 100644 --- a/src/main/menu/actions/file.js +++ b/src/main/menu/actions/file.js @@ -415,15 +415,20 @@ ipcMain.on('mt::format-link-click', (e, { data, dirname }) => { return } - const href = data.href || data.text - if (URL_REG.test(href)) { - shell.openExternal(href) + const urlCandidate = data.href || data.text + if (URL_REG.test(urlCandidate)) { + shell.openExternal(urlCandidate) return - } else if (/^[a-z0-9]+:\/\//i.test(href)) { + } else if (/^[a-z0-9]+:\/\//i.test(urlCandidate)) { // Prevent other URLs. return } + const href = data.href + if (!href) { + return + } + let pathname = null if (path.isAbsolute(href)) { pathname = href @@ -432,6 +437,7 @@ ipcMain.on('mt::format-link-click', (e, { data, dirname }) => { } if (pathname) { + pathname = path.normalize(pathname) if (isMarkdownFile(pathname)) { const win = BrowserWindow.fromWebContents(e.sender) openFileOrFolder(win, pathname) diff --git a/src/muya/lib/utils/markdownFile.js b/src/muya/lib/utils/markdownFile.js new file mode 100755 index 00000000..627f6af4 --- /dev/null +++ b/src/muya/lib/utils/markdownFile.js @@ -0,0 +1,24 @@ +// __MARKTEXT_ONLY__ + +const MARKDOWN_EXTENSIONS = Object.freeze([ + 'markdown', + 'mdown', + 'mkdn', + 'md', + 'mkd', + 'mdwn', + 'mdtxt', + 'mdtext', + 'text', + 'txt' +]) + +/** + * Returns true if the filename matches one of the markdown extensions allowed in MarkText. + * + * @param {string} filename Path or filename + */ +export const hasMarkdownExtension = filename => { + if (!filename || typeof filename !== 'string') return false + return MARKDOWN_EXTENSIONS.some(ext => filename.toLowerCase().endsWith(`.${ext}`)) +} diff --git a/src/muya/lib/utils/url.js b/src/muya/lib/utils/url.js index f6515841..885a4db8 100644 --- a/src/muya/lib/utils/url.js +++ b/src/muya/lib/utils/url.js @@ -1,8 +1,22 @@ import { isValidAttribute } from '../utils/dompurify' +import { isWin } from '../config' // __MARKTEXT_PATCH__ +import { hasMarkdownExtension } from './markdownFile' // __MARKTEXT_PATCH__ export const sanitizeHyperlink = rawLink => { - if (rawLink && typeof rawLink === 'string' && isValidAttribute('a', 'href', rawLink)) { - return rawLink + if (rawLink && typeof rawLink === 'string') { + if (isValidAttribute('a', 'href', rawLink)) { + return rawLink + } + + // __MARKTEXT_PATCH__ + if (isWin && /^[a-zA-Z]:[/\\].+/.test(rawLink) && hasMarkdownExtension(rawLink)) { + // Create and try UNC path on Windows because "C:\file.md" isn't allowed. + const uncPath = `\\\\?\\${rawLink}` + if (isValidAttribute('a', 'href', uncPath)) { + return uncPath + } + } + // END __MARKTEXT_PATCH__ } return '' }