diff --git a/CliClient/tests/urlUtils.js b/CliClient/tests/urlUtils.js index c4e67ce09d..9a893a3238 100644 --- a/CliClient/tests/urlUtils.js +++ b/CliClient/tests/urlUtils.js @@ -1,5 +1,6 @@ require('app-module-path').addPath(__dirname); +const { asyncTest } = require('test-utils.js'); const urlUtils = require('lib/urlUtils.js'); process.on('unhandledRejection', (reason, p) => { @@ -12,7 +13,7 @@ describe('urlUtils', function() { done(); }); - it('should prepend a base URL', async (done) => { + it('should prepend a base URL', asyncTest(async (done) => { expect(urlUtils.prependBaseUrl('testing.html', 'http://example.com')).toBe('http://example.com/testing.html'); expect(urlUtils.prependBaseUrl('testing.html', 'http://example.com/')).toBe('http://example.com/testing.html'); expect(urlUtils.prependBaseUrl('/jmp/?id=123&u=http://something.com/test', 'http://example.com/')).toBe('http://example.com/jmp/?id=123&u=http://something.com/test'); @@ -29,8 +30,29 @@ describe('urlUtils', function() { expect(urlUtils.prependBaseUrl('javascript:var%20testing=true', 'http://example.com')).toBe('javascript:var%20testing=true'); expect(urlUtils.prependBaseUrl('http://alreadyabsolute.com', 'http://example.com')).toBe('http://alreadyabsolute.com'); expect(urlUtils.prependBaseUrl('#local-anchor', 'http://example.com')).toBe('#local-anchor'); + })); - done(); - }); + it('should detect resource URLs', asyncTest(async (done) => { + const testCases = [ + [':/1234abcd1234abcd1234abcd1234abcd', { itemId: '1234abcd1234abcd1234abcd1234abcd', hash: '' }], + [':/1234abcd1234abcd1234abcd1234abcd#hash', { itemId: '1234abcd1234abcd1234abcd1234abcd', hash: 'hash' }], + ['joplin://1234abcd1234abcd1234abcd1234abcd', { itemId: '1234abcd1234abcd1234abcd1234abcd', hash: '' }], + ['joplin://1234abcd1234abcd1234abcd1234abcd#hash', { itemId: '1234abcd1234abcd1234abcd1234abcd', hash: 'hash' }], + [':/1234abcd1234abcd1234abcd1234abc', null], + ['joplin://1234abcd1234abcd1234abcd1234abc', null], + ]; + + for (const t of testCases) { + const u = urlUtils.parseResourceUrl(t[0]); + const expected = t[1]; + + if (!expected) { + expect(!u).toBe(true); + } else { + expect(u.itemId).toBe(expected.itemId); + expect(u.hash).toBe(expected.hash); + } + } + })); }); diff --git a/ReactNativeClient/lib/renderers/MdToHtml/rules/link_open.js b/ReactNativeClient/lib/renderers/MdToHtml/rules/link_open.js index 4fe6e6c9f0..174829889c 100644 --- a/ReactNativeClient/lib/renderers/MdToHtml/rules/link_open.js +++ b/ReactNativeClient/lib/renderers/MdToHtml/rules/link_open.js @@ -8,7 +8,7 @@ function installRule(markdownIt, mdOptions, ruleOptions) { const token = tokens[idx]; let href = utils.getAttr(token.attrs, 'href'); const resourceHrefInfo = urlUtils.parseResourceUrl(href); - const isResourceUrl = !!resourceHrefInfo.itemId; + const isResourceUrl = !!resourceHrefInfo; const title = isResourceUrl ? utils.getAttr(token.attrs, 'title') : href; let resourceIdAttr = ''; diff --git a/ReactNativeClient/lib/urlUtils.js b/ReactNativeClient/lib/urlUtils.js index bc31177cc4..565737559e 100644 --- a/ReactNativeClient/lib/urlUtils.js +++ b/ReactNativeClient/lib/urlUtils.js @@ -39,7 +39,13 @@ urlUtils.prependBaseUrl = function(url, baseUrl) { } }; +urlUtils.isResourceUrl = function(url) { + return !!url.match(/^(joplin:\/\/|:\/)[0-9a-zA-Z]{32}(|#.*)$/); +}; + urlUtils.parseResourceUrl = function(url) { + if (!urlUtils.isResourceUrl(url)) return null; + const filename = url.split('/').pop(); const splitted = filename.split('#');