diff --git a/ElectronClient/app/gui/NoteText.jsx b/ElectronClient/app/gui/NoteText.jsx
index 63177b259..28efa7890 100644
--- a/ElectronClient/app/gui/NoteText.jsx
+++ b/ElectronClient/app/gui/NoteText.jsx
@@ -6,6 +6,7 @@ const Search = require('lib/models/Search.js');
const { time } = require('lib/time-utils.js');
const Setting = require('lib/models/Setting.js');
const { IconButton } = require('./IconButton.min.js');
+const { urlDecode } = require('lib/string-utils');
const Toolbar = require('./Toolbar.min.js');
const { connect } = require('react-redux');
const { _ } = require('lib/locale.js');
@@ -569,7 +570,12 @@ class NoteTextComponent extends React.Component {
throw new Error('Unsupported item type: ' + item.type_);
}
} else if (urlUtils.urlProtocol(msg)) {
- require('electron').shell.openExternal(msg);
+ if (msg.indexOf('file://') === 0) {
+ // When using the file:// protocol, openExternal doesn't work (does nothing) with URL-encoded paths
+ require('electron').shell.openExternal(urlDecode(msg));
+ } else {
+ require('electron').shell.openExternal(msg);
+ }
} else {
bridge().showErrorMessageBox(_('Unsupported link or message: %s', msg));
}
diff --git a/ElectronClient/app/gui/note-viewer/index.html b/ElectronClient/app/gui/note-viewer/index.html
index 342df9221..3b66f3136 100644
--- a/ElectronClient/app/gui/note-viewer/index.html
+++ b/ElectronClient/app/gui/note-viewer/index.html
@@ -276,6 +276,15 @@
}
});
+ // Prevent URLs added via tags from being opened within the application itself
+ document.addEventListener('click', function(event) {
+ const t = event.target;
+ if (t && t.nodeName === 'A' && !t.hasAttribute('data-from-md')) {
+ event.preventDefault();
+ ipcProxySendToHost(t.getAttribute('href'));
+ }
+ });
+
// Disable drag and drop otherwise it's possible to drop a URL
// on it and it will open in the view as a website.
document.addEventListener('drop', function(e) {
diff --git a/ReactNativeClient/lib/MdToHtml.js b/ReactNativeClient/lib/MdToHtml.js
index d7c0f8fb0..15ea78b89 100644
--- a/ReactNativeClient/lib/MdToHtml.js
+++ b/ReactNativeClient/lib/MdToHtml.js
@@ -102,7 +102,7 @@ class MdToHtml {
const href = this.getAttr_(attrs, 'src');
if (!Resource.isResourceUrl(href)) {
- return '';
+ return '';
}
const resourceId = Resource.urlToId(href);
@@ -118,7 +118,7 @@ class MdToHtml {
if (Resource.isSupportedImageMimeType(mime)) {
let src = './' + Resource.filename(resource);
if (this.resourceBaseUrl_ !== null) src = this.resourceBaseUrl_ + src;
- let output = '';
+ let output = '';
return output;
}
@@ -167,7 +167,7 @@ class MdToHtml {
}
const js = options.postMessageSyntax + "(" + JSON.stringify(href) + "); return false;";
- let output = "" + icon;
+ let output = "" + icon;
return output;
}
@@ -487,7 +487,7 @@ class MdToHtml {
while (renderedBody.indexOf('mJOPm') >= 0) {
renderedBody = renderedBody.replace(/mJOPmCHECKBOXm([A-Z]+)m(\d+)m/, function(v, type, index) {
const js = options.postMessageSyntax + "('checkboxclick:" + type + ':' + index + "'); this.classList.contains('tick') ? this.classList.remove('tick') : this.classList.add('tick'); return false;";
- return '' + '' + '';
+ return '' + '' + '';
});
if (loopCount++ >= 9999) break;
}
diff --git a/ReactNativeClient/lib/string-utils.js b/ReactNativeClient/lib/string-utils.js
index 13256d901..780ac000c 100644
--- a/ReactNativeClient/lib/string-utils.js
+++ b/ReactNativeClient/lib/string-utils.js
@@ -206,4 +206,8 @@ function toTitleCase(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
+function urlDecode(string) {
+ return decodeURIComponent((string+'').replace(/\+/g, '%20'));
+}
+
module.exports = { removeDiacritics, escapeFilename, wrap, splitCommandString, padLeft, toTitleCase };
\ No newline at end of file