keeweb/app/scripts/comp/popup-notifier.js

142 lines
4.6 KiB
JavaScript

const Backbone = require('backbone');
const Alerts = require('./alerts');
const Launcher = require('./launcher');
const AuthReceiver = require('./auth-receiver');
const Links = require('../const/links');
const Timeouts = require('../const/timeouts');
const Locale = require('../util/locale');
const Logger = require('../util/logger');
const PopupNotifier = {
logger: null,
init: function() {
this.logger = new Logger('popup-notifier');
if (Launcher) {
window.open = this._openLauncherWindow.bind(this);
} else {
const windowOpen = window.open;
window.open = function() {
const win = windowOpen.apply(window, arguments);
if (win) {
PopupNotifier.deferCheckClosed(win);
Backbone.trigger('popup-opened', win);
} else {
if (!Alerts.alertDisplayed) {
Alerts.error({
header: Locale.authPopupRequired,
body: Locale.authPopupRequiredBody
});
}
}
return win;
};
}
},
_openLauncherWindow: function(url, title, settings) {
const opts = {
show: false,
webPreferences: {
nodeIntegration: false,
webSecurity: false,
allowDisplayingInsecureContent: true,
allowRunningInsecureContent: true
}
};
if (settings) {
const settingsObj = {};
settings.split(',').forEach(part => {
const parts = part.split('=');
settingsObj[parts[0].trim()] = parts[1].trim();
});
if (settingsObj.width) {
opts.width = +settingsObj.width;
}
if (settingsObj.height) {
opts.height = +settingsObj.height;
}
if (settingsObj.top) {
opts.y = +settingsObj.top;
}
if (settingsObj.left) {
opts.x = +settingsObj.left;
}
}
let win = Launcher.openWindow(opts);
win.webContents.on('will-redirect', (e, url) => {
if (PopupNotifier.isOwnUrl(url)) {
win.webContents.stop();
win.close();
PopupNotifier.processReturnToApp(url);
}
});
win.webContents.on('will-navigate', (e, url) => {
if (PopupNotifier.isOwnUrl(url)) {
e.preventDefault();
win.close();
PopupNotifier.processReturnToApp(url);
}
});
win.webContents.on('crashed', (e, killed) => {
this.logger.debug('crashed', e, killed);
this.deferCheckClosed(win);
win.close();
win = null;
});
win.webContents.on('did-fail-load', (e, errorCode, errorDescription, validatedUrl, isMainFrame) => {
this.logger.debug('did-fail-load', e, errorCode, errorDescription, validatedUrl, isMainFrame);
this.deferCheckClosed(win);
win.close();
win = null;
});
win.once('page-title-updated', () => {
setTimeout(() => {
if (win) {
win.show();
win.focus();
}
}, Timeouts.PopupWaitTime);
});
win.on('closed', () => {
setTimeout(PopupNotifier.triggerClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
win = null;
});
win.loadURL(url);
Backbone.trigger('popup-opened', win);
return win;
},
isOwnUrl(url) {
return url.lastIndexOf(Links.WebApp, 0) === 0 || url.lastIndexOf(location.origin + location.pathname, 0) === 0;
},
processReturnToApp: function(url) {
const returnMessage = AuthReceiver.urlArgsToMessage(url);
if (Object.keys(returnMessage).length > 0) {
const evt = new Event('message');
evt.data = returnMessage;
window.dispatchEvent(evt);
}
},
deferCheckClosed: function(win) {
setTimeout(PopupNotifier.checkClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
},
checkClosed: function(win) {
if (win.closed) {
setTimeout(PopupNotifier.triggerClosed.bind(PopupNotifier, win), Timeouts.CheckWindowClosed);
} else {
PopupNotifier.deferCheckClosed(win);
}
},
triggerClosed: function(win) {
Backbone.trigger('popup-closed', win);
}
};
module.exports = PopupNotifier;