-
-
Save Harti/47c88e2e1f7453bed70fe0eee5a4260c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Class WebAppWindow | |
*/ | |
class WebAppWindow { | |
/** | |
* Constructs a WebAppWindow instance | |
* @param {String or Object} profile Either the profile ID or a complete profile object | |
* @param {Function} cbSuccess Callback function to be called on success | |
* @param {Function} cbFailure Callback function to be called on failure | |
*/ | |
constructor(profile, cbSuccess, cbFailure) { | |
this.isHidden = true; | |
this.nwWindow = null; | |
this.webappVersion = null; | |
this.cancelled = false; | |
this.showWebAppOnLoaded = true; | |
this.notifier = null; | |
this.zoomNotification = null; | |
this.onOpenListenerInstalled = false; | |
this.cbSuccess = cbSuccess; | |
this.cbFailure = cbFailure; | |
this.webAppSettings = {}; | |
switch (typeof profile) { | |
case 'string': | |
this.profile = JSON.parse(JSON.stringify(global.settings.profiles[profile])); | |
break; | |
case 'object': | |
this.profile = JSON.parse(JSON.stringify(profile)); | |
break; | |
default: | |
this.cbFailure({ | |
message: global.gt.gettext('Failed to load profile.'), | |
MAPI_E: null | |
}); | |
break; | |
} | |
this.useSSO = this.profile.authType === 'sso'; | |
this.windowOptions = { | |
'title': 'Kopano DeskApp', | |
'width': 1366, | |
'height': 768, | |
'id': 'webapp_' + this.profile.id, | |
'show': false, | |
'inject_js_start': "app/injection/inject_start.js", | |
'inject_js_end': "app/injection/inject_end.js" | |
}; | |
} | |
/** | |
* Remove all WebApp Cookies | |
* @param {NWWindow} win The NWWindow that should be used for removing | |
* @param {String} url The url to clean up the cookies for | |
*/ | |
static removeWebappCookies(win, url, callback) { | |
let count = 0; | |
win.cookies.getAll({ | |
url: url.replace("index.php?logon", "") | |
}, | |
function(cookies) { | |
if (cookies.length === 0) { | |
callback(); | |
} | |
for (let cookie of cookies) { | |
console.log("Removing cookie:", cookie.name); | |
win.cookies.remove({ | |
url: url.replace("index.php?logon", ""), | |
name: cookie.name | |
}, | |
(details) => { | |
count++; | |
if (count >= cookies.length) { | |
callback(); | |
} | |
}); | |
} | |
} | |
); | |
} | |
/** | |
* Compares and saves the current webapp version to the previous one. | |
* If it has changed the cache is cleared. | |
* @param {String} curVer current webapp version string | |
*/ | |
static clearCache(curVer) { | |
var lastVer = global.settings.general.lastWebappVersion || null; | |
if (!curVer || (curVer === lastVer)) { | |
return; | |
} | |
global.settings.general.lastWebappVersion = curVer; | |
global.DA.saveSettings(); | |
nw.App.clearCache(); | |
} | |
/** | |
* Create a NWWindow and login to webapp | |
*/ | |
createWindowAndLogin() { | |
this.visibleWindow = global.DA.winWelcome.window; | |
WebAppWindow.removeWebappCookies(global.DA.winWelcome, this.getUrl(this.profile.requestOptions.url), () => {this.login()}); | |
} | |
getUrl(url) { | |
if(!this.profile.requestOptions.url.match(/^https.*/)) | |
{ | |
return this.profile.requestOptions.url.replace("//", "https://"); | |
} | |
return url; | |
} | |
/** | |
* Create or reload the window for webapp | |
*/ | |
createOrReloadWindow() { | |
let url = this.getUrl(this.profile.requestOptions.url.replace("index.php?logon", "")); | |
if (this.nwWindow && this.nwWindow.window && this.nwWindow.window.location.href === url) { | |
this.reload(); | |
return; | |
} | |
nw.Window.open(url, this.windowOptions, (win) => { | |
if (!win) { | |
return; | |
} | |
this.nwWindow = win; | |
global.DA.winWebApp = win; | |
this.setWebAppListeners(); | |
}); | |
} | |
/** | |
* Validates profile without creating a NWWindow. | |
*/ | |
validateAccountfromPreferences() { | |
this.visibleWindow = global.DA.winPreferences.window; | |
WebAppWindow.removeWebappCookies(global.DA.winWelcome, this.getUrl(this.profile.requestOptions.url), () => {this.login(false)}); | |
} | |
/** | |
* Runs a login and checks if it was successful. | |
*/ | |
login(openWindow = true) { | |
this.destroySession(); | |
var req = { | |
id: -1, | |
headerXZarafaHresult: undefined, | |
headerXZarafa: undefined, | |
redirect301: false, | |
wwwAuthMethods: {}, | |
}; | |
/** | |
* Remove all webRequest handlers set up by login. | |
*/ | |
function removeWebRequestHandlers() { | |
['onBeforeRequest', 'onHeadersReceived', 'onCompleted', 'onAuthRequired', 'onErrorOccurred'] | |
.forEach(function(item) { | |
chrome.webRequest[item].removeListener(webRequestHandlers[item + 'Handler']); | |
}); | |
} | |
/* webRequest eventhandler functions */ | |
let webRequestHandlers = { | |
/** | |
* Event handler for the onBeforeRequest event | |
* Sets the request id that should be watched | |
* @param {Object} details the details of the request | |
* @return {BlockingResponse} only if the user aborted the login | |
*/ | |
onBeforeRequestHandler: (details) => { | |
if (req.id === -1) { | |
req.id = details.requestId; | |
} | |
if (this.cancelled) { | |
return { | |
cancel: true | |
}; | |
} | |
}, | |
/** | |
* Event handler for the onHeadersReceived event | |
* Determines if the request was successful by analyzing the received headers | |
* @param {Object} details the details of the request | |
* @return {BlockingResponse} only if the user aborted the login | |
*/ | |
onHeadersReceivedHandler: (details) => { | |
if (details.requestId !== req.id) { | |
return; | |
} | |
if (this.cancelled) { | |
return { | |
cancel: true | |
}; | |
} | |
for (var i = 0; i < details.responseHeaders.length; i++) { | |
let header = details.responseHeaders[i]; | |
switch (header.name.toLowerCase()) { | |
case "x-zarafa-hresult": | |
req.headerXZarafaHresult = header.value; | |
break; | |
case "x-zarafa": | |
req.headerXZarafa = header.value; | |
this.webappVersion = header.value; | |
WebAppWindow.clearCache(header.value); | |
break; | |
case "www-authenticate": | |
req.wwwAuthMethods[header.value.split(' ')[0]] = true; | |
break; | |
case 'location': | |
req.location = header.value; | |
break; | |
} | |
} | |
console.log("HTTP statuscode: " + details.statusCode); | |
if (details.statusCode === 301) { | |
req.redirect301 = true; | |
this.profile.requestOptions.url = this.getUrl(req.location + 'index.php?logon'); | |
} | |
req.statusCode = details.statusCode; | |
}, | |
/** | |
* Event handler for the onAuthRequired event | |
* Determines if the request was successful by analyzing the received headers | |
* @param {Object} details the details of the request | |
* @param {Function} callbackFn Callback function that returns the auth object | |
* @return {BlockingResponse} can cancel the request or return auth credentials | |
*/ | |
onAuthRequiredHandler: (details, callbackFn) => { | |
if (details.requestId !== req.id) { | |
return; | |
} | |
if (this.cancelled) { | |
callbackFn({ | |
cancel: true | |
}); | |
} | |
if (!details.isProxy && (details.scheme === 'basic' || details.scheme === 'digest')) { | |
callbackFn({ | |
'authCredentials': { | |
'username': this.profile.requestOptions.form.username, | |
'password': DAEncryption.decrypt(this.profile.requestOptions.form.password) | |
} | |
}); | |
} else { | |
if (details.statusCode === 401) { | |
req.isProxy = details.isProxy; | |
this.onError('AUTHREQUIRED', req); | |
} | |
} | |
}, | |
/** | |
* Event handler for the onCompleted event | |
* Checks if the login was successful and calls onError or onSuccess accordingly | |
* Then removes all webRequest handlers | |
* @param {Object} details the details of the request | |
*/ | |
onCompletedHandler: (details) => { | |
if (details.requestId !== req.id) { | |
return; | |
} | |
if (!this.cancelled) { | |
/* In some cases the headers are returned here */ | |
for (var i = 0; i < details.responseHeaders.length; i++) { | |
let header = details.responseHeaders[i]; | |
switch (header.name.toLowerCase()) { | |
case "x-zarafa-hresult": | |
req.headerXZarafaHresult = header.value; | |
break; | |
case "x-zarafa": | |
req.headerXZarafa = header.value; | |
this.webappVersion = header.value; | |
WebAppWindow.clearCache(header.value); | |
break; | |
} | |
} | |
if (req.headerXZarafa && !req.headerXZarafaHresult) { | |
if (openWindow) { | |
this.createOrReloadWindow(); | |
} | |
this.onSuccess(req); | |
} else { | |
if (req.redirect301) { | |
this.profile.requestOptions.url = this.getUrl(req.location + 'index.php?logon'); | |
this.login(openWindow); | |
} else { | |
req.openWindow = openWindow; | |
this.onError('COMPLETED', req); | |
} | |
} | |
} | |
removeWebRequestHandlers(); | |
}, | |
/** | |
* Event handler for the onError event | |
* If this event is triggered something failed completely | |
* Calls onError if the request wasn't cancelled already | |
* Then removes all webRequest handlers | |
* @param {Object} details the details of the request | |
*/ | |
onErrorOccuredHandler: (details) => { | |
if (details.requestId !== req.id) { | |
return; | |
} | |
if (!this.cancelled) { | |
this.onError('ERROROCCURED', details); | |
} | |
removeWebRequestHandlers(); | |
this.close(true); | |
} | |
}; | |
chrome.webRequest.onBeforeRequest.addListener( | |
webRequestHandlers.onBeforeRequestHandler, { | |
urls: ['<all_urls>'] | |
}, ["blocking"] | |
); | |
chrome.webRequest.onHeadersReceived.addListener( | |
webRequestHandlers.onHeadersReceivedHandler, { | |
urls: ['<all_urls>'] | |
}, ['blocking', 'responseHeaders'] | |
); | |
chrome.webRequest.onCompleted.addListener( | |
webRequestHandlers.onCompletedHandler, { | |
urls: ['<all_urls>'] | |
}, ['responseHeaders'] | |
); | |
chrome.webRequest.onAuthRequired.addListener( | |
webRequestHandlers.onAuthRequiredHandler, { | |
urls: ['<all_urls>'] | |
}, ['asyncBlocking', 'responseHeaders'] | |
); | |
chrome.webRequest.onErrorOccurred.addListener( | |
webRequestHandlers.onErrorOccuredHandler, { | |
urls: ['<all_urls>'] | |
} | |
); | |
var data = new FormData(); | |
if (!this.useSSO) { | |
data.append('username', this.profile.requestOptions.form.username); | |
data.append('password', DAEncryption.decrypt(this.profile.requestOptions.form.password)); | |
} | |
var xhr = new XMLHttpRequest(); | |
xhr.open("POST", this.getUrl(this.profile.requestOptions.url)); | |
xhr.withCredentials = true; | |
xhr.send(data); | |
} | |
/** | |
* Checks error details and converts it to a user firendly message | |
* Then calls cbFailure with an object containing the error message | |
* @param {String} type Type of the error | |
* @param {Object} details Error details | |
*/ | |
onError(type, details) { | |
var s_admin = ' ' + global.gt.gettext('Please contact your system administrator.'); | |
var msg = global.gt.gettext('Unexpected error occured.' + s_admin); | |
switch (type) { | |
case 'AUTHREQUIRED': | |
if (details.isProxy) { | |
msg = 'WebApp' + ' '; | |
} else { | |
msg = 'Proxy' + ' '; | |
} | |
msg += global.gt.gettext('Single Sign On failed. Please provide username and password.'); | |
break; | |
case 'COMPLETED': | |
var MAPI_E = details.headerXZarafaHresult; | |
if (MAPI_E) { | |
switch (MAPI_E) { | |
case 'MAPI_E_LOGON_FAILED': | |
case 'MAPI_E_UNCONFIGURED': | |
msg = global.gt.gettext('Could not login, invalid username or password'); | |
break; | |
case 'MAPI_E_NETWORK_ERROR': | |
msg = global.gt.gettext('Cannot connect to Kopano Core.'); | |
break; | |
case 'MAPI_E_INVALID_WORKSTATION_ACCOUNT': | |
//msg = global.gt.gettext('Logon failed, another session already exists.'); | |
this.destroySession(); | |
this.login(details.openWindow); | |
return; | |
default: | |
msg = global.gt.gettext('Login failed, MAPI errror: ') + MAPI_E; | |
break; | |
} | |
} else { | |
switch (details.statusCode) { | |
case 200: | |
if (this.useSSO && !(details.wwwAuthMethods['ntlm'] || | |
details.wwwAuthMethods['negotiate'])) { | |
msg = global.gt.gettext( | |
'Single Sign On not supported by your webserver. Please enter Username and Password.'); | |
} | |
break; | |
case 401: | |
if (details.wwwAuthMethods['ntlm'] || details.wwwAuthMethods['negotiate']) { | |
msg = global.gt.gettext( | |
'The WebApp server requires SSO authentication. Please logon via SSO.'); | |
} else { | |
msg = global.gt.gettext('Unhandled authentication error.' + s_admin); | |
} | |
break; | |
case 404: | |
msg = global.gt.gettext('Page not found on webserver.'); | |
break; | |
case 500: | |
msg = global.gt.gettext('Internal server error.') + s_admin; | |
break; | |
default: | |
msg = global.gt.gettext('Unhandled http status code ') + details.statusCode + "." + s_admin; | |
} | |
} | |
break; | |
case 'ERROROCCURED': | |
switch (details.error) { | |
case 'net::ERR_NETWORK_ACCESS_DENIED': | |
msg = global.gt.gettext('Your Internet access is blocked.'); | |
break; | |
case 'net::ERR_INTERNET_DISCONNECTED': | |
msg = global.gt.gettext('There is no Internet connection.'); | |
break; | |
case 'net::ERR_CONNECTION_INTERRUPTED': | |
msg = global.gt.gettext('Your connection was interrupted.'); | |
break; | |
case 'net::ERR_CONNECTION_REFUSED': | |
msg = global.gt.gettext('Connection refused.') + s_admin; | |
break; | |
case 'net::ERR_CONNECTION_TIMED_OUT': | |
msg = global.gt.gettext('Connection timed out.') + s_admin; | |
break; | |
case 'net::ERR_NAME_NOT_RESOLVED': | |
msg = global.gt.gettext('Could not resolve domain.') + s_admin; | |
break; | |
case 'net::ERR_BLOCKED_BY_CLIENT': | |
case 'net::ERR_BLOCKED_BY_ADMINISTRATOR': | |
case 'net::ERR_BLOCKED_ENROLLMENT_CHECK_PENDING': | |
case 'net::ERR_BLOCKED_BY_RESPONSE': | |
case 'net::ERR_BLOCKED_BY_XSS_AUDITOR': | |
msg = global.gt.gettext('Access to WebApp is blocked.'); | |
break; | |
case 'net::ERR_ACCESS_DENIED': | |
msg = global.gt.gettext('Access to WebApp was denied.'); | |
break; | |
default: | |
msg = global.gt.gettext('Error in connection. Reason: ' + details.error); | |
break; | |
} | |
break; | |
} | |
this.cbFailure({ | |
message: msg, | |
MAPI_E: details.headerXZarafaHresult || null | |
}); | |
} | |
/** | |
* Called when the login was successful | |
* Calls cbSuccess with the authtype and the request details | |
* @param {Object} req The collected details of the request | |
*/ | |
onSuccess(req) { | |
this.profile.authType = 'webapp'; | |
if (this.useSSO) { | |
this.profile.authType = 'sso'; | |
} else if (req.wwwAuthMethods['basic']) { | |
this.profile.authType = 'basic'; | |
} | |
req.profile = this.profile; | |
this.cbSuccess(req); | |
} | |
/** | |
* Show the webapp window | |
* @param {Boolean} focus If the shown window should be focussed | |
*/ | |
show(focus) { | |
if (!this.nwWindow) { | |
return; | |
} | |
if (this.nwWindow.appWindow.isMinimized()) { | |
this.restore(); | |
} | |
this.nwWindow.setShowInTaskbar(true); | |
this.nwWindow.show(); | |
this.isHidden = false; | |
if (focus) { | |
this.focus(); | |
} | |
} | |
/** | |
* Hides the webapp window | |
*/ | |
hide() { | |
this.nwWindow.hide(); | |
this.isHidden = true; | |
} | |
/** | |
* Toggles the taskbar visibility | |
* @param {Boolean} show If true show else hide | |
*/ | |
setShowInTaskbar(show = true) { | |
this.nwWindow.setShowInTaskbar(show); | |
} | |
/** | |
* Does a reload of webapp | |
* @param {Boolean} silent If true reload in the background | |
*/ | |
reload() { | |
this.nwWindow.window.onbeforeunload = null; | |
this.nwWindow.reload(); | |
} | |
/** | |
* Restores a minimized webapp window | |
*/ | |
restore() { | |
this.nwWindow.restore(); | |
this.isHidden = false; | |
} | |
/** | |
* Focus the webapp window | |
*/ | |
focus() { | |
this.nwWindow.focus(); | |
} | |
/** | |
* Close the webapp window | |
* @param {Boolean} force If true the window is closed immediately | |
*/ | |
close(force = false) { | |
if (this.nwWindow) { | |
localStorage.setItem('wasMaximizedOnClose', this.nwWindow.appWindow.isMaximized() || | |
this.nwWindow.appWindow.isFullscreen()); | |
this.nwWindow.close(force); | |
} | |
} | |
/** | |
* Cancel everything and close the window | |
*/ | |
cancel() { | |
this.cancelled = true; | |
this.destroyWindow(); | |
this.nwWindow = null; | |
this.showWebAppOnLoaded = true; | |
} | |
/** | |
* This is executed when the connection to webapp has been paralyzed. | |
*/ | |
onParalyzed() { | |
let wasHiddenOrMinimized = this.isHidden || this.nwWindow.appWindow.isMinimized(); | |
if (!wasHiddenOrMinimized) { | |
this.hide(); | |
global.DA.winWelcome.window.showLoaderForm(); | |
global.DA.winWelcome.show(); | |
} else { | |
this.showWebAppOnLoaded = false; | |
} | |
this.login(); | |
} | |
/** | |
* Event handler that is called when the logout button is clicked | |
*/ | |
onLogout() { | |
global.DA.winWelcome.window.showWelcomeForm(); | |
this.destroySession(); | |
this.close(true); | |
this.nwWindow = null; | |
global.DA.winWelcome.show(); | |
this.showWebAppOnLoaded = true; | |
} | |
/** | |
* The session is not always destroyed correctly by container.logout. | |
* So be sure it's gone, by calling index.php?logout | |
*/ | |
destroySession() { | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", this.getUrl(this.profile.requestOptions.url.replace('index.php?logon', 'index.php?logout')), false); | |
xhr.withCredentials = true; | |
try { | |
xhr.send(); | |
} catch(err) { | |
console.log('Destroying the session failed.', err); | |
} | |
} | |
/** | |
* If a NWWindow is left in a bad state, it needs to be closed | |
* in a special way. Open it with it's id and url "about:blank", | |
* then close it immediately. | |
*/ | |
destroyWindow() { | |
if (this.nwWindow) { | |
nw.Window.open('about:blank', this.windowOptions, (win) => { | |
if (win) { | |
win.close(true); | |
} | |
}); | |
} | |
} | |
/** | |
* Event handler that is called when webapp has loaded completely | |
*/ | |
onLoaded() { | |
if (this.cancelled) { | |
this.close(true); | |
} | |
this.readWebAppSettings(); | |
this.setZoomListeners(); | |
this.setupParameterHandling(); | |
global.DA.winWelcome.hide(); | |
if (this.showWebAppOnLoaded) { | |
if (localStorage.getItem('wasMaximizedOnClose') === 'true') { | |
this.nwWindow.maximize(); | |
} | |
this.show(true); | |
} | |
} | |
/** | |
* Event handler that is called when webapp does a reload | |
*/ | |
onReload() { | |
this.hide(); | |
global.DA.winWelcome.window.showLoaderForm(); | |
global.DA.winWelcome.show(); | |
} | |
/** | |
* Event handler that is called when the webapp window is minimized | |
*/ | |
onMinimze() { | |
if (global.settings.general.hideOnMinimize) { | |
if (global.DA.isMacOS) { | |
this.setShowInTaskbar(false); | |
} else { | |
this.hide(); | |
} | |
} | |
} | |
/** | |
* Event handler that is called when the webapp window is closed | |
*/ | |
onClose() { | |
if (global.DA.winWelcome) { | |
global.DA.winWelcome.close(true); | |
} | |
if (global.DA.winPreferences) { | |
global.DA.winPreferences.close(true); | |
} | |
this.close(true); | |
nw.App.quit(); | |
} | |
/** | |
* Sets listeners for the 'close', 'minimize', and 'new-win-policy' events | |
* of the WebApp window and also the custom events that are emitted by the injected script | |
*/ | |
setWebAppListeners() { | |
this.nwWindow.on('close', () => { | |
this.onClose(); | |
}); | |
this.nwWindow.on('minimize', () => { | |
this.onMinimze(); | |
}); | |
this.nwWindow.on('new-win-policy', (frame, url, policy) => { | |
var isWebmeetingsUrl = url.startsWith(this.webAppSettings.webMeetingsUrl); | |
if (url) { | |
if (isWebmeetingsUrl) { | |
nw.Window.open(url, { | |
'title': 'Kopano DeskApp', | |
'width': 950, | |
'height': 600, | |
'position': 'center', | |
'inject_js_start': 'app/injection/inject_start.js', | |
'inject_js_end': 'app/injection/inject_webmeetings_end.js', | |
}, function(){}); | |
} else { | |
nw.Shell.openExternal(url); | |
} | |
policy.ignore(); | |
} | |
}); | |
// Not for MacOS | |
if (!global.DA.isMacOS) { | |
this.nwWindow.on('enter-fullscreen', () => { | |
// global shortcut to leave fullscreen | |
var escapeShortcut = new nw.Shortcut({ | |
key: "Escape", | |
active: () => { | |
if (this.nwWindow) { | |
this.nwWindow.leaveFullscreen(); | |
nw.App.unregisterGlobalHotKey(escapeShortcut); | |
} | |
} | |
}); | |
nw.App.registerGlobalHotKey(escapeShortcut); | |
}); | |
} | |
const EventEmitter = require('events'); | |
class WinWebAppEmitter extends EventEmitter {} | |
this.nwWindow.customEventEmitter = new WinWebAppEmitter(); | |
this.nwWindow.customEventEmitter.on('WAparalyzed', () => { | |
this.onParalyzed(); | |
}); | |
this.nwWindow.customEventEmitter.on('WAloaded', () => { | |
this.onLoaded(); | |
}); | |
this.nwWindow.customEventEmitter.on('WAlogout', () => { | |
this.onLogout(); | |
}); | |
this.nwWindow.customEventEmitter.on('WAreload', () => { | |
this.onReload(); | |
}); | |
} | |
/** | |
* Adds listeners to zoom in and out. | |
*/ | |
setZoomListeners() { | |
if (this.notifier) { | |
this.notifier = null; | |
} | |
/* load zoom level from localStorage */ | |
if (global.settings.general.zoomLevel) { | |
this.nwWindow.zoomLevel = parseFloat(global.settings.general.zoomLevel); | |
} | |
/** | |
* Zoom in or out. | |
* CTRL + mousewheel and CTRL + "+/-" | |
* @param {Event} e event calling the function | |
*/ | |
let zoom = (e) => { | |
if (e.ctrlKey) { | |
var zoomLevel, newZoomFactor; | |
var zoomStep = 5; | |
var zoomFactor = global.settings.general.zoomFactor ? parseInt(global.settings.general.zoomFactor) : | |
100; | |
/* | |
* That's not nice, but we can't detect the keyboard layout. | |
* NumpadSubtract and NumpadAdd, as the names say, | |
* BracketRight and Slash are plus and minus on a qwertz keyboard | |
* ShiftKey = true + Equal and Minus are plus and minus on a qwerty keyboard | |
* deltaY is the mousewheel | |
*/ | |
if (e.deltaY > 0 || | |
e.code === 'NumpadSubtract' || | |
e.code === 'Slash' || | |
e.code === 'Minus') { | |
newZoomFactor = zoomFactor - zoomStep; | |
} else if (e.deltaY < 0 || | |
e.code === 'NumpadAdd' || | |
e.code === 'BracketRight' || | |
(e.shiftKey && e.code === 'Equal')) { | |
newZoomFactor = zoomFactor + zoomStep; | |
} | |
if (newZoomFactor) { | |
zoomLevel = global.DA.zoomFactorToLevel(newZoomFactor); | |
this.nwWindow.zoomLevel = zoomLevel; | |
/* store zoom factor and level to localStorage */ | |
var zoomSettings = { | |
'general': { | |
'zoomFactor': newZoomFactor, | |
'zoomLevel': zoomLevel | |
} | |
}; | |
global.DA.saveSettings(zoomSettings); | |
/* Notify the user about the current zoom factor */ | |
if (this.notifier === null) { | |
this.notifier = this.nwWindow.window.container.getNotifier(); | |
} | |
if (this.zoomNotification && this.nwWindow.window.document.getElementById(this.zoomNotification.id)) { | |
this.notifier.notify('info.sent', 'Zoom', global.settings.general.zoomFactor + '%', { | |
reference: this.zoomNotification, | |
update: true | |
}); | |
} else { | |
this.zoomNotification = this.notifier.notify('info.sent', 'Zoom', global.settings.general.zoomFactor + | |
'%'); | |
} | |
} | |
} | |
}; | |
this.nwWindow.window.document.addEventListener("keydown", zoom); | |
this.nwWindow.window.document.addEventListener("wheel", zoom); | |
} | |
/** | |
* Set up how commandline parameters are handled. | |
* A determination between mac osx and others is needed, because | |
* apple does everything completely different. | |
*/ | |
setupParameterHandling() { | |
if (this.onOpenListenerInstalled) { | |
return; | |
} | |
this.onOpenListenerInstalled = true; | |
var getopt = global.DA.requireCustomModule('getopt'); | |
/* This is for the first start of deskapp */ | |
if (WebAppWindow.isFirstWebAppLogin) { | |
if (global.DA.isMacOS) { | |
if (/^mailto/.test(nw.App.argv[0])) { | |
getopt.parseMailto({ | |
'mailto': nw.App.argv[0] | |
}); | |
} | |
/* Only one file supported by nw.js for now */ | |
if (/^file/.test(nw.App.argv[0])) { | |
this.nwWindow.window.createMail({ | |
'attach': [nw.App.argv[0]] | |
}); | |
} | |
} else { | |
getopt.parseAndProcessArgv(nw.App.argv); | |
} | |
WebAppWindow.isFirstWebAppLogin = false; | |
} | |
/* Listen for the App open event from new DeskApp instances */ | |
nw.App.on('open', (cmdline) => { | |
this.show(true); | |
console.log("on open", cmdline); | |
if (global.DA.isMacOS) { | |
if (/^mailto/.test(cmdline)) { | |
getopt.parseMailto({ | |
'mailto': cmdline | |
}); | |
} | |
/* Only one file supported by nw.js for now */ | |
if (/^file/.test(cmdline)) { | |
this.nwWindow.window.createMail({ | |
'attach': [cmdline] | |
}); | |
} | |
} else { | |
getopt.parseAndProcessArgv(getopt.cmdlineToArgv(cmdline)); | |
} | |
}); | |
/* | |
* Listen for the reopen event. If fired set show in taskbar to true. | |
* This only applies to MacOS. | |
*/ | |
nw.App.on('reopen', () => { | |
this.setShowInTaskbar(true); | |
}); | |
} | |
/** | |
* Read some of webapps settings | |
* For now we only read webmeetings settings. | |
*/ | |
readWebAppSettings() { | |
this.webAppSettings.webMeetingsUrl = | |
this.nwWindow.window.container.getSettingsModel().get('zarafa/v1/plugins/spreedwebrtc/domain') + | |
this.nwWindow.window.container.getSettingsModel().get('zarafa/v1/plugins/spreedwebrtc/url'); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment