mirror of
https://github.com/zulip/zulip-desktop.git
synced 2025-11-02 04:53:17 +00:00
internal-links: open non-image links in hidden webview.
* This will make sure that the current server webview will not reload due to URL change. * Add an option to allow users to download the file attachments. Improves: #469.
This commit is contained in:
committed by
Akash Nimare
parent
60d693700e
commit
f70432f4e3
@@ -262,6 +262,11 @@ webview {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
webview.download-webview {
|
||||
z-index: -1;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
webview.onload {
|
||||
transition: opacity 1s cubic-bezier(0.95, 0.05, 0.795, 0.035);
|
||||
}
|
||||
|
||||
36
app/renderer/js/components/handle-external-link.js
Normal file
36
app/renderer/js/components/handle-external-link.js
Normal file
@@ -0,0 +1,36 @@
|
||||
const { shell } = require('electron').remote;
|
||||
const LinkUtil = require('../utils/link-util');
|
||||
const DomainUtil = require('../utils/domain-util');
|
||||
const hiddenWebView = require('../components/hidden-webview');
|
||||
|
||||
function handleExternalLink(event) {
|
||||
const { url } = event;
|
||||
const domainPrefix = DomainUtil.getDomain(this.props.index).url;
|
||||
|
||||
// Whitelist URLs which are allowed to be opened in the app
|
||||
const {
|
||||
isInternalUrl: isWhiteListURL,
|
||||
isUploadsUrl: isUploadsURL
|
||||
} = LinkUtil.isInternal(domainPrefix, url);
|
||||
|
||||
if (isWhiteListURL) {
|
||||
event.preventDefault();
|
||||
|
||||
// only open the pdf, mp3, mp4 etc.. in hidden webview since opening the
|
||||
// image in webview will do nothing and will not save it
|
||||
// whereas the pdf will be saved to user desktop once openened in
|
||||
// in the hidden webview and will not trigger webview reload
|
||||
if (!LinkUtil.isImage(url) && isUploadsURL) {
|
||||
hiddenWebView.loadURL(url);
|
||||
return;
|
||||
}
|
||||
|
||||
// open internal urls inside the current webview.
|
||||
this.$el.loadURL(url);
|
||||
} else {
|
||||
event.preventDefault();
|
||||
shell.openExternal(url);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = handleExternalLink;
|
||||
9
app/renderer/js/components/hidden-webview.js
Normal file
9
app/renderer/js/components/hidden-webview.js
Normal file
@@ -0,0 +1,9 @@
|
||||
// this hidden webview will be used to open pdf url and
|
||||
// save it to user's computer without triggering a reload
|
||||
// when navigating to pdf url to download it.
|
||||
const hiddenWebView = document.createElement('webview');
|
||||
hiddenWebView.classList.add('download-webview');
|
||||
hiddenWebView.src = 'about:blank';
|
||||
document.querySelector('#webviews-container').appendChild(hiddenWebView);
|
||||
|
||||
module.exports = hiddenWebView;
|
||||
@@ -3,13 +3,12 @@
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
|
||||
const DomainUtil = require(__dirname + '/../utils/domain-util.js');
|
||||
const ConfigUtil = require(__dirname + '/../utils/config-util.js');
|
||||
const SystemUtil = require(__dirname + '/../utils/system-util.js');
|
||||
const LinkUtil = require(__dirname + '/../utils/link-util.js');
|
||||
const { shell, app, dialog } = require('electron').remote;
|
||||
const { app, dialog } = require('electron').remote;
|
||||
|
||||
const BaseComponent = require(__dirname + '/../components/base.js');
|
||||
const handleExternalLink = require(__dirname + '/../components/handle-external-link.js');
|
||||
|
||||
const shouldSilentWebview = ConfigUtil.getConfigItem('silent');
|
||||
class WebView extends BaseComponent {
|
||||
@@ -46,22 +45,7 @@ class WebView extends BaseComponent {
|
||||
|
||||
registerListeners() {
|
||||
this.$el.addEventListener('new-window', event => {
|
||||
const { url } = event;
|
||||
const domainPrefix = DomainUtil.getDomain(this.props.index).url;
|
||||
|
||||
// Whitelist URLs which are allowed to be opened in the app
|
||||
const isWhiteListURL =
|
||||
LinkUtil.isInternal(domainPrefix, url) ||
|
||||
url === domainPrefix + '/' ||
|
||||
url.includes(domainPrefix + '/user_uploads/'); // URL containing the file attachments
|
||||
|
||||
if (isWhiteListURL) {
|
||||
event.preventDefault();
|
||||
this.$el.loadURL(url);
|
||||
} else {
|
||||
event.preventDefault();
|
||||
shell.openExternal(url);
|
||||
}
|
||||
handleExternalLink.call(this, event);
|
||||
});
|
||||
|
||||
if (shouldSilentWebview) {
|
||||
|
||||
@@ -19,7 +19,14 @@ class LinkUtil {
|
||||
const currentDomain = wurl('hostname', currentUrl);
|
||||
const newDomain = wurl('hostname', newUrl);
|
||||
|
||||
return (currentDomain === newDomain) && newUrl.includes('/#narrow');
|
||||
const sameDomainUrl = (currentDomain === newDomain || newUrl === currentUrl + '/');
|
||||
const isUploadsUrl = newUrl.includes(currentUrl + '/user_uploads/');
|
||||
const isInternalUrl = newUrl.includes('/#narrow') || isUploadsUrl;
|
||||
|
||||
return {
|
||||
isInternalUrl: sameDomainUrl && isInternalUrl,
|
||||
isUploadsUrl
|
||||
};
|
||||
}
|
||||
|
||||
isImage(url) {
|
||||
|
||||
Reference in New Issue
Block a user