diff --git a/dev/AdminBoot.js b/dev/AdminBoot.js new file mode 100644 index 000000000..a3c22bbb8 --- /dev/null +++ b/dev/AdminBoot.js @@ -0,0 +1,10 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +'use strict'; + +var + kn = require('./Knoin/Knoin.js'), + RL = require('./Boots/AdminApp.js') +; + +kn.bootstart(RL); \ No newline at end of file diff --git a/dev/Boots/AbstractApp.js b/dev/Boots/AbstractApp.js index 4774ee3f2..30ac22293 100644 --- a/dev/Boots/AbstractApp.js +++ b/dev/Boots/AbstractApp.js @@ -1,359 +1,385 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @constructor - * @extends KnoinAbstractBoot - */ -function AbstractApp() -{ - KnoinAbstractBoot.call(this); +(function (module) { - this.oSettings = null; - this.oPlugins = null; - this.oLocal = null; - this.oLink = null; - this.oSubs = {}; + 'use strict'; - this.isLocalAutocomplete = true; - - this.popupVisibilityNames = ko.observableArray([]); - - this.popupVisibility = ko.computed(function () { - return 0 < this.popupVisibilityNames().length; - }, this); - - this.iframe = $('').appendTo('body'); - - $window.on('error', function (oEvent) { - if (RL && oEvent && oEvent.originalEvent && oEvent.originalEvent.message && - -1 === Utils.inArray(oEvent.originalEvent.message, [ - 'Script error.', 'Uncaught Error: Error calling method on NPObject.' - ])) - { - RL.remote().jsError( - Utils.emptyFunction, - oEvent.originalEvent.message, - oEvent.originalEvent.filename, - oEvent.originalEvent.lineno, - location && location.toString ? location.toString() : '', - $html.attr('class'), - Utils.microtime() - Globals.now - ); - } - }); - - $document.on('keydown', function (oEvent) { - if (oEvent && oEvent.ctrlKey) - { - $html.addClass('rl-ctrl-key-pressed'); - } - }).on('keyup', function (oEvent) { - if (oEvent && !oEvent.ctrlKey) - { - $html.removeClass('rl-ctrl-key-pressed'); - } - }); -} - -_.extend(AbstractApp.prototype, KnoinAbstractBoot.prototype); - -AbstractApp.prototype.oSettings = null; -AbstractApp.prototype.oPlugins = null; -AbstractApp.prototype.oLocal = null; -AbstractApp.prototype.oLink = null; -AbstractApp.prototype.oSubs = {}; - -/** - * @param {string} sLink - * @return {boolean} - */ -AbstractApp.prototype.download = function (sLink) -{ var - oLink = null, - oE = null, - sUserAgent = navigator.userAgent.toLowerCase() + $ = require('../External/jquery.js'), + _ = require('../External/underscore.js'), + ko = require('../External/ko.js'), + window = require('../External/window.js'), + $html = require('../External/$html.js'), + $window = require('../External/$window.js'), + $doc = require('../External/$doc.js'), + AppData = require('../External/AppData.js'), + Globals = require('../Common/Globals.js'), + Utils = require('../Common/Utils.js'), + KnoinAbstractBoot = require('../Knoin/KnoinAbstractBoot.js'), + RL = require('./RL.js') ; - if (sUserAgent && (sUserAgent.indexOf('chrome') > -1 || sUserAgent.indexOf('chrome') > -1)) + /** + * @constructor + * @extends KnoinAbstractBoot + */ + function AbstractApp() { - oLink = document.createElement('a'); - oLink['href'] = sLink; + KnoinAbstractBoot.call(this); - if (document['createEvent']) - { - oE = document['createEvent']('MouseEvents'); - if (oE && oE['initEvent'] && oLink['dispatchEvent']) + this.oSettings = null; + this.oPlugins = null; + this.oLocal = null; + this.oLink = null; + this.oSubs = {}; + + this.isLocalAutocomplete = true; + + this.popupVisibilityNames = ko.observableArray([]); + + this.popupVisibility = ko.computed(function () { + return 0 < this.popupVisibilityNames().length; + }, this); + + this.iframe = $('').appendTo('body'); + + $window.on('error', function (oEvent) { + if (oEvent && oEvent.originalEvent && oEvent.originalEvent.message && + -1 === Utils.inArray(oEvent.originalEvent.message, [ + 'Script error.', 'Uncaught Error: Error calling method on NPObject.' + ])) { - oE['initEvent']('click', true, true); - oLink['dispatchEvent'](oE); - return true; + // TODO cjs + RL.remote().jsError( + Utils.emptyFunction, + oEvent.originalEvent.message, + oEvent.originalEvent.filename, + oEvent.originalEvent.lineno, + window.location && window.location.toString ? window.location.toString() : '', + $html.attr('class'), + Utils.microtime() - Globals.now + ); } - } - } + }); - if (Globals.bMobileDevice) - { - window.open(sLink, '_self'); - window.focus(); - } - else - { - this.iframe.attr('src', sLink); -// window.document.location.href = sLink; - } - - return true; -}; - -/** - * @return {LinkBuilder} - */ -AbstractApp.prototype.link = function () -{ - if (null === this.oLink) - { - this.oLink = new LinkBuilder(); - } - - return this.oLink; -}; - -/** - * @return {LocalStorage} - */ -AbstractApp.prototype.local = function () -{ - if (null === this.oLocal) - { - this.oLocal = new LocalStorage(); - } - - return this.oLocal; -}; - -/** - * @param {string} sName - * @return {?} - */ -AbstractApp.prototype.settingsGet = function (sName) -{ - if (null === this.oSettings) - { - this.oSettings = Utils.isNormal(AppData) ? AppData : {}; - } - - return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName]; -}; - -/** - * @param {string} sName - * @param {?} mValue - */ -AbstractApp.prototype.settingsSet = function (sName, mValue) -{ - if (null === this.oSettings) - { - this.oSettings = Utils.isNormal(AppData) ? AppData : {}; - } - - this.oSettings[sName] = mValue; -}; - -AbstractApp.prototype.setTitle = function (sTitle) -{ - sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') + - RL.settingsGet('Title') || ''; - - window.document.title = '_'; - window.document.title = sTitle; -}; - -/** - * @param {boolean=} bLogout = false - * @param {boolean=} bClose = false - */ -AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose) -{ - var - sCustomLogoutLink = Utils.pString(RL.settingsGet('CustomLogoutLink')), - bInIframe = !!RL.settingsGet('InIframe') - ; - - bLogout = Utils.isUnd(bLogout) ? false : !!bLogout; - bClose = Utils.isUnd(bClose) ? false : !!bClose; - - if (bLogout && bClose && window.close) - { - window.close(); - } - - if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink) - { - _.delay(function () { - if (bInIframe && window.parent) + $doc.on('keydown', function (oEvent) { + if (oEvent && oEvent.ctrlKey) { - window.parent.location.href = sCustomLogoutLink; + $html.addClass('rl-ctrl-key-pressed'); } - else + }).on('keyup', function (oEvent) { + if (oEvent && !oEvent.ctrlKey) { - window.location.href = sCustomLogoutLink; - } - }, 100); - } - else - { - kn.routeOff(); - kn.setHash(RL.link().root(), true); - kn.routeOff(); - - _.delay(function () { - if (bInIframe && window.parent) - { - window.parent.location.reload(); - } - else - { - window.location.reload(); - } - }, 100); - } -}; - -AbstractApp.prototype.historyBack = function () -{ - window.history.back(); -}; - -/** - * @param {string} sQuery - * @param {Function} fCallback - */ -AbstractApp.prototype.getAutocomplete = function (sQuery, fCallback) -{ - fCallback([], sQuery); -}; - -/** - * @param {string} sName - * @param {Function} fFunc - * @param {Object=} oContext - * @return {AbstractApp} - */ -AbstractApp.prototype.sub = function (sName, fFunc, oContext) -{ - if (Utils.isUnd(this.oSubs[sName])) - { - this.oSubs[sName] = []; - } - - this.oSubs[sName].push([fFunc, oContext]); - - return this; -}; - -/** - * @param {string} sName - * @param {Array=} aArgs - * @return {AbstractApp} - */ -AbstractApp.prototype.pub = function (sName, aArgs) -{ - Plugins.runHook('rl-pub', [sName, aArgs]); - if (!Utils.isUnd(this.oSubs[sName])) - { - _.each(this.oSubs[sName], function (aItem) { - if (aItem[0]) - { - aItem[0].apply(aItem[1] || null, aArgs || []); + $html.removeClass('rl-ctrl-key-pressed'); } }); } - return this; -}; + _.extend(AbstractApp.prototype, KnoinAbstractBoot.prototype); -/** - * @param {string} sName - * @return {boolean} - */ -AbstractApp.prototype.capa = function (sName) -{ - var mCapa = this.settingsGet('Capa'); - return Utils.isArray(mCapa) && Utils.isNormal(sName) && -1 < Utils.inArray(sName, mCapa); -}; + AbstractApp.prototype.oSettings = null; + AbstractApp.prototype.oPlugins = null; + AbstractApp.prototype.oLocal = null; + AbstractApp.prototype.oLink = null; + AbstractApp.prototype.oSubs = {}; -AbstractApp.prototype.bootstart = function () -{ - var self = this; + /** + * @param {string} sLink + * @return {boolean} + */ + AbstractApp.prototype.download = function (sLink) + { + var + oE = null, + oLink = null, + sUserAgent = window.navigator.userAgent.toLowerCase() + ; - Utils.initOnStartOrLangChange(function () { - Utils.initNotificationLanguage(); - }, null); + if (sUserAgent && (sUserAgent.indexOf('chrome') > -1 || sUserAgent.indexOf('chrome') > -1)) + { + oLink = window.document.createElement('a'); + oLink['href'] = sLink; - _.delay(function () { - Utils.windowResize(); - }, 1000); - - ssm.addState({ - 'id': 'mobile', - 'maxWidth': 767, - 'onEnter': function() { - $html.addClass('ssm-state-mobile'); - self.pub('ssm.mobile-enter'); - }, - 'onLeave': function() { - $html.removeClass('ssm-state-mobile'); - self.pub('ssm.mobile-leave'); + if (window.document['createEvent']) + { + oE = window.document['createEvent']('MouseEvents'); + if (oE && oE['initEvent'] && oLink['dispatchEvent']) + { + oE['initEvent']('click', true, true); + oLink['dispatchEvent'](oE); + return true; + } + } } - }); - ssm.addState({ - 'id': 'tablet', - 'minWidth': 768, - 'maxWidth': 999, - 'onEnter': function() { - $html.addClass('ssm-state-tablet'); - }, - 'onLeave': function() { - $html.removeClass('ssm-state-tablet'); + if (Globals.bMobileDevice) + { + window.open(sLink, '_self'); + window.focus(); } - }); - - ssm.addState({ - 'id': 'desktop', - 'minWidth': 1000, - 'maxWidth': 1400, - 'onEnter': function() { - $html.addClass('ssm-state-desktop'); - }, - 'onLeave': function() { - $html.removeClass('ssm-state-desktop'); + else + { + this.iframe.attr('src', sLink); + // window.document.location.href = sLink; } - }); - ssm.addState({ - 'id': 'desktop-large', - 'minWidth': 1400, - 'onEnter': function() { - $html.addClass('ssm-state-desktop-large'); - }, - 'onLeave': function() { - $html.removeClass('ssm-state-desktop-large'); + return true; + }; + + /** + * @return {LinkBuilder} + */ + AbstractApp.prototype.link = function () + { + if (null === this.oLink) + { + this.oLink = new LinkBuilder(); // TODO cjs } - }); - RL.sub('ssm.mobile-enter', function () { - RL.data().leftPanelDisabled(true); - }); + return this.oLink; + }; - RL.sub('ssm.mobile-leave', function () { - RL.data().leftPanelDisabled(false); - }); + /** + * @return {LocalStorage} + */ + AbstractApp.prototype.local = function () + { + if (null === this.oLocal) + { + this.oLocal = new LocalStorage(); // TODO cjs + } - RL.data().leftPanelDisabled.subscribe(function (bValue) { - $html.toggleClass('rl-left-panel-disabled', bValue); - }); + return this.oLocal; + }; - ssm.ready(); -}; + /** + * @param {string} sName + * @return {?} + */ + AbstractApp.prototype.settingsGet = function (sName) + { + if (null === this.oSettings) + { + this.oSettings = Utils.isNormal(AppData) ? AppData : {}; + } + + return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName]; + }; + + /** + * @param {string} sName + * @param {?} mValue + */ + AbstractApp.prototype.settingsSet = function (sName, mValue) + { + if (null === this.oSettings) + { + this.oSettings = Utils.isNormal(AppData) ? AppData : {}; + } + + this.oSettings[sName] = mValue; + }; + + AbstractApp.prototype.setTitle = function (sTitle) + { + sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') + + RL.settingsGet('Title') || ''; // TODO cjs + + window.document.title = '_'; + window.document.title = sTitle; + }; + + /** + * @param {boolean=} bLogout = false + * @param {boolean=} bClose = false + */ + AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose) + { + var + sCustomLogoutLink = Utils.pString(RL.settingsGet('CustomLogoutLink')), + bInIframe = !!RL.settingsGet('InIframe') + ; + + // TODO cjs + + bLogout = Utils.isUnd(bLogout) ? false : !!bLogout; + bClose = Utils.isUnd(bClose) ? false : !!bClose; + + if (bLogout && bClose && window.close) + { + window.close(); + } + + if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink) + { + _.delay(function () { + if (bInIframe && window.parent) + { + window.parent.location.href = sCustomLogoutLink; + } + else + { + window.location.href = sCustomLogoutLink; + } + }, 100); + } + else + { + kn.routeOff(); + kn.setHash(RL.link().root(), true); + kn.routeOff(); + + _.delay(function () { + if (bInIframe && window.parent) + { + window.parent.location.reload(); + } + else + { + window.location.reload(); + } + }, 100); + } + }; + + AbstractApp.prototype.historyBack = function () + { + window.history.back(); + }; + + /** + * @param {string} sQuery + * @param {Function} fCallback + */ + AbstractApp.prototype.getAutocomplete = function (sQuery, fCallback) + { + fCallback([], sQuery); + }; + + /** + * @param {string} sName + * @param {Function} fFunc + * @param {Object=} oContext + * @return {AbstractApp} + */ + AbstractApp.prototype.sub = function (sName, fFunc, oContext) + { + if (Utils.isUnd(this.oSubs[sName])) + { + this.oSubs[sName] = []; + } + + this.oSubs[sName].push([fFunc, oContext]); + + return this; + }; + + /** + * @param {string} sName + * @param {Array=} aArgs + * @return {AbstractApp} + */ + AbstractApp.prototype.pub = function (sName, aArgs) + { + Plugins.runHook('rl-pub', [sName, aArgs]); + if (!Utils.isUnd(this.oSubs[sName])) + { + _.each(this.oSubs[sName], function (aItem) { + if (aItem[0]) + { + aItem[0].apply(aItem[1] || null, aArgs || []); + } + }); + } + + return this; + }; + + /** + * @param {string} sName + * @return {boolean} + */ + AbstractApp.prototype.capa = function (sName) + { + var mCapa = this.settingsGet('Capa'); + return Utils.isArray(mCapa) && Utils.isNormal(sName) && -1 < Utils.inArray(sName, mCapa); + }; + + AbstractApp.prototype.bootstart = function () + { + var ssm = require('../External/ssm.js'); + + Utils.initOnStartOrLangChange(function () { + Utils.initNotificationLanguage(); + }, null); + + _.delay(function () { + Utils.windowResize(); + }, 1000); + + ssm.addState({ + 'id': 'mobile', + 'maxWidth': 767, + 'onEnter': function() { + $html.addClass('ssm-state-mobile'); + RL.pub('ssm.mobile-enter'); + }, + 'onLeave': function() { + $html.removeClass('ssm-state-mobile'); + RL.pub('ssm.mobile-leave'); + } + }); + + ssm.addState({ + 'id': 'tablet', + 'minWidth': 768, + 'maxWidth': 999, + 'onEnter': function() { + $html.addClass('ssm-state-tablet'); + }, + 'onLeave': function() { + $html.removeClass('ssm-state-tablet'); + } + }); + + ssm.addState({ + 'id': 'desktop', + 'minWidth': 1000, + 'maxWidth': 1400, + 'onEnter': function() { + $html.addClass('ssm-state-desktop'); + }, + 'onLeave': function() { + $html.removeClass('ssm-state-desktop'); + } + }); + + ssm.addState({ + 'id': 'desktop-large', + 'minWidth': 1400, + 'onEnter': function() { + $html.addClass('ssm-state-desktop-large'); + }, + 'onLeave': function() { + $html.removeClass('ssm-state-desktop-large'); + } + }); + + RL.sub('ssm.mobile-enter', function () { // TODO cjs + RL.data().leftPanelDisabled(true); + }); + + RL.sub('ssm.mobile-leave', function () { // TODO cjs + RL.data().leftPanelDisabled(false); + }); + + RL.data().leftPanelDisabled.subscribe(function (bValue) { // TODO cjs + $html.toggleClass('rl-left-panel-disabled', bValue); + }); + + ssm.ready(); + }; + + module.exports = AbstractApp; + +}(module)); \ No newline at end of file diff --git a/dev/Boots/AdminApp.js b/dev/Boots/AdminApp.js index 6b7c35b4b..7d3aaa440 100644 --- a/dev/Boots/AdminApp.js +++ b/dev/Boots/AdminApp.js @@ -1,302 +1,320 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @constructor - * @extends AbstractApp - */ -function AdminApp() -{ - AbstractApp.call(this); +(function (module) { - this.oData = null; - this.oRemote = null; - this.oCache = null; -} + 'use strict'; -_.extend(AdminApp.prototype, AbstractApp.prototype); + var + ko = require('../External/ko.js'), + _ = require('../External/underscore.js'), + window = require('../External/window.js'), + Enums = require('../Common/Enums.js'), + Utils = require('../Common/Utils.js'), + kn = require('../Knoin/Knoin.js'), + AbstractApp = require('./AbstractApp.js') + ; -AdminApp.prototype.oData = null; -AdminApp.prototype.oRemote = null; -AdminApp.prototype.oCache = null; - -/** - * @return {AdminDataStorage} - */ -AdminApp.prototype.data = function () -{ - if (null === this.oData) + /** + * @constructor + * @extends AbstractApp + */ + function AdminApp() { - this.oData = new AdminDataStorage(); + AbstractApp.call(this); + + this.oData = null; + this.oRemote = null; + this.oCache = null; } - return this.oData; -}; + _.extend(AdminApp.prototype, AbstractApp.prototype); -/** - * @return {AdminAjaxRemoteStorage} - */ -AdminApp.prototype.remote = function () -{ - if (null === this.oRemote) + AdminApp.prototype.oData = null; + AdminApp.prototype.oRemote = null; + AdminApp.prototype.oCache = null; + + /** + * @return {AdminDataStorage} + */ + AdminApp.prototype.data = function () { - this.oRemote = new AdminAjaxRemoteStorage(); - } - - return this.oRemote; -}; - -/** - * @return {AdminCacheStorage} - */ -AdminApp.prototype.cache = function () -{ - if (null === this.oCache) - { - this.oCache = new AdminCacheStorage(); - } - - return this.oCache; -}; - -AdminApp.prototype.reloadDomainList = function () -{ - RL.data().domainsLoading(true); - RL.remote().domainList(function (sResult, oData) { - RL.data().domainsLoading(false); - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + if (null === this.oData) { - var aList = _.map(oData.Result, function (bEnabled, sName) { - return { - 'name': sName, - 'disabled': ko.observable(!bEnabled), - 'deleteAccess': ko.observable(false) - }; - }, this); - - RL.data().domains(aList); + this.oData = new AdminDataStorage(); // TODO cjs } - }); -}; -AdminApp.prototype.reloadPluginList = function () -{ - RL.data().pluginsLoading(true); - RL.remote().pluginList(function (sResult, oData) { - RL.data().pluginsLoading(false); - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + return this.oData; + }; + + /** + * @return {AdminAjaxRemoteStorage} + */ + AdminApp.prototype.remote = function () + { + if (null === this.oRemote) { - var aList = _.map(oData.Result, function (oItem) { - return { - 'name': oItem['Name'], - 'disabled': ko.observable(!oItem['Enabled']), - 'configured': ko.observable(!!oItem['Configured']) - }; - }, this); - - RL.data().plugins(aList); + this.oRemote = new AdminAjaxRemoteStorage(); // TODO cjs } - }); -}; -AdminApp.prototype.reloadPackagesList = function () -{ - RL.data().packagesLoading(true); - RL.data().packagesReal(true); + return this.oRemote; + }; - RL.remote().packagesList(function (sResult, oData) { - - RL.data().packagesLoading(false); - - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + /** + * @return {AdminCacheStorage} + */ + AdminApp.prototype.cache = function () + { + if (null === this.oCache) { - RL.data().packagesReal(!!oData.Result.Real); - RL.data().packagesMainUpdatable(!!oData.Result.MainUpdatable); + this.oCache = new AdminCacheStorage(); // TODO cjs + } - var - aList = [], - aLoading = {} - ; + return this.oCache; + }; - _.each(RL.data().packages(), function (oItem) { - if (oItem && oItem['loading']()) - { - aLoading[oItem['file']] = oItem; - } - }); - - if (Utils.isArray(oData.Result.List)) + AdminApp.prototype.reloadDomainList = function () + { + // TODO cjs + RL.data().domainsLoading(true); + RL.remote().domainList(function (sResult, oData) { + RL.data().domainsLoading(false); + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { - aList = _.compact(_.map(oData.Result.List, function (oItem) { - if (oItem) - { - oItem['loading'] = ko.observable(!Utils.isUnd(aLoading[oItem['file']])); - return 'core' === oItem['type'] && !oItem['canBeInstalled'] ? null : oItem; - } - return null; - })); + var aList = _.map(oData.Result, function (bEnabled, sName) { + return { + 'name': sName, + 'disabled': ko.observable(!bEnabled), + 'deleteAccess': ko.observable(false) + }; + }, this); + + RL.data().domains(aList); } + }); + }; - RL.data().packages(aList); - } - else - { - RL.data().packagesReal(false); - } - }); -}; + AdminApp.prototype.reloadPluginList = function () + { + // TODO cjs + RL.data().pluginsLoading(true); + RL.remote().pluginList(function (sResult, oData) { + RL.data().pluginsLoading(false); + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + var aList = _.map(oData.Result, function (oItem) { + return { + 'name': oItem['Name'], + 'disabled': ko.observable(!oItem['Enabled']), + 'configured': ko.observable(!!oItem['Configured']) + }; + }, this); -AdminApp.prototype.updateCoreData = function () -{ - var oRainData = RL.data(); + RL.data().plugins(aList); + } + }); + }; - oRainData.coreUpdating(true); - RL.remote().updateCoreData(function (sResult, oData) { + AdminApp.prototype.reloadPackagesList = function () + { + // TODO cjs + RL.data().packagesLoading(true); + RL.data().packagesReal(true); - oRainData.coreUpdating(false); - oRainData.coreRemoteVersion(''); - oRainData.coreRemoteRelease(''); - oRainData.coreVersionCompare(-2); + RL.remote().packagesList(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) - { - oRainData.coreReal(true); - window.location.reload(); - } - else - { - oRainData.coreReal(false); - } - }); + RL.data().packagesLoading(false); -}; + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + RL.data().packagesReal(!!oData.Result.Real); + RL.data().packagesMainUpdatable(!!oData.Result.MainUpdatable); -AdminApp.prototype.reloadCoreData = function () -{ - var oRainData = RL.data(); + var + aList = [], + aLoading = {} + ; - oRainData.coreChecking(true); - oRainData.coreReal(true); + _.each(RL.data().packages(), function (oItem) { + if (oItem && oItem['loading']()) + { + aLoading[oItem['file']] = oItem; + } + }); - RL.remote().coreData(function (sResult, oData) { + if (Utils.isArray(oData.Result.List)) + { + aList = _.compact(_.map(oData.Result.List, function (oItem) { + if (oItem) + { + oItem['loading'] = ko.observable(!Utils.isUnd(aLoading[oItem['file']])); + return 'core' === oItem['type'] && !oItem['canBeInstalled'] ? null : oItem; + } + return null; + })); + } - oRainData.coreChecking(false); + RL.data().packages(aList); + } + else + { + RL.data().packagesReal(false); + } + }); + }; - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) - { - oRainData.coreReal(!!oData.Result.Real); - oRainData.coreUpdatable(!!oData.Result.Updatable); - oRainData.coreAccess(!!oData.Result.Access); - oRainData.coreRemoteVersion(oData.Result.RemoteVersion || ''); - oRainData.coreRemoteRelease(oData.Result.RemoteRelease || ''); - oRainData.coreVersionCompare(Utils.pInt(oData.Result.VersionCompare)); - } - else - { - oRainData.coreReal(false); + AdminApp.prototype.updateCoreData = function () + { + // TODO cjs + var oRainData = RL.data(); + + oRainData.coreUpdating(true); + RL.remote().updateCoreData(function (sResult, oData) { + + oRainData.coreUpdating(false); oRainData.coreRemoteVersion(''); oRainData.coreRemoteRelease(''); oRainData.coreVersionCompare(-2); - } - }); -}; -/** - * - * @param {boolean=} bForce = false - */ -AdminApp.prototype.reloadLicensing = function (bForce) -{ - bForce = Utils.isUnd(bForce) ? false : !!bForce; - - RL.data().licensingProcess(true); - RL.data().licenseError(''); - - RL.remote().licensing(function (sResult, oData) { - RL.data().licensingProcess(false); - if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isNormal(oData.Result['Expired'])) - { - RL.data().licenseValid(true); - RL.data().licenseExpired(Utils.pInt(oData.Result['Expired'])); - RL.data().licenseError(''); - - RL.data().licensing(true); - } - else - { - if (oData && oData.ErrorCode && -1 < Utils.inArray(Utils.pInt(oData.ErrorCode), [ - Enums.Notification.LicensingServerIsUnavailable, - Enums.Notification.LicensingExpired - ])) + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { - RL.data().licenseError(Utils.getNotification(Utils.pInt(oData.ErrorCode))); + oRainData.coreReal(true); + window.location.reload(); + } + else + { + oRainData.coreReal(false); + } + }); + + }; + + AdminApp.prototype.reloadCoreData = function () + { + var oRainData = RL.data(); + + oRainData.coreChecking(true); + oRainData.coreReal(true); + + RL.remote().coreData(function (sResult, oData) { + + oRainData.coreChecking(false); + + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + oRainData.coreReal(!!oData.Result.Real); + oRainData.coreUpdatable(!!oData.Result.Updatable); + oRainData.coreAccess(!!oData.Result.Access); + oRainData.coreRemoteVersion(oData.Result.RemoteVersion || ''); + oRainData.coreRemoteRelease(oData.Result.RemoteRelease || ''); + oRainData.coreVersionCompare(Utils.pInt(oData.Result.VersionCompare)); + } + else + { + oRainData.coreReal(false); + oRainData.coreRemoteVersion(''); + oRainData.coreRemoteRelease(''); + oRainData.coreVersionCompare(-2); + } + }); + }; + + /** + * + * @param {boolean=} bForce = false + */ + AdminApp.prototype.reloadLicensing = function (bForce) + { + bForce = Utils.isUnd(bForce) ? false : !!bForce; + + // TODO cjs + RL.data().licensingProcess(true); + RL.data().licenseError(''); + + RL.remote().licensing(function (sResult, oData) { + RL.data().licensingProcess(false); + if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isNormal(oData.Result['Expired'])) + { + RL.data().licenseValid(true); + RL.data().licenseExpired(Utils.pInt(oData.Result['Expired'])); + RL.data().licenseError(''); + RL.data().licensing(true); } else { - if (Enums.StorageResultType.Abort === sResult) + if (oData && oData.ErrorCode && -1 < Utils.inArray(Utils.pInt(oData.ErrorCode), [ + Enums.Notification.LicensingServerIsUnavailable, + Enums.Notification.LicensingExpired + ])) { - RL.data().licenseError(Utils.getNotification(Enums.Notification.LicensingServerIsUnavailable)); + RL.data().licenseError(Utils.getNotification(Utils.pInt(oData.ErrorCode))); RL.data().licensing(true); } else { - RL.data().licensing(false); + if (Enums.StorageResultType.Abort === sResult) + { + RL.data().licenseError(Utils.getNotification(Enums.Notification.LicensingServerIsUnavailable)); + RL.data().licensing(true); + } + else + { + RL.data().licensing(false); + } } } - } - }, bForce); -}; + }, bForce); + }; -AdminApp.prototype.bootstart = function () -{ - AbstractApp.prototype.bootstart.call(this); - - RL.data().populateDataOnStart(); - - kn.hideLoading(); - - if (!RL.settingsGet('AllowAdminPanel')) + AdminApp.prototype.bootstart = function () { - kn.routeOff(); - kn.setHash(RL.link().root(), true); - kn.routeOff(); + AbstractApp.prototype.bootstart.call(this); - _.defer(function () { - window.location.href = '/'; - }); - } - else - { -// Utils.removeSettingsViewModel(AdminAbout); + RL.data().populateDataOnStart(); - if (!RL.capa(Enums.Capa.Prem)) + kn.hideLoading(); + + if (!RL.settingsGet('AllowAdminPanel')) { - Utils.removeSettingsViewModel(AdminBranding); - } + kn.routeOff(); + kn.setHash(RL.link().root(), true); + kn.routeOff(); - if (!!RL.settingsGet('Auth')) - { -// TODO -// if (!RL.settingsGet('AllowPackages') && AdminPackages) -// { -// Utils.disableSettingsViewModel(AdminPackages); -// } - - kn.startScreens([AdminSettingsScreen]); + _.defer(function () { + window.location.href = '/'; + }); } else { - kn.startScreens([AdminLoginScreen]); + // Utils.removeSettingsViewModel(AdminAbout); + + if (!RL.capa(Enums.Capa.Prem)) + { + Utils.removeSettingsViewModel(AdminBranding); + } + + if (!!RL.settingsGet('Auth')) + { + // TODO + // if (!RL.settingsGet('AllowPackages') && AdminPackages) + // { + // Utils.disableSettingsViewModel(AdminPackages); + // } + + kn.startScreens([AdminSettingsScreen]); + } + else + { + kn.startScreens([AdminLoginScreen]); + } } - } - if (window.SimplePace) - { - window.SimplePace.set(100); - } -}; + if (window.SimplePace) + { + window.SimplePace.set(100); + } + }; -/** - * @type {AdminApp} - */ -RL = new AdminApp(); + module.exports = new AdminApp(); + +}(module)); \ No newline at end of file diff --git a/dev/Boots/RainLoopApp.js b/dev/Boots/RainLoopApp.js index 19d818362..655071e41 100644 --- a/dev/Boots/RainLoopApp.js +++ b/dev/Boots/RainLoopApp.js @@ -1,687 +1,596 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @constructor - * @extends AbstractApp - */ -function RainLoopApp() -{ - AbstractApp.call(this); +(function (module) { - this.oData = null; - this.oRemote = null; - this.oCache = null; - this.oMoveCache = {}; + 'use strict'; - this.quotaDebounce = _.debounce(this.quota, 1000 * 30); - this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this); + var + window = require('../External/window.js'), + $ = require('../External/jquery.js'), + _ = require('../External/underscore.js'), + Enums = require('../Common/Enums.js'), + Globals = require('../Common/Globals.js'), + Consts = require('../Common/Consts.js'), + Plugins = require('../Common/Plugins.js'), + Utils = require('../Common/Utils.js'), + kn = require('../Knoin/Knoin.js'), + AbstractApp = require('./AbstractApp.js') + ; - this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500); + /** + * @constructor + * @extends AbstractApp + */ + function RainLoopApp() + { + AbstractApp.call(this); - window.setInterval(function () { - RL.pub('interval.30s'); - }, 30000); + this.oData = null; + this.oRemote = null; + this.oCache = null; + this.oMoveCache = {}; - window.setInterval(function () { - RL.pub('interval.1m'); - }, 60000); + this.quotaDebounce = _.debounce(this.quota, 1000 * 30); + this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this); - window.setInterval(function () { - RL.pub('interval.2m'); - }, 60000 * 2); + this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500); - window.setInterval(function () { - RL.pub('interval.3m'); - }, 60000 * 3); - - window.setInterval(function () { - RL.pub('interval.5m'); - }, 60000 * 5); - - window.setInterval(function () { - RL.pub('interval.10m'); - }, 60000 * 10); - - window.setTimeout(function () { window.setInterval(function () { - RL.pub('interval.10m-after5m'); + RL.pub('interval.30s'); + }, 30000); + + window.setInterval(function () { + RL.pub('interval.1m'); + }, 60000); + + window.setInterval(function () { + RL.pub('interval.2m'); + }, 60000 * 2); + + window.setInterval(function () { + RL.pub('interval.3m'); + }, 60000 * 3); + + window.setInterval(function () { + RL.pub('interval.5m'); + }, 60000 * 5); + + window.setInterval(function () { + RL.pub('interval.10m'); }, 60000 * 10); - }, 60000 * 5); - $.wakeUp(function () { - RL.remote().jsVersion(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData && !oData.Result) - { - if (window.parent && !!RL.settingsGet('InIframe')) + window.setTimeout(function () { + window.setInterval(function () { + RL.pub('interval.10m-after5m'); + }, 60000 * 10); + }, 60000 * 5); + + $.wakeUp(function () { + RL.remote().jsVersion(function (sResult, oData) { + if (Enums.StorageResultType.Success === sResult && oData && !oData.Result) { - window.parent.location.reload(); + if (window.parent && !!RL.settingsGet('InIframe')) + { + window.parent.location.reload(); + } + else + { + window.location.reload(); + } } - else - { - window.location.reload(); - } - } - }, RL.settingsGet('Version')); - }, {}, 60 * 60 * 1000); -} - -_.extend(RainLoopApp.prototype, AbstractApp.prototype); - -RainLoopApp.prototype.oData = null; -RainLoopApp.prototype.oRemote = null; -RainLoopApp.prototype.oCache = null; - -/** - * @return {WebMailDataStorage} - */ -RainLoopApp.prototype.data = function () -{ - if (null === this.oData) - { - this.oData = new WebMailDataStorage(); + }, RL.settingsGet('Version')); + }, {}, 60 * 60 * 1000); } - return this.oData; -}; + _.extend(RainLoopApp.prototype, AbstractApp.prototype); -/** - * @return {WebMailAjaxRemoteStorage} - */ -RainLoopApp.prototype.remote = function () -{ - if (null === this.oRemote) + RainLoopApp.prototype.oData = null; + RainLoopApp.prototype.oRemote = null; + RainLoopApp.prototype.oCache = null; + + /** + * @return {WebMailDataStorage} + */ + RainLoopApp.prototype.data = function () { - this.oRemote = new WebMailAjaxRemoteStorage(); - } - - return this.oRemote; -}; - -/** - * @return {WebMailCacheStorage} - */ -RainLoopApp.prototype.cache = function () -{ - if (null === this.oCache) - { - this.oCache = new WebMailCacheStorage(); - } - - return this.oCache; -}; - -RainLoopApp.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function () -{ - var oCache = RL.cache(); - _.each(RL.data().messageList(), function (oMessage) { - oCache.initMessageFlagsFromCache(oMessage); - }); - - oCache.initMessageFlagsFromCache(RL.data().message()); -}; - -/** - * @param {boolean=} bDropPagePosition = false - * @param {boolean=} bDropCurrenFolderCache = false - */ -RainLoopApp.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache) -{ - var - oRLData = RL.data(), - iOffset = (oRLData.messageListPage() - 1) * oRLData.messagesPerPage() - ; - - if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache) - { - RL.cache().setFolderHash(oRLData.currentFolderFullNameRaw(), ''); - } - - if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition) - { - oRLData.messageListPage(1); - iOffset = 0; - } - - oRLData.messageListLoading(true); - RL.remote().messageList(function (sResult, oData, bCached) { - - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + if (null === this.oData) { - oRLData.messageListError(''); - oRLData.messageListLoading(false); - oRLData.setMessageList(oData, bCached); - } - else if (Enums.StorageResultType.Unload === sResult) - { - oRLData.messageListError(''); - oRLData.messageListLoading(false); - } - else if (Enums.StorageResultType.Abort !== sResult) - { - oRLData.messageList([]); - oRLData.messageListLoading(false); - oRLData.messageListError(oData && oData.ErrorCode ? - Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST') - ); + this.oData = new WebMailDataStorage(); } - }, oRLData.currentFolderFullNameRaw(), iOffset, oRLData.messagesPerPage(), oRLData.messageListSearch()); -}; + return this.oData; + }; -RainLoopApp.prototype.recacheInboxMessageList = function () -{ - RL.remote().messageList(Utils.emptyFunction, 'INBOX', 0, RL.data().messagesPerPage(), '', true); -}; - -RainLoopApp.prototype.reloadMessageListHelper = function (bEmptyList) -{ - RL.reloadMessageList(bEmptyList); -}; - -/** - * @param {Function} fResultFunc - * @returns {boolean} - */ -RainLoopApp.prototype.contactsSync = function (fResultFunc) -{ - var oContacts = RL.data().contacts; - if (oContacts.importing() || oContacts.syncing() || !RL.data().enableContactsSync() || !RL.data().allowContactsSync()) + /** + * @return {WebMailAjaxRemoteStorage} + */ + RainLoopApp.prototype.remote = function () { - return false; - } - - oContacts.syncing(true); - - RL.remote().contactsSync(function (sResult, oData) { - - oContacts.syncing(false); - - if (fResultFunc) + if (null === this.oRemote) { - fResultFunc(sResult, oData); - } - }); - - return true; -}; - -RainLoopApp.prototype.messagesMoveTrigger = function () -{ - var - self = this, - sSpamFolder = RL.data().spamFolder() - ; - - _.each(this.oMoveCache, function (oItem) { - - var - bSpam = sSpamFolder === oItem['To'], - bHam = !bSpam && sSpamFolder === oItem['From'] && 'INBOX' === oItem['To'] - ; - - RL.remote().messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'], - bSpam ? 'SPAM' : (bHam ? 'HAM' : '')); - }); - - this.oMoveCache = {}; -}; - -RainLoopApp.prototype.messagesMoveHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForMove) -{ - var sH = '$$' + sFromFolderFullNameRaw + '$$' + sToFolderFullNameRaw + '$$'; - if (!this.oMoveCache[sH]) - { - this.oMoveCache[sH] = { - 'From': sFromFolderFullNameRaw, - 'To': sToFolderFullNameRaw, - 'Uid': [] - }; - } - - this.oMoveCache[sH]['Uid'] = _.union(this.oMoveCache[sH]['Uid'], aUidForMove); - this.messagesMoveTrigger(); -}; - -RainLoopApp.prototype.messagesCopyHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy) -{ - RL.remote().messagesCopy( - this.moveOrDeleteResponseHelper, - sFromFolderFullNameRaw, - sToFolderFullNameRaw, - aUidForCopy - ); -}; - -RainLoopApp.prototype.messagesDeleteHelper = function (sFromFolderFullNameRaw, aUidForRemove) -{ - RL.remote().messagesDelete( - this.moveOrDeleteResponseHelper, - sFromFolderFullNameRaw, - aUidForRemove - ); -}; - -RainLoopApp.prototype.moveOrDeleteResponseHelper = function (sResult, oData) -{ - if (Enums.StorageResultType.Success === sResult && RL.data().currentFolder()) - { - if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length) - { - RL.cache().setFolderHash(oData.Result[0], oData.Result[1]); - } - else - { - RL.cache().setFolderHash(RL.data().currentFolderFullNameRaw(), ''); - - if (oData && -1 < Utils.inArray(oData.ErrorCode, - [Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage])) - { - window.alert(Utils.getNotification(oData.ErrorCode)); - } + this.oRemote = new WebMailAjaxRemoteStorage(); } - RL.reloadMessageListHelper(0 === RL.data().messageList().length); - RL.quotaDebounce(); - } -}; + return this.oRemote; + }; -/** - * @param {string} sFromFolderFullNameRaw - * @param {Array} aUidForRemove - */ -RainLoopApp.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove) -{ - this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); - RL.data().removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); -}; - -/** - * @param {number} iDeleteType - * @param {string} sFromFolderFullNameRaw - * @param {Array} aUidForRemove - * @param {boolean=} bUseFolder = true - */ -RainLoopApp.prototype.deleteMessagesFromFolder = function (iDeleteType, sFromFolderFullNameRaw, aUidForRemove, bUseFolder) -{ - var - self = this, - oData = RL.data(), - oCache = RL.cache(), - oMoveFolder = null, - nSetSystemFoldersNotification = null - ; - - switch (iDeleteType) + /** + * @return {WebMailCacheStorage} + */ + RainLoopApp.prototype.cache = function () { - case Enums.FolderType.Spam: - oMoveFolder = oCache.getFolderFromCacheList(oData.spamFolder()); - nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Spam; - break; - case Enums.FolderType.NotSpam: - oMoveFolder = oCache.getFolderFromCacheList('INBOX'); - break; - case Enums.FolderType.Trash: - oMoveFolder = oCache.getFolderFromCacheList(oData.trashFolder()); - nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Trash; - break; - case Enums.FolderType.Archive: - oMoveFolder = oCache.getFolderFromCacheList(oData.archiveFolder()); - nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Archive; - break; - } - - bUseFolder = Utils.isUnd(bUseFolder) ? true : !!bUseFolder; - if (bUseFolder) - { - if ((Enums.FolderType.Spam === iDeleteType && Consts.Values.UnuseOptionValue === oData.spamFolder()) || - (Enums.FolderType.Trash === iDeleteType && Consts.Values.UnuseOptionValue === oData.trashFolder()) || - (Enums.FolderType.Archive === iDeleteType && Consts.Values.UnuseOptionValue === oData.archiveFolder())) + if (null === this.oCache) { - bUseFolder = false; + this.oCache = new WebMailCacheStorage(); } - } - if (!oMoveFolder && bUseFolder) + return this.oCache; + }; + + RainLoopApp.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function () { - kn.showScreenPopup(PopupsFolderSystemViewModel, [nSetSystemFoldersNotification]); - } - else if (!bUseFolder || (Enums.FolderType.Trash === iDeleteType && - (sFromFolderFullNameRaw === oData.spamFolder() || sFromFolderFullNameRaw === oData.trashFolder()))) - { - kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () { + var oCache = RL.cache(); + _.each(RL.data().messageList(), function (oMessage) { + oCache.initMessageFlagsFromCache(oMessage); + }); - self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); - oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); + oCache.initMessageFlagsFromCache(RL.data().message()); + }; - }]); - } - else if (oMoveFolder) - { - this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove); - oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); - } -}; - -/** - * @param {string} sFromFolderFullNameRaw - * @param {Array} aUidForMove - * @param {string} sToFolderFullNameRaw - * @param {boolean=} bCopy = false - */ -RainLoopApp.prototype.moveMessagesToFolder = function (sFromFolderFullNameRaw, aUidForMove, sToFolderFullNameRaw, bCopy) -{ - if (sFromFolderFullNameRaw !== sToFolderFullNameRaw && Utils.isArray(aUidForMove) && 0 < aUidForMove.length) + /** + * @param {boolean=} bDropPagePosition = false + * @param {boolean=} bDropCurrenFolderCache = false + */ + RainLoopApp.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache) { var - oFromFolder = RL.cache().getFolderFromCacheList(sFromFolderFullNameRaw), - oToFolder = RL.cache().getFolderFromCacheList(sToFolderFullNameRaw) + oRLData = RL.data(), + iOffset = (oRLData.messageListPage() - 1) * oRLData.messagesPerPage() ; - if (oFromFolder && oToFolder) + if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache) { - if (Utils.isUnd(bCopy) ? false : !!bCopy) - { - this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); - } - else - { - this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); - } - - RL.data().removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); - return true; + RL.cache().setFolderHash(oRLData.currentFolderFullNameRaw(), ''); } - } - return false; -}; - -/** - * @param {Function=} fCallback - */ -RainLoopApp.prototype.folders = function (fCallback) -{ - this.data().foldersLoading(true); - this.remote().folders(_.bind(function (sResult, oData) { - - RL.data().foldersLoading(false); - if (Enums.StorageResultType.Success === sResult) + if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition) { - this.data().setFolders(oData); - if (fCallback) - { - fCallback(true); - } + oRLData.messageListPage(1); + iOffset = 0; } - else - { - if (fCallback) - { - fCallback(false); - } - } - }, this)); -}; -RainLoopApp.prototype.reloadOpenPgpKeys = function () -{ - if (RL.data().capaOpenPGP()) + oRLData.messageListLoading(true); + RL.remote().messageList(function (sResult, oData, bCached) { + + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) + { + oRLData.messageListError(''); + oRLData.messageListLoading(false); + oRLData.setMessageList(oData, bCached); + } + else if (Enums.StorageResultType.Unload === sResult) + { + oRLData.messageListError(''); + oRLData.messageListLoading(false); + } + else if (Enums.StorageResultType.Abort !== sResult) + { + oRLData.messageList([]); + oRLData.messageListLoading(false); + oRLData.messageListError(oData && oData.ErrorCode ? + Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST') + ); + } + + }, oRLData.currentFolderFullNameRaw(), iOffset, oRLData.messagesPerPage(), oRLData.messageListSearch()); + }; + + RainLoopApp.prototype.recacheInboxMessageList = function () { - var - aKeys = [], - oEmail = new EmailModel(), - oOpenpgpKeyring = RL.data().openpgpKeyring, - oOpenpgpKeys = oOpenpgpKeyring ? oOpenpgpKeyring.getAllKeys() : [] - ; + RL.remote().messageList(Utils.emptyFunction, 'INBOX', 0, RL.data().messagesPerPage(), '', true); + }; - _.each(oOpenpgpKeys, function (oItem, iIndex) { - if (oItem && oItem.primaryKey) + RainLoopApp.prototype.reloadMessageListHelper = function (bEmptyList) + { + RL.reloadMessageList(bEmptyList); + }; + + /** + * @param {Function} fResultFunc + * @returns {boolean} + */ + RainLoopApp.prototype.contactsSync = function (fResultFunc) + { + var oContacts = RL.data().contacts; + if (oContacts.importing() || oContacts.syncing() || !RL.data().enableContactsSync() || !RL.data().allowContactsSync()) + { + return false; + } + + oContacts.syncing(true); + + RL.remote().contactsSync(function (sResult, oData) { + + oContacts.syncing(false); + + if (fResultFunc) { - var - - oPrimaryUser = oItem.getPrimaryUser(), - sUser = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid - : (oItem.users && oItem.users[0] ? oItem.users[0].userId.userid : '') - ; - - oEmail.clear(); - oEmail.mailsoParse(sUser); - - if (oEmail.validate()) - { - aKeys.push(new OpenPgpKeyModel( - iIndex, - oItem.primaryKey.getFingerprint(), - oItem.primaryKey.getKeyId().toHex().toLowerCase(), - sUser, - oEmail.email, - oItem.isPrivate(), - oItem.armor()) - ); - } + fResultFunc(sResult, oData); } }); - RL.data().openpgpkeys(aKeys); - } -}; + return true; + }; -RainLoopApp.prototype.accountsAndIdentities = function () -{ - var oRainLoopData = RL.data(); + RainLoopApp.prototype.messagesMoveTrigger = function () + { + var + self = this, + sSpamFolder = RL.data().spamFolder() + ; - oRainLoopData.accountsLoading(true); - oRainLoopData.identitiesLoading(true); + _.each(this.oMoveCache, function (oItem) { - RL.remote().accountsAndIdentities(function (sResult, oData) { - - oRainLoopData.accountsLoading(false); - oRainLoopData.identitiesLoading(false); - - if (Enums.StorageResultType.Success === sResult && oData.Result) - { var - sParentEmail = RL.settingsGet('ParentEmail'), - sAccountEmail = oRainLoopData.accountEmail() + bSpam = sSpamFolder === oItem['To'], + bHam = !bSpam && sSpamFolder === oItem['From'] && 'INBOX' === oItem['To'] ; - sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail; + RL.remote().messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'], + bSpam ? 'SPAM' : (bHam ? 'HAM' : '')); + }); - if (Utils.isArray(oData.Result['Accounts'])) - { - oRainLoopData.accounts(_.map(oData.Result['Accounts'], function (sValue) { - return new AccountModel(sValue, sValue !== sParentEmail); - })); - } + this.oMoveCache = {}; + }; - if (Utils.isArray(oData.Result['Identities'])) - { - oRainLoopData.identities(_.map(oData.Result['Identities'], function (oIdentityData) { - - var - sId = Utils.pString(oIdentityData['Id']), - sEmail = Utils.pString(oIdentityData['Email']), - oIdentity = new IdentityModel(sId, sEmail, sId !== sAccountEmail) - ; - - oIdentity.name(Utils.pString(oIdentityData['Name'])); - oIdentity.replyTo(Utils.pString(oIdentityData['ReplyTo'])); - oIdentity.bcc(Utils.pString(oIdentityData['Bcc'])); - - return oIdentity; - })); - } - } - }); -}; - -RainLoopApp.prototype.quota = function () -{ - this.remote().quota(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData && oData.Result && - Utils.isArray(oData.Result) && 1 < oData.Result.length && - Utils.isPosNumeric(oData.Result[0], true) && Utils.isPosNumeric(oData.Result[1], true)) - { - RL.data().userQuota(Utils.pInt(oData.Result[1]) * 1024); - RL.data().userUsageSize(Utils.pInt(oData.Result[0]) * 1024); - } - }); -}; - -/** - * @param {string} sFolder - * @param {Array=} aList = [] - */ -RainLoopApp.prototype.folderInformation = function (sFolder, aList) -{ - if ('' !== Utils.trim(sFolder)) + RainLoopApp.prototype.messagesMoveHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForMove) { - this.remote().folderInformation(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult) + var sH = '$$' + sFromFolderFullNameRaw + '$$' + sToFolderFullNameRaw + '$$'; + if (!this.oMoveCache[sH]) + { + this.oMoveCache[sH] = { + 'From': sFromFolderFullNameRaw, + 'To': sToFolderFullNameRaw, + 'Uid': [] + }; + } + + this.oMoveCache[sH]['Uid'] = _.union(this.oMoveCache[sH]['Uid'], aUidForMove); + this.messagesMoveTrigger(); + }; + + RainLoopApp.prototype.messagesCopyHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy) + { + RL.remote().messagesCopy( + this.moveOrDeleteResponseHelper, + sFromFolderFullNameRaw, + sToFolderFullNameRaw, + aUidForCopy + ); + }; + + RainLoopApp.prototype.messagesDeleteHelper = function (sFromFolderFullNameRaw, aUidForRemove) + { + RL.remote().messagesDelete( + this.moveOrDeleteResponseHelper, + sFromFolderFullNameRaw, + aUidForRemove + ); + }; + + RainLoopApp.prototype.moveOrDeleteResponseHelper = function (sResult, oData) + { + if (Enums.StorageResultType.Success === sResult && RL.data().currentFolder()) + { + if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length) { - if (oData && oData.Result && oData.Result.Hash && oData.Result.Folder) + RL.cache().setFolderHash(oData.Result[0], oData.Result[1]); + } + else + { + RL.cache().setFolderHash(RL.data().currentFolderFullNameRaw(), ''); + + if (oData && -1 < Utils.inArray(oData.ErrorCode, + [Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage])) { - var - iUtc = moment().unix(), - sHash = RL.cache().getFolderHash(oData.Result.Folder), - oFolder = RL.cache().getFolderFromCacheList(oData.Result.Folder), - bCheck = false, - sUid = '', - aList = [], - bUnreadCountChange = false, - oFlags = null - ; - - if (oFolder) - { - oFolder.interval = iUtc; - - if (oData.Result.Hash) - { - RL.cache().setFolderHash(oData.Result.Folder, oData.Result.Hash); - } - - if (Utils.isNormal(oData.Result.MessageCount)) - { - oFolder.messageCountAll(oData.Result.MessageCount); - } - - if (Utils.isNormal(oData.Result.MessageUnseenCount)) - { - if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount)) - { - bUnreadCountChange = true; - } - - oFolder.messageCountUnread(oData.Result.MessageUnseenCount); - } - - if (bUnreadCountChange) - { - RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); - } - - if (oData.Result.Flags) - { - for (sUid in oData.Result.Flags) - { - if (oData.Result.Flags.hasOwnProperty(sUid)) - { - bCheck = true; - oFlags = oData.Result.Flags[sUid]; - RL.cache().storeMessageFlagsToCacheByFolderAndUid(oFolder.fullNameRaw, sUid.toString(), [ - !oFlags['IsSeen'], !!oFlags['IsFlagged'], !!oFlags['IsAnswered'], !!oFlags['IsForwarded'], !!oFlags['IsReadReceipt'] - ]); - } - } - - if (bCheck) - { - RL.reloadFlagsCurrentMessageListAndMessageFromCache(); - } - } - - RL.data().initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); - - if (oData.Result.Hash !== sHash || '' === sHash) - { - if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw()) - { - RL.reloadMessageList(); - } - else if ('INBOX' === oFolder.fullNameRaw) - { - RL.recacheInboxMessageList(); - } - } - else if (bUnreadCountChange) - { - if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw()) - { - aList = RL.data().messageList(); - if (Utils.isNonEmptyArray(aList)) - { - RL.folderInformation(oFolder.fullNameRaw, aList); - } - } - } - } + window.alert(Utils.getNotification(oData.ErrorCode)); } } - }, sFolder, aList); - } -}; -/** - * @param {boolean=} bBoot = false - */ -RainLoopApp.prototype.folderInformationMultiply = function (bBoot) -{ - bBoot = Utils.isUnd(bBoot) ? false : !!bBoot; + RL.reloadMessageListHelper(0 === RL.data().messageList().length); + RL.quotaDebounce(); + } + }; - var - iUtc = moment().unix(), - aFolders = RL.data().getNextFolderNames(bBoot) - ; - - if (Utils.isNonEmptyArray(aFolders)) + /** + * @param {string} sFromFolderFullNameRaw + * @param {Array} aUidForRemove + */ + RainLoopApp.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove) { - this.remote().folderInformationMultiply(function (sResult, oData) { + this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); + RL.data().removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); + }; + + /** + * @param {number} iDeleteType + * @param {string} sFromFolderFullNameRaw + * @param {Array} aUidForRemove + * @param {boolean=} bUseFolder = true + */ + RainLoopApp.prototype.deleteMessagesFromFolder = function (iDeleteType, sFromFolderFullNameRaw, aUidForRemove, bUseFolder) + { + var + self = this, + oData = RL.data(), + oCache = RL.cache(), + oMoveFolder = null, + nSetSystemFoldersNotification = null + ; + + switch (iDeleteType) + { + case Enums.FolderType.Spam: + oMoveFolder = oCache.getFolderFromCacheList(oData.spamFolder()); + nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Spam; + break; + case Enums.FolderType.NotSpam: + oMoveFolder = oCache.getFolderFromCacheList('INBOX'); + break; + case Enums.FolderType.Trash: + oMoveFolder = oCache.getFolderFromCacheList(oData.trashFolder()); + nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Trash; + break; + case Enums.FolderType.Archive: + oMoveFolder = oCache.getFolderFromCacheList(oData.archiveFolder()); + nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Archive; + break; + } + + bUseFolder = Utils.isUnd(bUseFolder) ? true : !!bUseFolder; + if (bUseFolder) + { + if ((Enums.FolderType.Spam === iDeleteType && Consts.Values.UnuseOptionValue === oData.spamFolder()) || + (Enums.FolderType.Trash === iDeleteType && Consts.Values.UnuseOptionValue === oData.trashFolder()) || + (Enums.FolderType.Archive === iDeleteType && Consts.Values.UnuseOptionValue === oData.archiveFolder())) + { + bUseFolder = false; + } + } + + if (!oMoveFolder && bUseFolder) + { + kn.showScreenPopup(PopupsFolderSystemViewModel, [nSetSystemFoldersNotification]); + } + else if (!bUseFolder || (Enums.FolderType.Trash === iDeleteType && + (sFromFolderFullNameRaw === oData.spamFolder() || sFromFolderFullNameRaw === oData.trashFolder()))) + { + kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () { + + self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove); + oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove); + + }]); + } + else if (oMoveFolder) + { + this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove); + oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw); + } + }; + + /** + * @param {string} sFromFolderFullNameRaw + * @param {Array} aUidForMove + * @param {string} sToFolderFullNameRaw + * @param {boolean=} bCopy = false + */ + RainLoopApp.prototype.moveMessagesToFolder = function (sFromFolderFullNameRaw, aUidForMove, sToFolderFullNameRaw, bCopy) + { + if (sFromFolderFullNameRaw !== sToFolderFullNameRaw && Utils.isArray(aUidForMove) && 0 < aUidForMove.length) + { + var + oFromFolder = RL.cache().getFolderFromCacheList(sFromFolderFullNameRaw), + oToFolder = RL.cache().getFolderFromCacheList(sToFolderFullNameRaw) + ; + + if (oFromFolder && oToFolder) + { + if (Utils.isUnd(bCopy) ? false : !!bCopy) + { + this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); + } + else + { + this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove); + } + + RL.data().removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy); + return true; + } + } + + return false; + }; + + /** + * @param {Function=} fCallback + */ + RainLoopApp.prototype.folders = function (fCallback) + { + this.data().foldersLoading(true); + this.remote().folders(_.bind(function (sResult, oData) { + + RL.data().foldersLoading(false); if (Enums.StorageResultType.Success === sResult) { - if (oData && oData.Result && oData.Result.List && Utils.isNonEmptyArray(oData.Result.List)) + this.data().setFolders(oData); + if (fCallback) { - _.each(oData.Result.List, function (oItem) { + fCallback(true); + } + } + else + { + if (fCallback) + { + fCallback(false); + } + } + }, this)); + }; + + RainLoopApp.prototype.reloadOpenPgpKeys = function () + { + if (RL.data().capaOpenPGP()) + { + var + aKeys = [], + oEmail = new EmailModel(), + oOpenpgpKeyring = RL.data().openpgpKeyring, + oOpenpgpKeys = oOpenpgpKeyring ? oOpenpgpKeyring.getAllKeys() : [] + ; + + _.each(oOpenpgpKeys, function (oItem, iIndex) { + if (oItem && oItem.primaryKey) + { + var + + oPrimaryUser = oItem.getPrimaryUser(), + sUser = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid + : (oItem.users && oItem.users[0] ? oItem.users[0].userId.userid : '') + ; + + oEmail.clear(); + oEmail.mailsoParse(sUser); + + if (oEmail.validate()) + { + aKeys.push(new OpenPgpKeyModel( + iIndex, + oItem.primaryKey.getFingerprint(), + oItem.primaryKey.getKeyId().toHex().toLowerCase(), + sUser, + oEmail.email, + oItem.isPrivate(), + oItem.armor()) + ); + } + } + }); + + RL.data().openpgpkeys(aKeys); + } + }; + + RainLoopApp.prototype.accountsAndIdentities = function () + { + var oRainLoopData = RL.data(); + + oRainLoopData.accountsLoading(true); + oRainLoopData.identitiesLoading(true); + + RL.remote().accountsAndIdentities(function (sResult, oData) { + + oRainLoopData.accountsLoading(false); + oRainLoopData.identitiesLoading(false); + + if (Enums.StorageResultType.Success === sResult && oData.Result) + { + var + sParentEmail = RL.settingsGet('ParentEmail'), + sAccountEmail = oRainLoopData.accountEmail() + ; + + sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail; + + if (Utils.isArray(oData.Result['Accounts'])) + { + oRainLoopData.accounts(_.map(oData.Result['Accounts'], function (sValue) { + return new AccountModel(sValue, sValue !== sParentEmail); + })); + } + + if (Utils.isArray(oData.Result['Identities'])) + { + oRainLoopData.identities(_.map(oData.Result['Identities'], function (oIdentityData) { var + sId = Utils.pString(oIdentityData['Id']), + sEmail = Utils.pString(oIdentityData['Email']), + oIdentity = new IdentityModel(sId, sEmail, sId !== sAccountEmail) + ; + + oIdentity.name(Utils.pString(oIdentityData['Name'])); + oIdentity.replyTo(Utils.pString(oIdentityData['ReplyTo'])); + oIdentity.bcc(Utils.pString(oIdentityData['Bcc'])); + + return oIdentity; + })); + } + } + }); + }; + + RainLoopApp.prototype.quota = function () + { + this.remote().quota(function (sResult, oData) { + if (Enums.StorageResultType.Success === sResult && oData && oData.Result && + Utils.isArray(oData.Result) && 1 < oData.Result.length && + Utils.isPosNumeric(oData.Result[0], true) && Utils.isPosNumeric(oData.Result[1], true)) + { + RL.data().userQuota(Utils.pInt(oData.Result[1]) * 1024); + RL.data().userUsageSize(Utils.pInt(oData.Result[0]) * 1024); + } + }); + }; + + /** + * @param {string} sFolder + * @param {Array=} aList = [] + */ + RainLoopApp.prototype.folderInformation = function (sFolder, aList) + { + if ('' !== Utils.trim(sFolder)) + { + this.remote().folderInformation(function (sResult, oData) { + if (Enums.StorageResultType.Success === sResult) + { + if (oData && oData.Result && oData.Result.Hash && oData.Result.Folder) + { + var + iUtc = moment().unix(), + sHash = RL.cache().getFolderHash(oData.Result.Folder), + oFolder = RL.cache().getFolderFromCacheList(oData.Result.Folder), + bCheck = false, + sUid = '', aList = [], - sHash = RL.cache().getFolderHash(oItem.Folder), - oFolder = RL.cache().getFolderFromCacheList(oItem.Folder), - bUnreadCountChange = false + bUnreadCountChange = false, + oFlags = null ; if (oFolder) { oFolder.interval = iUtc; - if (oItem.Hash) + if (oData.Result.Hash) { - RL.cache().setFolderHash(oItem.Folder, oItem.Hash); + RL.cache().setFolderHash(oData.Result.Folder, oData.Result.Hash); } - if (Utils.isNormal(oItem.MessageCount)) + if (Utils.isNormal(oData.Result.MessageCount)) { - oFolder.messageCountAll(oItem.MessageCount); + oFolder.messageCountAll(oData.Result.MessageCount); } - if (Utils.isNormal(oItem.MessageUnseenCount)) + if (Utils.isNormal(oData.Result.MessageUnseenCount)) { - if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oItem.MessageUnseenCount)) + if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount)) { bUnreadCountChange = true; } - oFolder.messageCountUnread(oItem.MessageUnseenCount); + oFolder.messageCountUnread(oData.Result.MessageUnseenCount); } if (bUnreadCountChange) @@ -689,12 +598,38 @@ RainLoopApp.prototype.folderInformationMultiply = function (bBoot) RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); } - if (oItem.Hash !== sHash || '' === sHash) + if (oData.Result.Flags) + { + for (sUid in oData.Result.Flags) + { + if (oData.Result.Flags.hasOwnProperty(sUid)) + { + bCheck = true; + oFlags = oData.Result.Flags[sUid]; + RL.cache().storeMessageFlagsToCacheByFolderAndUid(oFolder.fullNameRaw, sUid.toString(), [ + !oFlags['IsSeen'], !!oFlags['IsFlagged'], !!oFlags['IsAnswered'], !!oFlags['IsForwarded'], !!oFlags['IsReadReceipt'] + ]); + } + } + + if (bCheck) + { + RL.reloadFlagsCurrentMessageListAndMessageFromCache(); + } + } + + RL.data().initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages); + + if (oData.Result.Hash !== sHash || '' === sHash) { if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw()) { RL.reloadMessageList(); } + else if ('INBOX' === oFolder.fullNameRaw) + { + RL.recacheInboxMessageList(); + } } else if (bUnreadCountChange) { @@ -708,586 +643,667 @@ RainLoopApp.prototype.folderInformationMultiply = function (bBoot) } } } - }); - - if (bBoot) - { - RL.folderInformationMultiply(true); } } - } - }, aFolders); - } -}; - -RainLoopApp.prototype.setMessageSeen = function (oMessage) -{ - if (oMessage.unseen()) - { - oMessage.unseen(false); - - var oFolder = RL.cache().getFolderFromCacheList(oMessage.folderFullNameRaw); - if (oFolder) - { - oFolder.messageCountUnread(0 <= oFolder.messageCountUnread() - 1 ? - oFolder.messageCountUnread() - 1 : 0); + }, sFolder, aList); } + }; - RL.cache().storeMessageFlagsToCache(oMessage); - RL.reloadFlagsCurrentMessageListAndMessageFromCache(); - } - - RL.remote().messageSetSeen(Utils.emptyFunction, oMessage.folderFullNameRaw, [oMessage.uid], true); -}; - -RainLoopApp.prototype.googleConnect = function () -{ - window.open(RL.link().socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes'); -}; - -RainLoopApp.prototype.twitterConnect = function () -{ - window.open(RL.link().socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes'); -}; - -RainLoopApp.prototype.facebookConnect = function () -{ - window.open(RL.link().socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes'); -}; - -/** - * @param {boolean=} bFireAllActions - */ -RainLoopApp.prototype.socialUsers = function (bFireAllActions) -{ - var oRainLoopData = RL.data(); - - if (bFireAllActions) + /** + * @param {boolean=} bBoot = false + */ + RainLoopApp.prototype.folderInformationMultiply = function (bBoot) { - oRainLoopData.googleActions(true); - oRainLoopData.facebookActions(true); - oRainLoopData.twitterActions(true); - } - - RL.remote().socialUsers(function (sResult, oData) { - - if (Enums.StorageResultType.Success === sResult && oData && oData.Result) - { - oRainLoopData.googleUserName(oData.Result['Google'] || ''); - oRainLoopData.facebookUserName(oData.Result['Facebook'] || ''); - oRainLoopData.twitterUserName(oData.Result['Twitter'] || ''); - } - else - { - oRainLoopData.googleUserName(''); - oRainLoopData.facebookUserName(''); - oRainLoopData.twitterUserName(''); - } - - oRainLoopData.googleLoggined('' !== oRainLoopData.googleUserName()); - oRainLoopData.facebookLoggined('' !== oRainLoopData.facebookUserName()); - oRainLoopData.twitterLoggined('' !== oRainLoopData.twitterUserName()); - - oRainLoopData.googleActions(false); - oRainLoopData.facebookActions(false); - oRainLoopData.twitterActions(false); - }); -}; - -RainLoopApp.prototype.googleDisconnect = function () -{ - RL.data().googleActions(true); - RL.remote().googleDisconnect(function () { - RL.socialUsers(); - }); -}; - -RainLoopApp.prototype.facebookDisconnect = function () -{ - RL.data().facebookActions(true); - RL.remote().facebookDisconnect(function () { - RL.socialUsers(); - }); -}; - -RainLoopApp.prototype.twitterDisconnect = function () -{ - RL.data().twitterActions(true); - RL.remote().twitterDisconnect(function () { - RL.socialUsers(); - }); -}; - -/** - * @param {Array} aSystem - * @param {Array} aList - * @param {Array=} aDisabled - * @param {Array=} aHeaderLines - * @param {?number=} iUnDeep - * @param {Function=} fDisableCallback - * @param {Function=} fVisibleCallback - * @param {Function=} fRenameCallback - * @param {boolean=} bSystem - * @param {boolean=} bBuildUnvisible - * @return {Array} - */ -RainLoopApp.prototype.folderListOptionsBuilder = function (aSystem, aList, aDisabled, aHeaderLines, iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible) -{ - var - iIndex = 0, - iLen = 0, - /** - * @type {?FolderModel} - */ - oItem = null, - bSep = false, - sDeepPrefix = '\u00A0\u00A0\u00A0', - aResult = [] - ; - - bSystem = !Utils.isNormal(bSystem) ? 0 < aSystem.length : bSystem; - bBuildUnvisible = Utils.isUnd(bBuildUnvisible) ? false : !!bBuildUnvisible; - iUnDeep = !Utils.isNormal(iUnDeep) ? 0 : iUnDeep; - fDisableCallback = Utils.isNormal(fDisableCallback) ? fDisableCallback : null; - fVisibleCallback = Utils.isNormal(fVisibleCallback) ? fVisibleCallback : null; - fRenameCallback = Utils.isNormal(fRenameCallback) ? fRenameCallback : null; - - if (!Utils.isArray(aDisabled)) - { - aDisabled = []; - } - - if (!Utils.isArray(aHeaderLines)) - { - aHeaderLines = []; - } - - for (iIndex = 0, iLen = aHeaderLines.length; iIndex < iLen; iIndex++) - { - aResult.push({ - 'id': aHeaderLines[iIndex][0], - 'name': aHeaderLines[iIndex][1], - 'system': false, - 'seporator': false, - 'disabled': false - }); - } - - bSep = true; - for (iIndex = 0, iLen = aSystem.length; iIndex < iLen; iIndex++) - { - oItem = aSystem[iIndex]; - if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) - { - if (bSep && 0 < aResult.length) - { - aResult.push({ - 'id': '---', - 'name': '---', - 'system': false, - 'seporator': true, - 'disabled': true - }); - } - - bSep = false; - aResult.push({ - 'id': oItem.fullNameRaw, - 'name': fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name(), - 'system': true, - 'seporator': false, - 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || - (fDisableCallback ? fDisableCallback.call(null, oItem) : false) - }); - } - } - - bSep = true; - for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++) - { - oItem = aList[iIndex]; - if (oItem.subScribed() || !oItem.existen) - { - if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) - { - if (Enums.FolderType.User === oItem.type() || !bSystem || 0 < oItem.subFolders().length) - { - if (bSep && 0 < aResult.length) - { - aResult.push({ - 'id': '---', - 'name': '---', - 'system': false, - 'seporator': true, - 'disabled': true - }); - } - - bSep = false; - aResult.push({ - 'id': oItem.fullNameRaw, - 'name': (new window.Array(oItem.deep + 1 - iUnDeep)).join(sDeepPrefix) + - (fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name()), - 'system': false, - 'seporator': false, - 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || - (fDisableCallback ? fDisableCallback.call(null, oItem) : false) - }); - } - } - } - - if (oItem.subScribed() && 0 < oItem.subFolders().length) - { - aResult = aResult.concat(RL.folderListOptionsBuilder([], oItem.subFolders(), aDisabled, [], - iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible)); - } - } - - return aResult; -}; - -/** - * @param {string} sQuery - * @param {Function} fCallback - */ -RainLoopApp.prototype.getAutocomplete = function (sQuery, fCallback) -{ - var - aData = [] - ; - - RL.remote().suggestions(function (sResult, oData) { - if (Enums.StorageResultType.Success === sResult && oData && Utils.isArray(oData.Result)) - { - aData = _.map(oData.Result, function (aItem) { - return aItem && aItem[0] ? new EmailModel(aItem[0], aItem[1]) : null; - }); - - fCallback(_.compact(aData)); - } - else if (Enums.StorageResultType.Abort !== sResult) - { - fCallback([]); - } - - }, sQuery); -}; - -/** - * @param {string} sQuery - * @param {Function} fCallback - */ -RainLoopApp.prototype.getContactTagsAutocomplete = function (sQuery, fCallback) -{ - fCallback(_.filter(RL.data().contactTags(), function (oContactTag) { - return oContactTag && oContactTag.filterHelper(sQuery); - })); -}; - -/** - * @param {string} sMailToUrl - * @returns {boolean} - */ -RainLoopApp.prototype.mailToHelper = function (sMailToUrl) -{ - if (sMailToUrl && 'mailto:' === sMailToUrl.toString().substr(0, 7).toLowerCase()) - { - sMailToUrl = sMailToUrl.toString().substr(7); + bBoot = Utils.isUnd(bBoot) ? false : !!bBoot; var - oParams = {}, - oEmailModel = null, - sEmail = sMailToUrl.replace(/\?.+$/, ''), - sQueryString = sMailToUrl.replace(/^[^\?]*\?/, '') + iUtc = moment().unix(), + aFolders = RL.data().getNextFolderNames(bBoot) ; - oEmailModel = new EmailModel(); - oEmailModel.parse(window.decodeURIComponent(sEmail)); - - if (oEmailModel && oEmailModel.email) + if (Utils.isNonEmptyArray(aFolders)) { - oParams = Utils.simpleQueryParser(sQueryString); - kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Empty, null, [oEmailModel], - Utils.isUnd(oParams.subject) ? null : Utils.pString(oParams.subject), - Utils.isUnd(oParams.body) ? null : Utils.plainToHtml(Utils.pString(oParams.body)) - ]); + this.remote().folderInformationMultiply(function (sResult, oData) { + if (Enums.StorageResultType.Success === sResult) + { + if (oData && oData.Result && oData.Result.List && Utils.isNonEmptyArray(oData.Result.List)) + { + _.each(oData.Result.List, function (oItem) { + + var + aList = [], + sHash = RL.cache().getFolderHash(oItem.Folder), + oFolder = RL.cache().getFolderFromCacheList(oItem.Folder), + bUnreadCountChange = false + ; + + if (oFolder) + { + oFolder.interval = iUtc; + + if (oItem.Hash) + { + RL.cache().setFolderHash(oItem.Folder, oItem.Hash); + } + + if (Utils.isNormal(oItem.MessageCount)) + { + oFolder.messageCountAll(oItem.MessageCount); + } + + if (Utils.isNormal(oItem.MessageUnseenCount)) + { + if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oItem.MessageUnseenCount)) + { + bUnreadCountChange = true; + } + + oFolder.messageCountUnread(oItem.MessageUnseenCount); + } + + if (bUnreadCountChange) + { + RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw); + } + + if (oItem.Hash !== sHash || '' === sHash) + { + if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw()) + { + RL.reloadMessageList(); + } + } + else if (bUnreadCountChange) + { + if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw()) + { + aList = RL.data().messageList(); + if (Utils.isNonEmptyArray(aList)) + { + RL.folderInformation(oFolder.fullNameRaw, aList); + } + } + } + } + }); + + if (bBoot) + { + RL.folderInformationMultiply(true); + } + } + } + }, aFolders); + } + }; + + RainLoopApp.prototype.setMessageSeen = function (oMessage) + { + if (oMessage.unseen()) + { + oMessage.unseen(false); + + var oFolder = RL.cache().getFolderFromCacheList(oMessage.folderFullNameRaw); + if (oFolder) + { + oFolder.messageCountUnread(0 <= oFolder.messageCountUnread() - 1 ? + oFolder.messageCountUnread() - 1 : 0); + } + + RL.cache().storeMessageFlagsToCache(oMessage); + RL.reloadFlagsCurrentMessageListAndMessageFromCache(); } - return true; - } + RL.remote().messageSetSeen(Utils.emptyFunction, oMessage.folderFullNameRaw, [oMessage.uid], true); + }; - return false; -}; - -RainLoopApp.prototype.bootstart = function () -{ - RL.pub('rl.bootstart'); - AbstractApp.prototype.bootstart.call(this); - - RL.data().populateDataOnStart(); - - var - sCustomLoginLink = '', - sJsHash = RL.settingsGet('JsHash'), - iContactsSyncInterval = Utils.pInt(RL.settingsGet('ContactsSyncInterval')), - bGoogle = RL.settingsGet('AllowGoogleSocial'), - bFacebook = RL.settingsGet('AllowFacebookSocial'), - bTwitter = RL.settingsGet('AllowTwitterSocial') - ; - - if (!RL.settingsGet('ChangePasswordIsAllowed')) + RainLoopApp.prototype.googleConnect = function () { - Utils.removeSettingsViewModel(SettingsChangePasswordScreen); - } + window.open(RL.link().socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes'); + }; - if (!RL.settingsGet('ContactsIsAllowed')) + RainLoopApp.prototype.twitterConnect = function () { - Utils.removeSettingsViewModel(SettingsContacts); - } + window.open(RL.link().socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes'); + }; - if (!RL.capa(Enums.Capa.AdditionalAccounts)) + RainLoopApp.prototype.facebookConnect = function () { - Utils.removeSettingsViewModel(SettingsAccounts); - } + window.open(RL.link().socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes'); + }; - if (RL.capa(Enums.Capa.AdditionalIdentities)) + /** + * @param {boolean=} bFireAllActions + */ + RainLoopApp.prototype.socialUsers = function (bFireAllActions) { - Utils.removeSettingsViewModel(SettingsIdentity); - } - else - { - Utils.removeSettingsViewModel(SettingsIdentities); - } + var oRainLoopData = RL.data(); - if (!RL.capa(Enums.Capa.OpenPGP)) - { - Utils.removeSettingsViewModel(SettingsOpenPGP); - } + if (bFireAllActions) + { + oRainLoopData.googleActions(true); + oRainLoopData.facebookActions(true); + oRainLoopData.twitterActions(true); + } - if (!RL.capa(Enums.Capa.TwoFactor)) - { - Utils.removeSettingsViewModel(SettingsSecurity); - } + RL.remote().socialUsers(function (sResult, oData) { - if (!RL.capa(Enums.Capa.Themes)) - { - Utils.removeSettingsViewModel(SettingsThemes); - } - - if (!RL.capa(Enums.Capa.Filters)) - { - Utils.removeSettingsViewModel(SettingsFilters); - } - - if (!bGoogle && !bFacebook && !bTwitter) - { - Utils.removeSettingsViewModel(SettingsSocialScreen); - } - - Utils.initOnStartOrLangChange(function () { - - $.extend(true, $.magnificPopup.defaults, { - 'tClose': Utils.i18n('MAGNIFIC_POPUP/CLOSE'), - 'tLoading': Utils.i18n('MAGNIFIC_POPUP/LOADING'), - 'gallery': { - 'tPrev': Utils.i18n('MAGNIFIC_POPUP/GALLERY_PREV'), - 'tNext': Utils.i18n('MAGNIFIC_POPUP/GALLERY_NEXT'), - 'tCounter': Utils.i18n('MAGNIFIC_POPUP/GALLERY_COUNTER') - }, - 'image': { - 'tError': Utils.i18n('MAGNIFIC_POPUP/IMAGE_ERROR') - }, - 'ajax': { - 'tError': Utils.i18n('MAGNIFIC_POPUP/AJAX_ERROR') - } - }); - - }, this); - - if (window.SimplePace) - { - window.SimplePace.set(70); - window.SimplePace.sleep(); - } - - if (!!RL.settingsGet('Auth')) - { - this.setTitle(Utils.i18n('TITLES/LOADING')); - - this.folders(_.bind(function (bValue) { - - kn.hideLoading(); - - if (bValue) + if (Enums.StorageResultType.Success === sResult && oData && oData.Result) { - if (window.$LAB && window.crypto && window.crypto.getRandomValues && RL.capa(Enums.Capa.OpenPGP)) - { - window.$LAB.script(window.openpgp ? '' : RL.link().openPgpJs()).wait(function () { - if (window.openpgp) - { - RL.data().openpgpKeyring = new window.openpgp.Keyring(); - RL.data().capaOpenPGP(true); - - RL.pub('openpgp.init'); - - RL.reloadOpenPgpKeys(); - } - }); - } - else - { - RL.data().capaOpenPGP(false); - } - - kn.startScreens([MailBoxScreen, SettingsScreen]); - - if (bGoogle || bFacebook || bTwitter) - { - RL.socialUsers(true); - } - - RL.sub('interval.2m', function () { - RL.folderInformation('INBOX'); - }); - - RL.sub('interval.2m', function () { - var sF = RL.data().currentFolderFullNameRaw(); - if ('INBOX' !== sF) - { - RL.folderInformation(sF); - } - }); - - RL.sub('interval.3m', function () { - RL.folderInformationMultiply(); - }); - - RL.sub('interval.5m', function () { - RL.quota(); - }); - - RL.sub('interval.10m', function () { - RL.folders(); - }); - - iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20; - iContactsSyncInterval = 320 >= iContactsSyncInterval ? iContactsSyncInterval : 320; - - window.setInterval(function () { - RL.contactsSync(); - }, iContactsSyncInterval * 60000 + 5000); - - _.delay(function () { - RL.contactsSync(); - }, 5000); - - _.delay(function () { - RL.folderInformationMultiply(true); - }, 500); - - Plugins.runHook('rl-start-user-screens'); - RL.pub('rl.bootstart-user-screens'); - - if (!!RL.settingsGet('AccountSignMe') && window.navigator.registerProtocolHandler) - { - _.delay(function () { - try { - window.navigator.registerProtocolHandler('mailto', - window.location.protocol + '//' + window.location.host + window.location.pathname + '?mailto&to=%s', - '' + (RL.settingsGet('Title') || 'RainLoop')); - } catch(e) {} - - if (RL.settingsGet('MailToEmail')) - { - RL.mailToHelper(RL.settingsGet('MailToEmail')); - } - }, 500); - } + oRainLoopData.googleUserName(oData.Result['Google'] || ''); + oRainLoopData.facebookUserName(oData.Result['Facebook'] || ''); + oRainLoopData.twitterUserName(oData.Result['Twitter'] || ''); } else { + oRainLoopData.googleUserName(''); + oRainLoopData.facebookUserName(''); + oRainLoopData.twitterUserName(''); + } + + oRainLoopData.googleLoggined('' !== oRainLoopData.googleUserName()); + oRainLoopData.facebookLoggined('' !== oRainLoopData.facebookUserName()); + oRainLoopData.twitterLoggined('' !== oRainLoopData.twitterUserName()); + + oRainLoopData.googleActions(false); + oRainLoopData.facebookActions(false); + oRainLoopData.twitterActions(false); + }); + }; + + RainLoopApp.prototype.googleDisconnect = function () + { + RL.data().googleActions(true); + RL.remote().googleDisconnect(function () { + RL.socialUsers(); + }); + }; + + RainLoopApp.prototype.facebookDisconnect = function () + { + RL.data().facebookActions(true); + RL.remote().facebookDisconnect(function () { + RL.socialUsers(); + }); + }; + + RainLoopApp.prototype.twitterDisconnect = function () + { + RL.data().twitterActions(true); + RL.remote().twitterDisconnect(function () { + RL.socialUsers(); + }); + }; + + /** + * @param {Array} aSystem + * @param {Array} aList + * @param {Array=} aDisabled + * @param {Array=} aHeaderLines + * @param {?number=} iUnDeep + * @param {Function=} fDisableCallback + * @param {Function=} fVisibleCallback + * @param {Function=} fRenameCallback + * @param {boolean=} bSystem + * @param {boolean=} bBuildUnvisible + * @return {Array} + */ + RainLoopApp.prototype.folderListOptionsBuilder = function (aSystem, aList, aDisabled, aHeaderLines, iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible) + { + var + iIndex = 0, + iLen = 0, + /** + * @type {?FolderModel} + */ + oItem = null, + bSep = false, + sDeepPrefix = '\u00A0\u00A0\u00A0', + aResult = [] + ; + + bSystem = !Utils.isNormal(bSystem) ? 0 < aSystem.length : bSystem; + bBuildUnvisible = Utils.isUnd(bBuildUnvisible) ? false : !!bBuildUnvisible; + iUnDeep = !Utils.isNormal(iUnDeep) ? 0 : iUnDeep; + fDisableCallback = Utils.isNormal(fDisableCallback) ? fDisableCallback : null; + fVisibleCallback = Utils.isNormal(fVisibleCallback) ? fVisibleCallback : null; + fRenameCallback = Utils.isNormal(fRenameCallback) ? fRenameCallback : null; + + if (!Utils.isArray(aDisabled)) + { + aDisabled = []; + } + + if (!Utils.isArray(aHeaderLines)) + { + aHeaderLines = []; + } + + for (iIndex = 0, iLen = aHeaderLines.length; iIndex < iLen; iIndex++) + { + aResult.push({ + 'id': aHeaderLines[iIndex][0], + 'name': aHeaderLines[iIndex][1], + 'system': false, + 'seporator': false, + 'disabled': false + }); + } + + bSep = true; + for (iIndex = 0, iLen = aSystem.length; iIndex < iLen; iIndex++) + { + oItem = aSystem[iIndex]; + if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) + { + if (bSep && 0 < aResult.length) + { + aResult.push({ + 'id': '---', + 'name': '---', + 'system': false, + 'seporator': true, + 'disabled': true + }); + } + + bSep = false; + aResult.push({ + 'id': oItem.fullNameRaw, + 'name': fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name(), + 'system': true, + 'seporator': false, + 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || + (fDisableCallback ? fDisableCallback.call(null, oItem) : false) + }); + } + } + + bSep = true; + for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++) + { + oItem = aList[iIndex]; + if (oItem.subScribed() || !oItem.existen) + { + if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true) + { + if (Enums.FolderType.User === oItem.type() || !bSystem || 0 < oItem.subFolders().length) + { + if (bSep && 0 < aResult.length) + { + aResult.push({ + 'id': '---', + 'name': '---', + 'system': false, + 'seporator': true, + 'disabled': true + }); + } + + bSep = false; + aResult.push({ + 'id': oItem.fullNameRaw, + 'name': (new window.Array(oItem.deep + 1 - iUnDeep)).join(sDeepPrefix) + + (fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name()), + 'system': false, + 'seporator': false, + 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) || + (fDisableCallback ? fDisableCallback.call(null, oItem) : false) + }); + } + } + } + + if (oItem.subScribed() && 0 < oItem.subFolders().length) + { + aResult = aResult.concat(RL.folderListOptionsBuilder([], oItem.subFolders(), aDisabled, [], + iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible)); + } + } + + return aResult; + }; + + /** + * @param {string} sQuery + * @param {Function} fCallback + */ + RainLoopApp.prototype.getAutocomplete = function (sQuery, fCallback) + { + var + aData = [] + ; + + RL.remote().suggestions(function (sResult, oData) { + if (Enums.StorageResultType.Success === sResult && oData && Utils.isArray(oData.Result)) + { + aData = _.map(oData.Result, function (aItem) { + return aItem && aItem[0] ? new EmailModel(aItem[0], aItem[1]) : null; + }); + + fCallback(_.compact(aData)); + } + else if (Enums.StorageResultType.Abort !== sResult) + { + fCallback([]); + } + + }, sQuery); + }; + + /** + * @param {string} sQuery + * @param {Function} fCallback + */ + RainLoopApp.prototype.getContactTagsAutocomplete = function (sQuery, fCallback) + { + fCallback(_.filter(RL.data().contactTags(), function (oContactTag) { + return oContactTag && oContactTag.filterHelper(sQuery); + })); + }; + + /** + * @param {string} sMailToUrl + * @returns {boolean} + */ + RainLoopApp.prototype.mailToHelper = function (sMailToUrl) + { + if (sMailToUrl && 'mailto:' === sMailToUrl.toString().substr(0, 7).toLowerCase()) + { + sMailToUrl = sMailToUrl.toString().substr(7); + + var + oParams = {}, + oEmailModel = null, + sEmail = sMailToUrl.replace(/\?.+$/, ''), + sQueryString = sMailToUrl.replace(/^[^\?]*\?/, '') + ; + + oEmailModel = new EmailModel(); + oEmailModel.parse(window.decodeURIComponent(sEmail)); + + if (oEmailModel && oEmailModel.email) + { + oParams = Utils.simpleQueryParser(sQueryString); + kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Empty, null, [oEmailModel], + Utils.isUnd(oParams.subject) ? null : Utils.pString(oParams.subject), + Utils.isUnd(oParams.body) ? null : Utils.plainToHtml(Utils.pString(oParams.body)) + ]); + } + + return true; + } + + return false; + }; + + RainLoopApp.prototype.bootstart = function () + { + RL.pub('rl.bootstart'); + AbstractApp.prototype.bootstart.call(this); + + RL.data().populateDataOnStart(); + + var + sCustomLoginLink = '', + sJsHash = RL.settingsGet('JsHash'), + iContactsSyncInterval = Utils.pInt(RL.settingsGet('ContactsSyncInterval')), + bGoogle = RL.settingsGet('AllowGoogleSocial'), + bFacebook = RL.settingsGet('AllowFacebookSocial'), + bTwitter = RL.settingsGet('AllowTwitterSocial') + ; + + if (!RL.settingsGet('ChangePasswordIsAllowed')) + { + Utils.removeSettingsViewModel(SettingsChangePasswordScreen); + } + + if (!RL.settingsGet('ContactsIsAllowed')) + { + Utils.removeSettingsViewModel(SettingsContacts); + } + + if (!RL.capa(Enums.Capa.AdditionalAccounts)) + { + Utils.removeSettingsViewModel(SettingsAccounts); + } + + if (RL.capa(Enums.Capa.AdditionalIdentities)) + { + Utils.removeSettingsViewModel(SettingsIdentity); + } + else + { + Utils.removeSettingsViewModel(SettingsIdentities); + } + + if (!RL.capa(Enums.Capa.OpenPGP)) + { + Utils.removeSettingsViewModel(SettingsOpenPGP); + } + + if (!RL.capa(Enums.Capa.TwoFactor)) + { + Utils.removeSettingsViewModel(SettingsSecurity); + } + + if (!RL.capa(Enums.Capa.Themes)) + { + Utils.removeSettingsViewModel(SettingsThemes); + } + + if (!RL.capa(Enums.Capa.Filters)) + { + Utils.removeSettingsViewModel(SettingsFilters); + } + + if (!bGoogle && !bFacebook && !bTwitter) + { + Utils.removeSettingsViewModel(SettingsSocialScreen); + } + + Utils.initOnStartOrLangChange(function () { + + $.extend(true, $.magnificPopup.defaults, { + 'tClose': Utils.i18n('MAGNIFIC_POPUP/CLOSE'), + 'tLoading': Utils.i18n('MAGNIFIC_POPUP/LOADING'), + 'gallery': { + 'tPrev': Utils.i18n('MAGNIFIC_POPUP/GALLERY_PREV'), + 'tNext': Utils.i18n('MAGNIFIC_POPUP/GALLERY_NEXT'), + 'tCounter': Utils.i18n('MAGNIFIC_POPUP/GALLERY_COUNTER') + }, + 'image': { + 'tError': Utils.i18n('MAGNIFIC_POPUP/IMAGE_ERROR') + }, + 'ajax': { + 'tError': Utils.i18n('MAGNIFIC_POPUP/AJAX_ERROR') + } + }); + + }, this); + + if (window.SimplePace) + { + window.SimplePace.set(70); + window.SimplePace.sleep(); + } + + if (!!RL.settingsGet('Auth')) + { + this.setTitle(Utils.i18n('TITLES/LOADING')); + + this.folders(_.bind(function (bValue) { + + kn.hideLoading(); + + if (bValue) + { + if (window.$LAB && window.crypto && window.crypto.getRandomValues && RL.capa(Enums.Capa.OpenPGP)) + { + window.$LAB.script(window.openpgp ? '' : RL.link().openPgpJs()).wait(function () { + if (window.openpgp) + { + RL.data().openpgpKeyring = new window.openpgp.Keyring(); + RL.data().capaOpenPGP(true); + + RL.pub('openpgp.init'); + + RL.reloadOpenPgpKeys(); + } + }); + } + else + { + RL.data().capaOpenPGP(false); + } + + kn.startScreens([MailBoxScreen, SettingsScreen]); + + if (bGoogle || bFacebook || bTwitter) + { + RL.socialUsers(true); + } + + RL.sub('interval.2m', function () { + RL.folderInformation('INBOX'); + }); + + RL.sub('interval.2m', function () { + var sF = RL.data().currentFolderFullNameRaw(); + if ('INBOX' !== sF) + { + RL.folderInformation(sF); + } + }); + + RL.sub('interval.3m', function () { + RL.folderInformationMultiply(); + }); + + RL.sub('interval.5m', function () { + RL.quota(); + }); + + RL.sub('interval.10m', function () { + RL.folders(); + }); + + iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20; + iContactsSyncInterval = 320 >= iContactsSyncInterval ? iContactsSyncInterval : 320; + + window.setInterval(function () { + RL.contactsSync(); + }, iContactsSyncInterval * 60000 + 5000); + + _.delay(function () { + RL.contactsSync(); + }, 5000); + + _.delay(function () { + RL.folderInformationMultiply(true); + }, 500); + + Plugins.runHook('rl-start-user-screens'); + RL.pub('rl.bootstart-user-screens'); + + if (!!RL.settingsGet('AccountSignMe') && window.navigator.registerProtocolHandler) + { + _.delay(function () { + try { + window.navigator.registerProtocolHandler('mailto', + window.location.protocol + '//' + window.location.host + window.location.pathname + '?mailto&to=%s', + '' + (RL.settingsGet('Title') || 'RainLoop')); + } catch(e) {} + + if (RL.settingsGet('MailToEmail')) + { + RL.mailToHelper(RL.settingsGet('MailToEmail')); + } + }, 500); + } + } + else + { + kn.startScreens([LoginScreen]); + + Plugins.runHook('rl-start-login-screens'); + RL.pub('rl.bootstart-login-screens'); + } + + if (window.SimplePace) + { + window.SimplePace.set(100); + } + + if (!Globals.bMobileDevice) + { + _.defer(function () { + Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize); + }); + } + + }, this)); + } + else + { + sCustomLoginLink = Utils.pString(RL.settingsGet('CustomLoginLink')); + if (!sCustomLoginLink) + { + kn.hideLoading(); kn.startScreens([LoginScreen]); Plugins.runHook('rl-start-login-screens'); RL.pub('rl.bootstart-login-screens'); - } - if (window.SimplePace) - { - window.SimplePace.set(100); + if (window.SimplePace) + { + window.SimplePace.set(100); + } } - - if (!Globals.bMobileDevice) + else { + kn.routeOff(); + kn.setHash(RL.link().root(), true); + kn.routeOff(); + _.defer(function () { - Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize); + window.location.href = sCustomLoginLink; }); } - - }, this)); - } - else - { - sCustomLoginLink = Utils.pString(RL.settingsGet('CustomLoginLink')); - if (!sCustomLoginLink) - { - kn.hideLoading(); - kn.startScreens([LoginScreen]); - - Plugins.runHook('rl-start-login-screens'); - RL.pub('rl.bootstart-login-screens'); - - if (window.SimplePace) - { - window.SimplePace.set(100); - } } - else + + if (bGoogle) { - kn.routeOff(); - kn.setHash(RL.link().root(), true); - kn.routeOff(); - - _.defer(function () { - window.location.href = sCustomLoginLink; - }); + window['rl_' + sJsHash + '_google_service'] = function () { + RL.data().googleActions(true); + RL.socialUsers(); + }; } - } - if (bGoogle) - { - window['rl_' + sJsHash + '_google_service'] = function () { - RL.data().googleActions(true); - RL.socialUsers(); - }; - } + if (bFacebook) + { + window['rl_' + sJsHash + '_facebook_service'] = function () { + RL.data().facebookActions(true); + RL.socialUsers(); + }; + } - if (bFacebook) - { - window['rl_' + sJsHash + '_facebook_service'] = function () { - RL.data().facebookActions(true); - RL.socialUsers(); - }; - } + if (bTwitter) + { + window['rl_' + sJsHash + '_twitter_service'] = function () { + RL.data().twitterActions(true); + RL.socialUsers(); + }; + } - if (bTwitter) - { - window['rl_' + sJsHash + '_twitter_service'] = function () { - RL.data().twitterActions(true); - RL.socialUsers(); - }; - } + RL.sub('interval.1m', function () { + Globals.momentTrigger(!Globals.momentTrigger()); + }); - RL.sub('interval.1m', function () { - Globals.momentTrigger(!Globals.momentTrigger()); - }); + Plugins.runHook('rl-start-screens'); + RL.pub('rl.bootstart-end'); + }; - Plugins.runHook('rl-start-screens'); - RL.pub('rl.bootstart-end'); -}; + module.exports = new RainLoopApp(); -/** - * @type {RainLoopApp} - */ -RL = new RainLoopApp(); +}(module)); \ No newline at end of file diff --git a/dev/Common/Base64.js b/dev/Common/Base64.js index 1876dd067..1dc53472e 100644 --- a/dev/Common/Base64.js +++ b/dev/Common/Base64.js @@ -1,164 +1,171 @@ -/*jslint bitwise: true*/ // Base64 encode / decode // http://www.webtoolkit.info/ - -Base64 = { - - // private property - _keyStr : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', - - // public method for urlsafe encoding - urlsafe_encode : function (input) { - return Base64.encode(input).replace(/[+]/g, '-').replace(/[\/]/g, '_').replace(/[=]/g, '.'); - }, - - // public method for encoding - encode : function (input) { - var - output = '', - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0 - ; - - input = Base64._utf8_encode(input); - - while (i < input.length) - { - chr1 = input.charCodeAt(i++); - chr2 = input.charCodeAt(i++); - chr3 = input.charCodeAt(i++); - - enc1 = chr1 >> 2; - enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); - enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); - enc4 = chr3 & 63; - - if (isNaN(chr2)) - { - enc3 = enc4 = 64; - } - else if (isNaN(chr3)) - { - enc4 = 64; - } - - output = output + - this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + - this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); - } - - return output; - }, - - // public method for decoding - decode : function (input) { - var - output = '', - chr1, chr2, chr3, enc1, enc2, enc3, enc4, - i = 0 - ; - - input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); - - while (i < input.length) - { - enc1 = this._keyStr.indexOf(input.charAt(i++)); - enc2 = this._keyStr.indexOf(input.charAt(i++)); - enc3 = this._keyStr.indexOf(input.charAt(i++)); - enc4 = this._keyStr.indexOf(input.charAt(i++)); - - chr1 = (enc1 << 2) | (enc2 >> 4); - chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); - chr3 = ((enc3 & 3) << 6) | enc4; - - output = output + String.fromCharCode(chr1); - - if (enc3 !== 64) - { - output = output + String.fromCharCode(chr2); - } - - if (enc4 !== 64) - { - output = output + String.fromCharCode(chr3); - } - } - - return Base64._utf8_decode(output); - }, - - // private method for UTF-8 encoding - _utf8_encode : function (string) { - - string = string.replace(/\r\n/g, "\n"); - - var - utftext = '', - n = 0, - l = string.length, - c = 0 - ; - - for (; n < l; n++) { - - c = string.charCodeAt(n); - - if (c < 128) - { - utftext += String.fromCharCode(c); - } - else if ((c > 127) && (c < 2048)) - { - utftext += String.fromCharCode((c >> 6) | 192); - utftext += String.fromCharCode((c & 63) | 128); - } - else - { - utftext += String.fromCharCode((c >> 12) | 224); - utftext += String.fromCharCode(((c >> 6) & 63) | 128); - utftext += String.fromCharCode((c & 63) | 128); - } - } - - return utftext; - }, - - // private method for UTF-8 decoding - _utf8_decode : function (utftext) { - var - string = '', - i = 0, - c = 0, - c2 = 0, - c3 = 0 - ; - - while ( i < utftext.length ) - { - c = utftext.charCodeAt(i); - - if (c < 128) - { - string += String.fromCharCode(c); - i++; - } - else if((c > 191) && (c < 224)) - { - c2 = utftext.charCodeAt(i+1); - string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); - i += 2; - } - else - { - c2 = utftext.charCodeAt(i+1); - c3 = utftext.charCodeAt(i+2); - string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); - i += 3; - } - } - - return string; - } -}; -/*jslint bitwise: false*/ \ No newline at end of file +(function (module) { + + 'use strict'; + + /*jslint bitwise: true*/ + var Base64 = { + + // private property + _keyStr : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', + + // public method for urlsafe encoding + urlsafe_encode : function (input) { + return Base64.encode(input).replace(/[+]/g, '-').replace(/[\/]/g, '_').replace(/[=]/g, '.'); + }, + + // public method for encoding + encode : function (input) { + var + output = '', + chr1, chr2, chr3, enc1, enc2, enc3, enc4, + i = 0 + ; + + input = Base64._utf8_encode(input); + + while (i < input.length) + { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + + if (isNaN(chr2)) + { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) + { + enc4 = 64; + } + + output = output + + this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) + + this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4); + } + + return output; + }, + + // public method for decoding + decode : function (input) { + var + output = '', + chr1, chr2, chr3, enc1, enc2, enc3, enc4, + i = 0 + ; + + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ''); + + while (i < input.length) + { + enc1 = this._keyStr.indexOf(input.charAt(i++)); + enc2 = this._keyStr.indexOf(input.charAt(i++)); + enc3 = this._keyStr.indexOf(input.charAt(i++)); + enc4 = this._keyStr.indexOf(input.charAt(i++)); + + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + + output = output + String.fromCharCode(chr1); + + if (enc3 !== 64) + { + output = output + String.fromCharCode(chr2); + } + + if (enc4 !== 64) + { + output = output + String.fromCharCode(chr3); + } + } + + return Base64._utf8_decode(output); + }, + + // private method for UTF-8 encoding + _utf8_encode : function (string) { + + string = string.replace(/\r\n/g, "\n"); + + var + utftext = '', + n = 0, + l = string.length, + c = 0 + ; + + for (; n < l; n++) { + + c = string.charCodeAt(n); + + if (c < 128) + { + utftext += String.fromCharCode(c); + } + else if ((c > 127) && (c < 2048)) + { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else + { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + + return utftext; + }, + + // private method for UTF-8 decoding + _utf8_decode : function (utftext) { + var + string = '', + i = 0, + c = 0, + c2 = 0, + c3 = 0 + ; + + while ( i < utftext.length ) + { + c = utftext.charCodeAt(i); + + if (c < 128) + { + string += String.fromCharCode(c); + i++; + } + else if((c > 191) && (c < 224)) + { + c2 = utftext.charCodeAt(i+1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else + { + c2 = utftext.charCodeAt(i+1); + c3 = utftext.charCodeAt(i+2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + + return string; + } + }; + + module.exports = Base64; + /*jslint bitwise: false*/ + +}(module)); \ No newline at end of file diff --git a/dev/Common/Constants.js b/dev/Common/Constants.js deleted file mode 100644 index 1513b94e8..000000000 --- a/dev/Common/Constants.js +++ /dev/null @@ -1,119 +0,0 @@ -/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ - -Consts.Defaults = {}; -Consts.Values = {}; -Consts.DataImages = {}; - -/** - * @const - * @type {number} - */ -Consts.Defaults.MessagesPerPage = 20; - -/** - * @const - * @type {number} - */ -Consts.Defaults.ContactsPerPage = 50; - -/** - * @const - * @type {Array} - */ -Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/]; - -/** - * @const - * @type {number} - */ -Consts.Defaults.DefaultAjaxTimeout = 30000; - -/** - * @const - * @type {number} - */ -Consts.Defaults.SearchAjaxTimeout = 300000; - -/** - * @const - * @type {number} - */ -Consts.Defaults.SendMessageAjaxTimeout = 300000; - -/** - * @const - * @type {number} - */ -Consts.Defaults.SaveMessageAjaxTimeout = 200000; - -/** - * @const - * @type {number} - */ -Consts.Defaults.ContactsSyncAjaxTimeout = 200000; - -/** - * @const - * @type {string} - */ -Consts.Values.UnuseOptionValue = '__UNUSE__'; - -/** - * @const - * @type {string} - */ -Consts.Values.ClientSideCookieIndexName = 'rlcsc'; - -/** - * @const - * @type {number} - */ -Consts.Values.ImapDefaulPort = 143; - -/** - * @const - * @type {number} - */ -Consts.Values.ImapDefaulSecurePort = 993; - -/** - * @const - * @type {number} - */ -Consts.Values.SmtpDefaulPort = 25; - -/** - * @const - * @type {number} - */ -Consts.Values.SmtpDefaulSecurePort = 465; - -/** - * @const - * @type {number} - */ -Consts.Values.MessageBodyCacheLimit = 15; - -/** - * @const - * @type {number} - */ -Consts.Values.AjaxErrorLimit = 7; - -/** - * @const - * @type {number} - */ -Consts.Values.TokenErrorLimit = 10; - -/** - * @const - * @type {string} - */ -Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII='; - -/** - * @const - * @type {string} - */ -Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII='; diff --git a/dev/Common/Consts.js b/dev/Common/Consts.js new file mode 100644 index 000000000..aceeef5cb --- /dev/null +++ b/dev/Common/Consts.js @@ -0,0 +1,129 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ + +(function (module) { + + 'use strict'; + + var Consts = {}; + + Consts.Values = {}; + Consts.DataImages = {}; + Consts.Defaults = {}; + + /** + * @const + * @type {number} + */ + Consts.Defaults.MessagesPerPage = 20; + + /** + * @const + * @type {number} + */ + Consts.Defaults.ContactsPerPage = 50; + + /** + * @const + * @type {Array} + */ + Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/]; + + /** + * @const + * @type {number} + */ + Consts.Defaults.DefaultAjaxTimeout = 30000; + + /** + * @const + * @type {number} + */ + Consts.Defaults.SearchAjaxTimeout = 300000; + + /** + * @const + * @type {number} + */ + Consts.Defaults.SendMessageAjaxTimeout = 300000; + + /** + * @const + * @type {number} + */ + Consts.Defaults.SaveMessageAjaxTimeout = 200000; + + /** + * @const + * @type {number} + */ + Consts.Defaults.ContactsSyncAjaxTimeout = 200000; + + /** + * @const + * @type {string} + */ + Consts.Values.UnuseOptionValue = '__UNUSE__'; + + /** + * @const + * @type {string} + */ + Consts.Values.ClientSideCookieIndexName = 'rlcsc'; + + /** + * @const + * @type {number} + */ + Consts.Values.ImapDefaulPort = 143; + + /** + * @const + * @type {number} + */ + Consts.Values.ImapDefaulSecurePort = 993; + + /** + * @const + * @type {number} + */ + Consts.Values.SmtpDefaulPort = 25; + + /** + * @const + * @type {number} + */ + Consts.Values.SmtpDefaulSecurePort = 465; + + /** + * @const + * @type {number} + */ + Consts.Values.MessageBodyCacheLimit = 15; + + /** + * @const + * @type {number} + */ + Consts.Values.AjaxErrorLimit = 7; + + /** + * @const + * @type {number} + */ + Consts.Values.TokenErrorLimit = 10; + + /** + * @const + * @type {string} + */ + Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII='; + + /** + * @const + * @type {string} + */ + Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII='; + + module.exports = Consts; + +}(module)); \ No newline at end of file diff --git a/dev/Common/Enums.js b/dev/Common/Enums.js index 9b58ddc0b..5aa65f60c 100644 --- a/dev/Common/Enums.js +++ b/dev/Common/Enums.js @@ -1,430 +1,440 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @enum {string} - */ -Enums.StorageResultType = { - 'Success': 'success', - 'Abort': 'abort', - 'Error': 'error', - 'Unload': 'unload' -}; +(function (module) { -/** - * @enum {number} - */ -Enums.State = { - 'Empty': 10, - 'Login': 20, - 'Auth': 30 -}; + 'use strict'; -/** - * @enum {number} - */ -Enums.StateType = { - 'Webmail': 0, - 'Admin': 1 -}; + var Enums = {}; -/** - * @enum {string} - */ -Enums.Capa = { - 'Prem': 'PREM', - 'TwoFactor': 'TWO_FACTOR', - 'OpenPGP': 'OPEN_PGP', - 'Prefetch': 'PREFETCH', - 'Gravatar': 'GRAVATAR', - 'Themes': 'THEMES', - 'Filters': 'FILTERS', - 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS', - 'AdditionalIdentities': 'ADDITIONAL_IDENTITIES' -}; + /** + * @enum {string} + */ + Enums.StorageResultType = { + 'Success': 'success', + 'Abort': 'abort', + 'Error': 'error', + 'Unload': 'unload' + }; -/** - * @enum {string} - */ -Enums.KeyState = { - 'All': 'all', - 'None': 'none', - 'ContactList': 'contact-list', - 'MessageList': 'message-list', - 'FolderList': 'folder-list', - 'MessageView': 'message-view', - 'Compose': 'compose', - 'Settings': 'settings', - 'Menu': 'menu', - 'PopupComposeOpenPGP': 'compose-open-pgp', - 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help', - 'PopupAsk': 'popup-ask' -}; + /** + * @enum {number} + */ + Enums.State = { + 'Empty': 10, + 'Login': 20, + 'Auth': 30 + }; -/** - * @enum {number} - */ -Enums.FolderType = { - 'Inbox': 10, - 'SentItems': 11, - 'Draft': 12, - 'Trash': 13, - 'Spam': 14, - 'Archive': 15, - 'NotSpam': 80, - 'User': 99 -}; + /** + * @enum {number} + */ + Enums.StateType = { + 'Webmail': 0, + 'Admin': 1 + }; -/** - * @enum {string} - */ -Enums.LoginSignMeTypeAsString = { - 'DefaultOff': 'defaultoff', - 'DefaultOn': 'defaulton', - 'Unused': 'unused' -}; + /** + * @enum {string} + */ + Enums.Capa = { + 'Prem': 'PREM', + 'TwoFactor': 'TWO_FACTOR', + 'OpenPGP': 'OPEN_PGP', + 'Prefetch': 'PREFETCH', + 'Gravatar': 'GRAVATAR', + 'Themes': 'THEMES', + 'Filters': 'FILTERS', + 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS', + 'AdditionalIdentities': 'ADDITIONAL_IDENTITIES' + }; -/** - * @enum {number} - */ -Enums.LoginSignMeType = { - 'DefaultOff': 0, - 'DefaultOn': 1, - 'Unused': 2 -}; + /** + * @enum {string} + */ + Enums.KeyState = { + 'All': 'all', + 'None': 'none', + 'ContactList': 'contact-list', + 'MessageList': 'message-list', + 'FolderList': 'folder-list', + 'MessageView': 'message-view', + 'Compose': 'compose', + 'Settings': 'settings', + 'Menu': 'menu', + 'PopupComposeOpenPGP': 'compose-open-pgp', + 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help', + 'PopupAsk': 'popup-ask' + }; -/** - * @enum {string} - */ -Enums.ComposeType = { - 'Empty': 'empty', - 'Reply': 'reply', - 'ReplyAll': 'replyall', - 'Forward': 'forward', - 'ForwardAsAttachment': 'forward-as-attachment', - 'Draft': 'draft', - 'EditAsNew': 'editasnew' -}; + /** + * @enum {number} + */ + Enums.FolderType = { + 'Inbox': 10, + 'SentItems': 11, + 'Draft': 12, + 'Trash': 13, + 'Spam': 14, + 'Archive': 15, + 'NotSpam': 80, + 'User': 99 + }; -/** - * @enum {number} - */ -Enums.UploadErrorCode = { - 'Normal': 0, - 'FileIsTooBig': 1, - 'FilePartiallyUploaded': 2, - 'FileNoUploaded': 3, - 'MissingTempFolder': 4, - 'FileOnSaveingError': 5, - 'FileType': 98, - 'Unknown': 99 -}; + /** + * @enum {string} + */ + Enums.LoginSignMeTypeAsString = { + 'DefaultOff': 'defaultoff', + 'DefaultOn': 'defaulton', + 'Unused': 'unused' + }; -/** - * @enum {number} - */ -Enums.SetSystemFoldersNotification = { - 'None': 0, - 'Sent': 1, - 'Draft': 2, - 'Spam': 3, - 'Trash': 4, - 'Archive': 5 -}; + /** + * @enum {number} + */ + Enums.LoginSignMeType = { + 'DefaultOff': 0, + 'DefaultOn': 1, + 'Unused': 2 + }; -/** - * @enum {number} - */ -Enums.ClientSideKeyName = { - 'FoldersLashHash': 0, - 'MessagesInboxLastHash': 1, - 'MailBoxListSize': 2, - 'ExpandedFolders': 3, - 'FolderListSize': 4 -}; + /** + * @enum {string} + */ + Enums.ComposeType = { + 'Empty': 'empty', + 'Reply': 'reply', + 'ReplyAll': 'replyall', + 'Forward': 'forward', + 'ForwardAsAttachment': 'forward-as-attachment', + 'Draft': 'draft', + 'EditAsNew': 'editasnew' + }; -/** - * @enum {number} - */ -Enums.EventKeyCode = { - 'Backspace': 8, - 'Tab': 9, - 'Enter': 13, - 'Esc': 27, - 'PageUp': 33, - 'PageDown': 34, - 'Left': 37, - 'Right': 39, - 'Up': 38, - 'Down': 40, - 'End': 35, - 'Home': 36, - 'Space': 32, - 'Insert': 45, - 'Delete': 46, - 'A': 65, - 'S': 83 -}; + /** + * @enum {number} + */ + Enums.UploadErrorCode = { + 'Normal': 0, + 'FileIsTooBig': 1, + 'FilePartiallyUploaded': 2, + 'FileNoUploaded': 3, + 'MissingTempFolder': 4, + 'FileOnSaveingError': 5, + 'FileType': 98, + 'Unknown': 99 + }; -/** - * @enum {number} - */ -Enums.MessageSetAction = { - 'SetSeen': 0, - 'UnsetSeen': 1, - 'SetFlag': 2, - 'UnsetFlag': 3 -}; + /** + * @enum {number} + */ + Enums.SetSystemFoldersNotification = { + 'None': 0, + 'Sent': 1, + 'Draft': 2, + 'Spam': 3, + 'Trash': 4, + 'Archive': 5 + }; -/** - * @enum {number} - */ -Enums.MessageSelectAction = { - 'All': 0, - 'None': 1, - 'Invert': 2, - 'Unseen': 3, - 'Seen': 4, - 'Flagged': 5, - 'Unflagged': 6 -}; + /** + * @enum {number} + */ + Enums.ClientSideKeyName = { + 'FoldersLashHash': 0, + 'MessagesInboxLastHash': 1, + 'MailBoxListSize': 2, + 'ExpandedFolders': 3, + 'FolderListSize': 4 + }; -/** - * @enum {number} - */ -Enums.DesktopNotifications = { - 'Allowed': 0, - 'NotAllowed': 1, - 'Denied': 2, - 'NotSupported': 9 -}; + /** + * @enum {number} + */ + Enums.EventKeyCode = { + 'Backspace': 8, + 'Tab': 9, + 'Enter': 13, + 'Esc': 27, + 'PageUp': 33, + 'PageDown': 34, + 'Left': 37, + 'Right': 39, + 'Up': 38, + 'Down': 40, + 'End': 35, + 'Home': 36, + 'Space': 32, + 'Insert': 45, + 'Delete': 46, + 'A': 65, + 'S': 83 + }; -/** - * @enum {number} - */ -Enums.MessagePriority = { - 'Low': 5, - 'Normal': 3, - 'High': 1 -}; + /** + * @enum {number} + */ + Enums.MessageSetAction = { + 'SetSeen': 0, + 'UnsetSeen': 1, + 'SetFlag': 2, + 'UnsetFlag': 3 + }; -/** - * @enum {string} - */ -Enums.EditorDefaultType = { - 'Html': 'Html', - 'Plain': 'Plain' -}; + /** + * @enum {number} + */ + Enums.MessageSelectAction = { + 'All': 0, + 'None': 1, + 'Invert': 2, + 'Unseen': 3, + 'Seen': 4, + 'Flagged': 5, + 'Unflagged': 6 + }; -/** - * @enum {string} - */ -Enums.CustomThemeType = { - 'Light': 'Light', - 'Dark': 'Dark' -}; + /** + * @enum {number} + */ + Enums.DesktopNotifications = { + 'Allowed': 0, + 'NotAllowed': 1, + 'Denied': 2, + 'NotSupported': 9 + }; -/** - * @enum {number} - */ -Enums.ServerSecure = { - 'None': 0, - 'SSL': 1, - 'TLS': 2 -}; + /** + * @enum {number} + */ + Enums.MessagePriority = { + 'Low': 5, + 'Normal': 3, + 'High': 1 + }; -/** - * @enum {number} - */ -Enums.SearchDateType = { - 'All': -1, - 'Days3': 3, - 'Days7': 7, - 'Month': 30 -}; + /** + * @enum {string} + */ + Enums.EditorDefaultType = { + 'Html': 'Html', + 'Plain': 'Plain' + }; -/** - * @enum {number} - */ -Enums.EmailType = { - 'Defailt': 0, - 'Facebook': 1, - 'Google': 2 -}; + /** + * @enum {string} + */ + Enums.CustomThemeType = { + 'Light': 'Light', + 'Dark': 'Dark' + }; -/** - * @enum {number} - */ -Enums.SaveSettingsStep = { - 'Animate': -2, - 'Idle': -1, - 'TrueResult': 1, - 'FalseResult': 0 -}; + /** + * @enum {number} + */ + Enums.ServerSecure = { + 'None': 0, + 'SSL': 1, + 'TLS': 2 + }; -/** - * @enum {string} - */ -Enums.InterfaceAnimation = { - 'None': 'None', - 'Normal': 'Normal', - 'Full': 'Full' -}; + /** + * @enum {number} + */ + Enums.SearchDateType = { + 'All': -1, + 'Days3': 3, + 'Days7': 7, + 'Month': 30 + }; -/** - * @enum {number} - */ -Enums.Layout = { - 'NoPreview': 0, - 'SidePreview': 1, - 'BottomPreview': 2 -}; + /** + * @enum {number} + */ + Enums.EmailType = { + 'Defailt': 0, + 'Facebook': 1, + 'Google': 2 + }; -/** - * @enum {string} - */ -Enums.FilterConditionField = { - 'From': 'From', - 'To': 'To', - 'Recipient': 'Recipient', - 'Subject': 'Subject' -}; + /** + * @enum {number} + */ + Enums.SaveSettingsStep = { + 'Animate': -2, + 'Idle': -1, + 'TrueResult': 1, + 'FalseResult': 0 + }; -/** - * @enum {string} - */ -Enums.FilterConditionType = { - 'Contains': 'Contains', - 'NotContains': 'NotContains', - 'EqualTo': 'EqualTo', - 'NotEqualTo': 'NotEqualTo' -}; + /** + * @enum {string} + */ + Enums.InterfaceAnimation = { + 'None': 'None', + 'Normal': 'Normal', + 'Full': 'Full' + }; -/** - * @enum {string} - */ -Enums.FiltersAction = { - 'None': 'None', - 'Move': 'Move', - 'Discard': 'Discard', - 'Forward': 'Forward', -}; + /** + * @enum {number} + */ + Enums.Layout = { + 'NoPreview': 0, + 'SidePreview': 1, + 'BottomPreview': 2 + }; -/** - * @enum {string} - */ -Enums.FilterRulesType = { - 'And': 'And', - 'Or': 'Or' -}; + /** + * @enum {string} + */ + Enums.FilterConditionField = { + 'From': 'From', + 'To': 'To', + 'Recipient': 'Recipient', + 'Subject': 'Subject' + }; -/** - * @enum {number} - */ -Enums.SignedVerifyStatus = { - 'UnknownPublicKeys': -4, - 'UnknownPrivateKey': -3, - 'Unverified': -2, - 'Error': -1, - 'None': 0, - 'Success': 1 -}; + /** + * @enum {string} + */ + Enums.FilterConditionType = { + 'Contains': 'Contains', + 'NotContains': 'NotContains', + 'EqualTo': 'EqualTo', + 'NotEqualTo': 'NotEqualTo' + }; -/** - * @enum {number} - */ -Enums.ContactPropertyType = { + /** + * @enum {string} + */ + Enums.FiltersAction = { + 'None': 'None', + 'Move': 'Move', + 'Discard': 'Discard', + 'Forward': 'Forward', + }; - 'Unknown': 0, + /** + * @enum {string} + */ + Enums.FilterRulesType = { + 'And': 'And', + 'Or': 'Or' + }; - 'FullName': 10, + /** + * @enum {number} + */ + Enums.SignedVerifyStatus = { + 'UnknownPublicKeys': -4, + 'UnknownPrivateKey': -3, + 'Unverified': -2, + 'Error': -1, + 'None': 0, + 'Success': 1 + }; - 'FirstName': 15, - 'LastName': 16, - 'MiddleName': 16, - 'Nick': 18, + /** + * @enum {number} + */ + Enums.ContactPropertyType = { - 'NamePrefix': 20, - 'NameSuffix': 21, + 'Unknown': 0, - 'Email': 30, - 'Phone': 31, - 'Web': 32, + 'FullName': 10, - 'Birthday': 40, + 'FirstName': 15, + 'LastName': 16, + 'MiddleName': 16, + 'Nick': 18, - 'Facebook': 90, - 'Skype': 91, - 'GitHub': 92, + 'NamePrefix': 20, + 'NameSuffix': 21, - 'Note': 110, + 'Email': 30, + 'Phone': 31, + 'Web': 32, - 'Custom': 250 -}; + 'Birthday': 40, -/** - * @enum {number} - */ -Enums.Notification = { - 'InvalidToken': 101, - 'AuthError': 102, - 'AccessError': 103, - 'ConnectionError': 104, - 'CaptchaError': 105, - 'SocialFacebookLoginAccessDisable': 106, - 'SocialTwitterLoginAccessDisable': 107, - 'SocialGoogleLoginAccessDisable': 108, - 'DomainNotAllowed': 109, - 'AccountNotAllowed': 110, + 'Facebook': 90, + 'Skype': 91, + 'GitHub': 92, - 'AccountTwoFactorAuthRequired': 120, - 'AccountTwoFactorAuthError': 121, + 'Note': 110, - 'CouldNotSaveNewPassword': 130, - 'CurrentPasswordIncorrect': 131, - 'NewPasswordShort': 132, - 'NewPasswordWeak': 133, - 'NewPasswordForbidden': 134, + 'Custom': 250 + }; - 'ContactsSyncError': 140, + /** + * @enum {number} + */ + Enums.Notification = { + 'InvalidToken': 101, + 'AuthError': 102, + 'AccessError': 103, + 'ConnectionError': 104, + 'CaptchaError': 105, + 'SocialFacebookLoginAccessDisable': 106, + 'SocialTwitterLoginAccessDisable': 107, + 'SocialGoogleLoginAccessDisable': 108, + 'DomainNotAllowed': 109, + 'AccountNotAllowed': 110, - 'CantGetMessageList': 201, - 'CantGetMessage': 202, - 'CantDeleteMessage': 203, - 'CantMoveMessage': 204, - 'CantCopyMessage': 205, + 'AccountTwoFactorAuthRequired': 120, + 'AccountTwoFactorAuthError': 121, - 'CantSaveMessage': 301, - 'CantSendMessage': 302, - 'InvalidRecipients': 303, + 'CouldNotSaveNewPassword': 130, + 'CurrentPasswordIncorrect': 131, + 'NewPasswordShort': 132, + 'NewPasswordWeak': 133, + 'NewPasswordForbidden': 134, - 'CantCreateFolder': 400, - 'CantRenameFolder': 401, - 'CantDeleteFolder': 402, - 'CantSubscribeFolder': 403, - 'CantUnsubscribeFolder': 404, - 'CantDeleteNonEmptyFolder': 405, + 'ContactsSyncError': 140, - 'CantSaveSettings': 501, - 'CantSavePluginSettings': 502, + 'CantGetMessageList': 201, + 'CantGetMessage': 202, + 'CantDeleteMessage': 203, + 'CantMoveMessage': 204, + 'CantCopyMessage': 205, - 'DomainAlreadyExists': 601, + 'CantSaveMessage': 301, + 'CantSendMessage': 302, + 'InvalidRecipients': 303, - 'CantInstallPackage': 701, - 'CantDeletePackage': 702, - 'InvalidPluginPackage': 703, - 'UnsupportedPluginPackage': 704, + 'CantCreateFolder': 400, + 'CantRenameFolder': 401, + 'CantDeleteFolder': 402, + 'CantSubscribeFolder': 403, + 'CantUnsubscribeFolder': 404, + 'CantDeleteNonEmptyFolder': 405, - 'LicensingServerIsUnavailable': 710, - 'LicensingExpired': 711, - 'LicensingBanned': 712, + 'CantSaveSettings': 501, + 'CantSavePluginSettings': 502, - 'DemoSendMessageError': 750, + 'DomainAlreadyExists': 601, - 'AccountAlreadyExists': 801, + 'CantInstallPackage': 701, + 'CantDeletePackage': 702, + 'InvalidPluginPackage': 703, + 'UnsupportedPluginPackage': 704, - 'MailServerError': 901, - 'ClientViewError': 902, - 'InvalidInputArgument': 903, - 'UnknownNotification': 999, - 'UnknownError': 999 -}; + 'LicensingServerIsUnavailable': 710, + 'LicensingExpired': 711, + 'LicensingBanned': 712, + + 'DemoSendMessageError': 750, + + 'AccountAlreadyExists': 801, + + 'MailServerError': 901, + 'ClientViewError': 902, + 'InvalidInputArgument': 903, + 'UnknownNotification': 999, + 'UnknownError': 999 + }; + + module.exports = Enums; + +}(module)); \ No newline at end of file diff --git a/dev/Common/Globals.js b/dev/Common/Globals.js index 68baa890b..41e6c46ec 100644 --- a/dev/Common/Globals.js +++ b/dev/Common/Globals.js @@ -1,157 +1,184 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @type {?} - */ -Globals.now = (new Date()).getTime(); +(function (module) { -/** - * @type {?} - */ -Globals.momentTrigger = ko.observable(true); + 'use strict'; -/** - * @type {?} - */ -Globals.dropdownVisibility = ko.observable(false).extend({'rateLimit': 0}); + var + Globals = {}, + window = require('../External/window.js'), + ko = require('../External/ko.js'), + $html = require('../External/$html.js') + ; -/** - * @type {?} - */ -Globals.tooltipTrigger = ko.observable(false).extend({'rateLimit': 0}); + /** + * @type {?} + */ + Globals.now = (new window.Date()).getTime(); -/** - * @type {?} - */ -Globals.langChangeTrigger = ko.observable(true); + /** + * @type {?} + */ + Globals.momentTrigger = ko.observable(true); -/** - * @type {number} - */ -Globals.iAjaxErrorCount = 0; + /** + * @type {?} + */ + Globals.dropdownVisibility = ko.observable(false).extend({'rateLimit': 0}); -/** - * @type {number} - */ -Globals.iTokenErrorCount = 0; + /** + * @type {?} + */ + Globals.tooltipTrigger = ko.observable(false).extend({'rateLimit': 0}); -/** - * @type {number} - */ -Globals.iMessageBodyCacheCount = 0; + /** + * @type {?} + */ + Globals.langChangeTrigger = ko.observable(true); -/** - * @type {boolean} - */ -Globals.bUnload = false; + /** + * @type {number} + */ + Globals.iAjaxErrorCount = 0; -/** - * @type {string} - */ -Globals.sUserAgent = (navigator.userAgent || '').toLowerCase(); + /** + * @type {number} + */ + Globals.iTokenErrorCount = 0; -/** - * @type {boolean} - */ -Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad'); + /** + * @type {number} + */ + Globals.iMessageBodyCacheCount = 0; -/** - * @type {boolean} - */ -Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android'); + /** + * @type {boolean} + */ + Globals.bUnload = false; -/** - * @type {boolean} - */ -Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice; + /** + * @type {string} + */ + Globals.sUserAgent = (window.navigator.userAgent || '').toLowerCase(); -/** - * @type {boolean} - */ -Globals.bDisableNanoScroll = Globals.bMobileDevice; + /** + * @type {boolean} + */ + Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad'); -/** - * @type {boolean} - */ -Globals.bAllowPdfPreview = !Globals.bMobileDevice; + /** + * @type {boolean} + */ + Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android'); -/** - * @type {boolean} - */ -Globals.bAnimationSupported = !Globals.bMobileDevice && $html.hasClass('csstransitions'); + /** + * @type {boolean} + */ + Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice; -/** - * @type {boolean} - */ -Globals.bXMLHttpRequestSupported = !!window.XMLHttpRequest; + /** + * @type {boolean} + */ + Globals.bDisableNanoScroll = Globals.bMobileDevice; -/** - * @type {string} - */ -Globals.sAnimationType = ''; + /** + * @type {boolean} + */ + Globals.bAllowPdfPreview = !Globals.bMobileDevice; -/** - * @type {Object} - */ -Globals.oHtmlEditorDefaultConfig = { - 'title': false, - 'stylesSet': false, - 'customConfig': '', - 'contentsCss': '', - 'toolbarGroups': [ - {name: 'spec'}, - {name: 'styles'}, - {name: 'basicstyles', groups: ['basicstyles', 'cleanup']}, - {name: 'colors'}, - {name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align']}, - {name: 'links'}, - {name: 'insert'}, - {name: 'others'} -// {name: 'document', groups: ['mode', 'document', 'doctools']} - ], + /** + * @type {boolean} + */ + Globals.bAnimationSupported = !Globals.bMobileDevice && $html.hasClass('csstransitions'); - 'removePlugins': 'contextmenu', //blockquote - 'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll', - 'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced', + /** + * @type {boolean} + */ + Globals.bXMLHttpRequestSupported = !!window.XMLHttpRequest; - 'extraPlugins': 'plain', + /** + * @type {string} + */ + Globals.sAnimationType = ''; - 'allowedContent': true, - 'autoParagraph': false, + /** + * @type {Object} + */ + Globals.oHtmlEditorDefaultConfig = { + 'title': false, + 'stylesSet': false, + 'customConfig': '', + 'contentsCss': '', + 'toolbarGroups': [ + {name: 'spec'}, + {name: 'styles'}, + {name: 'basicstyles', groups: ['basicstyles', 'cleanup']}, + {name: 'colors'}, + {name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align']}, + {name: 'links'}, + {name: 'insert'}, + {name: 'others'} + // {name: 'document', groups: ['mode', 'document', 'doctools']} + ], - 'font_defaultLabel': 'Arial', - 'fontSize_defaultLabel': '13', - 'fontSize_sizes': '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px' -}; + 'removePlugins': 'contextmenu', //blockquote + 'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll', + 'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced', -/** - * @type {Object} - */ -Globals.oHtmlEditorLangsMap = { - 'de': 'de', - 'es': 'es', - 'fr': 'fr', - 'hu': 'hu', - 'is': 'is', - 'it': 'it', - 'ko': 'ko', - 'ko-kr': 'ko', - 'lv': 'lv', - 'nl': 'nl', - 'no': 'no', - 'pl': 'pl', - 'pt': 'pt', - 'pt-pt': 'pt', - 'pt-br': 'pt-br', - 'ru': 'ru', - 'ro': 'ro', - 'zh': 'zh', - 'zh-cn': 'zh-cn' -}; + 'extraPlugins': 'plain', -if (Globals.bAllowPdfPreview && navigator && navigator.mimeTypes) -{ - Globals.bAllowPdfPreview = !!_.find(navigator.mimeTypes, function (oType) { - return oType && 'application/pdf' === oType.type; - }); -} + 'allowedContent': true, + 'autoParagraph': false, + + 'font_defaultLabel': 'Arial', + 'fontSize_defaultLabel': '13', + 'fontSize_sizes': '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px' + }; + + /** + * @type {Object} + */ + Globals.oHtmlEditorLangsMap = { + 'de': 'de', + 'es': 'es', + 'fr': 'fr', + 'hu': 'hu', + 'is': 'is', + 'it': 'it', + 'ko': 'ko', + 'ko-kr': 'ko', + 'lv': 'lv', + 'nl': 'nl', + 'no': 'no', + 'pl': 'pl', + 'pt': 'pt', + 'pt-pt': 'pt', + 'pt-br': 'pt-br', + 'ru': 'ru', + 'ro': 'ro', + 'zh': 'zh', + 'zh-cn': 'zh-cn' + }; + + if (Globals.bAllowPdfPreview && window.navigator && window.navigator.mimeTypes) + { + Globals.bAllowPdfPreview = !!_.find(window.navigator.mimeTypes, function (oType) { + return oType && 'application/pdf' === oType.type; + }); + } + + Globals.oI18N = {}, + + Globals.oNotificationI18N = {}, + + Globals.aBootstrapDropdowns = [], + + Globals.aViewModels = { + 'settings': [], + 'settings-removed': [], + 'settings-disabled': [] + }; + + module.exports = Globals; + +}(module)); \ No newline at end of file diff --git a/dev/Common/Knockout.js b/dev/Common/Knockout.js deleted file mode 100644 index a15974c1c..000000000 --- a/dev/Common/Knockout.js +++ /dev/null @@ -1,846 +0,0 @@ -/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ - -ko.bindingHandlers.tooltip = { - 'init': function (oElement, fValueAccessor) { - if (!Globals.bMobileDevice) - { - var - $oEl = $(oElement), - sClass = $oEl.data('tooltip-class') || '', - sPlacement = $oEl.data('tooltip-placement') || 'top' - ; - - $oEl.tooltip({ - 'delay': { - 'show': 500, - 'hide': 100 - }, - 'html': true, - 'container': 'body', - 'placement': sPlacement, - 'trigger': 'hover', - 'title': function () { - return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '' + - Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + ''; - } - }).click(function () { - $oEl.tooltip('hide'); - }); - - Globals.tooltipTrigger.subscribe(function () { - $oEl.tooltip('hide'); - }); - } - } -}; - -ko.bindingHandlers.tooltip2 = { - 'init': function (oElement, fValueAccessor) { - var - $oEl = $(oElement), - sClass = $oEl.data('tooltip-class') || '', - sPlacement = $oEl.data('tooltip-placement') || 'top' - ; - - $oEl.tooltip({ - 'delay': { - 'show': 500, - 'hide': 100 - }, - 'html': true, - 'container': 'body', - 'placement': sPlacement, - 'title': function () { - return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : - '' + fValueAccessor()() + ''; - } - }).click(function () { - $oEl.tooltip('hide'); - }); - - Globals.tooltipTrigger.subscribe(function () { - $oEl.tooltip('hide'); - }); - } -}; - -ko.bindingHandlers.tooltip3 = { - 'init': function (oElement) { - - var $oEl = $(oElement); - - $oEl.tooltip({ - 'container': 'body', - 'trigger': 'hover manual', - 'title': function () { - return $oEl.data('tooltip3-data') || ''; - } - }); - - $document.click(function () { - $oEl.tooltip('hide'); - }); - - Globals.tooltipTrigger.subscribe(function () { - $oEl.tooltip('hide'); - }); - }, - 'update': function (oElement, fValueAccessor) { - var sValue = ko.utils.unwrapObservable(fValueAccessor()); - if ('' === sValue) - { - $(oElement).data('tooltip3-data', '').tooltip('hide'); - } - else - { - $(oElement).data('tooltip3-data', sValue).tooltip('show'); - } - } -}; - -ko.bindingHandlers.registrateBootstrapDropdown = { - 'init': function (oElement) { - BootstrapDropdowns.push($(oElement)); - } -}; - -ko.bindingHandlers.openDropdownTrigger = { - 'update': function (oElement, fValueAccessor) { - if (ko.utils.unwrapObservable(fValueAccessor())) - { - var $el = $(oElement); - if (!$el.hasClass('open')) - { - $el.find('.dropdown-toggle').dropdown('toggle'); - Utils.detectDropdownVisibility(); - } - - fValueAccessor()(false); - } - } -}; - -ko.bindingHandlers.dropdownCloser = { - 'init': function (oElement) { - $(oElement).closest('.dropdown').on('click', '.e-item', function () { - $(oElement).dropdown('toggle'); - }); - } -}; - -ko.bindingHandlers.popover = { - 'init': function (oElement, fValueAccessor) { - $(oElement).popover(ko.utils.unwrapObservable(fValueAccessor())); - } -}; - -ko.bindingHandlers.csstext = { - 'init': function (oElement, fValueAccessor) { - if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) - { - oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); - } - else - { - $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); - } - }, - 'update': function (oElement, fValueAccessor) { - if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText)) - { - oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor()); - } - else - { - $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); - } - } -}; - -ko.bindingHandlers.resizecrop = { - 'init': function (oElement) { - $(oElement).addClass('resizecrop').resizecrop({ - 'width': '100', - 'height': '100', - 'wrapperCSS': { - 'border-radius': '10px' - } - }); - }, - 'update': function (oElement, fValueAccessor) { - fValueAccessor()(); - $(oElement).resizecrop({ - 'width': '100', - 'height': '100' - }); - } -}; - -ko.bindingHandlers.onEnter = { - 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { - $(oElement).on('keypress', function (oEvent) { - if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) - { - $(oElement).trigger('change'); - fValueAccessor().call(oViewModel); - } - }); - } -}; - -ko.bindingHandlers.onEsc = { - 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { - $(oElement).on('keypress', function (oEvent) { - if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10)) - { - $(oElement).trigger('change'); - fValueAccessor().call(oViewModel); - } - }); - } -}; - -ko.bindingHandlers.clickOnTrue = { - 'update': function (oElement, fValueAccessor) { - if (ko.utils.unwrapObservable(fValueAccessor())) - { - $(oElement).click(); - } - } -}; - -ko.bindingHandlers.modal = { - 'init': function (oElement, fValueAccessor) { - - $(oElement).toggleClass('fade', !Globals.bMobileDevice).modal({ - 'keyboard': false, - 'show': ko.utils.unwrapObservable(fValueAccessor()) - }) - .on('shown', function () { - Utils.windowResize(); - }) - .find('.close').click(function () { - fValueAccessor()(false); - }); - }, - 'update': function (oElement, fValueAccessor) { - $(oElement).modal(ko.utils.unwrapObservable(fValueAccessor()) ? 'show' : 'hide'); - } -}; - -ko.bindingHandlers.i18nInit = { - 'init': function (oElement) { - Utils.i18nToNode(oElement); - } -}; - -ko.bindingHandlers.i18nUpdate = { - 'update': function (oElement, fValueAccessor) { - ko.utils.unwrapObservable(fValueAccessor()); - Utils.i18nToNode(oElement); - } -}; - -ko.bindingHandlers.link = { - 'update': function (oElement, fValueAccessor) { - $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor())); - } -}; - -ko.bindingHandlers.title = { - 'update': function (oElement, fValueAccessor) { - $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); - } -}; - -ko.bindingHandlers.textF = { - 'init': function (oElement, fValueAccessor) { - $(oElement).text(ko.utils.unwrapObservable(fValueAccessor())); - } -}; - -ko.bindingHandlers.initDom = { - 'init': function (oElement, fValueAccessor) { - fValueAccessor()(oElement); - } -}; - -ko.bindingHandlers.initResizeTrigger = { - 'init': function (oElement, fValueAccessor) { - var aValues = ko.utils.unwrapObservable(fValueAccessor()); - $(oElement).css({ - 'height': aValues[1], - 'min-height': aValues[1] - }); - }, - 'update': function (oElement, fValueAccessor) { - var - aValues = ko.utils.unwrapObservable(fValueAccessor()), - iValue = Utils.pInt(aValues[1]), - iSize = 0, - iOffset = $(oElement).offset().top - ; - - if (0 < iOffset) - { - iOffset += Utils.pInt(aValues[2]); - iSize = $window.height() - iOffset; - - if (iValue < iSize) - { - iValue = iSize; - } - - $(oElement).css({ - 'height': iValue, - 'min-height': iValue - }); - } - } -}; - -ko.bindingHandlers.appendDom = { - 'update': function (oElement, fValueAccessor) { - $(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show(); - } -}; - -ko.bindingHandlers.draggable = { - 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) { - - if (!Globals.bMobileDevice) - { - var - iTriggerZone = 100, - iScrollSpeed = 3, - fAllValueFunc = fAllBindingsAccessor(), - sDroppableSelector = fAllValueFunc && fAllValueFunc['droppableSelector'] ? fAllValueFunc['droppableSelector'] : '', - oConf = { - 'distance': 20, - 'handle': '.dragHandle', - 'cursorAt': {'top': 22, 'left': 3}, - 'refreshPositions': true, - 'scroll': true - } - ; - - if (sDroppableSelector) - { - oConf['drag'] = function (oEvent) { - - $(sDroppableSelector).each(function () { - var - moveUp = null, - moveDown = null, - $this = $(this), - oOffset = $this.offset(), - bottomPos = oOffset.top + $this.height() - ; - - window.clearInterval($this.data('timerScroll')); - $this.data('timerScroll', false); - - if (oEvent.pageX >= oOffset.left && oEvent.pageX <= oOffset.left + $this.width()) - { - if (oEvent.pageY >= bottomPos - iTriggerZone && oEvent.pageY <= bottomPos) - { - moveUp = function() { - $this.scrollTop($this.scrollTop() + iScrollSpeed); - Utils.windowResize(); - }; - - $this.data('timerScroll', window.setInterval(moveUp, 10)); - moveUp(); - } - - if (oEvent.pageY >= oOffset.top && oEvent.pageY <= oOffset.top + iTriggerZone) - { - moveDown = function() { - $this.scrollTop($this.scrollTop() - iScrollSpeed); - Utils.windowResize(); - }; - - $this.data('timerScroll', window.setInterval(moveDown, 10)); - moveDown(); - } - } - }); - }; - - oConf['stop'] = function() { - $(sDroppableSelector).each(function () { - window.clearInterval($(this).data('timerScroll')); - $(this).data('timerScroll', false); - }); - }; - } - - oConf['helper'] = function (oEvent) { - return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null); - }; - - $(oElement).draggable(oConf).on('mousedown', function () { - Utils.removeInFocus(); - }); - } - } -}; - -ko.bindingHandlers.droppable = { - 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) { - - if (!Globals.bMobileDevice) - { - var - fValueFunc = fValueAccessor(), - fAllValueFunc = fAllBindingsAccessor(), - fOverCallback = fAllValueFunc && fAllValueFunc['droppableOver'] ? fAllValueFunc['droppableOver'] : null, - fOutCallback = fAllValueFunc && fAllValueFunc['droppableOut'] ? fAllValueFunc['droppableOut'] : null, - oConf = { - 'tolerance': 'pointer', - 'hoverClass': 'droppableHover' - } - ; - - if (fValueFunc) - { - oConf['drop'] = function (oEvent, oUi) { - fValueFunc(oEvent, oUi); - }; - - if (fOverCallback) - { - oConf['over'] = function (oEvent, oUi) { - fOverCallback(oEvent, oUi); - }; - } - - if (fOutCallback) - { - oConf['out'] = function (oEvent, oUi) { - fOutCallback(oEvent, oUi); - }; - } - - $(oElement).droppable(oConf); - } - } - } -}; - -ko.bindingHandlers.nano = { - 'init': function (oElement) { - if (!Globals.bDisableNanoScroll) - { - $(oElement) - .addClass('nano') - .nanoScroller({ - 'iOSNativeScrolling': false, - 'preventPageScrolling': true - }) - ; - } - } -}; - -ko.bindingHandlers.saveTrigger = { - 'init': function (oElement) { - - var $oEl = $(oElement); - - $oEl.data('save-trigger-type', $oEl.is('input[type=text],input[type=email],input[type=password],select,textarea') ? 'input' : 'custom'); - - if ('custom' === $oEl.data('save-trigger-type')) - { - $oEl.append( - ' ' - ).addClass('settings-saved-trigger'); - } - else - { - $oEl.addClass('settings-saved-trigger-input'); - } - }, - 'update': function (oElement, fValueAccessor) { - var - mValue = ko.utils.unwrapObservable(fValueAccessor()), - $oEl = $(oElement) - ; - - if ('custom' === $oEl.data('save-trigger-type')) - { - switch (mValue.toString()) - { - case '1': - $oEl - .find('.animated,.error').hide().removeClass('visible') - .end() - .find('.success').show().addClass('visible') - ; - break; - case '0': - $oEl - .find('.animated,.success').hide().removeClass('visible') - .end() - .find('.error').show().addClass('visible') - ; - break; - case '-2': - $oEl - .find('.error,.success').hide().removeClass('visible') - .end() - .find('.animated').show().addClass('visible') - ; - break; - default: - $oEl - .find('.animated').hide() - .end() - .find('.error,.success').removeClass('visible') - ; - break; - } - } - else - { - switch (mValue.toString()) - { - case '1': - $oEl.addClass('success').removeClass('error'); - break; - case '0': - $oEl.addClass('error').removeClass('success'); - break; - case '-2': -// $oEl; - break; - default: - $oEl.removeClass('error success'); - break; - } - } - } -}; - -ko.bindingHandlers.emailsTags = { - 'init': function(oElement, fValueAccessor) { - var - $oEl = $(oElement), - fValue = fValueAccessor(), - fFocusCallback = function (bValue) { - if (fValue && fValue.focusTrigger) - { - fValue.focusTrigger(bValue); - } - } - ; - - $oEl.inputosaurus({ - 'parseOnBlur': true, - 'allowDragAndDrop': true, - 'focusCallback': fFocusCallback, - 'inputDelimiters': [',', ';'], - 'autoCompleteSource': function (oData, fResponse) { - RL.getAutocomplete(oData.term, function (aData) { - fResponse(_.map(aData, function (oEmailItem) { - return oEmailItem.toLine(false); - })); - }); - }, - 'parseHook': function (aInput) { - return _.map(aInput, function (sInputValue) { - - var - sValue = Utils.trim(sInputValue), - oEmail = null - ; - - if ('' !== sValue) - { - oEmail = new EmailModel(); - oEmail.mailsoParse(sValue); - oEmail.clearDuplicateName(); - return [oEmail.toLine(false), oEmail]; - } - - return [sValue, null]; - - }); - }, - 'change': _.bind(function (oEvent) { - $oEl.data('EmailsTagsValue', oEvent.target.value); - fValue(oEvent.target.value); - }, this) - }); - }, - 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { - - var - $oEl = $(oElement), - fAllValueFunc = fAllBindingsAccessor(), - fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null, - sValue = ko.utils.unwrapObservable(fValueAccessor()) - ; - - if ($oEl.data('EmailsTagsValue') !== sValue) - { - $oEl.val(sValue); - $oEl.data('EmailsTagsValue', sValue); - $oEl.inputosaurus('refresh'); - } - - if (fEmailsTagsFilter && ko.utils.unwrapObservable(fEmailsTagsFilter)) - { - $oEl.inputosaurus('focus'); - } - } -}; - -ko.bindingHandlers.contactTags = { - 'init': function(oElement, fValueAccessor) { - var - $oEl = $(oElement), - fValue = fValueAccessor(), - fFocusCallback = function (bValue) { - if (fValue && fValue.focusTrigger) - { - fValue.focusTrigger(bValue); - } - } - ; - - $oEl.inputosaurus({ - 'parseOnBlur': true, - 'allowDragAndDrop': false, - 'focusCallback': fFocusCallback, - 'inputDelimiters': [',', ';'], - 'outputDelimiter': ',', - 'autoCompleteSource': function (oData, fResponse) { - RL.getContactTagsAutocomplete(oData.term, function (aData) { - fResponse(_.map(aData, function (oTagItem) { - return oTagItem.toLine(false); - })); - }); - }, - 'parseHook': function (aInput) { - return _.map(aInput, function (sInputValue) { - - var - sValue = Utils.trim(sInputValue), - oTag = null - ; - - if ('' !== sValue) - { - oTag = new ContactTagModel(); - oTag.name(sValue); - return [oTag.toLine(false), oTag]; - } - - return [sValue, null]; - - }); - }, - 'change': _.bind(function (oEvent) { - $oEl.data('ContactTagsValue', oEvent.target.value); - fValue(oEvent.target.value); - }, this) - }); - }, - 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { - - var - $oEl = $(oElement), - fAllValueFunc = fAllBindingsAccessor(), - fContactTagsFilter = fAllValueFunc['contactTagsFilter'] || null, - sValue = ko.utils.unwrapObservable(fValueAccessor()) - ; - - if ($oEl.data('ContactTagsValue') !== sValue) - { - $oEl.val(sValue); - $oEl.data('ContactTagsValue', sValue); - $oEl.inputosaurus('refresh'); - } - - if (fContactTagsFilter && ko.utils.unwrapObservable(fContactTagsFilter)) - { - $oEl.inputosaurus('focus'); - } - } -}; - -ko.bindingHandlers.command = { - 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { - var - jqElement = $(oElement), - oCommand = fValueAccessor() - ; - - if (!oCommand || !oCommand.enabled || !oCommand.canExecute) - { - throw new Error('You are not using command function'); - } - - jqElement.addClass('command'); - ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments); - }, - - 'update': function (oElement, fValueAccessor) { - - var - bResult = true, - jqElement = $(oElement), - oCommand = fValueAccessor() - ; - - bResult = oCommand.enabled(); - jqElement.toggleClass('command-not-enabled', !bResult); - - if (bResult) - { - bResult = oCommand.canExecute(); - jqElement.toggleClass('command-can-not-be-execute', !bResult); - } - - jqElement.toggleClass('command-disabled disable disabled', !bResult).toggleClass('no-disabled', !!bResult); - - if (jqElement.is('input') || jqElement.is('button')) - { - jqElement.prop('disabled', !bResult); - } - } -}; - -ko.extenders.trimmer = function (oTarget) -{ - var oResult = ko.computed({ - 'read': oTarget, - 'write': function (sNewValue) { - oTarget(Utils.trim(sNewValue.toString())); - }, - 'owner': this - }); - - oResult(oTarget()); - return oResult; -}; - -ko.extenders.posInterer = function (oTarget, iDefault) -{ - var oResult = ko.computed({ - 'read': oTarget, - 'write': function (sNewValue) { - var iNew = Utils.pInt(sNewValue.toString(), iDefault); - if (0 >= iNew) - { - iNew = iDefault; - } - - if (iNew === oTarget() && '' + iNew !== '' + sNewValue) - { - oTarget(iNew + 1); - } - - oTarget(iNew); - } - }); - - oResult(oTarget()); - return oResult; -}; - -ko.extenders.reversible = function (oTarget) -{ - var mValue = oTarget(); - - oTarget.commit = function () - { - mValue = oTarget(); - }; - - oTarget.reverse = function () - { - oTarget(mValue); - }; - - oTarget.commitedValue = function () - { - return mValue; - }; - - return oTarget; -}; - -ko.extenders.toggleSubscribe = function (oTarget, oOptions) -{ - oTarget.subscribe(oOptions[1], oOptions[0], 'beforeChange'); - oTarget.subscribe(oOptions[2], oOptions[0]); - - return oTarget; -}; - -ko.extenders.falseTimeout = function (oTarget, iOption) -{ - oTarget.iTimeout = 0; - oTarget.subscribe(function (bValue) { - if (bValue) - { - window.clearTimeout(oTarget.iTimeout); - oTarget.iTimeout = window.setTimeout(function () { - oTarget(false); - oTarget.iTimeout = 0; - }, Utils.pInt(iOption)); - } - }); - - return oTarget; -}; - -ko.observable.fn.validateNone = function () -{ - this.hasError = ko.observable(false); - return this; -}; - -ko.observable.fn.validateEmail = function () -{ - this.hasError = ko.observable(false); - - this.subscribe(function (sValue) { - sValue = Utils.trim(sValue); - this.hasError('' !== sValue && !(/^[^@\s]+@[^@\s]+$/.test(sValue))); - }, this); - - this.valueHasMutated(); - return this; -}; - -ko.observable.fn.validateSimpleEmail = function () -{ - this.hasError = ko.observable(false); - - this.subscribe(function (sValue) { - sValue = Utils.trim(sValue); - this.hasError('' !== sValue && !(/^.+@.+$/.test(sValue))); - }, this); - - this.valueHasMutated(); - return this; -}; - -ko.observable.fn.validateFunc = function (fFunc) -{ - this.hasFuncError = ko.observable(false); - - if (Utils.isFunc(fFunc)) - { - this.subscribe(function (sValue) { - this.hasFuncError(!fFunc(sValue)); - }, this); - - this.valueHasMutated(); - } - - return this; -}; diff --git a/dev/Common/LinkBuilder.js b/dev/Common/LinkBuilder.js index a92f419e6..13c3df960 100644 --- a/dev/Common/LinkBuilder.js +++ b/dev/Common/LinkBuilder.js @@ -1,315 +1,328 @@ /* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @constructor - */ -function LinkBuilder() -{ - this.sBase = '#/'; - this.sServer = './?'; - this.sVersion = RL.settingsGet('Version'); - this.sSpecSuffix = RL.settingsGet('AuthAccountHash') || '0'; - this.sStaticPrefix = RL.settingsGet('StaticPrefix') || 'rainloop/v/' + this.sVersion + '/static/'; -} +(function (module) { -/** - * @return {string} - */ -LinkBuilder.prototype.root = function () -{ - return this.sBase; -}; + 'use strict'; -/** - * @param {string} sDownload - * @return {string} - */ -LinkBuilder.prototype.attachmentDownload = function (sDownload) -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sDownload; -}; - -/** - * @param {string} sDownload - * @return {string} - */ -LinkBuilder.prototype.attachmentPreview = function (sDownload) -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/View/' + sDownload; -}; - -/** - * @param {string} sDownload - * @return {string} - */ -LinkBuilder.prototype.attachmentPreviewAsPlain = function (sDownload) -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sDownload; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.upload = function () -{ - return this.sServer + '/Upload/' + this.sSpecSuffix + '/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.uploadContacts = function () -{ - return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.uploadBackground = function () -{ - return this.sServer + '/UploadBackground/' + this.sSpecSuffix + '/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.append = function () -{ - return this.sServer + '/Append/' + this.sSpecSuffix + '/'; -}; - -/** - * @param {string} sEmail - * @return {string} - */ -LinkBuilder.prototype.change = function (sEmail) -{ - return this.sServer + '/Change/' + this.sSpecSuffix + '/' + window.encodeURIComponent(sEmail) + '/'; -}; - -/** - * @param {string=} sAdd - * @return {string} - */ -LinkBuilder.prototype.ajax = function (sAdd) -{ - return this.sServer + '/Ajax/' + this.sSpecSuffix + '/' + sAdd; -}; - -/** - * @param {string} sRequestHash - * @return {string} - */ -LinkBuilder.prototype.messageViewLink = function (sRequestHash) -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sRequestHash; -}; - -/** - * @param {string} sRequestHash - * @return {string} - */ -LinkBuilder.prototype.messageDownloadLink = function (sRequestHash) -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sRequestHash; -}; - -/** - * @param {string} sEmail - * @return {string} - */ -LinkBuilder.prototype.avatarLink = function (sEmail) -{ - return this.sServer + '/Raw/0/Avatar/' + window.encodeURIComponent(sEmail) + '/'; -// return '//secure.gravatar.com/avatar/' + Utils.md5(sEmail.toLowerCase()) + '.jpg?s=80&d=mm'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.inbox = function () -{ - return this.sBase + 'mailbox/Inbox'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.messagePreview = function () -{ - return this.sBase + 'mailbox/message-preview'; -}; - -/** - * @param {string=} sScreenName - * @return {string} - */ -LinkBuilder.prototype.settings = function (sScreenName) -{ - var sResult = this.sBase + 'settings'; - if (!Utils.isUnd(sScreenName) && '' !== sScreenName) + var + window = require('../External/window.js'), + Utils = require('./Utils.js') + ; + + /** + * @constructor + */ + function LinkBuilder() { - sResult += '/' + sScreenName; + this.sBase = '#/'; + this.sServer = './?'; + this.sVersion = RL.settingsGet('Version'); + this.sSpecSuffix = RL.settingsGet('AuthAccountHash') || '0'; + this.sStaticPrefix = RL.settingsGet('StaticPrefix') || 'rainloop/v/' + this.sVersion + '/static/'; } - return sResult; -}; - -/** - * @param {string} sScreenName - * @return {string} - */ -LinkBuilder.prototype.admin = function (sScreenName) -{ - var sResult = this.sBase; - switch (sScreenName) { - case 'AdminDomains': - sResult += 'domains'; - break; - case 'AdminSecurity': - sResult += 'security'; - break; - case 'AdminLicensing': - sResult += 'licensing'; - break; - } - - return sResult; -}; - -/** - * @param {string} sFolder - * @param {number=} iPage = 1 - * @param {string=} sSearch = '' - * @return {string} - */ -LinkBuilder.prototype.mailBox = function (sFolder, iPage, sSearch) -{ - iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1; - sSearch = Utils.pString(sSearch); - - var sResult = this.sBase + 'mailbox/'; - if ('' !== sFolder) + /** + * @return {string} + */ + LinkBuilder.prototype.root = function () { - sResult += encodeURI(sFolder); - } - if (1 < iPage) + return this.sBase; + }; + + /** + * @param {string} sDownload + * @return {string} + */ + LinkBuilder.prototype.attachmentDownload = function (sDownload) { - sResult = sResult.replace(/[\/]+$/, ''); - sResult += '/p' + iPage; - } - if ('' !== sSearch) + return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sDownload; + }; + + /** + * @param {string} sDownload + * @return {string} + */ + LinkBuilder.prototype.attachmentPreview = function (sDownload) { - sResult = sResult.replace(/[\/]+$/, ''); - sResult += '/' + encodeURI(sSearch); - } + return this.sServer + '/Raw/' + this.sSpecSuffix + '/View/' + sDownload; + }; - return sResult; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.phpInfo = function () -{ - return this.sServer + 'Info'; -}; - -/** - * @param {string} sLang - * @return {string} - */ -LinkBuilder.prototype.langLink = function (sLang) -{ - return this.sServer + '/Lang/0/' + encodeURI(sLang) + '/' + this.sVersion + '/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.exportContactsVcf = function () -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.exportContactsCsv = function () -{ - return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/'; -}; - -/** - * @return {string} - */ -LinkBuilder.prototype.emptyContactPic = function () -{ - return this.sStaticPrefix + 'css/images/empty-contact.png'; -}; - -/** - * @param {string} sFileName - * @return {string} - */ -LinkBuilder.prototype.sound = function (sFileName) -{ - return this.sStaticPrefix + 'sounds/' + sFileName; -}; - -/** - * @param {string} sTheme - * @return {string} - */ -LinkBuilder.prototype.themePreviewLink = function (sTheme) -{ - var sPrefix = 'rainloop/v/' + this.sVersion + '/'; - if ('@custom' === sTheme.substr(-7)) + /** + * @param {string} sDownload + * @return {string} + */ + LinkBuilder.prototype.attachmentPreviewAsPlain = function (sDownload) { - sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7)); - sPrefix = ''; - } + return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sDownload; + }; - return sPrefix + 'themes/' + encodeURI(sTheme) + '/images/preview.png'; -}; + /** + * @return {string} + */ + LinkBuilder.prototype.upload = function () + { + return this.sServer + '/Upload/' + this.sSpecSuffix + '/'; + }; -/** - * @return {string} - */ -LinkBuilder.prototype.notificationMailIcon = function () -{ - return this.sStaticPrefix + 'css/images/icom-message-notification.png'; -}; + /** + * @return {string} + */ + LinkBuilder.prototype.uploadContacts = function () + { + return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/'; + }; -/** - * @return {string} - */ -LinkBuilder.prototype.openPgpJs = function () -{ - return this.sStaticPrefix + 'js/openpgp.min.js'; -}; + /** + * @return {string} + */ + LinkBuilder.prototype.uploadBackground = function () + { + return this.sServer + '/UploadBackground/' + this.sSpecSuffix + '/'; + }; -/** - * @return {string} - */ -LinkBuilder.prototype.socialGoogle = function () -{ - return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); -}; + /** + * @return {string} + */ + LinkBuilder.prototype.append = function () + { + return this.sServer + '/Append/' + this.sSpecSuffix + '/'; + }; -/** - * @return {string} - */ -LinkBuilder.prototype.socialTwitter = function () -{ - return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); -}; + /** + * @param {string} sEmail + * @return {string} + */ + LinkBuilder.prototype.change = function (sEmail) + { + return this.sServer + '/Change/' + this.sSpecSuffix + '/' + window.encodeURIComponent(sEmail) + '/'; + }; -/** - * @return {string} - */ -LinkBuilder.prototype.socialFacebook = function () -{ - return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); -}; + /** + * @param {string=} sAdd + * @return {string} + */ + LinkBuilder.prototype.ajax = function (sAdd) + { + return this.sServer + '/Ajax/' + this.sSpecSuffix + '/' + sAdd; + }; + + /** + * @param {string} sRequestHash + * @return {string} + */ + LinkBuilder.prototype.messageViewLink = function (sRequestHash) + { + return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sRequestHash; + }; + + /** + * @param {string} sRequestHash + * @return {string} + */ + LinkBuilder.prototype.messageDownloadLink = function (sRequestHash) + { + return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sRequestHash; + }; + + /** + * @param {string} sEmail + * @return {string} + */ + LinkBuilder.prototype.avatarLink = function (sEmail) + { + return this.sServer + '/Raw/0/Avatar/' + window.encodeURIComponent(sEmail) + '/'; + // return '//secure.gravatar.com/avatar/' + Utils.md5(sEmail.toLowerCase()) + '.jpg?s=80&d=mm'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.inbox = function () + { + return this.sBase + 'mailbox/Inbox'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.messagePreview = function () + { + return this.sBase + 'mailbox/message-preview'; + }; + + /** + * @param {string=} sScreenName + * @return {string} + */ + LinkBuilder.prototype.settings = function (sScreenName) + { + var sResult = this.sBase + 'settings'; + if (!Utils.isUnd(sScreenName) && '' !== sScreenName) + { + sResult += '/' + sScreenName; + } + + return sResult; + }; + + /** + * @param {string} sScreenName + * @return {string} + */ + LinkBuilder.prototype.admin = function (sScreenName) + { + var sResult = this.sBase; + switch (sScreenName) { + case 'AdminDomains': + sResult += 'domains'; + break; + case 'AdminSecurity': + sResult += 'security'; + break; + case 'AdminLicensing': + sResult += 'licensing'; + break; + } + + return sResult; + }; + + /** + * @param {string} sFolder + * @param {number=} iPage = 1 + * @param {string=} sSearch = '' + * @return {string} + */ + LinkBuilder.prototype.mailBox = function (sFolder, iPage, sSearch) + { + iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1; + sSearch = Utils.pString(sSearch); + + var sResult = this.sBase + 'mailbox/'; + if ('' !== sFolder) + { + sResult += encodeURI(sFolder); + } + if (1 < iPage) + { + sResult = sResult.replace(/[\/]+$/, ''); + sResult += '/p' + iPage; + } + if ('' !== sSearch) + { + sResult = sResult.replace(/[\/]+$/, ''); + sResult += '/' + encodeURI(sSearch); + } + + return sResult; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.phpInfo = function () + { + return this.sServer + 'Info'; + }; + + /** + * @param {string} sLang + * @return {string} + */ + LinkBuilder.prototype.langLink = function (sLang) + { + return this.sServer + '/Lang/0/' + encodeURI(sLang) + '/' + this.sVersion + '/'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.exportContactsVcf = function () + { + return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.exportContactsCsv = function () + { + return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.emptyContactPic = function () + { + return this.sStaticPrefix + 'css/images/empty-contact.png'; + }; + + /** + * @param {string} sFileName + * @return {string} + */ + LinkBuilder.prototype.sound = function (sFileName) + { + return this.sStaticPrefix + 'sounds/' + sFileName; + }; + + /** + * @param {string} sTheme + * @return {string} + */ + LinkBuilder.prototype.themePreviewLink = function (sTheme) + { + var sPrefix = 'rainloop/v/' + this.sVersion + '/'; + if ('@custom' === sTheme.substr(-7)) + { + sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7)); + sPrefix = ''; + } + + return sPrefix + 'themes/' + encodeURI(sTheme) + '/images/preview.png'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.notificationMailIcon = function () + { + return this.sStaticPrefix + 'css/images/icom-message-notification.png'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.openPgpJs = function () + { + return this.sStaticPrefix + 'js/openpgp.min.js'; + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.socialGoogle = function () + { + return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.socialTwitter = function () + { + return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); + }; + + /** + * @return {string} + */ + LinkBuilder.prototype.socialFacebook = function () + { + return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : ''); + }; + + module.exports = LinkBuilder; + +}(module)); \ No newline at end of file diff --git a/dev/Common/NewHtmlEditorWrapper.js b/dev/Common/NewHtmlEditorWrapper.js index df3cacb63..5944cfe0a 100644 --- a/dev/Common/NewHtmlEditorWrapper.js +++ b/dev/Common/NewHtmlEditorWrapper.js @@ -1,260 +1,274 @@ +/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */ -/** - * @constructor - * @param {Object} oElement - * @param {Function=} fOnBlur - * @param {Function=} fOnReady - * @param {Function=} fOnModeChange - */ -function NewHtmlEditorWrapper(oElement, fOnBlur, fOnReady, fOnModeChange) -{ - var self = this; - self.editor = null; - self.iBlurTimer = 0; - self.fOnBlur = fOnBlur || null; - self.fOnReady = fOnReady || null; - self.fOnModeChange = fOnModeChange || null; +(function (module) { - self.$element = $(oElement); + 'use strict'; - self.resize = _.throttle(_.bind(self.resize, self), 100); + var + window = require('../External/window.js'), + Globals = require('./Globals.js') + ; - self.init(); -} - -NewHtmlEditorWrapper.prototype.blurTrigger = function () -{ - if (this.fOnBlur) + /** + * @constructor + * @param {Object} oElement + * @param {Function=} fOnBlur + * @param {Function=} fOnReady + * @param {Function=} fOnModeChange + */ + function NewHtmlEditorWrapper(oElement, fOnBlur, fOnReady, fOnModeChange) { var self = this; - window.clearTimeout(self.iBlurTimer); - self.iBlurTimer = window.setTimeout(function () { - self.fOnBlur(); - }, 200); + self.editor = null; + self.iBlurTimer = 0; + self.fOnBlur = fOnBlur || null; + self.fOnReady = fOnReady || null; + self.fOnModeChange = fOnModeChange || null; + + self.$element = $(oElement); + + self.resize = _.throttle(_.bind(self.resize, self), 100); + + self.init(); } -}; -NewHtmlEditorWrapper.prototype.focusTrigger = function () -{ - if (this.fOnBlur) + NewHtmlEditorWrapper.prototype.blurTrigger = function () { - window.clearTimeout(this.iBlurTimer); - } -}; - -/** - * @return {boolean} - */ -NewHtmlEditorWrapper.prototype.isHtml = function () -{ - return this.editor ? 'wysiwyg' === this.editor.mode : false; -}; - -/** - * @return {boolean} - */ -NewHtmlEditorWrapper.prototype.checkDirty = function () -{ - return this.editor ? this.editor.checkDirty() : false; -}; - -NewHtmlEditorWrapper.prototype.resetDirty = function () -{ - if (this.editor) - { - this.editor.resetDirty(); - } -}; - -/** - * @return {string} - */ -NewHtmlEditorWrapper.prototype.getData = function (bWrapIsHtml) -{ - if (this.editor) - { - if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain) + if (this.fOnBlur) { - return this.editor.__plain.getRawData(); + var self = this; + window.clearTimeout(self.iBlurTimer); + self.iBlurTimer = window.setTimeout(function () { + self.fOnBlur(); + }, 200); + } + }; + + NewHtmlEditorWrapper.prototype.focusTrigger = function () + { + if (this.fOnBlur) + { + window.clearTimeout(this.iBlurTimer); + } + }; + + /** + * @return {boolean} + */ + NewHtmlEditorWrapper.prototype.isHtml = function () + { + return this.editor ? 'wysiwyg' === this.editor.mode : false; + }; + + /** + * @return {boolean} + */ + NewHtmlEditorWrapper.prototype.checkDirty = function () + { + return this.editor ? this.editor.checkDirty() : false; + }; + + NewHtmlEditorWrapper.prototype.resetDirty = function () + { + if (this.editor) + { + this.editor.resetDirty(); + } + }; + + /** + * @return {string} + */ + NewHtmlEditorWrapper.prototype.getData = function (bWrapIsHtml) + { + if (this.editor) + { + if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain) + { + return this.editor.__plain.getRawData(); + } + + return bWrapIsHtml ? + '
]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre)
- .replace(/[\s]+/gm, ' ')
- .replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue)
- .replace(/
]*>/gmi, '\n')
- .replace(/<\/h[\d]>/gi, '\n')
- .replace(/<\/p>/gi, '\n\n')
- .replace(/<\/li>/gi, '\n')
- .replace(/<\/td>/gi, '\n')
- .replace(/<\/tr>/gi, '\n')
- .replace(/
]*>/gmi, '\n_______________________________\n\n')
- .replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs)
- .replace(/]*>/gmi, '\n__bq__start__\n')
- .replace(/<\/blockquote>/gmi, '\n__bq__end__\n')
- .replace(/]*>([\s\S\r\n]*?)<\/a>/gmi, convertLinks)
- .replace(/<\/div>/gi, '\n')
- .replace(/ /gi, ' ')
- .replace(/"/gi, '"')
- .replace(/<[^>]*>/gm, '')
- ;
-
- sText = Utils.$div.html(sText).text();
-
- sText = sText
- .replace(/\n[ \t]+/gm, '\n')
- .replace(/[\n]{3,}/gm, '\n\n')
- .replace(/>/gi, '>')
- .replace(/</gi, '<')
- .replace(/&/gi, '&')
- ;
-
- iPos = 0;
- iLimit = 100;
-
- while (0 < iLimit)
- {
- iLimit--;
- iP1 = sText.indexOf('__bq__start__', iPos);
- if (-1 < iP1)
- {
- iP2 = sText.indexOf('__bq__start__', iP1 + 5);
- iP3 = sText.indexOf('__bq__end__', iP1 + 5);
-
- if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3)
- {
- sText = sText.substring(0, iP1) +
- convertBlockquote(sText.substring(iP1 + 13, iP3)) +
- sText.substring(iP3 + 11);
-
- iPos = 0;
- }
- else if (-1 < iP2 && iP2 < iP3)
- {
- iPos = iP2 - 1;
- }
- else
- {
- iPos = 0;
- }
- }
- else
- {
- break;
- }
- }
-
- sText = sText
- .replace(/__bq__start__/gm, '')
- .replace(/__bq__end__/gm, '')
- ;
-
- return sText;
-};
-
-/**
- * @param {string} sPlain
- * @param {boolean} bLinkify = false
- * @return {string}
- */
-Utils.plainToHtml = function (sPlain, bLinkify)
-{
- sPlain = sPlain.toString().replace(/\r/g, '');
-
- var
- bIn = false,
- bDo = true,
- bStart = true,
- aNextText = [],
- sLine = '',
- iIndex = 0,
- aText = sPlain.split("\n")
- ;
-
- do
- {
- bDo = false;
- aNextText = [];
- for (iIndex = 0; iIndex < aText.length; iIndex++)
- {
- sLine = aText[iIndex];
- bStart = '>' === sLine.substr(0, 1);
- if (bStart && !bIn)
- {
- bDo = true;
- bIn = true;
- aNextText.push('~~~blockquote~~~');
- aNextText.push(sLine.substr(1));
- }
- else if (!bStart && bIn)
- {
- bIn = false;
- aNextText.push('~~~/blockquote~~~');
- aNextText.push(sLine);
- }
- else if (bStart && bIn)
- {
- aNextText.push(sLine.substr(1));
- }
- else
- {
- aNextText.push(sLine);
- }
- }
-
- if (bIn)
- {
- bIn = false;
- aNextText.push('~~~/blockquote~~~');
- }
-
- aText = aNextText;
- }
- while (bDo);
-
- sPlain = aText.join("\n");
-
- sPlain = sPlain
- .replace(/&/g, '&')
- .replace(/>/g, '>').replace(/')
- .replace(/[\s]*~~~\/blockquote~~~/g, '
')
- .replace(/[\-_~]{10,}/g, '
')
- .replace(/\n/g, '
');
-
- return bLinkify ? Utils.linkify(sPlain) : sPlain;
-};
-
-window.rainloop_Utils_htmlToPlain = Utils.htmlToPlain;
-window.rainloop_Utils_plainToHtml = Utils.plainToHtml;
-
-/**
- * @param {string} sHtml
- * @return {string}
- */
-Utils.linkify = function (sHtml)
-{
- if ($.fn && $.fn.linkify)
- {
- sHtml = Utils.$div.html(sHtml.replace(/&/ig, 'amp_amp_12345_amp_amp'))
- .linkify()
- .find('.linkified').removeClass('linkified').end()
- .html()
- .replace(/amp_amp_12345_amp_amp/g, '&')
- ;
- }
-
- return sHtml;
-};
-
-Utils.resizeAndCrop = function (sUrl, iValue, fCallback)
-{
- var oTempImg = new window.Image();
- oTempImg.onload = function() {
-
- var
- aDiff = [0, 0],
- oCanvas = document.createElement('canvas'),
- oCtx = oCanvas.getContext('2d')
- ;
-
- oCanvas.width = iValue;
- oCanvas.height = iValue;
-
- if (this.width > this.height)
- {
- aDiff = [this.width - this.height, 0];
- }
- else
- {
- aDiff = [0, this.height - this.width];
- }
-
- oCtx.fillStyle = '#fff';
- oCtx.fillRect(0, 0, iValue, iValue);
- oCtx.drawImage(this, aDiff[0] / 2, aDiff[1] / 2, this.width - aDiff[0], this.height - aDiff[1], 0, 0, iValue, iValue);
-
- fCallback(oCanvas.toDataURL('image/jpeg'));
- };
-
- oTempImg.src = sUrl;
-};
-
-Utils.computedPagenatorHelper = function (koCurrentPage, koPageCount)
-{
- return function() {
- var
- iPrev = 0,
- iNext = 0,
- iLimit = 2,
- aResult = [],
- iCurrentPage = koCurrentPage(),
- iPageCount = koPageCount(),
-
- /**
- * @param {number} iIndex
- * @param {boolean=} bPush
- * @param {string=} sCustomName
- */
- fAdd = function (iIndex, bPush, sCustomName) {
-
- var oData = {
- 'current': iIndex === iCurrentPage,
- 'name': Utils.isUnd(sCustomName) ? iIndex.toString() : sCustomName.toString(),
- 'custom': Utils.isUnd(sCustomName) ? false : true,
- 'title': Utils.isUnd(sCustomName) ? '' : iIndex.toString(),
- 'value': iIndex.toString()
- };
-
- if (Utils.isUnd(bPush) ? true : !!bPush)
- {
- aResult.push(oData);
+ if (-1 < Utils.inArray(sValue, oData.languages()))
+ {
+ oData.language(sValue);
+ }
+ else if (0 < oData.languages().length)
+ {
+ oData.language(oData.languages()[0]);
+ }
}
else
{
- aResult.unshift(oData);
+ oData.language.valueHasMutated();
+ }
+ }
+ });
+
+ oData.theme = ko.observable('');
+ oData.themes = ko.observableArray([]);
+
+ oData.mainTheme = ko.computed({
+ 'read': oData.theme,
+ 'write': function (sValue) {
+ if (sValue !== oData.theme())
+ {
+ var aThemes = oData.themes();
+ if (-1 < Utils.inArray(sValue, aThemes))
+ {
+ oData.theme(sValue);
+ }
+ else if (0 < aThemes.length)
+ {
+ oData.theme(aThemes[0]);
+ }
+ }
+ else
+ {
+ oData.theme.valueHasMutated();
+ }
+ }
+ });
+
+ oData.capaAdditionalAccounts = ko.observable(false);
+ oData.capaAdditionalIdentities = ko.observable(false);
+ oData.capaGravatar = ko.observable(false);
+ oData.determineUserLanguage = ko.observable(false);
+ oData.determineUserDomain = ko.observable(false);
+
+ oData.messagesPerPage = ko.observable(Consts.Defaults.MessagesPerPage);//.extend({'throttle': 200});
+
+ oData.mainMessagesPerPage = oData.messagesPerPage;
+ oData.mainMessagesPerPage = ko.computed({
+ 'read': oData.messagesPerPage,
+ 'write': function (iValue) {
+ if (-1 < Utils.inArray(Utils.pInt(iValue), Consts.Defaults.MessagesPerPageArray))
+ {
+ if (iValue !== oData.messagesPerPage())
+ {
+ oData.messagesPerPage(iValue);
+ }
+ }
+ else
+ {
+ oData.messagesPerPage.valueHasMutated();
+ }
+ }
+ });
+
+ oData.facebookSupported = ko.observable(false);
+ oData.facebookEnable = ko.observable(false);
+ oData.facebookAppID = ko.observable('');
+ oData.facebookAppSecret = ko.observable('');
+
+ oData.twitterEnable = ko.observable(false);
+ oData.twitterConsumerKey = ko.observable('');
+ oData.twitterConsumerSecret = ko.observable('');
+
+ oData.googleEnable = ko.observable(false);
+ oData.googleClientID = ko.observable('');
+ oData.googleClientSecret = ko.observable('');
+ oData.googleApiKey = ko.observable('');
+
+ oData.dropboxEnable = ko.observable(false);
+ oData.dropboxApiKey = ko.observable('');
+
+ oData.contactsIsAllowed = ko.observable(false);
+ };
+
+ /**
+ * @param {{moment:Function}} oObject
+ */
+ Utils.createMomentDate = function (oObject)
+ {
+ if (Utils.isUnd(oObject.moment))
+ {
+ oObject.moment = ko.observable(moment());
+ }
+
+ return ko.computed(function () {
+ Globals.momentTrigger();
+ var oMoment = this.moment();
+ return 1970 === oMoment.year() ? '' : oMoment.fromNow();
+ }, oObject);
+ };
+
+ /**
+ * @param {{moment:Function, momentDate:Function}} oObject
+ */
+ Utils.createMomentShortDate = function (oObject)
+ {
+ return ko.computed(function () {
+
+ var
+ sResult = '',
+ oMomentNow = moment(),
+ oMoment = this.moment(),
+ sMomentDate = this.momentDate()
+ ;
+
+ if (1970 === oMoment.year())
+ {
+ sResult = '';
+ }
+ else if (4 >= oMomentNow.diff(oMoment, 'hours'))
+ {
+ sResult = sMomentDate;
+ }
+ else if (oMomentNow.format('L') === oMoment.format('L'))
+ {
+ sResult = Utils.i18n('MESSAGE_LIST/TODAY_AT', {
+ 'TIME': oMoment.format('LT')
+ });
+ }
+ else if (oMomentNow.clone().subtract('days', 1).format('L') === oMoment.format('L'))
+ {
+ sResult = Utils.i18n('MESSAGE_LIST/YESTERDAY_AT', {
+ 'TIME': oMoment.format('LT')
+ });
+ }
+ else if (oMomentNow.year() === oMoment.year())
+ {
+ sResult = oMoment.format('D MMM.');
+ }
+ else
+ {
+ sResult = oMoment.format('LL');
+ }
+
+ return sResult;
+
+ }, oObject);
+ };
+
+ /**
+ * @param {string} sFullNameHash
+ * @return {boolean}
+ */
+ Utils.isFolderExpanded = function (sFullNameHash)
+ {
+ var aExpandedList = /** @type {Array|null} */ RL.local().get(Enums.ClientSideKeyName.ExpandedFolders);
+ return _.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash);
+ };
+
+ /**
+ * @param {string} sFullNameHash
+ * @param {boolean} bExpanded
+ */
+ Utils.setExpandedFolder = function (sFullNameHash, bExpanded)
+ {
+ var aExpandedList = /** @type {Array|null} */ RL.local().get(Enums.ClientSideKeyName.ExpandedFolders);
+ if (!_.isArray(aExpandedList))
+ {
+ aExpandedList = [];
+ }
+
+ if (bExpanded)
+ {
+ aExpandedList.push(sFullNameHash);
+ aExpandedList = _.uniq(aExpandedList);
+ }
+ else
+ {
+ aExpandedList = _.without(aExpandedList, sFullNameHash);
+ }
+
+ RL.local().set(Enums.ClientSideKeyName.ExpandedFolders, aExpandedList);
+ };
+
+ Utils.initLayoutResizer = function (sLeft, sRight, sClientSideKeyName)
+ {
+ var
+ iDisabledWidth = 60,
+ iMinWidth = 155,
+ oLeft = $(sLeft),
+ oRight = $(sRight),
+
+ mLeftWidth = RL.local().get(sClientSideKeyName) || null,
+
+ fSetWidth = function (iWidth) {
+ if (iWidth)
+ {
+ oLeft.css({
+ 'width': '' + iWidth + 'px'
+ });
+
+ oRight.css({
+ 'left': '' + iWidth + 'px'
+ });
+ }
+ },
+
+ fDisable = function (bDisable) {
+ if (bDisable)
+ {
+ oLeft.resizable('disable');
+ fSetWidth(iDisabledWidth);
+ }
+ else
+ {
+ oLeft.resizable('enable');
+ var iWidth = Utils.pInt(RL.local().get(sClientSideKeyName)) || iMinWidth;
+ fSetWidth(iWidth > iMinWidth ? iWidth : iMinWidth);
+ }
+ },
+
+ fResizeFunction = function (oEvent, oObject) {
+ if (oObject && oObject.size && oObject.size.width)
+ {
+ RL.local().set(sClientSideKeyName, oObject.size.width);
+
+ oRight.css({
+ 'left': '' + oObject.size.width + 'px'
+ });
}
}
;
- if (1 < iPageCount || (0 < iPageCount && iPageCount < iCurrentPage))
-// if (0 < iPageCount && 0 < iCurrentPage)
+ if (null !== mLeftWidth)
{
- if (iPageCount < iCurrentPage)
+ fSetWidth(mLeftWidth > iMinWidth ? mLeftWidth : iMinWidth);
+ }
+
+ oLeft.resizable({
+ 'helper': 'ui-resizable-helper',
+ 'minWidth': iMinWidth,
+ 'maxWidth': 350,
+ 'handles': 'e',
+ 'stop': fResizeFunction
+ });
+
+ RL.sub('left-panel.off', function () {
+ fDisable(true);
+ });
+
+ RL.sub('left-panel.on', function () {
+ fDisable(false);
+ });
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.initBlockquoteSwitcher = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function () {
+ return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length;
+ });
+
+ if ($oList && 0 < $oList.length)
{
- fAdd(iPageCount);
- iPrev = iPageCount;
- iNext = iPageCount;
+ $oList.each(function () {
+ var $self = $(this), iH = $self.height();
+ if (0 === iH || 100 < iH)
+ {
+ $self.addClass('rl-bq-switcher hidden-bq');
+ $('')
+ .insertBefore($self)
+ .click(function () {
+ $self.toggleClass('hidden-bq');
+ Utils.windowResize();
+ })
+ .after('
')
+ .before('
')
+ ;
+ }
+ });
+ }
+ }
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.removeBlockquoteSwitcher = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ $(oMessageTextBody).find('blockquote.rl-bq-switcher').each(function () {
+ $(this).removeClass('rl-bq-switcher hidden-bq');
+ });
+
+ $(oMessageTextBody).find('.rlBlockquoteSwitcher').each(function () {
+ $(this).remove();
+ });
+ }
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.toggleMessageBlockquote = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ oMessageTextBody.find('.rlBlockquoteSwitcher').click();
+ }
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Function} ViewModelClass
+ * @param {Function=} AbstractViewModel = KnoinAbstractViewModel
+ */
+ Utils.extendAsViewModel = function (sName, ViewModelClass, AbstractViewModel)
+ {
+ if (ViewModelClass)
+ {
+ if (!AbstractViewModel)
+ {
+ AbstractViewModel = KnoinAbstractViewModel;
+ }
+
+ ViewModelClass.__name = sName;
+ Plugins.regViewModelHook(sName, ViewModelClass);
+ _.extend(ViewModelClass.prototype, AbstractViewModel.prototype);
+ }
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ * @param {string} sLabelName
+ * @param {string} sTemplate
+ * @param {string} sRoute
+ * @param {boolean=} bDefault
+ */
+ Utils.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute, bDefault)
+ {
+ SettingsViewModelClass.__rlSettingsData = {
+ 'Label': sLabelName,
+ 'Template': sTemplate,
+ 'Route': sRoute,
+ 'IsDefault': !!bDefault
+ };
+
+ Globals.aViewModels['settings'].push(SettingsViewModelClass);
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ */
+ Utils.removeSettingsViewModel = function (SettingsViewModelClass)
+ {
+ Globals.aViewModels['settings-removed'].push(SettingsViewModelClass);
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ */
+ Utils.disableSettingsViewModel = function (SettingsViewModelClass)
+ {
+ Globals.aViewModels['settings-disabled'].push(SettingsViewModelClass);
+ };
+
+ Utils.convertThemeName = function (sTheme)
+ {
+ if ('@custom' === sTheme.substr(-7))
+ {
+ sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7));
+ }
+
+ return Utils.trim(sTheme.replace(/[^a-zA-Z]+/g, ' ').replace(/([A-Z])/g, ' $1').replace(/[\s]+/g, ' '));
+ };
+
+ /**
+ * @param {string} sName
+ * @return {string}
+ */
+ Utils.quoteName = function (sName)
+ {
+ return sName.replace(/["]/g, '\\"');
+ };
+
+ /**
+ * @return {number}
+ */
+ Utils.microtime = function ()
+ {
+ return (new Date()).getTime();
+ };
+
+ /**
+ *
+ * @param {string} sLanguage
+ * @param {boolean=} bEng = false
+ * @return {string}
+ */
+ Utils.convertLangName = function (sLanguage, bEng)
+ {
+ return Utils.i18n('LANGS_NAMES' + (true === bEng ? '_EN' : '') + '/LANG_' +
+ sLanguage.toUpperCase().replace(/[^a-zA-Z0-9]+/, '_'), null, sLanguage);
+ };
+
+ /**
+ * @param {number=} iLen
+ * @return {string}
+ */
+ Utils.fakeMd5 = function(iLen)
+ {
+ var
+ sResult = '',
+ sLine = '0123456789abcdefghijklmnopqrstuvwxyz'
+ ;
+
+ iLen = Utils.isUnd(iLen) ? 32 : Utils.pInt(iLen);
+
+ while (sResult.length < iLen)
+ {
+ sResult += sLine.substr(Math.round(Math.random() * sLine.length), 1);
+ }
+
+ return sResult;
+ };
+
+ /* jshint ignore:start */
+
+ /**
+ * @param {string} s
+ * @return {string}
+ */
+ Utils.md5 = function(s){function L(k,d){return(k<>>(32-d))}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H>>29;return aa}function B(x){var k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");var d="";for(var F=0;F127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P /g, '>').replace(/');
+ };
+
+ Utils.draggeblePlace = function ()
+ {
+ return $(' ').appendTo('#rl-hidden');
+ };
+
+ Utils.defautOptionsAfterRender = function (oOption, oItem)
+ {
+ if (oItem && !Utils.isUnd(oItem.disabled) && oOption)
+ {
+ $(oOption)
+ .toggleClass('disabled', oItem.disabled)
+ .prop('disabled', oItem.disabled)
+ ;
+ }
+ };
+
+ /**
+ * @param {Object} oViewModel
+ * @param {string} sTemplateID
+ * @param {string} sTitle
+ * @param {Function=} fCallback
+ */
+ Utils.windowPopupKnockout = function (oViewModel, sTemplateID, sTitle, fCallback)
+ {
+ var
+ oScript = null,
+ oWin = window.open(''),
+ sFunc = '__OpenerApplyBindingsUid' + Utils.fakeMd5() + '__',
+ oTemplate = $('#' + sTemplateID)
+ ;
+
+ window[sFunc] = function () {
+
+ if (oWin && oWin.document.body && oTemplate && oTemplate[0])
+ {
+ var oBody = $(oWin.document.body);
+
+ $('#rl-content', oBody).html(oTemplate.html());
+ $('html', oWin.document).addClass('external ' + $('html').attr('class'));
+
+ Utils.i18nToNode(oBody);
+
+ Knoin.prototype.applyExternal(oViewModel, $('#rl-content', oBody)[0]);
+
+ window[sFunc] = null;
+
+ fCallback(oWin);
+ }
+ };
+
+ oWin.document.open();
+ oWin.document.write('' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' + Utils.encodeHtml(sTitle) + ' ' +
+ '');
+ oWin.document.close();
+
+ oScript = oWin.document.createElement('script');
+ oScript.type = 'text/javascript';
+ oScript.innerHTML = 'if(window&&window.opener&&window.opener[\'' + sFunc + '\']){window.opener[\'' + sFunc + '\']();window.opener[\'' + sFunc + '\']=null}';
+ oWin.document.getElementsByTagName('head')[0].appendChild(oScript);
+ };
+
+ Utils.settingsSaveHelperFunction = function (fCallback, koTrigger, oContext, iTimer)
+ {
+ oContext = oContext || null;
+ iTimer = Utils.isUnd(iTimer) ? 1000 : Utils.pInt(iTimer);
+ return function (sType, mData, bCached, sRequestAction, oRequestParameters) {
+ koTrigger.call(oContext, mData && mData['Result'] ? Enums.SaveSettingsStep.TrueResult : Enums.SaveSettingsStep.FalseResult);
+ if (fCallback)
+ {
+ fCallback.call(oContext, sType, mData, bCached, sRequestAction, oRequestParameters);
+ }
+ _.delay(function () {
+ koTrigger.call(oContext, Enums.SaveSettingsStep.Idle);
+ }, iTimer);
+ };
+ };
+
+ Utils.settingsSaveHelperSimpleFunction = function (koTrigger, oContext)
+ {
+ return Utils.settingsSaveHelperFunction(null, koTrigger, oContext, 1000);
+ };
+
+ Utils.$div = $('');
+
+ /**
+ * @param {string} sHtml
+ * @return {string}
+ */
+ Utils.htmlToPlain = function (sHtml)
+ {
+ var
+ iPos = 0,
+ iP1 = 0,
+ iP2 = 0,
+ iP3 = 0,
+ iLimit = 0,
+
+ sText = '',
+
+ splitPlainText = function (sText)
+ {
+ var
+ iLen = 100,
+ sPrefix = '',
+ sSubText = '',
+ sResult = sText,
+ iSpacePos = 0,
+ iNewLinePos = 0
+ ;
+
+ while (sResult.length > iLen)
+ {
+ sSubText = sResult.substring(0, iLen);
+ iSpacePos = sSubText.lastIndexOf(' ');
+ iNewLinePos = sSubText.lastIndexOf('\n');
+
+ if (-1 !== iNewLinePos)
+ {
+ iSpacePos = iNewLinePos;
+ }
+
+ if (-1 === iSpacePos)
+ {
+ iSpacePos = iLen;
+ }
+
+ sPrefix += sSubText.substring(0, iSpacePos) + '\n';
+ sResult = sResult.substring(iSpacePos + 1);
+ }
+
+ return sPrefix + sResult;
+ },
+
+ convertBlockquote = function (sText) {
+ sText = splitPlainText($.trim(sText));
+ sText = '> ' + sText.replace(/\n/gm, '\n> ');
+ return sText.replace(/(^|\n)([> ]+)/gm, function () {
+ return (arguments && 2 < arguments.length) ? arguments[1] + $.trim(arguments[2].replace(/[\s]/, '')) + ' ' : '';
+ });
+ },
+
+ convertDivs = function () {
+ if (arguments && 1 < arguments.length)
+ {
+ var sText = $.trim(arguments[1]);
+ if (0 < sText.length)
+ {
+ sText = sText.replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs);
+ sText = '\n' + $.trim(sText) + '\n';
+ }
+
+ return sText;
+ }
+
+ return '';
+ },
+
+ convertPre = function () {
+ return (arguments && 1 < arguments.length) ? arguments[1].toString().replace(/[\n]/gm, '
') : '';
+ },
+
+ fixAttibuteValue = function () {
+ return (arguments && 1 < arguments.length) ?
+ '' + arguments[1] + arguments[2].replace(//g, '>') : '';
+ },
+
+ convertLinks = function () {
+ return (arguments && 1 < arguments.length) ? $.trim(arguments[1]) : '';
+ }
+ ;
+
+ sText = sHtml
+ .replace(/]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre)
+ .replace(/[\s]+/gm, ' ')
+ .replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue)
+ .replace(/
]*>/gmi, '\n')
+ .replace(/<\/h[\d]>/gi, '\n')
+ .replace(/<\/p>/gi, '\n\n')
+ .replace(/<\/li>/gi, '\n')
+ .replace(/<\/td>/gi, '\n')
+ .replace(/<\/tr>/gi, '\n')
+ .replace(/
]*>/gmi, '\n_______________________________\n\n')
+ .replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs)
+ .replace(/]*>/gmi, '\n__bq__start__\n')
+ .replace(/<\/blockquote>/gmi, '\n__bq__end__\n')
+ .replace(/]*>([\s\S\r\n]*?)<\/a>/gmi, convertLinks)
+ .replace(/<\/div>/gi, '\n')
+ .replace(/ /gi, ' ')
+ .replace(/"/gi, '"')
+ .replace(/<[^>]*>/gm, '')
+ ;
+
+ sText = Utils.$div.html(sText).text();
+
+ sText = sText
+ .replace(/\n[ \t]+/gm, '\n')
+ .replace(/[\n]{3,}/gm, '\n\n')
+ .replace(/>/gi, '>')
+ .replace(/</gi, '<')
+ .replace(/&/gi, '&')
+ ;
+
+ iPos = 0;
+ iLimit = 100;
+
+ while (0 < iLimit)
+ {
+ iLimit--;
+ iP1 = sText.indexOf('__bq__start__', iPos);
+ if (-1 < iP1)
+ {
+ iP2 = sText.indexOf('__bq__start__', iP1 + 5);
+ iP3 = sText.indexOf('__bq__end__', iP1 + 5);
+
+ if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3)
+ {
+ sText = sText.substring(0, iP1) +
+ convertBlockquote(sText.substring(iP1 + 13, iP3)) +
+ sText.substring(iP3 + 11);
+
+ iPos = 0;
+ }
+ else if (-1 < iP2 && iP2 < iP3)
+ {
+ iPos = iP2 - 1;
+ }
+ else
+ {
+ iPos = 0;
+ }
}
else
{
- if (3 >= iCurrentPage || iPageCount - 2 <= iCurrentPage)
- {
- iLimit += 2;
- }
-
- fAdd(iCurrentPage);
- iPrev = iCurrentPage;
- iNext = iCurrentPage;
- }
-
- while (0 < iLimit) {
-
- iPrev -= 1;
- iNext += 1;
-
- if (0 < iPrev)
- {
- fAdd(iPrev, false);
- iLimit--;
- }
-
- if (iPageCount >= iNext)
- {
- fAdd(iNext, true);
- iLimit--;
- }
- else if (0 >= iPrev)
- {
- break;
- }
- }
-
- if (3 === iPrev)
- {
- fAdd(2, false);
- }
- else if (3 < iPrev)
- {
- fAdd(Math.round((iPrev - 1) / 2), false, '...');
- }
-
- if (iPageCount - 2 === iNext)
- {
- fAdd(iPageCount - 1, true);
- }
- else if (iPageCount - 2 > iNext)
- {
- fAdd(Math.round((iPageCount + iNext) / 2), true, '...');
- }
-
- // first and last
- if (1 < iPrev)
- {
- fAdd(1, false);
- }
-
- if (iPageCount > iNext)
- {
- fAdd(iPageCount, true);
+ break;
}
}
- return aResult;
+ sText = sText
+ .replace(/__bq__start__/gm, '')
+ .replace(/__bq__end__/gm, '')
+ ;
+
+ return sText;
};
-};
-Utils.selectElement = function (element)
-{
- /* jshint onevar: false */
- if (window.getSelection)
+ /**
+ * @param {string} sPlain
+ * @param {boolean} bLinkify = false
+ * @return {string}
+ */
+ Utils.plainToHtml = function (sPlain, bLinkify)
{
- var sel = window.getSelection();
- sel.removeAllRanges();
- var range = document.createRange();
- range.selectNodeContents(element);
- sel.addRange(range);
- }
- else if (document.selection)
- {
- var textRange = document.body.createTextRange();
- textRange.moveToElementText(element);
- textRange.select();
- }
- /* jshint onevar: true */
-};
+ sPlain = sPlain.toString().replace(/\r/g, '');
-Utils.disableKeyFilter = function ()
-{
- if (window.key)
- {
- key.filter = function () {
- return RL.data().useKeyboardShortcuts();
- };
- }
-};
+ var
+ bIn = false,
+ bDo = true,
+ bStart = true,
+ aNextText = [],
+ sLine = '',
+ iIndex = 0,
+ aText = sPlain.split("\n")
+ ;
-Utils.restoreKeyFilter = function ()
-{
- if (window.key)
- {
- key.filter = function (event) {
-
- if (RL.data().useKeyboardShortcuts())
+ do
+ {
+ bDo = false;
+ aNextText = [];
+ for (iIndex = 0; iIndex < aText.length; iIndex++)
{
- var
- element = event.target || event.srcElement,
- tagName = element ? element.tagName : ''
- ;
-
- tagName = tagName.toUpperCase();
- return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
- (element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
- );
+ sLine = aText[iIndex];
+ bStart = '>' === sLine.substr(0, 1);
+ if (bStart && !bIn)
+ {
+ bDo = true;
+ bIn = true;
+ aNextText.push('~~~blockquote~~~');
+ aNextText.push(sLine.substr(1));
+ }
+ else if (!bStart && bIn)
+ {
+ bIn = false;
+ aNextText.push('~~~/blockquote~~~');
+ aNextText.push(sLine);
+ }
+ else if (bStart && bIn)
+ {
+ aNextText.push(sLine.substr(1));
+ }
+ else
+ {
+ aNextText.push(sLine);
+ }
}
- return false;
- };
- }
-};
+ if (bIn)
+ {
+ bIn = false;
+ aNextText.push('~~~/blockquote~~~');
+ }
-Utils.detectDropdownVisibility = _.debounce(function () {
- Globals.dropdownVisibility(!!_.find(BootstrapDropdowns, function (oItem) {
- return oItem.hasClass('open');
- }));
-}, 50);
+ aText = aNextText;
+ }
+ while (bDo);
-Utils.triggerAutocompleteInputChange = function (bDelay) {
+ sPlain = aText.join("\n");
- var fFunc = function () {
- $('.checkAutocomplete').trigger('change');
+ sPlain = sPlain
+ .replace(/&/g, '&')
+ .replace(/>/g, '>').replace(/')
+ .replace(/[\s]*~~~\/blockquote~~~/g, '
')
+ .replace(/[\-_~]{10,}/g, '
')
+ .replace(/\n/g, '
');
+
+ return bLinkify ? Utils.linkify(sPlain) : sPlain;
};
- if (bDelay)
- {
- _.delay(fFunc, 100);
- }
- else
- {
- fFunc();
- }
-};
+ window.rainloop_Utils_htmlToPlain = Utils.htmlToPlain;
+ window.rainloop_Utils_plainToHtml = Utils.plainToHtml;
+ /**
+ * @param {string} sHtml
+ * @return {string}
+ */
+ Utils.linkify = function (sHtml)
+ {
+ if ($.fn && $.fn.linkify)
+ {
+ sHtml = Utils.$div.html(sHtml.replace(/&/ig, 'amp_amp_12345_amp_amp'))
+ .linkify()
+ .find('.linkified').removeClass('linkified').end()
+ .html()
+ .replace(/amp_amp_12345_amp_amp/g, '&')
+ ;
+ }
+ return sHtml;
+ };
+
+ Utils.resizeAndCrop = function (sUrl, iValue, fCallback)
+ {
+ var oTempImg = new window.Image();
+ oTempImg.onload = function() {
+
+ var
+ aDiff = [0, 0],
+ oCanvas = document.createElement('canvas'),
+ oCtx = oCanvas.getContext('2d')
+ ;
+
+ oCanvas.width = iValue;
+ oCanvas.height = iValue;
+
+ if (this.width > this.height)
+ {
+ aDiff = [this.width - this.height, 0];
+ }
+ else
+ {
+ aDiff = [0, this.height - this.width];
+ }
+
+ oCtx.fillStyle = '#fff';
+ oCtx.fillRect(0, 0, iValue, iValue);
+ oCtx.drawImage(this, aDiff[0] / 2, aDiff[1] / 2, this.width - aDiff[0], this.height - aDiff[1], 0, 0, iValue, iValue);
+
+ fCallback(oCanvas.toDataURL('image/jpeg'));
+ };
+
+ oTempImg.src = sUrl;
+ };
+
+ Utils.computedPagenatorHelper = function (koCurrentPage, koPageCount)
+ {
+ return function() {
+ var
+ iPrev = 0,
+ iNext = 0,
+ iLimit = 2,
+ aResult = [],
+ iCurrentPage = koCurrentPage(),
+ iPageCount = koPageCount(),
+
+ /**
+ * @param {number} iIndex
+ * @param {boolean=} bPush
+ * @param {string=} sCustomName
+ */
+ fAdd = function (iIndex, bPush, sCustomName) {
+
+ var oData = {
+ 'current': iIndex === iCurrentPage,
+ 'name': Utils.isUnd(sCustomName) ? iIndex.toString() : sCustomName.toString(),
+ 'custom': Utils.isUnd(sCustomName) ? false : true,
+ 'title': Utils.isUnd(sCustomName) ? '' : iIndex.toString(),
+ 'value': iIndex.toString()
+ };
+
+ if (Utils.isUnd(bPush) ? true : !!bPush)
+ {
+ aResult.push(oData);
+ }
+ else
+ {
+ aResult.unshift(oData);
+ }
+ }
+ ;
+
+ if (1 < iPageCount || (0 < iPageCount && iPageCount < iCurrentPage))
+ // if (0 < iPageCount && 0 < iCurrentPage)
+ {
+ if (iPageCount < iCurrentPage)
+ {
+ fAdd(iPageCount);
+ iPrev = iPageCount;
+ iNext = iPageCount;
+ }
+ else
+ {
+ if (3 >= iCurrentPage || iPageCount - 2 <= iCurrentPage)
+ {
+ iLimit += 2;
+ }
+
+ fAdd(iCurrentPage);
+ iPrev = iCurrentPage;
+ iNext = iCurrentPage;
+ }
+
+ while (0 < iLimit) {
+
+ iPrev -= 1;
+ iNext += 1;
+
+ if (0 < iPrev)
+ {
+ fAdd(iPrev, false);
+ iLimit--;
+ }
+
+ if (iPageCount >= iNext)
+ {
+ fAdd(iNext, true);
+ iLimit--;
+ }
+ else if (0 >= iPrev)
+ {
+ break;
+ }
+ }
+
+ if (3 === iPrev)
+ {
+ fAdd(2, false);
+ }
+ else if (3 < iPrev)
+ {
+ fAdd(Math.round((iPrev - 1) / 2), false, '...');
+ }
+
+ if (iPageCount - 2 === iNext)
+ {
+ fAdd(iPageCount - 1, true);
+ }
+ else if (iPageCount - 2 > iNext)
+ {
+ fAdd(Math.round((iPageCount + iNext) / 2), true, '...');
+ }
+
+ // first and last
+ if (1 < iPrev)
+ {
+ fAdd(1, false);
+ }
+
+ if (iPageCount > iNext)
+ {
+ fAdd(iPageCount, true);
+ }
+ }
+
+ return aResult;
+ };
+ };
+
+ Utils.selectElement = function (element)
+ {
+ /* jshint onevar: false */
+ if (window.getSelection)
+ {
+ var sel = window.getSelection();
+ sel.removeAllRanges();
+ var range = document.createRange();
+ range.selectNodeContents(element);
+ sel.addRange(range);
+ }
+ else if (document.selection)
+ {
+ var textRange = document.body.createTextRange();
+ textRange.moveToElementText(element);
+ textRange.select();
+ }
+ /* jshint onevar: true */
+ };
+
+ Utils.disableKeyFilter = function ()
+ {
+ if (window.key)
+ {
+ key.filter = function () {
+ return RL.data().useKeyboardShortcuts();
+ };
+ }
+ };
+
+ Utils.restoreKeyFilter = function ()
+ {
+ if (window.key)
+ {
+ key.filter = function (event) {
+
+ if (RL.data().useKeyboardShortcuts())
+ {
+ var
+ element = event.target || event.srcElement,
+ tagName = element ? element.tagName : ''
+ ;
+
+ tagName = tagName.toUpperCase();
+ return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
+ (element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
+ );
+ }
+
+ return false;
+ };
+ }
+ };
+
+ Utils.detectDropdownVisibility = _.debounce(function () {
+ Globals.dropdownVisibility(!!_.find(Globals.aBootstrapDropdowns, function (oItem) {
+ return oItem.hasClass('open');
+ }));
+ }, 50);
+
+ Utils.triggerAutocompleteInputChange = function (bDelay) {
+
+ var fFunc = function () {
+ $('.checkAutocomplete').trigger('change');
+ };
+
+ if (bDelay)
+ {
+ _.delay(fFunc, 100);
+ }
+ else
+ {
+ fFunc();
+ }
+ };
+
+ module.exports = Utils;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Common/_Begin.js b/dev/Common/_Begin.js
deleted file mode 100644
index be16a54fb..000000000
--- a/dev/Common/_Begin.js
+++ /dev/null
@@ -1,78 +0,0 @@
-
-'use strict';
-
-var
- /**
- * @type {Object}
- */
- Consts = {},
-
- /**
- * @type {Object}
- */
- Enums = {},
-
- /**
- * @type {Object}
- */
- NotificationI18N = {},
-
- /**
- * @type {Object.}
- */
- Utils = {},
-
- /**
- * @type {Object.}
- */
- Plugins = {},
-
- /**
- * @type {Object.}
- */
- Base64 = {},
-
- /**
- * @type {Object}
- */
- Globals = {},
-
- /**
- * @type {Object}
- */
- ViewModels = {
- 'settings': [],
- 'settings-removed': [],
- 'settings-disabled': []
- },
-
- /**
- * @type {Array}
- */
- BootstrapDropdowns = [],
-
- /**
- * @type {*}
- */
- kn = null,
-
- /**
- * @type {Object}
- */
- AppData = window['rainloopAppData'] || {},
-
- /**
- * @type {Object}
- */
- I18n = window['rainloopI18N'] || {},
-
- $html = $('html'),
-
-// $body = $('body'),
-
- $window = $(window),
-
- $document = $(window.document),
-
- NotificationClass = window.Notification && window.Notification.requestPermission ? window.Notification : null
-;
\ No newline at end of file
diff --git a/dev/Common/_BeginA.js b/dev/Common/_BeginA.js
deleted file mode 100644
index 93a28a701..000000000
--- a/dev/Common/_BeginA.js
+++ /dev/null
@@ -1,8 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/*jshint onevar: false*/
-/**
- * @type {?AdminApp}
- */
-var RL = null;
-/*jshint onevar: true*/
diff --git a/dev/Common/_BeginW.js b/dev/Common/_BeginW.js
deleted file mode 100644
index 3c7fc77d0..000000000
--- a/dev/Common/_BeginW.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/*jshint onevar: false*/
-/**
- * @type {?RainLoopApp}
- */
-var
- RL = null,
-
- $proxyDiv = $('')
-;
-/*jshint onevar: true*/
\ No newline at end of file
diff --git a/dev/Common/_End.js b/dev/Common/_End.js
deleted file mode 100644
index efe4a28b2..000000000
--- a/dev/Common/_End.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-$html.addClass(Globals.bMobileDevice ? 'mobile' : 'no-mobile');
-
-$window.keydown(Utils.killCtrlAandS).keyup(Utils.killCtrlAandS);
-$window.unload(function () {
- Globals.bUnload = true;
-});
-
-$html.on('click.dropdown.data-api', function () {
- Utils.detectDropdownVisibility();
-});
-
-// export
-window['rl'] = window['rl'] || {};
-window['rl']['addHook'] = Plugins.addHook;
-window['rl']['settingsGet'] = Plugins.mainSettingsGet;
-window['rl']['remoteRequest'] = Plugins.remoteRequest;
-window['rl']['pluginSettingsGet'] = Plugins.settingsGet;
-window['rl']['addSettingsViewModel'] = Utils.addSettingsViewModel;
-window['rl']['createCommand'] = Utils.createCommand;
-
-window['rl']['EmailModel'] = EmailModel;
-window['rl']['Enums'] = Enums;
-
-window['__RLBOOT'] = function (fCall) {
-
- // boot
- $(function () {
-
- if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0])
- {
- $('#rl-templates').html(window['rainloopTEMPLATES'][0]);
-
- _.delay(function () {
- window['rainloopAppData'] = {};
- window['rainloopI18N'] = {};
- window['rainloopTEMPLATES'] = {};
-
- kn.setBoot(RL).bootstart();
- $html.removeClass('no-js rl-booted-trigger').addClass('rl-booted');
-
- }, 50);
- }
- else
- {
- fCall(false);
- }
-
- window['__RLBOOT'] = null;
- });
-};
diff --git a/dev/External/$div.js b/dev/External/$div.js
new file mode 100644
index 000000000..b0b64c43f
--- /dev/null
+++ b/dev/External/$div.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')('');
diff --git a/dev/External/$doc.js b/dev/External/$doc.js
new file mode 100644
index 000000000..c598629de
--- /dev/null
+++ b/dev/External/$doc.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')(window.document);
diff --git a/dev/External/$html.js b/dev/External/$html.js
new file mode 100644
index 000000000..8ebaa01bf
--- /dev/null
+++ b/dev/External/$html.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')('html');
diff --git a/dev/External/$window.js b/dev/External/$window.js
new file mode 100644
index 000000000..2d1d5bae7
--- /dev/null
+++ b/dev/External/$window.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')(window);
diff --git a/dev/External/AppData.js b/dev/External/AppData.js
new file mode 100644
index 000000000..f1e359be3
--- /dev/null
+++ b/dev/External/AppData.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./window.js')['rainloopAppData'] || {};
\ No newline at end of file
diff --git a/dev/External/JSON.js b/dev/External/JSON.js
new file mode 100644
index 000000000..24da22fae
--- /dev/null
+++ b/dev/External/JSON.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = JSON;
\ No newline at end of file
diff --git a/dev/External/NotificationClass.js b/dev/External/NotificationClass.js
new file mode 100644
index 000000000..7913dc71f
--- /dev/null
+++ b/dev/External/NotificationClass.js
@@ -0,0 +1,9 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+var
+ window = require('./window.js')
+;
+
+module.exports = window.Notification && window.Notification.requestPermission ? window.Notification : null;
\ No newline at end of file
diff --git a/dev/External/crossroads.js b/dev/External/crossroads.js
new file mode 100644
index 000000000..2b2e8b73a
--- /dev/null
+++ b/dev/External/crossroads.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = crossroads;
\ No newline at end of file
diff --git a/dev/External/hasher.js b/dev/External/hasher.js
new file mode 100644
index 000000000..b729b4298
--- /dev/null
+++ b/dev/External/hasher.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = hasher;
\ No newline at end of file
diff --git a/dev/External/jquery.js b/dev/External/jquery.js
new file mode 100644
index 000000000..fc7053940
--- /dev/null
+++ b/dev/External/jquery.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = $;
\ No newline at end of file
diff --git a/dev/External/key.js b/dev/External/key.js
new file mode 100644
index 000000000..b6dc467e9
--- /dev/null
+++ b/dev/External/key.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = key;
\ No newline at end of file
diff --git a/dev/External/ko.js b/dev/External/ko.js
new file mode 100644
index 000000000..c1eb7e90f
--- /dev/null
+++ b/dev/External/ko.js
@@ -0,0 +1,864 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ $ = require('./jquery.js'),
+ _ = require('./underscore.js'),
+ window = require('./window.js'),
+ $window = require('./$window.js'),
+ $doc = require('./$doc.js'),
+ Globals = require('../Common/Globals.js'),
+ Utils = require('../Common/Utils.js')
+ ;
+
+ ko.bindingHandlers.tooltip = {
+ 'init': function (oElement, fValueAccessor) {
+ if (!Globals.bMobileDevice)
+ {
+ var
+ $oEl = $(oElement),
+ sClass = $oEl.data('tooltip-class') || '',
+ sPlacement = $oEl.data('tooltip-placement') || 'top'
+ ;
+
+ $oEl.tooltip({
+ 'delay': {
+ 'show': 500,
+ 'hide': 100
+ },
+ 'html': true,
+ 'container': 'body',
+ 'placement': sPlacement,
+ 'trigger': 'hover',
+ 'title': function () {
+ return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '' +
+ Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + '';
+ }
+ }).click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.tooltip2 = {
+ 'init': function (oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ sClass = $oEl.data('tooltip-class') || '',
+ sPlacement = $oEl.data('tooltip-placement') || 'top'
+ ;
+
+ $oEl.tooltip({
+ 'delay': {
+ 'show': 500,
+ 'hide': 100
+ },
+ 'html': true,
+ 'container': 'body',
+ 'placement': sPlacement,
+ 'title': function () {
+ return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' :
+ '' + fValueAccessor()() + '';
+ }
+ }).click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ }
+ };
+
+ ko.bindingHandlers.tooltip3 = {
+ 'init': function (oElement) {
+
+ var $oEl = $(oElement);
+
+ $oEl.tooltip({
+ 'container': 'body',
+ 'trigger': 'hover manual',
+ 'title': function () {
+ return $oEl.data('tooltip3-data') || '';
+ }
+ });
+
+ $doc.click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var sValue = ko.utils.unwrapObservable(fValueAccessor());
+ if ('' === sValue)
+ {
+ $(oElement).data('tooltip3-data', '').tooltip('hide');
+ }
+ else
+ {
+ $(oElement).data('tooltip3-data', sValue).tooltip('show');
+ }
+ }
+ };
+
+ ko.bindingHandlers.registrateBootstrapDropdown = {
+ 'init': function (oElement) {
+ Globals.aBootstrapDropdowns.push($(oElement));
+ }
+ };
+
+ ko.bindingHandlers.openDropdownTrigger = {
+ 'update': function (oElement, fValueAccessor) {
+ if (ko.utils.unwrapObservable(fValueAccessor()))
+ {
+ var $el = $(oElement);
+ if (!$el.hasClass('open'))
+ {
+ $el.find('.dropdown-toggle').dropdown('toggle');
+ Utils.detectDropdownVisibility();
+ }
+
+ fValueAccessor()(false);
+ }
+ }
+ };
+
+ ko.bindingHandlers.dropdownCloser = {
+ 'init': function (oElement) {
+ $(oElement).closest('.dropdown').on('click', '.e-item', function () {
+ $(oElement).dropdown('toggle');
+ });
+ }
+ };
+
+ ko.bindingHandlers.popover = {
+ 'init': function (oElement, fValueAccessor) {
+ $(oElement).popover(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.csstext = {
+ 'init': function (oElement, fValueAccessor) {
+ if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
+ {
+ oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
+ }
+ else
+ {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ },
+ 'update': function (oElement, fValueAccessor) {
+ if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
+ {
+ oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
+ }
+ else
+ {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ }
+ };
+
+ ko.bindingHandlers.resizecrop = {
+ 'init': function (oElement) {
+ $(oElement).addClass('resizecrop').resizecrop({
+ 'width': '100',
+ 'height': '100',
+ 'wrapperCSS': {
+ 'border-radius': '10px'
+ }
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ fValueAccessor()();
+ $(oElement).resizecrop({
+ 'width': '100',
+ 'height': '100'
+ });
+ }
+ };
+
+ ko.bindingHandlers.onEnter = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ $(oElement).on('keypress', function (oEvent) {
+ if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10))
+ {
+ $(oElement).trigger('change');
+ fValueAccessor().call(oViewModel);
+ }
+ });
+ }
+ };
+
+ ko.bindingHandlers.onEsc = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ $(oElement).on('keypress', function (oEvent) {
+ if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10))
+ {
+ $(oElement).trigger('change');
+ fValueAccessor().call(oViewModel);
+ }
+ });
+ }
+ };
+
+ ko.bindingHandlers.clickOnTrue = {
+ 'update': function (oElement, fValueAccessor) {
+ if (ko.utils.unwrapObservable(fValueAccessor()))
+ {
+ $(oElement).click();
+ }
+ }
+ };
+
+ ko.bindingHandlers.modal = {
+ 'init': function (oElement, fValueAccessor) {
+
+ $(oElement).toggleClass('fade', !Globals.bMobileDevice).modal({
+ 'keyboard': false,
+ 'show': ko.utils.unwrapObservable(fValueAccessor())
+ })
+ .on('shown', function () {
+ Utils.windowResize();
+ })
+ .find('.close').click(function () {
+ fValueAccessor()(false);
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).modal(ko.utils.unwrapObservable(fValueAccessor()) ? 'show' : 'hide');
+ }
+ };
+
+ ko.bindingHandlers.i18nInit = {
+ 'init': function (oElement) {
+ Utils.i18nToNode(oElement);
+ }
+ };
+
+ ko.bindingHandlers.i18nUpdate = {
+ 'update': function (oElement, fValueAccessor) {
+ ko.utils.unwrapObservable(fValueAccessor());
+ Utils.i18nToNode(oElement);
+ }
+ };
+
+ ko.bindingHandlers.link = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.title = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.textF = {
+ 'init': function (oElement, fValueAccessor) {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.initDom = {
+ 'init': function (oElement, fValueAccessor) {
+ fValueAccessor()(oElement);
+ }
+ };
+
+ ko.bindingHandlers.initResizeTrigger = {
+ 'init': function (oElement, fValueAccessor) {
+ var aValues = ko.utils.unwrapObservable(fValueAccessor());
+ $(oElement).css({
+ 'height': aValues[1],
+ 'min-height': aValues[1]
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var
+ aValues = ko.utils.unwrapObservable(fValueAccessor()),
+ iValue = Utils.pInt(aValues[1]),
+ iSize = 0,
+ iOffset = $(oElement).offset().top
+ ;
+
+ if (0 < iOffset)
+ {
+ iOffset += Utils.pInt(aValues[2]);
+ iSize = $window.height() - iOffset;
+
+ if (iValue < iSize)
+ {
+ iValue = iSize;
+ }
+
+ $(oElement).css({
+ 'height': iValue,
+ 'min-height': iValue
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.appendDom = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show();
+ }
+ };
+
+ ko.bindingHandlers.draggable = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ if (!Globals.bMobileDevice)
+ {
+ var
+ iTriggerZone = 100,
+ iScrollSpeed = 3,
+ fAllValueFunc = fAllBindingsAccessor(),
+ sDroppableSelector = fAllValueFunc && fAllValueFunc['droppableSelector'] ? fAllValueFunc['droppableSelector'] : '',
+ oConf = {
+ 'distance': 20,
+ 'handle': '.dragHandle',
+ 'cursorAt': {'top': 22, 'left': 3},
+ 'refreshPositions': true,
+ 'scroll': true
+ }
+ ;
+
+ if (sDroppableSelector)
+ {
+ oConf['drag'] = function (oEvent) {
+
+ $(sDroppableSelector).each(function () {
+ var
+ moveUp = null,
+ moveDown = null,
+ $this = $(this),
+ oOffset = $this.offset(),
+ bottomPos = oOffset.top + $this.height()
+ ;
+
+ window.clearInterval($this.data('timerScroll'));
+ $this.data('timerScroll', false);
+
+ if (oEvent.pageX >= oOffset.left && oEvent.pageX <= oOffset.left + $this.width())
+ {
+ if (oEvent.pageY >= bottomPos - iTriggerZone && oEvent.pageY <= bottomPos)
+ {
+ moveUp = function() {
+ $this.scrollTop($this.scrollTop() + iScrollSpeed);
+ Utils.windowResize();
+ };
+
+ $this.data('timerScroll', window.setInterval(moveUp, 10));
+ moveUp();
+ }
+
+ if (oEvent.pageY >= oOffset.top && oEvent.pageY <= oOffset.top + iTriggerZone)
+ {
+ moveDown = function() {
+ $this.scrollTop($this.scrollTop() - iScrollSpeed);
+ Utils.windowResize();
+ };
+
+ $this.data('timerScroll', window.setInterval(moveDown, 10));
+ moveDown();
+ }
+ }
+ });
+ };
+
+ oConf['stop'] = function() {
+ $(sDroppableSelector).each(function () {
+ window.clearInterval($(this).data('timerScroll'));
+ $(this).data('timerScroll', false);
+ });
+ };
+ }
+
+ oConf['helper'] = function (oEvent) {
+ return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null);
+ };
+
+ $(oElement).draggable(oConf).on('mousedown', function () {
+ Utils.removeInFocus();
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.droppable = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ if (!Globals.bMobileDevice)
+ {
+ var
+ fValueFunc = fValueAccessor(),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fOverCallback = fAllValueFunc && fAllValueFunc['droppableOver'] ? fAllValueFunc['droppableOver'] : null,
+ fOutCallback = fAllValueFunc && fAllValueFunc['droppableOut'] ? fAllValueFunc['droppableOut'] : null,
+ oConf = {
+ 'tolerance': 'pointer',
+ 'hoverClass': 'droppableHover'
+ }
+ ;
+
+ if (fValueFunc)
+ {
+ oConf['drop'] = function (oEvent, oUi) {
+ fValueFunc(oEvent, oUi);
+ };
+
+ if (fOverCallback)
+ {
+ oConf['over'] = function (oEvent, oUi) {
+ fOverCallback(oEvent, oUi);
+ };
+ }
+
+ if (fOutCallback)
+ {
+ oConf['out'] = function (oEvent, oUi) {
+ fOutCallback(oEvent, oUi);
+ };
+ }
+
+ $(oElement).droppable(oConf);
+ }
+ }
+ }
+ };
+
+ ko.bindingHandlers.nano = {
+ 'init': function (oElement) {
+ if (!Globals.bDisableNanoScroll)
+ {
+ $(oElement)
+ .addClass('nano')
+ .nanoScroller({
+ 'iOSNativeScrolling': false,
+ 'preventPageScrolling': true
+ })
+ ;
+ }
+ }
+ };
+
+ ko.bindingHandlers.saveTrigger = {
+ 'init': function (oElement) {
+
+ var $oEl = $(oElement);
+
+ $oEl.data('save-trigger-type', $oEl.is('input[type=text],input[type=email],input[type=password],select,textarea') ? 'input' : 'custom');
+
+ if ('custom' === $oEl.data('save-trigger-type'))
+ {
+ $oEl.append(
+ ' '
+ ).addClass('settings-saved-trigger');
+ }
+ else
+ {
+ $oEl.addClass('settings-saved-trigger-input');
+ }
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var
+ mValue = ko.utils.unwrapObservable(fValueAccessor()),
+ $oEl = $(oElement)
+ ;
+
+ if ('custom' === $oEl.data('save-trigger-type'))
+ {
+ switch (mValue.toString())
+ {
+ case '1':
+ $oEl
+ .find('.animated,.error').hide().removeClass('visible')
+ .end()
+ .find('.success').show().addClass('visible')
+ ;
+ break;
+ case '0':
+ $oEl
+ .find('.animated,.success').hide().removeClass('visible')
+ .end()
+ .find('.error').show().addClass('visible')
+ ;
+ break;
+ case '-2':
+ $oEl
+ .find('.error,.success').hide().removeClass('visible')
+ .end()
+ .find('.animated').show().addClass('visible')
+ ;
+ break;
+ default:
+ $oEl
+ .find('.animated').hide()
+ .end()
+ .find('.error,.success').removeClass('visible')
+ ;
+ break;
+ }
+ }
+ else
+ {
+ switch (mValue.toString())
+ {
+ case '1':
+ $oEl.addClass('success').removeClass('error');
+ break;
+ case '0':
+ $oEl.addClass('error').removeClass('success');
+ break;
+ case '-2':
+ // $oEl;
+ break;
+ default:
+ $oEl.removeClass('error success');
+ break;
+ }
+ }
+ }
+ };
+
+ ko.bindingHandlers.emailsTags = {
+ 'init': function(oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ fValue = fValueAccessor(),
+ fFocusCallback = function (bValue) {
+ if (fValue && fValue.focusTrigger)
+ {
+ fValue.focusTrigger(bValue);
+ }
+ }
+ ;
+
+ $oEl.inputosaurus({
+ 'parseOnBlur': true,
+ 'allowDragAndDrop': true,
+ 'focusCallback': fFocusCallback,
+ 'inputDelimiters': [',', ';'],
+ 'autoCompleteSource': function (oData, fResponse) {
+ RL.getAutocomplete(oData.term, function (aData) {
+ fResponse(_.map(aData, function (oEmailItem) {
+ return oEmailItem.toLine(false);
+ }));
+ });
+ },
+ 'parseHook': function (aInput) {
+ return _.map(aInput, function (sInputValue) {
+
+ var
+ sValue = Utils.trim(sInputValue),
+ oEmail = null
+ ;
+
+ if ('' !== sValue)
+ {
+ oEmail = new EmailModel();
+ oEmail.mailsoParse(sValue);
+ oEmail.clearDuplicateName();
+ return [oEmail.toLine(false), oEmail];
+ }
+
+ return [sValue, null];
+
+ });
+ },
+ 'change': _.bind(function (oEvent) {
+ $oEl.data('EmailsTagsValue', oEvent.target.value);
+ fValue(oEvent.target.value);
+ }, this)
+ });
+ },
+ 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ var
+ $oEl = $(oElement),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null,
+ sValue = ko.utils.unwrapObservable(fValueAccessor())
+ ;
+
+ if ($oEl.data('EmailsTagsValue') !== sValue)
+ {
+ $oEl.val(sValue);
+ $oEl.data('EmailsTagsValue', sValue);
+ $oEl.inputosaurus('refresh');
+ }
+
+ if (fEmailsTagsFilter && ko.utils.unwrapObservable(fEmailsTagsFilter))
+ {
+ $oEl.inputosaurus('focus');
+ }
+ }
+ };
+
+ ko.bindingHandlers.contactTags = {
+ 'init': function(oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ fValue = fValueAccessor(),
+ fFocusCallback = function (bValue) {
+ if (fValue && fValue.focusTrigger)
+ {
+ fValue.focusTrigger(bValue);
+ }
+ }
+ ;
+
+ $oEl.inputosaurus({
+ 'parseOnBlur': true,
+ 'allowDragAndDrop': false,
+ 'focusCallback': fFocusCallback,
+ 'inputDelimiters': [',', ';'],
+ 'outputDelimiter': ',',
+ 'autoCompleteSource': function (oData, fResponse) {
+ RL.getContactTagsAutocomplete(oData.term, function (aData) { // TODO cjs
+ fResponse(_.map(aData, function (oTagItem) {
+ return oTagItem.toLine(false);
+ }));
+ });
+ },
+ 'parseHook': function (aInput) {
+ return _.map(aInput, function (sInputValue) {
+
+ var
+ sValue = Utils.trim(sInputValue),
+ oTag = null
+ ;
+
+ if ('' !== sValue)
+ {
+ oTag = new ContactTagModel();
+ oTag.name(sValue);
+ return [oTag.toLine(false), oTag];
+ }
+
+ return [sValue, null];
+
+ });
+ },
+ 'change': _.bind(function (oEvent) {
+ $oEl.data('ContactTagsValue', oEvent.target.value);
+ fValue(oEvent.target.value);
+ }, this)
+ });
+ },
+ 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ var
+ $oEl = $(oElement),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fContactTagsFilter = fAllValueFunc['contactTagsFilter'] || null,
+ sValue = ko.utils.unwrapObservable(fValueAccessor())
+ ;
+
+ if ($oEl.data('ContactTagsValue') !== sValue)
+ {
+ $oEl.val(sValue);
+ $oEl.data('ContactTagsValue', sValue);
+ $oEl.inputosaurus('refresh');
+ }
+
+ if (fContactTagsFilter && ko.utils.unwrapObservable(fContactTagsFilter))
+ {
+ $oEl.inputosaurus('focus');
+ }
+ }
+ };
+
+ ko.bindingHandlers.command = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ var
+ jqElement = $(oElement),
+ oCommand = fValueAccessor()
+ ;
+
+ if (!oCommand || !oCommand.enabled || !oCommand.canExecute)
+ {
+ throw new Error('You are not using command function');
+ }
+
+ jqElement.addClass('command');
+ ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments);
+ },
+
+ 'update': function (oElement, fValueAccessor) {
+
+ var
+ bResult = true,
+ jqElement = $(oElement),
+ oCommand = fValueAccessor()
+ ;
+
+ bResult = oCommand.enabled();
+ jqElement.toggleClass('command-not-enabled', !bResult);
+
+ if (bResult)
+ {
+ bResult = oCommand.canExecute();
+ jqElement.toggleClass('command-can-not-be-execute', !bResult);
+ }
+
+ jqElement.toggleClass('command-disabled disable disabled', !bResult).toggleClass('no-disabled', !!bResult);
+
+ if (jqElement.is('input') || jqElement.is('button'))
+ {
+ jqElement.prop('disabled', !bResult);
+ }
+ }
+ };
+
+ ko.extenders.trimmer = function (oTarget)
+ {
+ var oResult = ko.computed({
+ 'read': oTarget,
+ 'write': function (sNewValue) {
+ oTarget(Utils.trim(sNewValue.toString()));
+ },
+ 'owner': this
+ });
+
+ oResult(oTarget());
+ return oResult;
+ };
+
+ ko.extenders.posInterer = function (oTarget, iDefault)
+ {
+ var oResult = ko.computed({
+ 'read': oTarget,
+ 'write': function (sNewValue) {
+ var iNew = Utils.pInt(sNewValue.toString(), iDefault);
+ if (0 >= iNew)
+ {
+ iNew = iDefault;
+ }
+
+ if (iNew === oTarget() && '' + iNew !== '' + sNewValue)
+ {
+ oTarget(iNew + 1);
+ }
+
+ oTarget(iNew);
+ }
+ });
+
+ oResult(oTarget());
+ return oResult;
+ };
+
+ ko.extenders.reversible = function (oTarget)
+ {
+ var mValue = oTarget();
+
+ oTarget.commit = function ()
+ {
+ mValue = oTarget();
+ };
+
+ oTarget.reverse = function ()
+ {
+ oTarget(mValue);
+ };
+
+ oTarget.commitedValue = function ()
+ {
+ return mValue;
+ };
+
+ return oTarget;
+ };
+
+ ko.extenders.toggleSubscribe = function (oTarget, oOptions)
+ {
+ oTarget.subscribe(oOptions[1], oOptions[0], 'beforeChange');
+ oTarget.subscribe(oOptions[2], oOptions[0]);
+
+ return oTarget;
+ };
+
+ ko.extenders.falseTimeout = function (oTarget, iOption)
+ {
+ oTarget.iTimeout = 0;
+ oTarget.subscribe(function (bValue) {
+ if (bValue)
+ {
+ window.clearTimeout(oTarget.iTimeout);
+ oTarget.iTimeout = window.setTimeout(function () {
+ oTarget(false);
+ oTarget.iTimeout = 0;
+ }, Utils.pInt(iOption));
+ }
+ });
+
+ return oTarget;
+ };
+
+ ko.observable.fn.validateNone = function ()
+ {
+ this.hasError = ko.observable(false);
+ return this;
+ };
+
+ ko.observable.fn.validateEmail = function ()
+ {
+ this.hasError = ko.observable(false);
+
+ this.subscribe(function (sValue) {
+ sValue = Utils.trim(sValue);
+ this.hasError('' !== sValue && !(/^[^@\s]+@[^@\s]+$/.test(sValue)));
+ }, this);
+
+ this.valueHasMutated();
+ return this;
+ };
+
+ ko.observable.fn.validateSimpleEmail = function ()
+ {
+ this.hasError = ko.observable(false);
+
+ this.subscribe(function (sValue) {
+ sValue = Utils.trim(sValue);
+ this.hasError('' !== sValue && !(/^.+@.+$/.test(sValue)));
+ }, this);
+
+ this.valueHasMutated();
+ return this;
+ };
+
+ ko.observable.fn.validateFunc = function (fFunc)
+ {
+ this.hasFuncError = ko.observable(false);
+
+ if (Utils.isFunc(fFunc))
+ {
+ this.subscribe(function (sValue) {
+ this.hasFuncError(!fFunc(sValue));
+ }, this);
+
+ this.valueHasMutated();
+ }
+
+ return this;
+ };
+
+ module.exports = ko;
+
+}(module));
\ No newline at end of file
diff --git a/dev/External/moment.js b/dev/External/moment.js
new file mode 100644
index 000000000..55751d793
--- /dev/null
+++ b/dev/External/moment.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = moment;
\ No newline at end of file
diff --git a/dev/External/ssm.js b/dev/External/ssm.js
new file mode 100644
index 000000000..762f091a4
--- /dev/null
+++ b/dev/External/ssm.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = ssm;
\ No newline at end of file
diff --git a/dev/External/underscore.js b/dev/External/underscore.js
new file mode 100644
index 000000000..d2175d760
--- /dev/null
+++ b/dev/External/underscore.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = window;
\ No newline at end of file
diff --git a/dev/External/window.js b/dev/External/window.js
new file mode 100644
index 000000000..921d4c754
--- /dev/null
+++ b/dev/External/window.js
@@ -0,0 +1,5 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = window;
diff --git a/dev/Knoin/AbstractBoot.js b/dev/Knoin/AbstractBoot.js
deleted file mode 100644
index 274e5690d..000000000
--- a/dev/Knoin/AbstractBoot.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- */
-function KnoinAbstractBoot()
-{
-
-}
-
-KnoinAbstractBoot.prototype.bootstart = function ()
-{
-
-};
diff --git a/dev/Knoin/AbstractScreen.js b/dev/Knoin/AbstractScreen.js
deleted file mode 100644
index 27270ba47..000000000
--- a/dev/Knoin/AbstractScreen.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @param {string} sScreenName
- * @param {?=} aViewModels = []
- * @constructor
- */
-function KnoinAbstractScreen(sScreenName, aViewModels)
-{
- this.sScreenName = sScreenName;
- this.aViewModels = Utils.isArray(aViewModels) ? aViewModels : [];
-}
-
-/**
- * @type {Array}
- */
-KnoinAbstractScreen.prototype.oCross = null;
-
-/**
- * @type {string}
- */
-KnoinAbstractScreen.prototype.sScreenName = '';
-
-/**
- * @type {Array}
- */
-KnoinAbstractScreen.prototype.aViewModels = [];
-
-/**
- * @return {Array}
- */
-KnoinAbstractScreen.prototype.viewModels = function ()
-{
- return this.aViewModels;
-};
-
-/**
- * @return {string}
- */
-KnoinAbstractScreen.prototype.screenName = function ()
-{
- return this.sScreenName;
-};
-
-KnoinAbstractScreen.prototype.routes = function ()
-{
- return null;
-};
-
-/**
- * @return {?Object}
- */
-KnoinAbstractScreen.prototype.__cross = function ()
-{
- return this.oCross;
-};
-
-KnoinAbstractScreen.prototype.__start = function ()
-{
- var
- aRoutes = this.routes(),
- oRoute = null,
- fMatcher = null
- ;
-
- if (Utils.isNonEmptyArray(aRoutes))
- {
- fMatcher = _.bind(this.onRoute || Utils.emptyFunction, this);
- oRoute = crossroads.create();
-
- _.each(aRoutes, function (aItem) {
- oRoute.addRoute(aItem[0], fMatcher).rules = aItem[1];
- });
-
- this.oCross = oRoute;
- }
-};
diff --git a/dev/Knoin/AbstractViewModel.js b/dev/Knoin/AbstractViewModel.js
deleted file mode 100644
index 2fa64c690..000000000
--- a/dev/Knoin/AbstractViewModel.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @param {string=} sPosition = ''
- * @param {string=} sTemplate = ''
- * @constructor
- */
-function KnoinAbstractViewModel(sPosition, sTemplate)
-{
- this.bDisabeCloseOnEsc = false;
- this.sPosition = Utils.pString(sPosition);
- this.sTemplate = Utils.pString(sTemplate);
-
- this.sDefaultKeyScope = Enums.KeyState.None;
- this.sCurrentKeyScope = this.sDefaultKeyScope;
-
- this.viewModelName = '';
- this.viewModelVisibility = ko.observable(false);
- this.modalVisibility = ko.observable(false).extend({'rateLimit': 0});
-
- this.viewModelDom = null;
-}
-
-/**
- * @type {string}
- */
-KnoinAbstractViewModel.prototype.sPosition = '';
-
-/**
- * @type {string}
- */
-KnoinAbstractViewModel.prototype.sTemplate = '';
-
-/**
- * @type {string}
- */
-KnoinAbstractViewModel.prototype.viewModelName = '';
-
-/**
- * @type {?}
- */
-KnoinAbstractViewModel.prototype.viewModelDom = null;
-
-/**
- * @return {string}
- */
-KnoinAbstractViewModel.prototype.viewModelTemplate = function ()
-{
- return this.sTemplate;
-};
-
-/**
- * @return {string}
- */
-KnoinAbstractViewModel.prototype.viewModelPosition = function ()
-{
- return this.sPosition;
-};
-
-KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototype.closeCommand = function ()
-{
-};
-
-KnoinAbstractViewModel.prototype.storeAndSetKeyScope = function ()
-{
- this.sCurrentKeyScope = RL.data().keyScope();
- RL.data().keyScope(this.sDefaultKeyScope);
-};
-
-KnoinAbstractViewModel.prototype.restoreKeyScope = function ()
-{
- RL.data().keyScope(this.sCurrentKeyScope);
-};
-
-KnoinAbstractViewModel.prototype.registerPopupKeyDown = function ()
-{
- var self = this;
- $window.on('keydown', function (oEvent) {
- if (oEvent && self.modalVisibility && self.modalVisibility())
- {
- if (!this.bDisabeCloseOnEsc && Enums.EventKeyCode.Esc === oEvent.keyCode)
- {
- Utils.delegateRun(self, 'cancelCommand');
- return false;
- }
- else if (Enums.EventKeyCode.Backspace === oEvent.keyCode && !Utils.inFocus())
- {
- return false;
- }
- }
-
- return true;
- });
-};
diff --git a/dev/Knoin/Knoin.js b/dev/Knoin/Knoin.js
index 8954efce8..29da06e4e 100644
--- a/dev/Knoin/Knoin.js
+++ b/dev/Knoin/Knoin.js
@@ -1,415 +1,486 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function Knoin()
-{
- this.sDefaultScreenName = '';
- this.oScreens = {};
- this.oBoot = null;
- this.oCurrentScreen = null;
-}
+(function (module) {
-/**
- * @param {Object} thisObject
- */
-Knoin.constructorEnd = function (thisObject)
-{
- if (Utils.isFunc(thisObject['__constructor_end']))
+ 'use strict';
+
+ var
+ $ = require('../External/jquery.js'),
+ _ = require('../External/underscore.js'),
+ ko = require('../External/ko.js'),
+ hasher = require('../External/hasher.js'),
+ crossroads = require('../External/crossroads.js'),
+ $html = require('../External/$html.js'),
+ Utils = require('../Common/Utils.js'),
+ Globals = require('../Common/Globals.js'),
+ Enums = require('../Common/Enums.js')
+ ;
+
+ /**
+ * @constructor
+ */
+ function Knoin()
{
- thisObject['__constructor_end'].call(thisObject);
- }
-};
-
-Knoin.prototype.sDefaultScreenName = '';
-Knoin.prototype.oScreens = {};
-Knoin.prototype.oBoot = null;
-Knoin.prototype.oCurrentScreen = null;
-
-Knoin.prototype.hideLoading = function ()
-{
- $('#rl-loading').hide();
-};
-
-Knoin.prototype.routeOff = function ()
-{
- hasher.changed.active = false;
-};
-
-Knoin.prototype.routeOn = function ()
-{
- hasher.changed.active = true;
-};
-
-/**
- * @param {Object} oBoot
- * @return {Knoin}
- */
-Knoin.prototype.setBoot = function (oBoot)
-{
- if (Utils.isNormal(oBoot))
- {
- this.oBoot = oBoot;
+ this.sDefaultScreenName = '';
+ this.oScreens = {};
+ this.oBoot = null;
+ this.oCurrentScreen = null;
}
- return this;
-};
+ /**
+ * @param {Object} thisObject
+ */
+ Knoin.constructorEnd = function (thisObject)
+ {
+ if (Utils.isFunc(thisObject['__constructor_end']))
+ {
+ thisObject['__constructor_end'].call(thisObject);
+ }
+ };
-/**
- * @param {string} sScreenName
- * @return {?Object}
- */
-Knoin.prototype.screen = function (sScreenName)
-{
- return ('' !== sScreenName && !Utils.isUnd(this.oScreens[sScreenName])) ? this.oScreens[sScreenName] : null;
-};
+ Knoin.prototype.sDefaultScreenName = '';
+ Knoin.prototype.oScreens = {};
+ Knoin.prototype.oBoot = null;
+ Knoin.prototype.oCurrentScreen = null;
-/**
- * @param {Function} ViewModelClass
- * @param {Object=} oScreen
- */
-Knoin.prototype.buildViewModel = function (ViewModelClass, oScreen)
-{
- if (ViewModelClass && !ViewModelClass.__builded)
+ Knoin.prototype.hideLoading = function ()
+ {
+ $('#rl-loading').hide();
+ };
+
+ Knoin.prototype.rl = function ()
+ {
+ return this.oBoot;
+ };
+
+ /**
+ * @param {Object} thisObject
+ */
+ Knoin.prototype.constructorEnd = function (thisObject)
+ {
+ if (Utils.isFunc(thisObject['__constructor_end']))
+ {
+ thisObject['__constructor_end'].call(thisObject);
+ }
+ };
+
+ Knoin.prototype.routeOff = function ()
+ {
+ hasher.changed.active = false;
+ };
+
+ Knoin.prototype.routeOn = function ()
+ {
+ hasher.changed.active = true;
+ };
+
+ /**
+ * @param {string} sScreenName
+ * @return {?Object}
+ */
+ Knoin.prototype.screen = function (sScreenName)
+ {
+ return ('' !== sScreenName && !Utils.isUnd(this.oScreens[sScreenName])) ? this.oScreens[sScreenName] : null;
+ };
+
+ /**
+ * @param {Function} ViewModelClass
+ * @param {Object=} oScreen
+ */
+ Knoin.prototype.buildViewModel = function (ViewModelClass, oScreen)
+ {
+ if (ViewModelClass && !ViewModelClass.__builded)
+ {
+ var
+ oViewModel = new ViewModelClass(oScreen),
+ sPosition = oViewModel.viewModelPosition(),
+ oViewModelPlace = $('#rl-content #rl-' + sPosition.toLowerCase()),
+ oViewModelDom = null
+ ;
+
+ ViewModelClass.__builded = true;
+ ViewModelClass.__vm = oViewModel;
+ oViewModel.data = RL.data(); // TODO cjs
+
+ oViewModel.viewModelName = ViewModelClass.__name;
+
+ if (oViewModelPlace && 1 === oViewModelPlace.length)
+ {
+ oViewModelDom = $('').addClass('rl-view-model').addClass('RL-' + oViewModel.viewModelTemplate()).hide();
+ oViewModelDom.appendTo(oViewModelPlace);
+
+ oViewModel.viewModelDom = oViewModelDom;
+ ViewModelClass.__dom = oViewModelDom;
+
+ if ('Popups' === sPosition)
+ {
+ oViewModel.cancelCommand = oViewModel.closeCommand = Utils.createCommand(oViewModel, function () {
+ kn.hideScreenPopup(ViewModelClass); // TODO cjs
+ });
+
+ oViewModel.modalVisibility.subscribe(function (bValue) {
+
+ var self = this;
+ if (bValue)
+ {
+ this.viewModelDom.show();
+ this.storeAndSetKeyScope();
+
+ RL.popupVisibilityNames.push(this.viewModelName); // TODO cjs
+ oViewModel.viewModelDom.css('z-index', 3000 + RL.popupVisibilityNames().length + 10); // TODO cjs
+
+ Utils.delegateRun(this, 'onFocus', [], 500);
+ }
+ else
+ {
+ Utils.delegateRun(this, 'onHide');
+ this.restoreKeyScope();
+
+ RL.popupVisibilityNames.remove(this.viewModelName); // TODO cjs
+ oViewModel.viewModelDom.css('z-index', 2000);
+
+ Globals.tooltipTrigger(!Globals.tooltipTrigger());
+
+ _.delay(function () {
+ self.viewModelDom.hide();
+ }, 300);
+ }
+
+ }, oViewModel);
+ }
+
+ Plugins.runHook('view-model-pre-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs
+
+ ko.applyBindingAccessorsToNode(oViewModelDom[0], {
+ 'i18nInit': true,
+ 'template': function () { return {'name': oViewModel.viewModelTemplate()};}
+ }, oViewModel);
+
+ Utils.delegateRun(oViewModel, 'onBuild', [oViewModelDom]);
+ if (oViewModel && 'Popups' === sPosition)
+ {
+ oViewModel.registerPopupKeyDown();
+ }
+
+ Plugins.runHook('view-model-post-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs
+ }
+ else
+ {
+ Utils.log('Cannot find view model position: ' + sPosition);
+ }
+ }
+
+ return ViewModelClass ? ViewModelClass.__vm : null;
+ };
+
+ /**
+ * @param {Object} oViewModel
+ * @param {Object} oViewModelDom
+ */
+ Knoin.prototype.applyExternal = function (oViewModel, oViewModelDom)
+ {
+ if (oViewModel && oViewModelDom)
+ {
+ ko.applyBindings(oViewModel, oViewModelDom);
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToHide
+ */
+ Knoin.prototype.hideScreenPopup = function (ViewModelClassToHide)
+ {
+ if (ViewModelClassToHide && ViewModelClassToHide.__vm && ViewModelClassToHide.__dom)
+ {
+ ViewModelClassToHide.__vm.modalVisibility(false);
+ Plugins.runHook('view-model-on-hide', [ViewModelClassToHide.__name, ViewModelClassToHide.__vm]); // TODO cjs
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToShow
+ * @param {Array=} aParameters
+ */
+ Knoin.prototype.showScreenPopup = function (ViewModelClassToShow, aParameters)
+ {
+ if (ViewModelClassToShow)
+ {
+ this.buildViewModel(ViewModelClassToShow);
+
+ if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom)
+ {
+ ViewModelClassToShow.__vm.modalVisibility(true);
+ Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []);
+ Plugins.runHook('view-model-on-show', [ViewModelClassToShow.__name, ViewModelClassToShow.__vm, aParameters || []]); // TODO cjs
+ }
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToShow
+ * @return {boolean}
+ */
+ Knoin.prototype.isPopupVisible = function (ViewModelClassToShow)
+ {
+ return ViewModelClassToShow && ViewModelClassToShow.__vm ? ViewModelClassToShow.__vm.modalVisibility() : false;
+ };
+
+ /**
+ * @param {string} sScreenName
+ * @param {string} sSubPart
+ */
+ Knoin.prototype.screenOnRoute = function (sScreenName, sSubPart)
{
var
- oViewModel = new ViewModelClass(oScreen),
- sPosition = oViewModel.viewModelPosition(),
- oViewModelPlace = $('#rl-content #rl-' + sPosition.toLowerCase()),
- oViewModelDom = null
+ self = this,
+ oScreen = null,
+ oCross = null
;
- ViewModelClass.__builded = true;
- ViewModelClass.__vm = oViewModel;
- oViewModel.data = RL.data();
-
- oViewModel.viewModelName = ViewModelClass.__name;
-
- if (oViewModelPlace && 1 === oViewModelPlace.length)
+ if ('' === Utils.pString(sScreenName))
{
- oViewModelDom = $('').addClass('rl-view-model').addClass('RL-' + oViewModel.viewModelTemplate()).hide();
- oViewModelDom.appendTo(oViewModelPlace);
+ sScreenName = this.sDefaultScreenName;
+ }
- oViewModel.viewModelDom = oViewModelDom;
- ViewModelClass.__dom = oViewModelDom;
-
- if ('Popups' === sPosition)
+ if ('' !== sScreenName)
+ {
+ oScreen = this.screen(sScreenName);
+ if (!oScreen)
{
- oViewModel.cancelCommand = oViewModel.closeCommand = Utils.createCommand(oViewModel, function () {
- kn.hideScreenPopup(ViewModelClass);
+ oScreen = this.screen(this.sDefaultScreenName);
+ if (oScreen)
+ {
+ sSubPart = sScreenName + '/' + sSubPart;
+ sScreenName = this.sDefaultScreenName;
+ }
+ }
+
+ if (oScreen && oScreen.__started)
+ {
+ if (!oScreen.__builded)
+ {
+ oScreen.__builded = true;
+
+ if (Utils.isNonEmptyArray(oScreen.viewModels()))
+ {
+ _.each(oScreen.viewModels(), function (ViewModelClass) {
+ this.buildViewModel(ViewModelClass, oScreen);
+ }, this);
+ }
+
+ Utils.delegateRun(oScreen, 'onBuild');
+ }
+
+ _.defer(function () {
+
+ // hide screen
+ if (self.oCurrentScreen)
+ {
+ Utils.delegateRun(self.oCurrentScreen, 'onHide');
+
+ if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
+ {
+ _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
+
+ if (ViewModelClass.__vm && ViewModelClass.__dom &&
+ 'Popups' !== ViewModelClass.__vm.viewModelPosition())
+ {
+ ViewModelClass.__dom.hide();
+ ViewModelClass.__vm.viewModelVisibility(false);
+ Utils.delegateRun(ViewModelClass.__vm, 'onHide');
+ }
+
+ });
+ }
+ }
+ // --
+
+ self.oCurrentScreen = oScreen;
+
+ // show screen
+ if (self.oCurrentScreen)
+ {
+ Utils.delegateRun(self.oCurrentScreen, 'onShow');
+
+ Plugins.runHook('screen-on-show', [self.oCurrentScreen.screenName(), self.oCurrentScreen]); // TODO cjs
+
+ if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
+ {
+ _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
+
+ if (ViewModelClass.__vm && ViewModelClass.__dom &&
+ 'Popups' !== ViewModelClass.__vm.viewModelPosition())
+ {
+ ViewModelClass.__dom.show();
+ ViewModelClass.__vm.viewModelVisibility(true);
+ Utils.delegateRun(ViewModelClass.__vm, 'onShow');
+ Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200);
+
+ Plugins.runHook('view-model-on-show', [ViewModelClass.__name, ViewModelClass.__vm]); // TODO cjs
+ }
+
+ }, self);
+ }
+ }
+ // --
+
+ oCross = oScreen.__cross();
+ if (oCross)
+ {
+ oCross.parse(sSubPart);
+ }
});
-
- oViewModel.modalVisibility.subscribe(function (bValue) {
-
- var self = this;
- if (bValue)
- {
- this.viewModelDom.show();
- this.storeAndSetKeyScope();
-
- RL.popupVisibilityNames.push(this.viewModelName);
- oViewModel.viewModelDom.css('z-index', 3000 + RL.popupVisibilityNames().length + 10);
-
- Utils.delegateRun(this, 'onFocus', [], 500);
- }
- else
- {
- Utils.delegateRun(this, 'onHide');
- this.restoreKeyScope();
-
- RL.popupVisibilityNames.remove(this.viewModelName);
- oViewModel.viewModelDom.css('z-index', 2000);
-
- Globals.tooltipTrigger(!Globals.tooltipTrigger());
-
- _.delay(function () {
- self.viewModelDom.hide();
- }, 300);
- }
-
- }, oViewModel);
}
+ }
+ };
- Plugins.runHook('view-model-pre-build', [ViewModelClass.__name, oViewModel, oViewModelDom]);
+ /**
+ * @param {Array} aScreensClasses
+ */
+ Knoin.prototype.startScreens = function (aScreensClasses)
+ {
+ $('#rl-content').css({
+ 'visibility': 'hidden'
+ });
- ko.applyBindingAccessorsToNode(oViewModelDom[0], {
- 'i18nInit': true,
- 'template': function () { return {'name': oViewModel.viewModelTemplate()};}
- }, oViewModel);
+ _.each(aScreensClasses, function (CScreen) {
- Utils.delegateRun(oViewModel, 'onBuild', [oViewModelDom]);
- if (oViewModel && 'Popups' === sPosition)
+ var
+ oScreen = new CScreen(),
+ sScreenName = oScreen ? oScreen.screenName() : ''
+ ;
+
+ if (oScreen && '' !== sScreenName)
+ {
+ if ('' === this.sDefaultScreenName)
+ {
+ this.sDefaultScreenName = sScreenName;
+ }
+
+ this.oScreens[sScreenName] = oScreen;
+ }
+
+ }, this);
+
+
+ _.each(this.oScreens, function (oScreen) {
+ if (oScreen && !oScreen.__started && oScreen.__start)
{
- oViewModel.registerPopupKeyDown();
- }
+ oScreen.__started = true;
+ oScreen.__start();
- Plugins.runHook('view-model-post-build', [ViewModelClass.__name, oViewModel, oViewModelDom]);
+ Plugins.runHook('screen-pre-start', [oScreen.screenName(), oScreen]); // TODO cjs
+ Utils.delegateRun(oScreen, 'onStart');
+ Plugins.runHook('screen-post-start', [oScreen.screenName(), oScreen]); // TODO cjs
+ }
+ }, this);
+
+ var oCross = crossroads.create();
+ oCross.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/, _.bind(this.screenOnRoute, this));
+
+ hasher.initialized.add(oCross.parse, oCross);
+ hasher.changed.add(oCross.parse, oCross);
+ hasher.init();
+
+ $('#rl-content').css({
+ 'visibility': 'visible'
+ });
+
+ _.delay(function () {
+ $html.removeClass('rl-started-trigger').addClass('rl-started');
+ }, 50);
+ };
+
+ /**
+ * @param {string} sHash
+ * @param {boolean=} bSilence = false
+ * @param {boolean=} bReplace = false
+ */
+ Knoin.prototype.setHash = function (sHash, bSilence, bReplace)
+ {
+ sHash = '#' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
+ sHash = '/' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
+
+ bReplace = Utils.isUnd(bReplace) ? false : !!bReplace;
+
+ if (Utils.isUnd(bSilence) ? false : !!bSilence)
+ {
+ hasher.changed.active = false;
+ hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
+ hasher.changed.active = true;
}
else
{
- Utils.log('Cannot find view model position: ' + sPosition);
+ hasher.changed.active = true;
+ hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
+ hasher.setHash(sHash);
}
- }
+ };
- return ViewModelClass ? ViewModelClass.__vm : null;
-};
-
-/**
- * @param {Object} oViewModel
- * @param {Object} oViewModelDom
- */
-Knoin.prototype.applyExternal = function (oViewModel, oViewModelDom)
-{
- if (oViewModel && oViewModelDom)
+ /**
+ * @return {Knoin}
+ */
+ Knoin.prototype.bootstart = function (RL)
{
- ko.applyBindings(oViewModel, oViewModelDom);
- }
-};
+ this.oBoot = RL;
+
+ var
+ window = require('../External/window.js'),
+ $window = require('../External/$window.js'),
+ $html = require('../External/$html.js'),
+ Plugins = require('../Common/Plugins.js'),
+ EmailModel = require('../Models/EmailModel.js')
+ ;
+
+ $html.addClass(Globals.bMobileDevice ? 'mobile' : 'no-mobile');
-/**
- * @param {Function} ViewModelClassToHide
- */
-Knoin.prototype.hideScreenPopup = function (ViewModelClassToHide)
-{
- if (ViewModelClassToHide && ViewModelClassToHide.__vm && ViewModelClassToHide.__dom)
- {
- ViewModelClassToHide.__vm.modalVisibility(false);
- Plugins.runHook('view-model-on-hide', [ViewModelClassToHide.__name, ViewModelClassToHide.__vm]);
- }
-};
+ $window.keydown(Utils.killCtrlAandS).keyup(Utils.killCtrlAandS);
+ $window.unload(function () {
+ Globals.bUnload = true;
+ });
-/**
- * @param {Function} ViewModelClassToShow
- * @param {Array=} aParameters
- */
-Knoin.prototype.showScreenPopup = function (ViewModelClassToShow, aParameters)
-{
- if (ViewModelClassToShow)
- {
- this.buildViewModel(ViewModelClassToShow);
+ $html.on('click.dropdown.data-api', function () {
+ Utils.detectDropdownVisibility();
+ });
- if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom)
- {
- ViewModelClassToShow.__vm.modalVisibility(true);
- Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []);
- Plugins.runHook('view-model-on-show', [ViewModelClassToShow.__name, ViewModelClassToShow.__vm, aParameters || []]);
- }
- }
-};
+ // export
+ window['rl'] = window['rl'] || {};
+ window['rl']['addHook'] = Plugins.addHook;
+ window['rl']['settingsGet'] = Plugins.mainSettingsGet;
+ window['rl']['remoteRequest'] = Plugins.remoteRequest;
+ window['rl']['pluginSettingsGet'] = Plugins.settingsGet;
+ window['rl']['addSettingsViewModel'] = Utils.addSettingsViewModel;
+ window['rl']['createCommand'] = Utils.createCommand;
-/**
- * @param {Function} ViewModelClassToShow
- * @return {boolean}
- */
-Knoin.prototype.isPopupVisible = function (ViewModelClassToShow)
-{
- return ViewModelClassToShow && ViewModelClassToShow.__vm ? ViewModelClassToShow.__vm.modalVisibility() : false;
-};
+ window['rl']['EmailModel'] = EmailModel;
+ window['rl']['Enums'] = Enums;
-/**
- * @param {string} sScreenName
- * @param {string} sSubPart
- */
-Knoin.prototype.screenOnRoute = function (sScreenName, sSubPart)
-{
- var
- self = this,
- oScreen = null,
- oCross = null
- ;
+ window['__RLBOOT'] = function (fCall) {
- if ('' === Utils.pString(sScreenName))
- {
- sScreenName = this.sDefaultScreenName;
- }
+ // boot
+ $(function () {
- if ('' !== sScreenName)
- {
- oScreen = this.screen(sScreenName);
- if (!oScreen)
- {
- oScreen = this.screen(this.sDefaultScreenName);
- if (oScreen)
- {
- sSubPart = sScreenName + '/' + sSubPart;
- sScreenName = this.sDefaultScreenName;
- }
- }
-
- if (oScreen && oScreen.__started)
- {
- if (!oScreen.__builded)
- {
- oScreen.__builded = true;
-
- if (Utils.isNonEmptyArray(oScreen.viewModels()))
+ if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0])
{
- _.each(oScreen.viewModels(), function (ViewModelClass) {
- this.buildViewModel(ViewModelClass, oScreen);
- }, this);
+ $('#rl-templates').html(window['rainloopTEMPLATES'][0]);
+
+ _.delay(function () {
+
+ RL.bootstart();
+
+ $html.removeClass('no-js rl-booted-trigger').addClass('rl-booted');
+ }, 50);
+ }
+ else
+ {
+ fCall(false);
}
- Utils.delegateRun(oScreen, 'onBuild');
- }
-
- _.defer(function () {
-
- // hide screen
- if (self.oCurrentScreen)
- {
- Utils.delegateRun(self.oCurrentScreen, 'onHide');
-
- if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
- {
- _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
-
- if (ViewModelClass.__vm && ViewModelClass.__dom &&
- 'Popups' !== ViewModelClass.__vm.viewModelPosition())
- {
- ViewModelClass.__dom.hide();
- ViewModelClass.__vm.viewModelVisibility(false);
- Utils.delegateRun(ViewModelClass.__vm, 'onHide');
- }
-
- });
- }
- }
- // --
-
- self.oCurrentScreen = oScreen;
-
- // show screen
- if (self.oCurrentScreen)
- {
- Utils.delegateRun(self.oCurrentScreen, 'onShow');
-
- Plugins.runHook('screen-on-show', [self.oCurrentScreen.screenName(), self.oCurrentScreen]);
-
- if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
- {
- _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
-
- if (ViewModelClass.__vm && ViewModelClass.__dom &&
- 'Popups' !== ViewModelClass.__vm.viewModelPosition())
- {
- ViewModelClass.__dom.show();
- ViewModelClass.__vm.viewModelVisibility(true);
- Utils.delegateRun(ViewModelClass.__vm, 'onShow');
- Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200);
-
- Plugins.runHook('view-model-on-show', [ViewModelClass.__name, ViewModelClass.__vm]);
- }
-
- }, self);
- }
- }
- // --
-
- oCross = oScreen.__cross();
- if (oCross)
- {
- oCross.parse(sSubPart);
- }
+ window['__RLBOOT'] = null;
});
- }
- }
-};
+ };
+ };
-/**
- * @param {Array} aScreensClasses
- */
-Knoin.prototype.startScreens = function (aScreensClasses)
-{
- $('#rl-content').css({
- 'visibility': 'hidden'
- });
+ module.exports = new Knoin();
- _.each(aScreensClasses, function (CScreen) {
-
- var
- oScreen = new CScreen(),
- sScreenName = oScreen ? oScreen.screenName() : ''
- ;
-
- if (oScreen && '' !== sScreenName)
- {
- if ('' === this.sDefaultScreenName)
- {
- this.sDefaultScreenName = sScreenName;
- }
-
- this.oScreens[sScreenName] = oScreen;
- }
-
- }, this);
-
-
- _.each(this.oScreens, function (oScreen) {
- if (oScreen && !oScreen.__started && oScreen.__start)
- {
- oScreen.__started = true;
- oScreen.__start();
-
- Plugins.runHook('screen-pre-start', [oScreen.screenName(), oScreen]);
- Utils.delegateRun(oScreen, 'onStart');
- Plugins.runHook('screen-post-start', [oScreen.screenName(), oScreen]);
- }
- }, this);
-
- var oCross = crossroads.create();
- oCross.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/, _.bind(this.screenOnRoute, this));
-
- hasher.initialized.add(oCross.parse, oCross);
- hasher.changed.add(oCross.parse, oCross);
- hasher.init();
-
- $('#rl-content').css({
- 'visibility': 'visible'
- });
-
- _.delay(function () {
- $html.removeClass('rl-started-trigger').addClass('rl-started');
- }, 50);
-};
-
-/**
- * @param {string} sHash
- * @param {boolean=} bSilence = false
- * @param {boolean=} bReplace = false
- */
-Knoin.prototype.setHash = function (sHash, bSilence, bReplace)
-{
- sHash = '#' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
- sHash = '/' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
-
- bReplace = Utils.isUnd(bReplace) ? false : !!bReplace;
-
- if (Utils.isUnd(bSilence) ? false : !!bSilence)
- {
- hasher.changed.active = false;
- hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
- hasher.changed.active = true;
- }
- else
- {
- hasher.changed.active = true;
- hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
- hasher.setHash(sHash);
- }
-};
-
-/**
- * @return {Knoin}
- */
-Knoin.prototype.bootstart = function ()
-{
- if (this.oBoot && this.oBoot.bootstart)
- {
- this.oBoot.bootstart();
- }
-
- return this;
-};
-
-kn = new Knoin();
+}(module));
\ No newline at end of file
diff --git a/dev/Knoin/KnoinAbstractBoot.js b/dev/Knoin/KnoinAbstractBoot.js
new file mode 100644
index 000000000..56fad3644
--- /dev/null
+++ b/dev/Knoin/KnoinAbstractBoot.js
@@ -0,0 +1,22 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function KnoinAbstractBoot()
+ {
+
+ }
+
+ KnoinAbstractBoot.prototype.bootstart = function ()
+ {
+
+ };
+
+ module.exports = KnoinAbstractBoot;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Knoin/KnoinAbstractScreen.js b/dev/Knoin/KnoinAbstractScreen.js
new file mode 100644
index 000000000..19f29cc47
--- /dev/null
+++ b/dev/Knoin/KnoinAbstractScreen.js
@@ -0,0 +1,90 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ crossroads = require('../External/crossroads.js'),
+ Utils = require('../Common/Utils.js')
+ ;
+
+ /**
+ * @param {string} sScreenName
+ * @param {?=} aViewModels = []
+ * @constructor
+ */
+ function KnoinAbstractScreen(sScreenName, aViewModels)
+ {
+ this.sScreenName = sScreenName;
+ this.aViewModels = Utils.isArray(aViewModels) ? aViewModels : [];
+ }
+
+ /**
+ * @type {Array}
+ */
+ KnoinAbstractScreen.prototype.oCross = null;
+
+ /**
+ * @type {string}
+ */
+ KnoinAbstractScreen.prototype.sScreenName = '';
+
+ /**
+ * @type {Array}
+ */
+ KnoinAbstractScreen.prototype.aViewModels = [];
+
+ /**
+ * @return {Array}
+ */
+ KnoinAbstractScreen.prototype.viewModels = function ()
+ {
+ return this.aViewModels;
+ };
+
+ /**
+ * @return {string}
+ */
+ KnoinAbstractScreen.prototype.screenName = function ()
+ {
+ return this.sScreenName;
+ };
+
+ KnoinAbstractScreen.prototype.routes = function ()
+ {
+ return null;
+ };
+
+ /**
+ * @return {?Object}
+ */
+ KnoinAbstractScreen.prototype.__cross = function ()
+ {
+ return this.oCross;
+ };
+
+ KnoinAbstractScreen.prototype.__start = function ()
+ {
+ var
+ aRoutes = this.routes(),
+ oRoute = null,
+ fMatcher = null
+ ;
+
+ if (Utils.isNonEmptyArray(aRoutes))
+ {
+ fMatcher = _.bind(this.onRoute || Utils.emptyFunction, this);
+ oRoute = crossroads.create();
+
+ _.each(aRoutes, function (aItem) {
+ oRoute.addRoute(aItem[0], fMatcher).rules = aItem[1];
+ });
+
+ this.oCross = oRoute;
+ }
+ };
+
+ module.exports = KnoinAbstractScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Knoin/KnoinAbstractViewModel.js b/dev/Knoin/KnoinAbstractViewModel.js
new file mode 100644
index 000000000..7814d789e
--- /dev/null
+++ b/dev/Knoin/KnoinAbstractViewModel.js
@@ -0,0 +1,109 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ ko = require('../External/ko.js'),
+ $window = require('../External/$window.js'),
+ Utils = require('../Common/Utils.js'),
+ Enums = require('../Common/Enums.js')
+ ;
+
+ /**
+ * @param {string=} sPosition = ''
+ * @param {string=} sTemplate = ''
+ * @constructor
+ */
+ function KnoinAbstractViewModel(sPosition, sTemplate)
+ {
+ this.bDisabeCloseOnEsc = false;
+ this.sPosition = Utils.pString(sPosition);
+ this.sTemplate = Utils.pString(sTemplate);
+
+ this.sDefaultKeyScope = Enums.KeyState.None;
+ this.sCurrentKeyScope = this.sDefaultKeyScope;
+
+ this.viewModelName = '';
+ this.viewModelVisibility = ko.observable(false);
+ this.modalVisibility = ko.observable(false).extend({'rateLimit': 0});
+
+ this.viewModelDom = null;
+ }
+
+ /**
+ * @type {string}
+ */
+ KnoinAbstractViewModel.prototype.sPosition = '';
+
+ /**
+ * @type {string}
+ */
+ KnoinAbstractViewModel.prototype.sTemplate = '';
+
+ /**
+ * @type {string}
+ */
+ KnoinAbstractViewModel.prototype.viewModelName = '';
+
+ /**
+ * @type {?}
+ */
+ KnoinAbstractViewModel.prototype.viewModelDom = null;
+
+ /**
+ * @return {string}
+ */
+ KnoinAbstractViewModel.prototype.viewModelTemplate = function ()
+ {
+ return this.sTemplate;
+ };
+
+ /**
+ * @return {string}
+ */
+ KnoinAbstractViewModel.prototype.viewModelPosition = function ()
+ {
+ return this.sPosition;
+ };
+
+ KnoinAbstractViewModel.prototype.cancelCommand = KnoinAbstractViewModel.prototype.closeCommand = function ()
+ {
+ };
+
+ KnoinAbstractViewModel.prototype.storeAndSetKeyScope = function ()
+ {
+ this.sCurrentKeyScope = RL.data().keyScope(); // TODO cjs
+ RL.data().keyScope(this.sDefaultKeyScope); // TODO cjs
+ };
+
+ KnoinAbstractViewModel.prototype.restoreKeyScope = function ()
+ {
+ RL.data().keyScope(this.sCurrentKeyScope); // TODO cjs
+ };
+
+ KnoinAbstractViewModel.prototype.registerPopupKeyDown = function ()
+ {
+ var self = this;
+ $window.on('keydown', function (oEvent) {
+ if (oEvent && self.modalVisibility && self.modalVisibility())
+ {
+ if (!this.bDisabeCloseOnEsc && Enums.EventKeyCode.Esc === oEvent.keyCode)
+ {
+ Utils.delegateRun(self, 'cancelCommand');
+ return false;
+ }
+ else if (Enums.EventKeyCode.Backspace === oEvent.keyCode && !Utils.inFocus())
+ {
+ return false;
+ }
+ }
+
+ return true;
+ });
+ };
+
+ module.exports = KnoinAbstractViewModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/AccountModel.js b/dev/Models/AccountModel.js
index 48f70a913..c089bd6e6 100644
--- a/dev/Models/AccountModel.js
+++ b/dev/Models/AccountModel.js
@@ -1,23 +1,35 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {string} sEmail
- * @param {boolean=} bCanBeDelete = true
- * @constructor
- */
-function AccountModel(sEmail, bCanBeDelete)
-{
- this.email = sEmail;
- this.deleteAccess = ko.observable(false);
- this.canBeDalete = ko.observable(bCanBeDelete);
-}
+(function (module) {
-AccountModel.prototype.email = '';
+ 'use strict';
-/**
- * @return {string}
- */
-AccountModel.prototype.changeAccountLink = function ()
-{
- return RL.link().change(this.email);
-};
\ No newline at end of file
+ var
+ ko = require('../External/ko.js')
+ ;
+
+ /**
+ * @param {string} sEmail
+ * @param {boolean=} bCanBeDelete = true
+ * @constructor
+ */
+ function AccountModel(sEmail, bCanBeDelete)
+ {
+ this.email = sEmail;
+ this.deleteAccess = ko.observable(false);
+ this.canBeDalete = ko.observable(bCanBeDelete);
+ }
+
+ AccountModel.prototype.email = '';
+
+ /**
+ * @return {string}
+ */
+ AccountModel.prototype.changeAccountLink = function ()
+ {
+ return RL.link().change(this.email); // TODO cjs
+ };
+
+ module.exports = AccountModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/AttachmentModel.js b/dev/Models/AttachmentModel.js
index a3dfe92d6..c2109eb64 100644
--- a/dev/Models/AttachmentModel.js
+++ b/dev/Models/AttachmentModel.js
@@ -1,237 +1,251 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function AttachmentModel()
-{
- this.mimeType = '';
- this.fileName = '';
- this.estimatedSize = 0;
- this.friendlySize = '';
- this.isInline = false;
- this.isLinked = false;
- this.cid = '';
- this.cidWithOutTags = '';
- this.contentLocation = '';
- this.download = '';
- this.folder = '';
- this.uid = '';
- this.mimeIndex = '';
-}
+(function (module) {
-/**
- * @static
- * @param {AjaxJsonAttachment} oJsonAttachment
- * @return {?AttachmentModel}
- */
-AttachmentModel.newInstanceFromJson = function (oJsonAttachment)
-{
- var oAttachmentModel = new AttachmentModel();
- return oAttachmentModel.initByJson(oJsonAttachment) ? oAttachmentModel : null;
-};
+ 'use strict';
-AttachmentModel.prototype.mimeType = '';
-AttachmentModel.prototype.fileName = '';
-AttachmentModel.prototype.estimatedSize = 0;
-AttachmentModel.prototype.friendlySize = '';
-AttachmentModel.prototype.isInline = false;
-AttachmentModel.prototype.isLinked = false;
-AttachmentModel.prototype.cid = '';
-AttachmentModel.prototype.cidWithOutTags = '';
-AttachmentModel.prototype.contentLocation = '';
-AttachmentModel.prototype.download = '';
-AttachmentModel.prototype.folder = '';
-AttachmentModel.prototype.uid = '';
-AttachmentModel.prototype.mimeIndex = '';
-
-/**
- * @param {AjaxJsonAttachment} oJsonAttachment
- */
-AttachmentModel.prototype.initByJson = function (oJsonAttachment)
-{
- var bResult = false;
- if (oJsonAttachment && 'Object/Attachment' === oJsonAttachment['@Object'])
- {
- this.mimeType = (oJsonAttachment.MimeType || '').toLowerCase();
- this.fileName = oJsonAttachment.FileName;
- this.estimatedSize = Utils.pInt(oJsonAttachment.EstimatedSize);
- this.isInline = !!oJsonAttachment.IsInline;
- this.isLinked = !!oJsonAttachment.IsLinked;
- this.cid = oJsonAttachment.CID;
- this.contentLocation = oJsonAttachment.ContentLocation;
- this.download = oJsonAttachment.Download;
-
- this.folder = oJsonAttachment.Folder;
- this.uid = oJsonAttachment.Uid;
- this.mimeIndex = oJsonAttachment.MimeIndex;
-
- this.friendlySize = Utils.friendlySize(this.estimatedSize);
- this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
-
- bResult = true;
- }
-
- return bResult;
-};
-
-/**
- * @return {boolean}
- */
-AttachmentModel.prototype.isImage = function ()
-{
- return -1 < Utils.inArray(this.mimeType.toLowerCase(),
- ['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
- );
-};
-
-/**
- * @return {boolean}
- */
-AttachmentModel.prototype.isText = function ()
-{
- return 'text/' === this.mimeType.substr(0, 5) &&
- -1 === Utils.inArray(this.mimeType, ['text/html']);
-};
-
-/**
- * @return {boolean}
- */
-AttachmentModel.prototype.isPdf = function ()
-{
- return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType;
-};
-
-/**
- * @return {string}
- */
-AttachmentModel.prototype.linkDownload = function ()
-{
- return RL.link().attachmentDownload(this.download);
-};
-
-/**
- * @return {string}
- */
-AttachmentModel.prototype.linkPreview = function ()
-{
- return RL.link().attachmentPreview(this.download);
-};
-
-/**
- * @return {string}
- */
-AttachmentModel.prototype.linkPreviewAsPlain = function ()
-{
- return RL.link().attachmentPreviewAsPlain(this.download);
-};
-
-/**
- * @return {string}
- */
-AttachmentModel.prototype.generateTransferDownloadUrl = function ()
-{
- var sLink = this.linkDownload();
- if ('http' !== sLink.substr(0, 4))
- {
- sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink;
- }
-
- return this.mimeType + ':' + this.fileName + ':' + sLink;
-};
-
-/**
- * @param {AttachmentModel} oAttachment
- * @param {*} oEvent
- * @return {boolean}
- */
-AttachmentModel.prototype.eventDragStart = function (oAttachment, oEvent)
-{
- var oLocalEvent = oEvent.originalEvent || oEvent;
- if (oAttachment && oLocalEvent && oLocalEvent.dataTransfer && oLocalEvent.dataTransfer.setData)
- {
- oLocalEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl());
- }
-
- return true;
-};
-
-AttachmentModel.prototype.iconClass = function ()
-{
var
- aParts = this.mimeType.toLocaleString().split('/'),
- sClass = 'icon-file'
+ window = require('../External/window.js'),
+ Globals = require('../Common/Globals.js'),
+ Utils = require('../Common/Utils.js')
;
-
- if (aParts && aParts[1])
+
+ /**
+ * @constructor
+ */
+ function AttachmentModel()
{
- if ('image' === aParts[0])
- {
- sClass = 'icon-file-image';
- }
- else if ('text' === aParts[0])
- {
- sClass = 'icon-file-text';
- }
- else if ('audio' === aParts[0])
- {
- sClass = 'icon-file-music';
- }
- else if ('video' === aParts[0])
- {
- sClass = 'icon-file-movie';
- }
- else if (-1 < Utils.inArray(aParts[1],
- ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed']))
- {
- sClass = 'icon-file-zip';
- }
-// else if (-1 < Utils.inArray(aParts[1],
-// ['pdf', 'x-pdf']))
-// {
-// sClass = 'icon-file-pdf';
-// }
-// else if (-1 < Utils.inArray(aParts[1], [
-// 'exe', 'x-exe', 'x-winexe', 'bat'
-// ]))
-// {
-// sClass = 'icon-console';
-// }
- else if (-1 < Utils.inArray(aParts[1], [
- 'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
- 'vnd.openxmlformats-officedocument.wordprocessingml.template',
- 'vnd.ms-word.document.macroEnabled.12',
- 'vnd.ms-word.template.macroEnabled.12'
- ]))
- {
- sClass = 'icon-file-text';
- }
- else if (-1 < Utils.inArray(aParts[1], [
- 'excel', 'ms-excel', 'vnd.ms-excel',
- 'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
- 'vnd.openxmlformats-officedocument.spreadsheetml.template',
- 'vnd.ms-excel.sheet.macroEnabled.12',
- 'vnd.ms-excel.template.macroEnabled.12',
- 'vnd.ms-excel.addin.macroEnabled.12',
- 'vnd.ms-excel.sheet.binary.macroEnabled.12'
- ]))
- {
- sClass = 'icon-file-excel';
- }
- else if (-1 < Utils.inArray(aParts[1], [
- 'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
- 'vnd.openxmlformats-officedocument.presentationml.presentation',
- 'vnd.openxmlformats-officedocument.presentationml.template',
- 'vnd.openxmlformats-officedocument.presentationml.slideshow',
- 'vnd.ms-powerpoint.addin.macroEnabled.12',
- 'vnd.ms-powerpoint.presentation.macroEnabled.12',
- 'vnd.ms-powerpoint.template.macroEnabled.12',
- 'vnd.ms-powerpoint.slideshow.macroEnabled.12'
- ]))
- {
- sClass = 'icon-file-chart-graph';
- }
+ this.mimeType = '';
+ this.fileName = '';
+ this.estimatedSize = 0;
+ this.friendlySize = '';
+ this.isInline = false;
+ this.isLinked = false;
+ this.cid = '';
+ this.cidWithOutTags = '';
+ this.contentLocation = '';
+ this.download = '';
+ this.folder = '';
+ this.uid = '';
+ this.mimeIndex = '';
}
- return sClass;
-};
+ /**
+ * @static
+ * @param {AjaxJsonAttachment} oJsonAttachment
+ * @return {?AttachmentModel}
+ */
+ AttachmentModel.newInstanceFromJson = function (oJsonAttachment)
+ {
+ var oAttachmentModel = new AttachmentModel();
+ return oAttachmentModel.initByJson(oJsonAttachment) ? oAttachmentModel : null;
+ };
+
+ AttachmentModel.prototype.mimeType = '';
+ AttachmentModel.prototype.fileName = '';
+ AttachmentModel.prototype.estimatedSize = 0;
+ AttachmentModel.prototype.friendlySize = '';
+ AttachmentModel.prototype.isInline = false;
+ AttachmentModel.prototype.isLinked = false;
+ AttachmentModel.prototype.cid = '';
+ AttachmentModel.prototype.cidWithOutTags = '';
+ AttachmentModel.prototype.contentLocation = '';
+ AttachmentModel.prototype.download = '';
+ AttachmentModel.prototype.folder = '';
+ AttachmentModel.prototype.uid = '';
+ AttachmentModel.prototype.mimeIndex = '';
+
+ /**
+ * @param {AjaxJsonAttachment} oJsonAttachment
+ */
+ AttachmentModel.prototype.initByJson = function (oJsonAttachment)
+ {
+ var bResult = false;
+ if (oJsonAttachment && 'Object/Attachment' === oJsonAttachment['@Object'])
+ {
+ this.mimeType = (oJsonAttachment.MimeType || '').toLowerCase();
+ this.fileName = oJsonAttachment.FileName;
+ this.estimatedSize = Utils.pInt(oJsonAttachment.EstimatedSize);
+ this.isInline = !!oJsonAttachment.IsInline;
+ this.isLinked = !!oJsonAttachment.IsLinked;
+ this.cid = oJsonAttachment.CID;
+ this.contentLocation = oJsonAttachment.ContentLocation;
+ this.download = oJsonAttachment.Download;
+
+ this.folder = oJsonAttachment.Folder;
+ this.uid = oJsonAttachment.Uid;
+ this.mimeIndex = oJsonAttachment.MimeIndex;
+
+ this.friendlySize = Utils.friendlySize(this.estimatedSize);
+ this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ AttachmentModel.prototype.isImage = function ()
+ {
+ return -1 < Utils.inArray(this.mimeType.toLowerCase(),
+ ['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
+ );
+ };
+
+ /**
+ * @return {boolean}
+ */
+ AttachmentModel.prototype.isText = function ()
+ {
+ return 'text/' === this.mimeType.substr(0, 5) &&
+ -1 === Utils.inArray(this.mimeType, ['text/html']);
+ };
+
+ /**
+ * @return {boolean}
+ */
+ AttachmentModel.prototype.isPdf = function ()
+ {
+ return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType;
+ };
+
+ /**
+ * @return {string}
+ */
+ AttachmentModel.prototype.linkDownload = function ()
+ {
+ return RL.link().attachmentDownload(this.download); // TODO cjs
+ };
+
+ /**
+ * @return {string}
+ */
+ AttachmentModel.prototype.linkPreview = function ()
+ {
+ return RL.link().attachmentPreview(this.download); // TODO cjs
+ };
+
+ /**
+ * @return {string}
+ */
+ AttachmentModel.prototype.linkPreviewAsPlain = function ()
+ {
+ return RL.link().attachmentPreviewAsPlain(this.download);
+ };
+
+ /**
+ * @return {string}
+ */
+ AttachmentModel.prototype.generateTransferDownloadUrl = function ()
+ {
+ var sLink = this.linkDownload();
+ if ('http' !== sLink.substr(0, 4))
+ {
+ sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink;
+ }
+
+ return this.mimeType + ':' + this.fileName + ':' + sLink;
+ };
+
+ /**
+ * @param {AttachmentModel} oAttachment
+ * @param {*} oEvent
+ * @return {boolean}
+ */
+ AttachmentModel.prototype.eventDragStart = function (oAttachment, oEvent)
+ {
+ var oLocalEvent = oEvent.originalEvent || oEvent;
+ if (oAttachment && oLocalEvent && oLocalEvent.dataTransfer && oLocalEvent.dataTransfer.setData)
+ {
+ oLocalEvent.dataTransfer.setData('DownloadURL', this.generateTransferDownloadUrl());
+ }
+
+ return true;
+ };
+
+ AttachmentModel.prototype.iconClass = function ()
+ {
+ var
+ aParts = this.mimeType.toLocaleString().split('/'),
+ sClass = 'icon-file'
+ ;
+
+ if (aParts && aParts[1])
+ {
+ if ('image' === aParts[0])
+ {
+ sClass = 'icon-file-image';
+ }
+ else if ('text' === aParts[0])
+ {
+ sClass = 'icon-file-text';
+ }
+ else if ('audio' === aParts[0])
+ {
+ sClass = 'icon-file-music';
+ }
+ else if ('video' === aParts[0])
+ {
+ sClass = 'icon-file-movie';
+ }
+ else if (-1 < Utils.inArray(aParts[1],
+ ['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed']))
+ {
+ sClass = 'icon-file-zip';
+ }
+ // else if (-1 < Utils.inArray(aParts[1],
+ // ['pdf', 'x-pdf']))
+ // {
+ // sClass = 'icon-file-pdf';
+ // }
+ // else if (-1 < Utils.inArray(aParts[1], [
+ // 'exe', 'x-exe', 'x-winexe', 'bat'
+ // ]))
+ // {
+ // sClass = 'icon-console';
+ // }
+ else if (-1 < Utils.inArray(aParts[1], [
+ 'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
+ 'vnd.openxmlformats-officedocument.wordprocessingml.template',
+ 'vnd.ms-word.document.macroEnabled.12',
+ 'vnd.ms-word.template.macroEnabled.12'
+ ]))
+ {
+ sClass = 'icon-file-text';
+ }
+ else if (-1 < Utils.inArray(aParts[1], [
+ 'excel', 'ms-excel', 'vnd.ms-excel',
+ 'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+ 'vnd.openxmlformats-officedocument.spreadsheetml.template',
+ 'vnd.ms-excel.sheet.macroEnabled.12',
+ 'vnd.ms-excel.template.macroEnabled.12',
+ 'vnd.ms-excel.addin.macroEnabled.12',
+ 'vnd.ms-excel.sheet.binary.macroEnabled.12'
+ ]))
+ {
+ sClass = 'icon-file-excel';
+ }
+ else if (-1 < Utils.inArray(aParts[1], [
+ 'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
+ 'vnd.openxmlformats-officedocument.presentationml.presentation',
+ 'vnd.openxmlformats-officedocument.presentationml.template',
+ 'vnd.openxmlformats-officedocument.presentationml.slideshow',
+ 'vnd.ms-powerpoint.addin.macroEnabled.12',
+ 'vnd.ms-powerpoint.presentation.macroEnabled.12',
+ 'vnd.ms-powerpoint.template.macroEnabled.12',
+ 'vnd.ms-powerpoint.slideshow.macroEnabled.12'
+ ]))
+ {
+ sClass = 'icon-file-chart-graph';
+ }
+ }
+
+ return sClass;
+ };
+
+ module.exports = AttachmentModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/ComposeAttachmentModel.js b/dev/Models/ComposeAttachmentModel.js
index 37dcdd96a..6489c9c15 100644
--- a/dev/Models/ComposeAttachmentModel.js
+++ b/dev/Models/ComposeAttachmentModel.js
@@ -1,63 +1,76 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @param {string} sId
- * @param {string} sFileName
- * @param {?number=} nSize
- * @param {boolean=} bInline
- * @param {boolean=} bLinked
- * @param {string=} sCID
- * @param {string=} sContentLocation
- */
-function ComposeAttachmentModel(sId, sFileName, nSize, bInline, bLinked, sCID, sContentLocation)
-{
- this.id = sId;
- this.isInline = Utils.isUnd(bInline) ? false : !!bInline;
- this.isLinked = Utils.isUnd(bLinked) ? false : !!bLinked;
- this.CID = Utils.isUnd(sCID) ? '' : sCID;
- this.contentLocation = Utils.isUnd(sContentLocation) ? '' : sContentLocation;
- this.fromMessage = false;
+(function (module) {
- this.fileName = ko.observable(sFileName);
- this.size = ko.observable(Utils.isUnd(nSize) ? null : nSize);
- this.tempName = ko.observable('');
+ 'use strict';
- this.progress = ko.observable('');
- this.error = ko.observable('');
- this.waiting = ko.observable(true);
- this.uploading = ko.observable(false);
- this.enabled = ko.observable(true);
+ var
+ ko = require('../External/ko.js'),
+ Utils = require('../Common/Utils.js')
+ ;
- this.friendlySize = ko.computed(function () {
- var mSize = this.size();
- return null === mSize ? '' : Utils.friendlySize(this.size());
- }, this);
-}
-
-ComposeAttachmentModel.prototype.id = '';
-ComposeAttachmentModel.prototype.isInline = false;
-ComposeAttachmentModel.prototype.isLinked = false;
-ComposeAttachmentModel.prototype.CID = '';
-ComposeAttachmentModel.prototype.contentLocation = '';
-ComposeAttachmentModel.prototype.fromMessage = false;
-ComposeAttachmentModel.prototype.cancel = Utils.emptyFunction;
-
-/**
- * @param {AjaxJsonComposeAttachment} oJsonAttachment
- */
-ComposeAttachmentModel.prototype.initByUploadJson = function (oJsonAttachment)
-{
- var bResult = false;
- if (oJsonAttachment)
+ /**
+ * @constructor
+ * @param {string} sId
+ * @param {string} sFileName
+ * @param {?number=} nSize
+ * @param {boolean=} bInline
+ * @param {boolean=} bLinked
+ * @param {string=} sCID
+ * @param {string=} sContentLocation
+ */
+ function ComposeAttachmentModel(sId, sFileName, nSize, bInline, bLinked, sCID, sContentLocation)
{
- this.fileName(oJsonAttachment.Name);
- this.size(Utils.isUnd(oJsonAttachment.Size) ? 0 : Utils.pInt(oJsonAttachment.Size));
- this.tempName(Utils.isUnd(oJsonAttachment.TempName) ? '' : oJsonAttachment.TempName);
- this.isInline = false;
+ this.id = sId;
+ this.isInline = Utils.isUnd(bInline) ? false : !!bInline;
+ this.isLinked = Utils.isUnd(bLinked) ? false : !!bLinked;
+ this.CID = Utils.isUnd(sCID) ? '' : sCID;
+ this.contentLocation = Utils.isUnd(sContentLocation) ? '' : sContentLocation;
+ this.fromMessage = false;
- bResult = true;
+ this.fileName = ko.observable(sFileName);
+ this.size = ko.observable(Utils.isUnd(nSize) ? null : nSize);
+ this.tempName = ko.observable('');
+
+ this.progress = ko.observable('');
+ this.error = ko.observable('');
+ this.waiting = ko.observable(true);
+ this.uploading = ko.observable(false);
+ this.enabled = ko.observable(true);
+
+ this.friendlySize = ko.computed(function () {
+ var mSize = this.size();
+ return null === mSize ? '' : Utils.friendlySize(this.size());
+ }, this);
}
- return bResult;
-};
\ No newline at end of file
+ ComposeAttachmentModel.prototype.id = '';
+ ComposeAttachmentModel.prototype.isInline = false;
+ ComposeAttachmentModel.prototype.isLinked = false;
+ ComposeAttachmentModel.prototype.CID = '';
+ ComposeAttachmentModel.prototype.contentLocation = '';
+ ComposeAttachmentModel.prototype.fromMessage = false;
+ ComposeAttachmentModel.prototype.cancel = Utils.emptyFunction;
+
+ /**
+ * @param {AjaxJsonComposeAttachment} oJsonAttachment
+ */
+ ComposeAttachmentModel.prototype.initByUploadJson = function (oJsonAttachment)
+ {
+ var bResult = false;
+ if (oJsonAttachment)
+ {
+ this.fileName(oJsonAttachment.Name);
+ this.size(Utils.isUnd(oJsonAttachment.Size) ? 0 : Utils.pInt(oJsonAttachment.Size));
+ this.tempName(Utils.isUnd(oJsonAttachment.TempName) ? '' : oJsonAttachment.TempName);
+ this.isInline = false;
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ module.exports = ComposeAttachmentModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/ContactModel.js b/dev/Models/ContactModel.js
index 4bc933b03..9cdf931a8 100644
--- a/dev/Models/ContactModel.js
+++ b/dev/Models/ContactModel.js
@@ -1,125 +1,140 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function ContactModel()
-{
- this.idContact = 0;
- this.display = '';
- this.properties = [];
- this.tags = '';
- this.readOnly = false;
+(function (module) {
- this.focused = ko.observable(false);
- this.selected = ko.observable(false);
- this.checked = ko.observable(false);
- this.deleted = ko.observable(false);
-}
+ 'use strict';
-/**
- * @return {Array|null}
- */
-ContactModel.prototype.getNameAndEmailHelper = function ()
-{
var
- sName = '',
- sEmail = ''
+ _ = require('../External/underscore.js'),
+ ko = require('../External/ko.js'),
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js')
;
-
- if (Utils.isNonEmptyArray(this.properties))
+
+ /**
+ * @constructor
+ */
+ function ContactModel()
{
- _.each(this.properties, function (aProperty) {
- if (aProperty)
- {
- if (Enums.ContactPropertyType.FirstName === aProperty[0])
- {
- sName = Utils.trim(aProperty[1] + ' ' + sName);
- }
- else if (Enums.ContactPropertyType.LastName === aProperty[0])
- {
- sName = Utils.trim(sName + ' ' + aProperty[1]);
- }
- else if ('' === sEmail && Enums.ContactPropertyType.Email === aProperty[0])
- {
- sEmail = aProperty[1];
- }
- }
- }, this);
+ this.idContact = 0;
+ this.display = '';
+ this.properties = [];
+ this.tags = '';
+ this.readOnly = false;
+
+ this.focused = ko.observable(false);
+ this.selected = ko.observable(false);
+ this.checked = ko.observable(false);
+ this.deleted = ko.observable(false);
}
- return '' === sEmail ? null : [sEmail, sName];
-};
-
-ContactModel.prototype.parse = function (oItem)
-{
- var bResult = false;
- if (oItem && 'Object/Contact' === oItem['@Object'])
+ /**
+ * @return {Array|null}
+ */
+ ContactModel.prototype.getNameAndEmailHelper = function ()
{
- this.idContact = Utils.pInt(oItem['IdContact']);
- this.display = Utils.pString(oItem['Display']);
- this.readOnly = !!oItem['ReadOnly'];
- this.tags = '';
+ var
+ sName = '',
+ sEmail = ''
+ ;
- if (Utils.isNonEmptyArray(oItem['Properties']))
+ if (Utils.isNonEmptyArray(this.properties))
{
- _.each(oItem['Properties'], function (oProperty) {
- if (oProperty && oProperty['Type'] && Utils.isNormal(oProperty['Value']) && Utils.isNormal(oProperty['TypeStr']))
+ _.each(this.properties, function (aProperty) {
+ if (aProperty)
{
- this.properties.push([Utils.pInt(oProperty['Type']), Utils.pString(oProperty['Value']), Utils.pString(oProperty['TypeStr'])]);
+ if (Enums.ContactPropertyType.FirstName === aProperty[0])
+ {
+ sName = Utils.trim(aProperty[1] + ' ' + sName);
+ }
+ else if (Enums.ContactPropertyType.LastName === aProperty[0])
+ {
+ sName = Utils.trim(sName + ' ' + aProperty[1]);
+ }
+ else if ('' === sEmail && Enums.ContactPropertyType.Email === aProperty[0])
+ {
+ sEmail = aProperty[1];
+ }
}
}, this);
}
- if (Utils.isNonEmptyArray(oItem['Tags']))
+ return '' === sEmail ? null : [sEmail, sName];
+ };
+
+ ContactModel.prototype.parse = function (oItem)
+ {
+ var bResult = false;
+ if (oItem && 'Object/Contact' === oItem['@Object'])
{
- this.tags = oItem['Tags'].join(',');
+ this.idContact = Utils.pInt(oItem['IdContact']);
+ this.display = Utils.pString(oItem['Display']);
+ this.readOnly = !!oItem['ReadOnly'];
+ this.tags = '';
+
+ if (Utils.isNonEmptyArray(oItem['Properties']))
+ {
+ _.each(oItem['Properties'], function (oProperty) {
+ if (oProperty && oProperty['Type'] && Utils.isNormal(oProperty['Value']) && Utils.isNormal(oProperty['TypeStr']))
+ {
+ this.properties.push([Utils.pInt(oProperty['Type']), Utils.pString(oProperty['Value']), Utils.pString(oProperty['TypeStr'])]);
+ }
+ }, this);
+ }
+
+ if (Utils.isNonEmptyArray(oItem['Tags']))
+ {
+ this.tags = oItem['Tags'].join(',');
+ }
+
+ bResult = true;
}
- bResult = true;
- }
+ return bResult;
+ };
- return bResult;
-};
-
-/**
- * @return {string}
- */
-ContactModel.prototype.srcAttr = function ()
-{
- return RL.link().emptyContactPic();
-};
-
-/**
- * @return {string}
- */
-ContactModel.prototype.generateUid = function ()
-{
- return '' + this.idContact;
-};
-
-/**
- * @return string
- */
-ContactModel.prototype.lineAsCcc = function ()
-{
- var aResult = [];
- if (this.deleted())
+ /**
+ * @return {string}
+ */
+ ContactModel.prototype.srcAttr = function ()
{
- aResult.push('deleted');
- }
- if (this.selected())
- {
- aResult.push('selected');
- }
- if (this.checked())
- {
- aResult.push('checked');
- }
- if (this.focused())
- {
- aResult.push('focused');
- }
+ return RL.link().emptyContactPic(); // TODO cjs
+ };
- return aResult.join(' ');
-};
+ /**
+ * @return {string}
+ */
+ ContactModel.prototype.generateUid = function ()
+ {
+ return '' + this.idContact;
+ };
+
+ /**
+ * @return string
+ */
+ ContactModel.prototype.lineAsCcc = function ()
+ {
+ var aResult = [];
+ if (this.deleted())
+ {
+ aResult.push('deleted');
+ }
+ if (this.selected())
+ {
+ aResult.push('selected');
+ }
+ if (this.checked())
+ {
+ aResult.push('checked');
+ }
+ if (this.focused())
+ {
+ aResult.push('focused');
+ }
+
+ return aResult.join(' ');
+ };
+
+ module.exports = ContactModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/ContactPropertyModel.js b/dev/Models/ContactPropertyModel.js
index 87c1053fb..ce629e292 100644
--- a/dev/Models/ContactPropertyModel.js
+++ b/dev/Models/ContactPropertyModel.js
@@ -1,30 +1,43 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {number=} iType = Enums.ContactPropertyType.Unknown
- * @param {string=} sTypeStr = ''
- * @param {string=} sValue = ''
- * @param {boolean=} bFocused = false
- * @param {string=} sPlaceholder = ''
- *
- * @constructor
- */
-function ContactPropertyModel(iType, sTypeStr, sValue, bFocused, sPlaceholder)
-{
- this.type = ko.observable(Utils.isUnd(iType) ? Enums.ContactPropertyType.Unknown : iType);
- this.typeStr = ko.observable(Utils.isUnd(sTypeStr) ? '' : sTypeStr);
- this.focused = ko.observable(Utils.isUnd(bFocused) ? false : !!bFocused);
- this.value = ko.observable(Utils.pString(sValue));
+(function (module) {
- this.placeholder = ko.observable(sPlaceholder || '');
+ 'use strict';
- this.placeholderValue = ko.computed(function () {
- var sPlaceholder = this.placeholder();
- return sPlaceholder ? Utils.i18n(sPlaceholder) : '';
- }, this);
+ var
+ ko = require('../External/ko.js'),
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js')
+ ;
- this.largeValue = ko.computed(function () {
- return Enums.ContactPropertyType.Note === this.type();
- }, this);
+ /**
+ * @param {number=} iType = Enums.ContactPropertyType.Unknown
+ * @param {string=} sTypeStr = ''
+ * @param {string=} sValue = ''
+ * @param {boolean=} bFocused = false
+ * @param {string=} sPlaceholder = ''
+ *
+ * @constructor
+ */
+ function ContactPropertyModel(iType, sTypeStr, sValue, bFocused, sPlaceholder)
+ {
+ this.type = ko.observable(Utils.isUnd(iType) ? Enums.ContactPropertyType.Unknown : iType);
+ this.typeStr = ko.observable(Utils.isUnd(sTypeStr) ? '' : sTypeStr);
+ this.focused = ko.observable(Utils.isUnd(bFocused) ? false : !!bFocused);
+ this.value = ko.observable(Utils.pString(sValue));
-}
+ this.placeholder = ko.observable(sPlaceholder || '');
+
+ this.placeholderValue = ko.computed(function () {
+ var sPlaceholder = this.placeholder();
+ return sPlaceholder ? Utils.i18n(sPlaceholder) : '';
+ }, this);
+
+ this.largeValue = ko.computed(function () {
+ return Enums.ContactPropertyType.Note === this.type();
+ }, this);
+ }
+
+ module.exports = ContactPropertyModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/ContactTagModel.js b/dev/Models/ContactTagModel.js
index 5141fecee..2af2c8022 100644
--- a/dev/Models/ContactTagModel.js
+++ b/dev/Models/ContactTagModel.js
@@ -1,45 +1,58 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function ContactTagModel()
-{
- this.idContactTag = 0;
- this.name = ko.observable('');
- this.readOnly = false;
-}
+(function (module) {
-ContactTagModel.prototype.parse = function (oItem)
-{
- var bResult = false;
- if (oItem && 'Object/Tag' === oItem['@Object'])
+ 'use strict';
+
+ var
+ ko = require('../External/ko.js'),
+ Utils = require('../Common/Utils.js')
+ ;
+
+ /**
+ * @constructor
+ */
+ function ContactTagModel()
{
- this.idContact = Utils.pInt(oItem['IdContactTag']);
- this.name(Utils.pString(oItem['Name']));
- this.readOnly = !!oItem['ReadOnly'];
-
- bResult = true;
+ this.idContactTag = 0;
+ this.name = ko.observable('');
+ this.readOnly = false;
}
- return bResult;
-};
+ ContactTagModel.prototype.parse = function (oItem)
+ {
+ var bResult = false;
+ if (oItem && 'Object/Tag' === oItem['@Object'])
+ {
+ this.idContact = Utils.pInt(oItem['IdContactTag']);
+ this.name(Utils.pString(oItem['Name']));
+ this.readOnly = !!oItem['ReadOnly'];
-/**
- * @param {string} sSearch
- * @return {boolean}
- */
-ContactTagModel.prototype.filterHelper = function (sSearch)
-{
- return this.name().toLowerCase().indexOf(sSearch.toLowerCase()) !== -1;
-};
+ bResult = true;
+ }
-/**
- * @param {boolean=} bEncodeHtml = false
- * @return {string}
- */
-ContactTagModel.prototype.toLine = function (bEncodeHtml)
-{
- return (Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml) ?
- Utils.encodeHtml(this.name()) : this.name();
-};
+ return bResult;
+ };
+
+ /**
+ * @param {string} sSearch
+ * @return {boolean}
+ */
+ ContactTagModel.prototype.filterHelper = function (sSearch)
+ {
+ return this.name().toLowerCase().indexOf(sSearch.toLowerCase()) !== -1;
+ };
+
+ /**
+ * @param {boolean=} bEncodeHtml = false
+ * @return {string}
+ */
+ ContactTagModel.prototype.toLine = function (bEncodeHtml)
+ {
+ return (Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml) ?
+ Utils.encodeHtml(this.name()) : this.name();
+ };
+
+ module.exports = ContactTagModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/EmailModel.js b/dev/Models/EmailModel.js
index b502cc267..7e15f2f0a 100644
--- a/dev/Models/EmailModel.js
+++ b/dev/Models/EmailModel.js
@@ -1,365 +1,378 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {string=} sEmail
- * @param {string=} sName
- *
- * @constructor
- */
-function EmailModel(sEmail, sName)
-{
- this.email = sEmail || '';
- this.name = sName || '';
- this.privateType = null;
+(function (module) {
- this.clearDuplicateName();
-}
+ 'use strict';
-/**
- * @static
- * @param {AjaxJsonEmail} oJsonEmail
- * @return {?EmailModel}
- */
-EmailModel.newInstanceFromJson = function (oJsonEmail)
-{
- var oEmailModel = new EmailModel();
- return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
-};
+ var
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js')
+ ;
-/**
- * @type {string}
- */
-EmailModel.prototype.name = '';
-
-/**
- * @type {string}
- */
-EmailModel.prototype.email = '';
-
-/**
- * @type {(number|null)}
- */
-EmailModel.prototype.privateType = null;
-
-EmailModel.prototype.clear = function ()
-{
- this.email = '';
- this.name = '';
- this.privateType = null;
-};
-
-/**
- * @returns {boolean}
- */
-EmailModel.prototype.validate = function ()
-{
- return '' !== this.name || '' !== this.email;
-};
-
-/**
- * @param {boolean} bWithoutName = false
- * @return {string}
- */
-EmailModel.prototype.hash = function (bWithoutName)
-{
- return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#';
-};
-
-EmailModel.prototype.clearDuplicateName = function ()
-{
- if (this.name === this.email)
+ /**
+ * @param {string=} sEmail
+ * @param {string=} sName
+ *
+ * @constructor
+ */
+ function EmailModel(sEmail, sName)
{
- this.name = '';
+ this.email = sEmail || '';
+ this.name = sName || '';
+ this.privateType = null;
+
+ this.clearDuplicateName();
}
-};
-/**
- * @return {number}
- */
-EmailModel.prototype.type = function ()
-{
- if (null === this.privateType)
+ /**
+ * @static
+ * @param {AjaxJsonEmail} oJsonEmail
+ * @return {?EmailModel}
+ */
+ EmailModel.newInstanceFromJson = function (oJsonEmail)
{
- if (this.email && '@facebook.com' === this.email.substr(-13))
- {
- this.privateType = Enums.EmailType.Facebook;
- }
+ var oEmailModel = new EmailModel();
+ return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
+ };
+ /**
+ * @type {string}
+ */
+ EmailModel.prototype.name = '';
+
+ /**
+ * @type {string}
+ */
+ EmailModel.prototype.email = '';
+
+ /**
+ * @type {(number|null)}
+ */
+ EmailModel.prototype.privateType = null;
+
+ EmailModel.prototype.clear = function ()
+ {
+ this.email = '';
+ this.name = '';
+ this.privateType = null;
+ };
+
+ /**
+ * @returns {boolean}
+ */
+ EmailModel.prototype.validate = function ()
+ {
+ return '' !== this.name || '' !== this.email;
+ };
+
+ /**
+ * @param {boolean} bWithoutName = false
+ * @return {string}
+ */
+ EmailModel.prototype.hash = function (bWithoutName)
+ {
+ return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#';
+ };
+
+ EmailModel.prototype.clearDuplicateName = function ()
+ {
+ if (this.name === this.email)
+ {
+ this.name = '';
+ }
+ };
+
+ /**
+ * @return {number}
+ */
+ EmailModel.prototype.type = function ()
+ {
if (null === this.privateType)
{
- this.privateType = Enums.EmailType.Default;
- }
- }
-
- return this.privateType;
-};
-
-/**
- * @param {string} sQuery
- * @return {boolean}
- */
-EmailModel.prototype.search = function (sQuery)
-{
- return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase());
-};
-
-/**
- * @param {string} sString
- */
-EmailModel.prototype.parse = function (sString)
-{
- this.clear();
-
- sString = Utils.trim(sString);
-
- var
- mRegex = /(?:"([^"]+)")? ?(.*?@[^>,]+)>?,? ?/g,
- mMatch = mRegex.exec(sString)
- ;
-
- if (mMatch)
- {
- this.name = mMatch[1] || '';
- this.email = mMatch[2] || '';
-
- this.clearDuplicateName();
- }
- else if ((/^[^@]+@[^@]+$/).test(sString))
- {
- this.name = '';
- this.email = sString;
- }
-};
-
-/**
- * @param {AjaxJsonEmail} oJsonEmail
- * @return {boolean}
- */
-EmailModel.prototype.initByJson = function (oJsonEmail)
-{
- var bResult = false;
- if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object'])
- {
- this.name = Utils.trim(oJsonEmail.Name);
- this.email = Utils.trim(oJsonEmail.Email);
-
- bResult = '' !== this.email;
- this.clearDuplicateName();
- }
-
- return bResult;
-};
-
-/**
- * @param {boolean} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @param {boolean=} bEncodeHtml = false
- * @return {string}
- */
-EmailModel.prototype.toLine = function (bFriendlyView, bWrapWithLink, bEncodeHtml)
-{
- var sResult = '';
- if ('' !== this.email)
- {
- bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink;
- bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml;
-
- if (bFriendlyView && '' !== this.name)
- {
- sResult = bWrapWithLink ? '') +
- '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '' :
- (bEncodeHtml ? Utils.encodeHtml(this.name) : this.name);
- }
- else
- {
- sResult = this.email;
- if ('' !== this.name)
+ if (this.email && '@facebook.com' === this.email.substr(-13))
{
- if (bWrapWithLink)
+ this.privateType = Enums.EmailType.Facebook;
+ }
+
+ if (null === this.privateType)
+ {
+ this.privateType = Enums.EmailType.Default;
+ }
+ }
+
+ return this.privateType;
+ };
+
+ /**
+ * @param {string} sQuery
+ * @return {boolean}
+ */
+ EmailModel.prototype.search = function (sQuery)
+ {
+ return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase());
+ };
+
+ /**
+ * @param {string} sString
+ */
+ EmailModel.prototype.parse = function (sString)
+ {
+ this.clear();
+
+ sString = Utils.trim(sString);
+
+ var
+ mRegex = /(?:"([^"]+)")? ?(.*?@[^>,]+)>?,? ?/g,
+ mMatch = mRegex.exec(sString)
+ ;
+
+ if (mMatch)
+ {
+ this.name = mMatch[1] || '';
+ this.email = mMatch[2] || '';
+
+ this.clearDuplicateName();
+ }
+ else if ((/^[^@]+@[^@]+$/).test(sString))
+ {
+ this.name = '';
+ this.email = sString;
+ }
+ };
+
+ /**
+ * @param {AjaxJsonEmail} oJsonEmail
+ * @return {boolean}
+ */
+ EmailModel.prototype.initByJson = function (oJsonEmail)
+ {
+ var bResult = false;
+ if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object'])
+ {
+ this.name = Utils.trim(oJsonEmail.Name);
+ this.email = Utils.trim(oJsonEmail.Email);
+
+ bResult = '' !== this.email;
+ this.clearDuplicateName();
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @param {boolean=} bEncodeHtml = false
+ * @return {string}
+ */
+ EmailModel.prototype.toLine = function (bFriendlyView, bWrapWithLink, bEncodeHtml)
+ {
+ var sResult = '';
+ if ('' !== this.email)
+ {
+ bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink;
+ bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml;
+
+ if (bFriendlyView && '' !== this.name)
+ {
+ sResult = bWrapWithLink ? '') +
+ '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '' :
+ (bEncodeHtml ? Utils.encodeHtml(this.name) : this.name);
+ }
+ else
+ {
+ sResult = this.email;
+ if ('' !== this.name)
{
- sResult = Utils.encodeHtml('"' + this.name + '" <') +
- '') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(sResult) + '' + Utils.encodeHtml('>');
- }
- else
- {
- sResult = '"' + this.name + '" <' + sResult + '>';
- if (bEncodeHtml)
+ if (bWrapWithLink)
{
- sResult = Utils.encodeHtml(sResult);
+ sResult = Utils.encodeHtml('"' + this.name + '" <') +
+ '') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(sResult) + '' + Utils.encodeHtml('>');
+ }
+ else
+ {
+ sResult = '"' + this.name + '" <' + sResult + '>';
+ if (bEncodeHtml)
+ {
+ sResult = Utils.encodeHtml(sResult);
+ }
}
}
+ else if (bWrapWithLink)
+ {
+ sResult = '' + Utils.encodeHtml(this.email) + '';
+ }
}
- else if (bWrapWithLink)
+ }
+
+ return sResult;
+ };
+
+ /**
+ * @param {string} $sEmailAddress
+ * @return {boolean}
+ */
+ EmailModel.prototype.mailsoParse = function ($sEmailAddress)
+ {
+ $sEmailAddress = Utils.trim($sEmailAddress);
+ if ('' === $sEmailAddress)
+ {
+ return false;
+ }
+
+ var
+ substr = function (str, start, len) {
+ str += '';
+ var end = str.length;
+
+ if (start < 0) {
+ start += end;
+ }
+
+ end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
+
+ return start >= str.length || start < 0 || start > end ? false : str.slice(start, end);
+ },
+
+ substr_replace = function (str, replace, start, length) {
+ if (start < 0) {
+ start = start + str.length;
+ }
+ length = length !== undefined ? length : str.length;
+ if (length < 0) {
+ length = length + str.length - start;
+ }
+ return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
+ },
+
+ $sName = '',
+ $sEmail = '',
+ $sComment = '',
+
+ $bInName = false,
+ $bInAddress = false,
+ $bInComment = false,
+
+ $aRegs = null,
+
+ $iStartIndex = 0,
+ $iEndIndex = 0,
+ $iCurrentIndex = 0
+ ;
+
+ while ($iCurrentIndex < $sEmailAddress.length)
+ {
+ switch ($sEmailAddress.substr($iCurrentIndex, 1))
{
- sResult = '' + Utils.encodeHtml(this.email) + '';
- }
- }
- }
-
- return sResult;
-};
-
-/**
- * @param {string} $sEmailAddress
- * @return {boolean}
- */
-EmailModel.prototype.mailsoParse = function ($sEmailAddress)
-{
- $sEmailAddress = Utils.trim($sEmailAddress);
- if ('' === $sEmailAddress)
- {
- return false;
- }
-
- var
- substr = function (str, start, len) {
- str += '';
- var end = str.length;
-
- if (start < 0) {
- start += end;
- }
-
- end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
-
- return start >= str.length || start < 0 || start > end ? false : str.slice(start, end);
- },
-
- substr_replace = function (str, replace, start, length) {
- if (start < 0) {
- start = start + str.length;
- }
- length = length !== undefined ? length : str.length;
- if (length < 0) {
- length = length + str.length - start;
- }
- return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
- },
-
- $sName = '',
- $sEmail = '',
- $sComment = '',
-
- $bInName = false,
- $bInAddress = false,
- $bInComment = false,
-
- $aRegs = null,
-
- $iStartIndex = 0,
- $iEndIndex = 0,
- $iCurrentIndex = 0
- ;
-
- while ($iCurrentIndex < $sEmailAddress.length)
- {
- switch ($sEmailAddress.substr($iCurrentIndex, 1))
- {
- case '"':
- if ((!$bInName) && (!$bInAddress) && (!$bInComment))
- {
- $bInName = true;
- $iStartIndex = $iCurrentIndex;
- }
- else if ((!$bInAddress) && (!$bInComment))
- {
- $iEndIndex = $iCurrentIndex;
- $sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
- $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
- $iEndIndex = 0;
- $iCurrentIndex = 0;
- $iStartIndex = 0;
- $bInName = false;
- }
- break;
- case '<':
- if ((!$bInName) && (!$bInAddress) && (!$bInComment))
- {
- if ($iCurrentIndex > 0 && $sName.length === 0)
+ case '"':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
{
- $sName = substr($sEmailAddress, 0, $iCurrentIndex);
+ $bInName = true;
+ $iStartIndex = $iCurrentIndex;
}
+ else if ((!$bInAddress) && (!$bInComment))
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInName = false;
+ }
+ break;
+ case '<':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
+ {
+ if ($iCurrentIndex > 0 && $sName.length === 0)
+ {
+ $sName = substr($sEmailAddress, 0, $iCurrentIndex);
+ }
- $bInAddress = true;
- $iStartIndex = $iCurrentIndex;
- }
- break;
- case '>':
- if ($bInAddress)
- {
- $iEndIndex = $iCurrentIndex;
- $sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
- $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
- $iEndIndex = 0;
- $iCurrentIndex = 0;
- $iStartIndex = 0;
- $bInAddress = false;
- }
- break;
- case '(':
- if ((!$bInName) && (!$bInAddress) && (!$bInComment))
- {
- $bInComment = true;
- $iStartIndex = $iCurrentIndex;
- }
- break;
- case ')':
- if ($bInComment)
- {
- $iEndIndex = $iCurrentIndex;
- $sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
- $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
- $iEndIndex = 0;
- $iCurrentIndex = 0;
- $iStartIndex = 0;
- $bInComment = false;
- }
- break;
- case '\\':
- $iCurrentIndex++;
- break;
+ $bInAddress = true;
+ $iStartIndex = $iCurrentIndex;
+ }
+ break;
+ case '>':
+ if ($bInAddress)
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInAddress = false;
+ }
+ break;
+ case '(':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
+ {
+ $bInComment = true;
+ $iStartIndex = $iCurrentIndex;
+ }
+ break;
+ case ')':
+ if ($bInComment)
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInComment = false;
+ }
+ break;
+ case '\\':
+ $iCurrentIndex++;
+ break;
+ }
+
+ $iCurrentIndex++;
}
- $iCurrentIndex++;
- }
-
- if ($sEmail.length === 0)
- {
- $aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
- if ($aRegs && $aRegs[0])
+ if ($sEmail.length === 0)
{
- $sEmail = $aRegs[0];
+ $aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
+ if ($aRegs && $aRegs[0])
+ {
+ $sEmail = $aRegs[0];
+ }
+ else
+ {
+ $sName = $sEmailAddress;
+ }
}
- else
+
+ if ($sEmail.length > 0 && $sName.length === 0 && $sComment.length === 0)
{
- $sName = $sEmailAddress;
+ $sName = $sEmailAddress.replace($sEmail, '');
}
- }
- if ($sEmail.length > 0 && $sName.length === 0 && $sComment.length === 0)
+ $sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
+ $sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
+ $sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');
+
+ // Remove backslash
+ $sName = $sName.replace(/\\\\(.)/, '$1');
+ $sComment = $sComment.replace(/\\\\(.)/, '$1');
+
+ this.name = $sName;
+ this.email = $sEmail;
+
+ this.clearDuplicateName();
+ return true;
+ };
+
+ /**
+ * @return {string}
+ */
+ EmailModel.prototype.inputoTagLine = function ()
{
- $sName = $sEmailAddress.replace($sEmail, '');
- }
+ return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email;
+ };
- $sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
- $sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
- $sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');
+ module.exports = EmailModel;
- // Remove backslash
- $sName = $sName.replace(/\\\\(.)/, '$1');
- $sComment = $sComment.replace(/\\\\(.)/, '$1');
-
- this.name = $sName;
- this.email = $sEmail;
-
- this.clearDuplicateName();
- return true;
-};
-
-/**
- * @return {string}
- */
-EmailModel.prototype.inputoTagLine = function ()
-{
- return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email;
-};
+}(module));
\ No newline at end of file
diff --git a/dev/Models/FilterConditionModel.js b/dev/Models/FilterConditionModel.js
index 674b6bdc1..2e62ce492 100644
--- a/dev/Models/FilterConditionModel.js
+++ b/dev/Models/FilterConditionModel.js
@@ -1,48 +1,62 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function FilterConditionModel(oKoList)
-{
- this.parentList = oKoList;
+(function (module) {
- this.field = ko.observable(Enums.FilterConditionField.From);
+ 'use strict';
- this.fieldOptions = [ // TODO i18n
- {'id': Enums.FilterConditionField.From, 'name': 'From'},
- {'id': Enums.FilterConditionField.Recipient, 'name': 'Recipient (To or CC)'},
- {'id': Enums.FilterConditionField.To, 'name': 'To'},
- {'id': Enums.FilterConditionField.Subject, 'name': 'Subject'}
- ];
+ var
+ ko = require('../External/ko.js'),
+ Enums = require('../Common/Enums.js')
+ ;
- this.type = ko.observable(Enums.FilterConditionType.EqualTo);
-
- this.typeOptions = [ // TODO i18n
- {'id': Enums.FilterConditionType.EqualTo, 'name': 'Equal To'},
- {'id': Enums.FilterConditionType.NotEqualTo, 'name': 'Not Equal To'},
- {'id': Enums.FilterConditionType.Contains, 'name': 'Contains'},
- {'id': Enums.FilterConditionType.NotContains, 'name': 'Not Contains'}
- ];
+ /**
+ * @param {*} oKoList
+ * @constructor
+ */
+ function FilterConditionModel(oKoList)
+ {
+ this.parentList = oKoList;
- this.value = ko.observable('');
+ this.field = ko.observable(Enums.FilterConditionField.From);
- this.template = ko.computed(function () {
+ this.fieldOptions = [ // TODO i18n
+ {'id': Enums.FilterConditionField.From, 'name': 'From'},
+ {'id': Enums.FilterConditionField.Recipient, 'name': 'Recipient (To or CC)'},
+ {'id': Enums.FilterConditionField.To, 'name': 'To'},
+ {'id': Enums.FilterConditionField.Subject, 'name': 'Subject'}
+ ];
- var sTemplate = '';
- switch (this.type())
- {
- default:
- sTemplate = 'SettingsFiltersConditionDefault';
- break;
- }
+ this.type = ko.observable(Enums.FilterConditionType.EqualTo);
- return sTemplate;
+ this.typeOptions = [ // TODO i18n
+ {'id': Enums.FilterConditionType.EqualTo, 'name': 'Equal To'},
+ {'id': Enums.FilterConditionType.NotEqualTo, 'name': 'Not Equal To'},
+ {'id': Enums.FilterConditionType.Contains, 'name': 'Contains'},
+ {'id': Enums.FilterConditionType.NotContains, 'name': 'Not Contains'}
+ ];
- }, this);
-}
+ this.value = ko.observable('');
-FilterConditionModel.prototype.removeSelf = function ()
-{
- this.parentList.remove(this);
-};
+ this.template = ko.computed(function () {
+
+ var sTemplate = '';
+ switch (this.type())
+ {
+ default:
+ sTemplate = 'SettingsFiltersConditionDefault';
+ break;
+ }
+
+ return sTemplate;
+
+ }, this);
+ }
+
+ FilterConditionModel.prototype.removeSelf = function ()
+ {
+ this.parentList.remove(this);
+ };
+
+ module.exports = FilterConditionModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/FilterModel.js b/dev/Models/FilterModel.js
index 1240a6797..03e2654ec 100644
--- a/dev/Models/FilterModel.js
+++ b/dev/Models/FilterModel.js
@@ -1,79 +1,94 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function FilterModel()
-{
- this.new = ko.observable(true);
- this.enabled = ko.observable(true);
+(function (module) {
- this.name = ko.observable('');
+ 'use strict';
- this.conditionsType = ko.observable(Enums.FilterRulesType.And);
+ var
+ ko = require('../External/ko.js'),
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js'),
+ FilterConditionModel = require('./FilterConditionModel.js')
+ ;
- this.conditions = ko.observableArray([]);
-
- this.conditions.subscribe(function () {
- Utils.windowResize();
- });
-
- // Actions
- this.actionMarkAsRead = ko.observable(false);
- this.actionSkipOtherFilters = ko.observable(true);
- this.actionValue = ko.observable('');
-
- this.actionType = ko.observable(Enums.FiltersAction.Move);
- this.actionTypeOptions = [ // TODO i18n
- {'id': Enums.FiltersAction.None, 'name': 'Action - None'},
- {'id': Enums.FiltersAction.Move, 'name': 'Action - Move to'},
-// {'id': Enums.FiltersAction.Forward, 'name': 'Action - Forward to'},
- {'id': Enums.FiltersAction.Discard, 'name': 'Action - Discard'}
- ];
-
- this.actionMarkAsReadVisiblity = ko.computed(function () {
- return -1 < Utils.inArray(this.actionType(), [
- Enums.FiltersAction.None, Enums.FiltersAction.Forward, Enums.FiltersAction.Move
- ]);
- }, this);
-
- this.actionTemplate = ko.computed(function () {
-
- var sTemplate = '';
- switch (this.actionType())
- {
- default:
- case Enums.FiltersAction.Move:
- sTemplate = 'SettingsFiltersActionValueAsFolders';
- break;
- case Enums.FiltersAction.Forward:
- sTemplate = 'SettingsFiltersActionWithValue';
- break;
- case Enums.FiltersAction.None:
- case Enums.FiltersAction.Discard:
- sTemplate = 'SettingsFiltersActionNoValue';
- break;
- }
-
- return sTemplate;
-
- }, this);
-}
-
-FilterModel.prototype.addCondition = function ()
-{
- this.conditions.push(new FilterConditionModel(this.conditions));
-};
-
-FilterModel.prototype.parse = function (oItem)
-{
- var bResult = false;
- if (oItem && 'Object/Filter' === oItem['@Object'])
+ /**
+ * @constructor
+ */
+ function FilterModel()
{
- this.name(Utils.pString(oItem['Name']));
+ this.new = ko.observable(true);
+ this.enabled = ko.observable(true);
- bResult = true;
+ this.name = ko.observable('');
+
+ this.conditionsType = ko.observable(Enums.FilterRulesType.And);
+
+ this.conditions = ko.observableArray([]);
+
+ this.conditions.subscribe(function () {
+ Utils.windowResize();
+ });
+
+ // Actions
+ this.actionMarkAsRead = ko.observable(false);
+ this.actionSkipOtherFilters = ko.observable(true);
+ this.actionValue = ko.observable('');
+
+ this.actionType = ko.observable(Enums.FiltersAction.Move);
+ this.actionTypeOptions = [ // TODO i18n
+ {'id': Enums.FiltersAction.None, 'name': 'Action - None'},
+ {'id': Enums.FiltersAction.Move, 'name': 'Action - Move to'},
+ // {'id': Enums.FiltersAction.Forward, 'name': 'Action - Forward to'},
+ {'id': Enums.FiltersAction.Discard, 'name': 'Action - Discard'}
+ ];
+
+ this.actionMarkAsReadVisiblity = ko.computed(function () {
+ return -1 < Utils.inArray(this.actionType(), [
+ Enums.FiltersAction.None, Enums.FiltersAction.Forward, Enums.FiltersAction.Move
+ ]);
+ }, this);
+
+ this.actionTemplate = ko.computed(function () {
+
+ var sTemplate = '';
+ switch (this.actionType())
+ {
+ default:
+ case Enums.FiltersAction.Move:
+ sTemplate = 'SettingsFiltersActionValueAsFolders';
+ break;
+ case Enums.FiltersAction.Forward:
+ sTemplate = 'SettingsFiltersActionWithValue';
+ break;
+ case Enums.FiltersAction.None:
+ case Enums.FiltersAction.Discard:
+ sTemplate = 'SettingsFiltersActionNoValue';
+ break;
+ }
+
+ return sTemplate;
+
+ }, this);
}
- return bResult;
-};
+ FilterModel.prototype.addCondition = function ()
+ {
+ this.conditions.push(new FilterConditionModel(this.conditions));
+ };
+
+ FilterModel.prototype.parse = function (oItem)
+ {
+ var bResult = false;
+ if (oItem && 'Object/Filter' === oItem['@Object'])
+ {
+ this.name(Utils.pString(oItem['Name']));
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ module.exports = FilterModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/FolderModel.js b/dev/Models/FolderModel.js
index f6932a237..04efd68ad 100644
--- a/dev/Models/FolderModel.js
+++ b/dev/Models/FolderModel.js
@@ -1,333 +1,350 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function FolderModel()
-{
- this.name = ko.observable('');
- this.fullName = '';
- this.fullNameRaw = '';
- this.fullNameHash = '';
- this.delimiter = '';
- this.namespace = '';
- this.deep = 0;
- this.interval = 0;
+(function (module) {
- this.selectable = false;
- this.existen = true;
+ 'use strict';
- this.type = ko.observable(Enums.FolderType.User);
+ var
+ _ = require('../External/underscore.js'),
+ ko = require('./External/ko.js'),
+ $window = require('../External/$window.js'),
+ Enums = require('../Common/Enums.js'),
+ Globals = require('../Common/Globals.js'),
+ Utils = require('../Common/Utils.js')
+ ;
- this.focused = ko.observable(false);
- this.selected = ko.observable(false);
- this.edited = ko.observable(false);
- this.collapsed = ko.observable(true);
- this.subScribed = ko.observable(true);
- this.subFolders = ko.observableArray([]);
- this.deleteAccess = ko.observable(false);
- this.actionBlink = ko.observable(false).extend({'falseTimeout': 1000});
-
- this.nameForEdit = ko.observable('');
-
- this.name.subscribe(function (sValue) {
- this.nameForEdit(sValue);
- }, this);
-
- this.edited.subscribe(function (bValue) {
- if (bValue)
- {
- this.nameForEdit(this.name());
- }
- }, this);
-
- this.privateMessageCountAll = ko.observable(0);
- this.privateMessageCountUnread = ko.observable(0);
-
- this.collapsedPrivate = ko.observable(true);
-}
-
-/**
- * @static
- * @param {AjaxJsonFolder} oJsonFolder
- * @return {?FolderModel}
- */
-FolderModel.newInstanceFromJson = function (oJsonFolder)
-{
- var oFolderModel = new FolderModel();
- return oFolderModel.initByJson(oJsonFolder) ? oFolderModel.initComputed() : null;
-};
-
-/**
- * @return {FolderModel}
- */
-FolderModel.prototype.initComputed = function ()
-{
- this.hasSubScribedSubfolders = ko.computed(function () {
- return !!_.find(this.subFolders(), function (oFolder) {
- return oFolder.subScribed() && !oFolder.isSystemFolder();
- });
- }, this);
-
- this.canBeEdited = ko.computed(function () {
- return Enums.FolderType.User === this.type() && this.existen && this.selectable;
- }, this);
-
- this.visible = ko.computed(function () {
- var
- bSubScribed = this.subScribed(),
- bSubFolders = this.hasSubScribedSubfolders()
- ;
-
- return (bSubScribed || (bSubFolders && (!this.existen || !this.selectable)));
- }, this);
-
- this.isSystemFolder = ko.computed(function () {
- return Enums.FolderType.User !== this.type();
- }, this);
-
- this.hidden = ko.computed(function () {
- var
- bSystem = this.isSystemFolder(),
- bSubFolders = this.hasSubScribedSubfolders()
- ;
-
- return (bSystem && !bSubFolders) || (!this.selectable && !bSubFolders);
-
- }, this);
-
- this.selectableForFolderList = ko.computed(function () {
- return !this.isSystemFolder() && this.selectable;
- }, this);
-
- this.messageCountAll = ko.computed({
- 'read': this.privateMessageCountAll,
- 'write': function (iValue) {
- if (Utils.isPosNumeric(iValue, true))
- {
- this.privateMessageCountAll(iValue);
- }
- else
- {
- this.privateMessageCountAll.valueHasMutated();
- }
- },
- 'owner': this
- });
-
- this.messageCountUnread = ko.computed({
- 'read': this.privateMessageCountUnread,
- 'write': function (iValue) {
- if (Utils.isPosNumeric(iValue, true))
- {
- this.privateMessageCountUnread(iValue);
- }
- else
- {
- this.privateMessageCountUnread.valueHasMutated();
- }
- },
- 'owner': this
- });
-
- this.printableUnreadCount = ko.computed(function () {
- var
- iCount = this.messageCountAll(),
- iUnread = this.messageCountUnread(),
- iType = this.type()
- ;
-
- if (Enums.FolderType.Inbox === iType)
- {
- RL.data().foldersInboxUnreadCount(iUnread);
- }
-
- if (0 < iCount)
- {
- if (Enums.FolderType.Draft === iType)
- {
- return '' + iCount;
- }
- else if (0 < iUnread && Enums.FolderType.Trash !== iType && Enums.FolderType.Archive !== iType && Enums.FolderType.SentItems !== iType)
- {
- return '' + iUnread;
- }
- }
-
- return '';
-
- }, this);
-
- this.canBeDeleted = ko.computed(function () {
- var
- bSystem = this.isSystemFolder()
- ;
- return !bSystem && 0 === this.subFolders().length && 'INBOX' !== this.fullNameRaw;
- }, this);
-
- this.canBeSubScribed = ko.computed(function () {
- return !this.isSystemFolder() && this.selectable && 'INBOX' !== this.fullNameRaw;
- }, this);
-
- this.visible.subscribe(function () {
- Utils.timeOutAction('folder-list-folder-visibility-change', function () {
- $window.trigger('folder-list-folder-visibility-change');
- }, 100);
- });
-
- this.localName = ko.computed(function () {
-
- Globals.langChangeTrigger();
-
- var
- iType = this.type(),
- sName = this.name()
- ;
-
- if (this.isSystemFolder())
- {
- switch (iType)
- {
- case Enums.FolderType.Inbox:
- sName = Utils.i18n('FOLDER_LIST/INBOX_NAME');
- break;
- case Enums.FolderType.SentItems:
- sName = Utils.i18n('FOLDER_LIST/SENT_NAME');
- break;
- case Enums.FolderType.Draft:
- sName = Utils.i18n('FOLDER_LIST/DRAFTS_NAME');
- break;
- case Enums.FolderType.Spam:
- sName = Utils.i18n('FOLDER_LIST/SPAM_NAME');
- break;
- case Enums.FolderType.Trash:
- sName = Utils.i18n('FOLDER_LIST/TRASH_NAME');
- break;
- case Enums.FolderType.Archive:
- sName = Utils.i18n('FOLDER_LIST/ARCHIVE_NAME');
- break;
- }
- }
-
- return sName;
-
- }, this);
-
- this.manageFolderSystemName = ko.computed(function () {
-
- Globals.langChangeTrigger();
-
- var
- sSuffix = '',
- iType = this.type(),
- sName = this.name()
- ;
-
- if (this.isSystemFolder())
- {
- switch (iType)
- {
- case Enums.FolderType.Inbox:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/INBOX_NAME') + ')';
- break;
- case Enums.FolderType.SentItems:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/SENT_NAME') + ')';
- break;
- case Enums.FolderType.Draft:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
- break;
- case Enums.FolderType.Spam:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/SPAM_NAME') + ')';
- break;
- case Enums.FolderType.Trash:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/TRASH_NAME') + ')';
- break;
- case Enums.FolderType.Archive:
- sSuffix = '(' + Utils.i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
- break;
- }
- }
-
- if ('' !== sSuffix && '(' + sName + ')' === sSuffix || '(inbox)' === sSuffix.toLowerCase())
- {
- sSuffix = '';
- }
-
- return sSuffix;
-
- }, this);
-
- this.collapsed = ko.computed({
- 'read': function () {
- return !this.hidden() && this.collapsedPrivate();
- },
- 'write': function (mValue) {
- this.collapsedPrivate(mValue);
- },
- 'owner': this
- });
-
- this.hasUnreadMessages = ko.computed(function () {
- return 0 < this.messageCountUnread();
- }, this);
-
- this.hasSubScribedUnreadMessagesSubfolders = ko.computed(function () {
- return !!_.find(this.subFolders(), function (oFolder) {
- return oFolder.hasUnreadMessages() || oFolder.hasSubScribedUnreadMessagesSubfolders();
- });
- }, this);
-
- return this;
-};
-
-FolderModel.prototype.fullName = '';
-FolderModel.prototype.fullNameRaw = '';
-FolderModel.prototype.fullNameHash = '';
-FolderModel.prototype.delimiter = '';
-FolderModel.prototype.namespace = '';
-FolderModel.prototype.deep = 0;
-FolderModel.prototype.interval = 0;
-
-/**
- * @return {string}
- */
-FolderModel.prototype.collapsedCss = function ()
-{
- return this.hasSubScribedSubfolders() ?
- (this.collapsed() ? 'icon-right-mini e-collapsed-sign' : 'icon-down-mini e-collapsed-sign') : 'icon-none e-collapsed-sign';
-};
-
-/**
- * @param {AjaxJsonFolder} oJsonFolder
- * @return {boolean}
- */
-FolderModel.prototype.initByJson = function (oJsonFolder)
-{
- var bResult = false;
- if (oJsonFolder && 'Object/Folder' === oJsonFolder['@Object'])
+ /**
+ * @constructor
+ */
+ function FolderModel()
{
- this.name(oJsonFolder.Name);
- this.delimiter = oJsonFolder.Delimiter;
- this.fullName = oJsonFolder.FullName;
- this.fullNameRaw = oJsonFolder.FullNameRaw;
- this.fullNameHash = oJsonFolder.FullNameHash;
- this.deep = oJsonFolder.FullNameRaw.split(this.delimiter).length - 1;
- this.selectable = !!oJsonFolder.IsSelectable;
- this.existen = !!oJsonFolder.IsExists;
+ this.name = ko.observable('');
+ this.fullName = '';
+ this.fullNameRaw = '';
+ this.fullNameHash = '';
+ this.delimiter = '';
+ this.namespace = '';
+ this.deep = 0;
+ this.interval = 0;
- this.subScribed(!!oJsonFolder.IsSubscribed);
- this.type('INBOX' === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
+ this.selectable = false;
+ this.existen = true;
- bResult = true;
+ this.type = ko.observable(Enums.FolderType.User);
+
+ this.focused = ko.observable(false);
+ this.selected = ko.observable(false);
+ this.edited = ko.observable(false);
+ this.collapsed = ko.observable(true);
+ this.subScribed = ko.observable(true);
+ this.subFolders = ko.observableArray([]);
+ this.deleteAccess = ko.observable(false);
+ this.actionBlink = ko.observable(false).extend({'falseTimeout': 1000});
+
+ this.nameForEdit = ko.observable('');
+
+ this.name.subscribe(function (sValue) {
+ this.nameForEdit(sValue);
+ }, this);
+
+ this.edited.subscribe(function (bValue) {
+ if (bValue)
+ {
+ this.nameForEdit(this.name());
+ }
+ }, this);
+
+ this.privateMessageCountAll = ko.observable(0);
+ this.privateMessageCountUnread = ko.observable(0);
+
+ this.collapsedPrivate = ko.observable(true);
}
- return bResult;
-};
+ /**
+ * @static
+ * @param {AjaxJsonFolder} oJsonFolder
+ * @return {?FolderModel}
+ */
+ FolderModel.newInstanceFromJson = function (oJsonFolder)
+ {
+ var oFolderModel = new FolderModel();
+ return oFolderModel.initByJson(oJsonFolder) ? oFolderModel.initComputed() : null;
+ };
-/**
- * @return {string}
- */
-FolderModel.prototype.printableFullName = function ()
-{
- return this.fullName.split(this.delimiter).join(' / ');
-};
+ /**
+ * @return {FolderModel}
+ */
+ FolderModel.prototype.initComputed = function ()
+ {
+ this.hasSubScribedSubfolders = ko.computed(function () {
+ return !!_.find(this.subFolders(), function (oFolder) {
+ return oFolder.subScribed() && !oFolder.isSystemFolder();
+ });
+ }, this);
+
+ this.canBeEdited = ko.computed(function () {
+ return Enums.FolderType.User === this.type() && this.existen && this.selectable;
+ }, this);
+
+ this.visible = ko.computed(function () {
+ var
+ bSubScribed = this.subScribed(),
+ bSubFolders = this.hasSubScribedSubfolders()
+ ;
+
+ return (bSubScribed || (bSubFolders && (!this.existen || !this.selectable)));
+ }, this);
+
+ this.isSystemFolder = ko.computed(function () {
+ return Enums.FolderType.User !== this.type();
+ }, this);
+
+ this.hidden = ko.computed(function () {
+ var
+ bSystem = this.isSystemFolder(),
+ bSubFolders = this.hasSubScribedSubfolders()
+ ;
+
+ return (bSystem && !bSubFolders) || (!this.selectable && !bSubFolders);
+
+ }, this);
+
+ this.selectableForFolderList = ko.computed(function () {
+ return !this.isSystemFolder() && this.selectable;
+ }, this);
+
+ this.messageCountAll = ko.computed({
+ 'read': this.privateMessageCountAll,
+ 'write': function (iValue) {
+ if (Utils.isPosNumeric(iValue, true))
+ {
+ this.privateMessageCountAll(iValue);
+ }
+ else
+ {
+ this.privateMessageCountAll.valueHasMutated();
+ }
+ },
+ 'owner': this
+ });
+
+ this.messageCountUnread = ko.computed({
+ 'read': this.privateMessageCountUnread,
+ 'write': function (iValue) {
+ if (Utils.isPosNumeric(iValue, true))
+ {
+ this.privateMessageCountUnread(iValue);
+ }
+ else
+ {
+ this.privateMessageCountUnread.valueHasMutated();
+ }
+ },
+ 'owner': this
+ });
+
+ this.printableUnreadCount = ko.computed(function () {
+ var
+ iCount = this.messageCountAll(),
+ iUnread = this.messageCountUnread(),
+ iType = this.type()
+ ;
+
+ if (Enums.FolderType.Inbox === iType)
+ {
+ RL.data().foldersInboxUnreadCount(iUnread); // TODO cjs
+ }
+
+ if (0 < iCount)
+ {
+ if (Enums.FolderType.Draft === iType)
+ {
+ return '' + iCount;
+ }
+ else if (0 < iUnread && Enums.FolderType.Trash !== iType && Enums.FolderType.Archive !== iType && Enums.FolderType.SentItems !== iType)
+ {
+ return '' + iUnread;
+ }
+ }
+
+ return '';
+
+ }, this);
+
+ this.canBeDeleted = ko.computed(function () {
+ var
+ bSystem = this.isSystemFolder()
+ ;
+ return !bSystem && 0 === this.subFolders().length && 'INBOX' !== this.fullNameRaw;
+ }, this);
+
+ this.canBeSubScribed = ko.computed(function () {
+ return !this.isSystemFolder() && this.selectable && 'INBOX' !== this.fullNameRaw;
+ }, this);
+
+ this.visible.subscribe(function () {
+ Utils.timeOutAction('folder-list-folder-visibility-change', function () {
+ $window.trigger('folder-list-folder-visibility-change');
+ }, 100);
+ });
+
+ this.localName = ko.computed(function () {
+
+ Globals.langChangeTrigger();
+
+ var
+ iType = this.type(),
+ sName = this.name()
+ ;
+
+ if (this.isSystemFolder())
+ {
+ switch (iType)
+ {
+ case Enums.FolderType.Inbox:
+ sName = Utils.i18n('FOLDER_LIST/INBOX_NAME');
+ break;
+ case Enums.FolderType.SentItems:
+ sName = Utils.i18n('FOLDER_LIST/SENT_NAME');
+ break;
+ case Enums.FolderType.Draft:
+ sName = Utils.i18n('FOLDER_LIST/DRAFTS_NAME');
+ break;
+ case Enums.FolderType.Spam:
+ sName = Utils.i18n('FOLDER_LIST/SPAM_NAME');
+ break;
+ case Enums.FolderType.Trash:
+ sName = Utils.i18n('FOLDER_LIST/TRASH_NAME');
+ break;
+ case Enums.FolderType.Archive:
+ sName = Utils.i18n('FOLDER_LIST/ARCHIVE_NAME');
+ break;
+ }
+ }
+
+ return sName;
+
+ }, this);
+
+ this.manageFolderSystemName = ko.computed(function () {
+
+ Globals.langChangeTrigger();
+
+ var
+ sSuffix = '',
+ iType = this.type(),
+ sName = this.name()
+ ;
+
+ if (this.isSystemFolder())
+ {
+ switch (iType)
+ {
+ case Enums.FolderType.Inbox:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/INBOX_NAME') + ')';
+ break;
+ case Enums.FolderType.SentItems:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/SENT_NAME') + ')';
+ break;
+ case Enums.FolderType.Draft:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
+ break;
+ case Enums.FolderType.Spam:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/SPAM_NAME') + ')';
+ break;
+ case Enums.FolderType.Trash:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/TRASH_NAME') + ')';
+ break;
+ case Enums.FolderType.Archive:
+ sSuffix = '(' + Utils.i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
+ break;
+ }
+ }
+
+ if ('' !== sSuffix && '(' + sName + ')' === sSuffix || '(inbox)' === sSuffix.toLowerCase())
+ {
+ sSuffix = '';
+ }
+
+ return sSuffix;
+
+ }, this);
+
+ this.collapsed = ko.computed({
+ 'read': function () {
+ return !this.hidden() && this.collapsedPrivate();
+ },
+ 'write': function (mValue) {
+ this.collapsedPrivate(mValue);
+ },
+ 'owner': this
+ });
+
+ this.hasUnreadMessages = ko.computed(function () {
+ return 0 < this.messageCountUnread();
+ }, this);
+
+ this.hasSubScribedUnreadMessagesSubfolders = ko.computed(function () {
+ return !!_.find(this.subFolders(), function (oFolder) {
+ return oFolder.hasUnreadMessages() || oFolder.hasSubScribedUnreadMessagesSubfolders();
+ });
+ }, this);
+
+ return this;
+ };
+
+ FolderModel.prototype.fullName = '';
+ FolderModel.prototype.fullNameRaw = '';
+ FolderModel.prototype.fullNameHash = '';
+ FolderModel.prototype.delimiter = '';
+ FolderModel.prototype.namespace = '';
+ FolderModel.prototype.deep = 0;
+ FolderModel.prototype.interval = 0;
+
+ /**
+ * @return {string}
+ */
+ FolderModel.prototype.collapsedCss = function ()
+ {
+ return this.hasSubScribedSubfolders() ?
+ (this.collapsed() ? 'icon-right-mini e-collapsed-sign' : 'icon-down-mini e-collapsed-sign') : 'icon-none e-collapsed-sign';
+ };
+
+ /**
+ * @param {AjaxJsonFolder} oJsonFolder
+ * @return {boolean}
+ */
+ FolderModel.prototype.initByJson = function (oJsonFolder)
+ {
+ var bResult = false;
+ if (oJsonFolder && 'Object/Folder' === oJsonFolder['@Object'])
+ {
+ this.name(oJsonFolder.Name);
+ this.delimiter = oJsonFolder.Delimiter;
+ this.fullName = oJsonFolder.FullName;
+ this.fullNameRaw = oJsonFolder.FullNameRaw;
+ this.fullNameHash = oJsonFolder.FullNameHash;
+ this.deep = oJsonFolder.FullNameRaw.split(this.delimiter).length - 1;
+ this.selectable = !!oJsonFolder.IsSelectable;
+ this.existen = !!oJsonFolder.IsExists;
+
+ this.subScribed(!!oJsonFolder.IsSubscribed);
+ this.type('INBOX' === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @return {string}
+ */
+ FolderModel.prototype.printableFullName = function ()
+ {
+ return this.fullName.split(this.delimiter).join(' / ');
+ };
+
+ module.exports = FolderModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/IdentityModel.js b/dev/Models/IdentityModel.js
index 394405f67..011a5d76e 100644
--- a/dev/Models/IdentityModel.js
+++ b/dev/Models/IdentityModel.js
@@ -1,37 +1,50 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {string} sId
- * @param {string} sEmail
- * @param {boolean=} bCanBeDelete = true
- * @constructor
- */
-function IdentityModel(sId, sEmail, bCanBeDelete)
-{
- this.id = sId;
- this.email = ko.observable(sEmail);
- this.name = ko.observable('');
- this.replyTo = ko.observable('');
- this.bcc = ko.observable('');
+(function (module) {
- this.deleteAccess = ko.observable(false);
- this.canBeDalete = ko.observable(bCanBeDelete);
-}
+ 'use strict';
-IdentityModel.prototype.formattedName = function ()
-{
- var sName = this.name();
- return '' === sName ? this.email() : sName + ' <' + this.email() + '>';
-};
+ var
+ ko = require('../External/ko.js'),
+ Utils = require('../Common/Utils.js')
+ ;
-IdentityModel.prototype.formattedNameForCompose = function ()
-{
- var sName = this.name();
- return '' === sName ? this.email() : sName + ' (' + this.email() + ')';
-};
+ /**
+ * @param {string} sId
+ * @param {string} sEmail
+ * @param {boolean=} bCanBeDelete = true
+ * @constructor
+ */
+ function IdentityModel(sId, sEmail, bCanBeDelete)
+ {
+ this.id = sId;
+ this.email = ko.observable(sEmail);
+ this.name = ko.observable('');
+ this.replyTo = ko.observable('');
+ this.bcc = ko.observable('');
-IdentityModel.prototype.formattedNameForEmail = function ()
-{
- var sName = this.name();
- return '' === sName ? this.email() : '"' + Utils.quoteName(sName) + '" <' + this.email() + '>';
-};
+ this.deleteAccess = ko.observable(false);
+ this.canBeDalete = ko.observable(bCanBeDelete);
+ }
+
+ IdentityModel.prototype.formattedName = function ()
+ {
+ var sName = this.name();
+ return '' === sName ? this.email() : sName + ' <' + this.email() + '>';
+ };
+
+ IdentityModel.prototype.formattedNameForCompose = function ()
+ {
+ var sName = this.name();
+ return '' === sName ? this.email() : sName + ' (' + this.email() + ')';
+ };
+
+ IdentityModel.prototype.formattedNameForEmail = function ()
+ {
+ var sName = this.name();
+ return '' === sName ? this.email() : '"' + Utils.quoteName(sName) + '" <' + this.email() + '>';
+ };
+
+ module.exports = IdentityModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/MessageModel.js b/dev/Models/MessageModel.js
index 691f9d68a..93151a7bd 100644
--- a/dev/Models/MessageModel.js
+++ b/dev/Models/MessageModel.js
@@ -1,1262 +1,1279 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function MessageModel()
-{
- this.folderFullNameRaw = '';
- this.uid = '';
- this.hash = '';
- this.requestHash = '';
- this.subject = ko.observable('');
- this.subjectPrefix = ko.observable('');
- this.subjectSuffix = ko.observable('');
- this.size = ko.observable(0);
- this.dateTimeStampInUTC = ko.observable(0);
- this.priority = ko.observable(Enums.MessagePriority.Normal);
+(function (module) {
- this.proxy = false;
+ 'use strict';
- this.fromEmailString = ko.observable('');
- this.fromClearEmailString = ko.observable('');
- this.toEmailsString = ko.observable('');
- this.toClearEmailsString = ko.observable('');
-
- this.senderEmailsString = ko.observable('');
- this.senderClearEmailsString = ko.observable('');
-
- this.emails = [];
-
- this.from = [];
- this.to = [];
- this.cc = [];
- this.bcc = [];
- this.replyTo = [];
- this.deliveredTo = [];
-
- this.newForAnimation = ko.observable(false);
-
- this.deleted = ko.observable(false);
- this.unseen = ko.observable(false);
- this.flagged = ko.observable(false);
- this.answered = ko.observable(false);
- this.forwarded = ko.observable(false);
- this.isReadReceipt = ko.observable(false);
-
- this.focused = ko.observable(false);
- this.selected = ko.observable(false);
- this.checked = ko.observable(false);
- this.hasAttachments = ko.observable(false);
- this.attachmentsMainType = ko.observable('');
-
- this.moment = ko.observable(moment(moment.unix(0)));
-
- this.attachmentIconClass = ko.computed(function () {
- var sClass = '';
- if (this.hasAttachments())
- {
- sClass = 'icon-attachment';
- switch (this.attachmentsMainType())
- {
- case 'image':
- sClass = 'icon-image';
- break;
- case 'archive':
- sClass = 'icon-file-zip';
- break;
- case 'doc':
- sClass = 'icon-file-text';
- break;
-// case 'pdf':
-// sClass = 'icon-file-pdf';
-// break;
- }
- }
- return sClass;
- }, this);
-
- this.fullFormatDateValue = ko.computed(function () {
- return MessageModel.calculateFullFromatDateValue(this.dateTimeStampInUTC());
- }, this);
-
- this.momentDate = Utils.createMomentDate(this);
- this.momentShortDate = Utils.createMomentShortDate(this);
-
- this.dateTimeStampInUTC.subscribe(function (iValue) {
- var iNow = moment().unix();
- this.moment(moment.unix(iNow < iValue ? iNow : iValue));
- }, this);
-
- this.body = null;
- this.plainRaw = '';
- this.isHtml = ko.observable(false);
- this.hasImages = ko.observable(false);
- this.attachments = ko.observableArray([]);
-
- this.isPgpSigned = ko.observable(false);
- this.isPgpEncrypted = ko.observable(false);
- this.pgpSignedVerifyStatus = ko.observable(Enums.SignedVerifyStatus.None);
- this.pgpSignedVerifyUser = ko.observable('');
-
- this.priority = ko.observable(Enums.MessagePriority.Normal);
- this.readReceipt = ko.observable('');
-
- this.aDraftInfo = [];
- this.sMessageId = '';
- this.sInReplyTo = '';
- this.sReferences = '';
-
- this.parentUid = ko.observable(0);
- this.threads = ko.observableArray([]);
- this.threadsLen = ko.observable(0);
- this.hasUnseenSubMessage = ko.observable(false);
- this.hasFlaggedSubMessage = ko.observable(false);
-
- this.lastInCollapsedThread = ko.observable(false);
- this.lastInCollapsedThreadLoading = ko.observable(false);
-
- this.threadsLenResult = ko.computed(function () {
- var iCount = this.threadsLen();
- return 0 === this.parentUid() && 0 < iCount ? iCount + 1 : '';
- }, this);
-}
-
-/**
- * @static
- * @param {AjaxJsonMessage} oJsonMessage
- * @return {?MessageModel}
- */
-MessageModel.newInstanceFromJson = function (oJsonMessage)
-{
- var oMessageModel = new MessageModel();
- return oMessageModel.initByJson(oJsonMessage) ? oMessageModel : null;
-};
-
-/**
- * @static
- * @param {number} iTimeStampInUTC
- * @return {string}
- */
-MessageModel.calculateFullFromatDateValue = function (iTimeStampInUTC)
-{
- return 0 < iTimeStampInUTC ? moment.unix(iTimeStampInUTC).format('LLL') : '';
-};
-
-/**
- * @static
- * @param {Array} aEmail
- * @param {boolean=} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @return {string}
- */
-MessageModel.emailsToLine = function (aEmail, bFriendlyView, bWrapWithLink)
-{
var
- aResult = [],
- iIndex = 0,
- iLen = 0
+ window = require('../External/window.js'),
+ $ = require('../External/jquery.js'),
+ _ = require('../External/underscore.js'),
+ ko = require('../External/ko.js'),
+ moment = require('../External/moment.js'),
+ $window = require('../External/$window.js'),
+ $div = require('../External/$div.js'),
+
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js'),
+
+ EmailModel = require('./EmailModel.js'),
+ AttachmentModel = require('./AttachmentModel.js')
;
- if (Utils.isNonEmptyArray(aEmail))
+ /**
+ * @constructor
+ */
+ function MessageModel()
{
- for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++)
- {
- aResult.push(aEmail[iIndex].toLine(bFriendlyView, bWrapWithLink));
- }
+ this.folderFullNameRaw = '';
+ this.uid = '';
+ this.hash = '';
+ this.requestHash = '';
+ this.subject = ko.observable('');
+ this.subjectPrefix = ko.observable('');
+ this.subjectSuffix = ko.observable('');
+ this.size = ko.observable(0);
+ this.dateTimeStampInUTC = ko.observable(0);
+ this.priority = ko.observable(Enums.MessagePriority.Normal);
+
+ this.proxy = false;
+
+ this.fromEmailString = ko.observable('');
+ this.fromClearEmailString = ko.observable('');
+ this.toEmailsString = ko.observable('');
+ this.toClearEmailsString = ko.observable('');
+
+ this.senderEmailsString = ko.observable('');
+ this.senderClearEmailsString = ko.observable('');
+
+ this.emails = [];
+
+ this.from = [];
+ this.to = [];
+ this.cc = [];
+ this.bcc = [];
+ this.replyTo = [];
+ this.deliveredTo = [];
+
+ this.newForAnimation = ko.observable(false);
+
+ this.deleted = ko.observable(false);
+ this.unseen = ko.observable(false);
+ this.flagged = ko.observable(false);
+ this.answered = ko.observable(false);
+ this.forwarded = ko.observable(false);
+ this.isReadReceipt = ko.observable(false);
+
+ this.focused = ko.observable(false);
+ this.selected = ko.observable(false);
+ this.checked = ko.observable(false);
+ this.hasAttachments = ko.observable(false);
+ this.attachmentsMainType = ko.observable('');
+
+ this.moment = ko.observable(moment(moment.unix(0)));
+
+ this.attachmentIconClass = ko.computed(function () {
+ var sClass = '';
+ if (this.hasAttachments())
+ {
+ sClass = 'icon-attachment';
+ switch (this.attachmentsMainType())
+ {
+ case 'image':
+ sClass = 'icon-image';
+ break;
+ case 'archive':
+ sClass = 'icon-file-zip';
+ break;
+ case 'doc':
+ sClass = 'icon-file-text';
+ break;
+ // case 'pdf':
+ // sClass = 'icon-file-pdf';
+ // break;
+ }
+ }
+ return sClass;
+ }, this);
+
+ this.fullFormatDateValue = ko.computed(function () {
+ return MessageModel.calculateFullFromatDateValue(this.dateTimeStampInUTC());
+ }, this);
+
+ this.momentDate = Utils.createMomentDate(this);
+ this.momentShortDate = Utils.createMomentShortDate(this);
+
+ this.dateTimeStampInUTC.subscribe(function (iValue) {
+ var iNow = moment().unix();
+ this.moment(moment.unix(iNow < iValue ? iNow : iValue));
+ }, this);
+
+ this.body = null;
+ this.plainRaw = '';
+ this.isHtml = ko.observable(false);
+ this.hasImages = ko.observable(false);
+ this.attachments = ko.observableArray([]);
+
+ this.isPgpSigned = ko.observable(false);
+ this.isPgpEncrypted = ko.observable(false);
+ this.pgpSignedVerifyStatus = ko.observable(Enums.SignedVerifyStatus.None);
+ this.pgpSignedVerifyUser = ko.observable('');
+
+ this.priority = ko.observable(Enums.MessagePriority.Normal);
+ this.readReceipt = ko.observable('');
+
+ this.aDraftInfo = [];
+ this.sMessageId = '';
+ this.sInReplyTo = '';
+ this.sReferences = '';
+
+ this.parentUid = ko.observable(0);
+ this.threads = ko.observableArray([]);
+ this.threadsLen = ko.observable(0);
+ this.hasUnseenSubMessage = ko.observable(false);
+ this.hasFlaggedSubMessage = ko.observable(false);
+
+ this.lastInCollapsedThread = ko.observable(false);
+ this.lastInCollapsedThreadLoading = ko.observable(false);
+
+ this.threadsLenResult = ko.computed(function () {
+ var iCount = this.threadsLen();
+ return 0 === this.parentUid() && 0 < iCount ? iCount + 1 : '';
+ }, this);
}
- return aResult.join(', ');
-};
-
-/**
- * @static
- * @param {Array} aEmail
- * @return {string}
- */
-MessageModel.emailsToLineClear = function (aEmail)
-{
- var
- aResult = [],
- iIndex = 0,
- iLen = 0
- ;
-
- if (Utils.isNonEmptyArray(aEmail))
+ /**
+ * @static
+ * @param {AjaxJsonMessage} oJsonMessage
+ * @return {?MessageModel}
+ */
+ MessageModel.newInstanceFromJson = function (oJsonMessage)
{
- for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++)
+ var oMessageModel = new MessageModel();
+ return oMessageModel.initByJson(oJsonMessage) ? oMessageModel : null;
+ };
+
+ /**
+ * @static
+ * @param {number} iTimeStampInUTC
+ * @return {string}
+ */
+ MessageModel.calculateFullFromatDateValue = function (iTimeStampInUTC)
+ {
+ return 0 < iTimeStampInUTC ? moment.unix(iTimeStampInUTC).format('LLL') : '';
+ };
+
+ /**
+ * @static
+ * @param {Array} aEmail
+ * @param {boolean=} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @return {string}
+ */
+ MessageModel.emailsToLine = function (aEmail, bFriendlyView, bWrapWithLink)
+ {
+ var
+ aResult = [],
+ iIndex = 0,
+ iLen = 0
+ ;
+
+ if (Utils.isNonEmptyArray(aEmail))
{
- if (aEmail[iIndex] && aEmail[iIndex].email && '' !== aEmail[iIndex].name)
+ for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++)
{
- aResult.push(aEmail[iIndex].email);
+ aResult.push(aEmail[iIndex].toLine(bFriendlyView, bWrapWithLink));
}
}
- }
- return aResult.join(', ');
-};
+ return aResult.join(', ');
+ };
-/**
- * @static
- * @param {?Array} aJsonEmails
- * @return {Array.}
- */
-MessageModel.initEmailsFromJson = function (aJsonEmails)
-{
- var
- iIndex = 0,
- iLen = 0,
- oEmailModel = null,
- aResult = []
- ;
-
- if (Utils.isNonEmptyArray(aJsonEmails))
+ /**
+ * @static
+ * @param {Array} aEmail
+ * @return {string}
+ */
+ MessageModel.emailsToLineClear = function (aEmail)
{
- for (iIndex = 0, iLen = aJsonEmails.length; iIndex < iLen; iIndex++)
+ var
+ aResult = [],
+ iIndex = 0,
+ iLen = 0
+ ;
+
+ if (Utils.isNonEmptyArray(aEmail))
{
- oEmailModel = EmailModel.newInstanceFromJson(aJsonEmails[iIndex]);
- if (oEmailModel)
+ for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++)
{
- aResult.push(oEmailModel);
+ if (aEmail[iIndex] && aEmail[iIndex].email && '' !== aEmail[iIndex].name)
+ {
+ aResult.push(aEmail[iIndex].email);
+ }
}
}
- }
- return aResult;
-};
+ return aResult.join(', ');
+ };
-/**
- * @static
- * @param {Array.} aMessageEmails
- * @param {Object} oLocalUnic
- * @param {Array} aLocalEmails
- */
-MessageModel.replyHelper = function (aMessageEmails, oLocalUnic, aLocalEmails)
-{
- if (aMessageEmails && 0 < aMessageEmails.length)
+ /**
+ * @static
+ * @param {?Array} aJsonEmails
+ * @return {Array.}
+ */
+ MessageModel.initEmailsFromJson = function (aJsonEmails)
{
var
iIndex = 0,
- iLen = aMessageEmails.length
+ iLen = 0,
+ oEmailModel = null,
+ aResult = []
;
- for (; iIndex < iLen; iIndex++)
+ if (Utils.isNonEmptyArray(aJsonEmails))
{
- if (Utils.isUnd(oLocalUnic[aMessageEmails[iIndex].email]))
+ for (iIndex = 0, iLen = aJsonEmails.length; iIndex < iLen; iIndex++)
{
- oLocalUnic[aMessageEmails[iIndex].email] = true;
- aLocalEmails.push(aMessageEmails[iIndex]);
- }
- }
- }
-};
-
-MessageModel.prototype.clear = function ()
-{
- this.folderFullNameRaw = '';
- this.uid = '';
- this.hash = '';
- this.requestHash = '';
- this.subject('');
- this.subjectPrefix('');
- this.subjectSuffix('');
- this.size(0);
- this.dateTimeStampInUTC(0);
- this.priority(Enums.MessagePriority.Normal);
-
- this.proxy = false;
-
- this.fromEmailString('');
- this.fromClearEmailString('');
- this.toEmailsString('');
- this.toClearEmailsString('');
- this.senderEmailsString('');
- this.senderClearEmailsString('');
-
- this.emails = [];
-
- this.from = [];
- this.to = [];
- this.cc = [];
- this.bcc = [];
- this.replyTo = [];
- this.deliveredTo = [];
-
- this.newForAnimation(false);
-
- this.deleted(false);
- this.unseen(false);
- this.flagged(false);
- this.answered(false);
- this.forwarded(false);
- this.isReadReceipt(false);
-
- this.selected(false);
- this.checked(false);
- this.hasAttachments(false);
- this.attachmentsMainType('');
-
- this.body = null;
- this.isHtml(false);
- this.hasImages(false);
- this.attachments([]);
-
- this.isPgpSigned(false);
- this.isPgpEncrypted(false);
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
- this.pgpSignedVerifyUser('');
-
- this.priority(Enums.MessagePriority.Normal);
- this.readReceipt('');
- this.aDraftInfo = [];
- this.sMessageId = '';
- this.sInReplyTo = '';
- this.sReferences = '';
-
- this.parentUid(0);
- this.threads([]);
- this.threadsLen(0);
- this.hasUnseenSubMessage(false);
- this.hasFlaggedSubMessage(false);
-
- this.lastInCollapsedThread(false);
- this.lastInCollapsedThreadLoading(false);
-};
-
-MessageModel.prototype.computeSenderEmail = function ()
-{
- var
- sSent = RL.data().sentFolder(),
- sDraft = RL.data().draftFolder()
- ;
-
- this.senderEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ?
- this.toEmailsString() : this.fromEmailString());
-
- this.senderClearEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ?
- this.toClearEmailsString() : this.fromClearEmailString());
-};
-
-/**
- * @param {AjaxJsonMessage} oJsonMessage
- * @return {boolean}
- */
-MessageModel.prototype.initByJson = function (oJsonMessage)
-{
- var bResult = false;
- if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
- {
- this.folderFullNameRaw = oJsonMessage.Folder;
- this.uid = oJsonMessage.Uid;
- this.hash = oJsonMessage.Hash;
- this.requestHash = oJsonMessage.RequestHash;
-
- this.proxy = !!oJsonMessage.ExternalProxy;
-
- this.size(Utils.pInt(oJsonMessage.Size));
-
- this.from = MessageModel.initEmailsFromJson(oJsonMessage.From);
- this.to = MessageModel.initEmailsFromJson(oJsonMessage.To);
- this.cc = MessageModel.initEmailsFromJson(oJsonMessage.Cc);
- this.bcc = MessageModel.initEmailsFromJson(oJsonMessage.Bcc);
- this.replyTo = MessageModel.initEmailsFromJson(oJsonMessage.ReplyTo);
- this.deliveredTo = MessageModel.initEmailsFromJson(oJsonMessage.DeliveredTo);
-
- this.subject(oJsonMessage.Subject);
- if (Utils.isArray(oJsonMessage.SubjectParts))
- {
- this.subjectPrefix(oJsonMessage.SubjectParts[0]);
- this.subjectSuffix(oJsonMessage.SubjectParts[1]);
- }
- else
- {
- this.subjectPrefix('');
- this.subjectSuffix(this.subject());
- }
-
- this.dateTimeStampInUTC(Utils.pInt(oJsonMessage.DateTimeStampInUTC));
- this.hasAttachments(!!oJsonMessage.HasAttachments);
- this.attachmentsMainType(oJsonMessage.AttachmentsMainType);
-
- this.fromEmailString(MessageModel.emailsToLine(this.from, true));
- this.fromClearEmailString(MessageModel.emailsToLineClear(this.from));
- this.toEmailsString(MessageModel.emailsToLine(this.to, true));
- this.toClearEmailsString(MessageModel.emailsToLineClear(this.to));
-
- this.parentUid(Utils.pInt(oJsonMessage.ParentThread));
- this.threads(Utils.isArray(oJsonMessage.Threads) ? oJsonMessage.Threads : []);
- this.threadsLen(Utils.pInt(oJsonMessage.ThreadsLen));
-
- this.initFlagsByJson(oJsonMessage);
- this.computeSenderEmail();
-
- bResult = true;
- }
-
- return bResult;
-};
-
-/**
- * @param {AjaxJsonMessage} oJsonMessage
- * @return {boolean}
- */
-MessageModel.prototype.initUpdateByMessageJson = function (oJsonMessage)
-{
- var
- bResult = false,
- iPriority = Enums.MessagePriority.Normal
- ;
-
- if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
- {
- iPriority = Utils.pInt(oJsonMessage.Priority);
- this.priority(-1 < Utils.inArray(iPriority, [Enums.MessagePriority.High, Enums.MessagePriority.Low]) ?
- iPriority : Enums.MessagePriority.Normal);
-
- this.aDraftInfo = oJsonMessage.DraftInfo;
-
- this.sMessageId = oJsonMessage.MessageId;
- this.sInReplyTo = oJsonMessage.InReplyTo;
- this.sReferences = oJsonMessage.References;
-
- this.proxy = !!oJsonMessage.ExternalProxy;
-
- if (RL.data().capaOpenPGP())
- {
- this.isPgpSigned(!!oJsonMessage.PgpSigned);
- this.isPgpEncrypted(!!oJsonMessage.PgpEncrypted);
- }
-
- this.hasAttachments(!!oJsonMessage.HasAttachments);
- this.attachmentsMainType(oJsonMessage.AttachmentsMainType);
-
- this.foundedCIDs = Utils.isArray(oJsonMessage.FoundedCIDs) ? oJsonMessage.FoundedCIDs : [];
- this.attachments(this.initAttachmentsFromJson(oJsonMessage.Attachments));
-
- this.readReceipt(oJsonMessage.ReadReceipt || '');
-
- this.computeSenderEmail();
-
- bResult = true;
- }
-
- return bResult;
-};
-
-/**
- * @param {(AjaxJsonAttachment|null)} oJsonAttachments
- * @return {Array}
- */
-MessageModel.prototype.initAttachmentsFromJson = function (oJsonAttachments)
-{
- var
- iIndex = 0,
- iLen = 0,
- oAttachmentModel = null,
- aResult = []
- ;
-
- if (oJsonAttachments && 'Collection/AttachmentCollection' === oJsonAttachments['@Object'] &&
- Utils.isNonEmptyArray(oJsonAttachments['@Collection']))
- {
- for (iIndex = 0, iLen = oJsonAttachments['@Collection'].length; iIndex < iLen; iIndex++)
- {
- oAttachmentModel = AttachmentModel.newInstanceFromJson(oJsonAttachments['@Collection'][iIndex]);
- if (oAttachmentModel)
- {
- if ('' !== oAttachmentModel.cidWithOutTags && 0 < this.foundedCIDs.length &&
- 0 <= Utils.inArray(oAttachmentModel.cidWithOutTags, this.foundedCIDs))
+ oEmailModel = EmailModel.newInstanceFromJson(aJsonEmails[iIndex]);
+ if (oEmailModel)
{
- oAttachmentModel.isLinked = true;
+ aResult.push(oEmailModel);
}
-
- aResult.push(oAttachmentModel);
}
}
- }
- return aResult;
-};
-
-/**
- * @param {AjaxJsonMessage} oJsonMessage
- * @return {boolean}
- */
-MessageModel.prototype.initFlagsByJson = function (oJsonMessage)
-{
- var bResult = false;
-
- if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
- {
- this.unseen(!oJsonMessage.IsSeen);
- this.flagged(!!oJsonMessage.IsFlagged);
- this.answered(!!oJsonMessage.IsAnswered);
- this.forwarded(!!oJsonMessage.IsForwarded);
- this.isReadReceipt(!!oJsonMessage.IsReadReceipt);
-
- bResult = true;
- }
-
- return bResult;
-};
-
-/**
- * @param {boolean} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @return {string}
- */
-MessageModel.prototype.fromToLine = function (bFriendlyView, bWrapWithLink)
-{
- return MessageModel.emailsToLine(this.from, bFriendlyView, bWrapWithLink);
-};
-
-/**
- * @param {boolean} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @return {string}
- */
-MessageModel.prototype.toToLine = function (bFriendlyView, bWrapWithLink)
-{
- return MessageModel.emailsToLine(this.to, bFriendlyView, bWrapWithLink);
-};
-
-/**
- * @param {boolean} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @return {string}
- */
-MessageModel.prototype.ccToLine = function (bFriendlyView, bWrapWithLink)
-{
- return MessageModel.emailsToLine(this.cc, bFriendlyView, bWrapWithLink);
-};
-
-/**
- * @param {boolean} bFriendlyView
- * @param {boolean=} bWrapWithLink = false
- * @return {string}
- */
-MessageModel.prototype.bccToLine = function (bFriendlyView, bWrapWithLink)
-{
- return MessageModel.emailsToLine(this.bcc, bFriendlyView, bWrapWithLink);
-};
-
-/**
- * @return string
- */
-MessageModel.prototype.lineAsCcc = function ()
-{
- var aResult = [];
- if (this.deleted())
- {
- aResult.push('deleted');
- }
- if (this.selected())
- {
- aResult.push('selected');
- }
- if (this.checked())
- {
- aResult.push('checked');
- }
- if (this.flagged())
- {
- aResult.push('flagged');
- }
- if (this.unseen())
- {
- aResult.push('unseen');
- }
- if (this.answered())
- {
- aResult.push('answered');
- }
- if (this.forwarded())
- {
- aResult.push('forwarded');
- }
- if (this.focused())
- {
- aResult.push('focused');
- }
- if (this.hasAttachments())
- {
- aResult.push('withAttachments');
- switch (this.attachmentsMainType())
- {
- case 'image':
- aResult.push('imageOnlyAttachments');
- break;
- case 'archive':
- aResult.push('archiveOnlyAttachments');
- break;
- }
- }
- if (this.newForAnimation())
- {
- aResult.push('new');
- }
- if ('' === this.subject())
- {
- aResult.push('emptySubject');
- }
- if (0 < this.parentUid())
- {
- aResult.push('hasParentMessage');
- }
- if (0 < this.threadsLen() && 0 === this.parentUid())
- {
- aResult.push('hasChildrenMessage');
- }
- if (this.hasUnseenSubMessage())
- {
- aResult.push('hasUnseenSubMessage');
- }
- if (this.hasFlaggedSubMessage())
- {
- aResult.push('hasFlaggedSubMessage');
- }
-
- return aResult.join(' ');
-};
-
-/**
- * @return {boolean}
- */
-MessageModel.prototype.hasVisibleAttachments = function ()
-{
- return !!_.find(this.attachments(), function (oAttachment) {
- return !oAttachment.isLinked;
- });
-// return 0 < this.attachments().length;
-};
-
-/**
- * @param {string} sCid
- * @return {*}
- */
-MessageModel.prototype.findAttachmentByCid = function (sCid)
-{
- var
- oResult = null,
- aAttachments = this.attachments()
- ;
-
- if (Utils.isNonEmptyArray(aAttachments))
- {
- sCid = sCid.replace(/^<+/, '').replace(/>+$/, '');
- oResult = _.find(aAttachments, function (oAttachment) {
- return sCid === oAttachment.cidWithOutTags;
- });
- }
-
- return oResult || null;
-};
-
-/**
- * @param {string} sContentLocation
- * @return {*}
- */
-MessageModel.prototype.findAttachmentByContentLocation = function (sContentLocation)
-{
- var
- oResult = null,
- aAttachments = this.attachments()
- ;
-
- if (Utils.isNonEmptyArray(aAttachments))
- {
- oResult = _.find(aAttachments, function (oAttachment) {
- return sContentLocation === oAttachment.contentLocation;
- });
- }
-
- return oResult || null;
-};
-
-
-/**
- * @return {string}
- */
-MessageModel.prototype.messageId = function ()
-{
- return this.sMessageId;
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.inReplyTo = function ()
-{
- return this.sInReplyTo;
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.references = function ()
-{
- return this.sReferences;
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.fromAsSingleEmail = function ()
-{
- return Utils.isArray(this.from) && this.from[0] ? this.from[0].email : '';
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.viewLink = function ()
-{
- return RL.link().messageViewLink(this.requestHash);
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.downloadLink = function ()
-{
- return RL.link().messageDownloadLink(this.requestHash);
-};
-
-/**
- * @param {Object} oExcludeEmails
- * @return {Array}
- */
-MessageModel.prototype.replyEmails = function (oExcludeEmails)
-{
- var
- aResult = [],
- oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
- ;
-
- MessageModel.replyHelper(this.replyTo, oUnic, aResult);
- if (0 === aResult.length)
- {
- MessageModel.replyHelper(this.from, oUnic, aResult);
- }
-
- return aResult;
-};
-
-/**
- * @param {Object} oExcludeEmails
- * @return {Array.}
- */
-MessageModel.prototype.replyAllEmails = function (oExcludeEmails)
-{
- var
- aToResult = [],
- aCcResult = [],
- oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
- ;
-
- MessageModel.replyHelper(this.replyTo, oUnic, aToResult);
- if (0 === aToResult.length)
- {
- MessageModel.replyHelper(this.from, oUnic, aToResult);
- }
-
- MessageModel.replyHelper(this.to, oUnic, aToResult);
- MessageModel.replyHelper(this.cc, oUnic, aCcResult);
-
- return [aToResult, aCcResult];
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.textBodyToString = function ()
-{
- return this.body ? this.body.html() : '';
-};
-
-/**
- * @return {string}
- */
-MessageModel.prototype.attachmentsToStringLine = function ()
-{
- var aAttachLines = _.map(this.attachments(), function (oItem) {
- return oItem.fileName + ' (' + oItem.friendlySize + ')';
- });
-
- return aAttachLines && 0 < aAttachLines.length ? aAttachLines.join(', ') : '';
-};
-
-/**
- * @return {Object}
- */
-MessageModel.prototype.getDataForWindowPopup = function ()
-{
- return {
- 'popupFrom': this.fromToLine(false),
- 'popupTo': this.toToLine(false),
- 'popupCc': this.ccToLine(false),
- 'popupBcc': this.bccToLine(false),
- 'popupSubject': this.subject(),
- 'popupDate': this.fullFormatDateValue(),
- 'popupAttachments': this.attachmentsToStringLine(),
- 'popupBody': this.textBodyToString()
+ return aResult;
};
-};
-/**
- * @param {boolean=} bPrint = false
- */
-MessageModel.prototype.viewPopupMessage = function (bPrint)
-{
- Utils.windowPopupKnockout(this.getDataForWindowPopup(), 'PopupsWindowSimpleMessage', this.subject(), function (oPopupWin) {
- if (oPopupWin && oPopupWin.document && oPopupWin.document.body)
- {
- $('img.lazy', oPopupWin.document.body).each(function (iIndex, oImg) {
-
- var
- $oImg = $(oImg),
- sOrig = $oImg.data('original'),
- sSrc = $oImg.attr('src')
- ;
-
- if (0 <= iIndex && sOrig && !sSrc)
- {
- $oImg.attr('src', sOrig);
- }
- });
-
- if (bPrint)
- {
- window.setTimeout(function () {
- oPopupWin.print();
- }, 100);
- }
- }
- });
-};
-
-MessageModel.prototype.printMessage = function ()
-{
- this.viewPopupMessage(true);
-};
-
-/**
- * @returns {string}
- */
-MessageModel.prototype.generateUid = function ()
-{
- return this.folderFullNameRaw + '/' + this.uid;
-};
-
-/**
- * @param {MessageModel} oMessage
- * @return {MessageModel}
- */
-MessageModel.prototype.populateByMessageListItem = function (oMessage)
-{
- this.folderFullNameRaw = oMessage.folderFullNameRaw;
- this.uid = oMessage.uid;
- this.hash = oMessage.hash;
- this.requestHash = oMessage.requestHash;
- this.subject(oMessage.subject());
- this.subjectPrefix(this.subjectPrefix());
- this.subjectSuffix(this.subjectSuffix());
-
- this.size(oMessage.size());
- this.dateTimeStampInUTC(oMessage.dateTimeStampInUTC());
- this.priority(oMessage.priority());
-
- this.proxy = oMessage.proxy;
-
- this.fromEmailString(oMessage.fromEmailString());
- this.fromClearEmailString(oMessage.fromClearEmailString());
- this.toEmailsString(oMessage.toEmailsString());
- this.toClearEmailsString(oMessage.toClearEmailsString());
-
- this.emails = oMessage.emails;
-
- this.from = oMessage.from;
- this.to = oMessage.to;
- this.cc = oMessage.cc;
- this.bcc = oMessage.bcc;
- this.replyTo = oMessage.replyTo;
- this.deliveredTo = oMessage.deliveredTo;
-
- this.unseen(oMessage.unseen());
- this.flagged(oMessage.flagged());
- this.answered(oMessage.answered());
- this.forwarded(oMessage.forwarded());
- this.isReadReceipt(oMessage.isReadReceipt());
-
- this.selected(oMessage.selected());
- this.checked(oMessage.checked());
- this.hasAttachments(oMessage.hasAttachments());
- this.attachmentsMainType(oMessage.attachmentsMainType());
-
- this.moment(oMessage.moment());
-
- this.body = null;
-// this.isHtml(false);
-// this.hasImages(false);
-// this.attachments([]);
-
-// this.isPgpSigned(false);
-// this.isPgpEncrypted(false);
-
- this.priority(Enums.MessagePriority.Normal);
- this.aDraftInfo = [];
- this.sMessageId = '';
- this.sInReplyTo = '';
- this.sReferences = '';
-
- this.parentUid(oMessage.parentUid());
- this.threads(oMessage.threads());
- this.threadsLen(oMessage.threadsLen());
-
- this.computeSenderEmail();
-
- return this;
-};
-
-MessageModel.prototype.showExternalImages = function (bLazy)
-{
- if (this.body && this.body.data('rl-has-images'))
+ /**
+ * @static
+ * @param {Array.} aMessageEmails
+ * @param {Object} oLocalUnic
+ * @param {Array} aLocalEmails
+ */
+ MessageModel.replyHelper = function (aMessageEmails, oLocalUnic, aLocalEmails)
{
- var sAttr = '';
- bLazy = Utils.isUnd(bLazy) ? false : bLazy;
+ if (aMessageEmails && 0 < aMessageEmails.length)
+ {
+ var
+ iIndex = 0,
+ iLen = aMessageEmails.length
+ ;
- this.hasImages(false);
- this.body.data('rl-has-images', false);
+ for (; iIndex < iLen; iIndex++)
+ {
+ if (Utils.isUnd(oLocalUnic[aMessageEmails[iIndex].email]))
+ {
+ oLocalUnic[aMessageEmails[iIndex].email] = true;
+ aLocalEmails.push(aMessageEmails[iIndex]);
+ }
+ }
+ }
+ };
- sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src';
- $('[' + sAttr + ']', this.body).each(function () {
- if (bLazy && $(this).is('img'))
- {
- $(this)
- .addClass('lazy')
- .attr('data-original', $(this).attr(sAttr))
- .removeAttr(sAttr)
- ;
- }
- else
- {
- $(this).attr('src', $(this).attr(sAttr)).removeAttr(sAttr);
- }
- });
-
- sAttr = this.proxy ? 'data-x-additional-style-url' : 'data-x-style-url';
- $('[' + sAttr + ']', this.body).each(function () {
- var sStyle = Utils.trim($(this).attr('style'));
- sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
- $(this).attr('style', sStyle + $(this).attr(sAttr)).removeAttr(sAttr);
- });
-
- if (bLazy)
- {
- $('img.lazy', this.body).addClass('lazy-inited').lazyload({
- 'threshold' : 400,
- 'effect' : 'fadeIn',
- 'skip_invisible' : false,
- 'container': $('.RL-MailMessageView .messageView .messageItem .content')[0]
- });
-
- $window.resize();
- }
-
- Utils.windowResize(500);
- }
-};
-
-MessageModel.prototype.showInternalImages = function (bLazy)
-{
- if (this.body && !this.body.data('rl-init-internal-images'))
+ MessageModel.prototype.clear = function ()
{
- this.body.data('rl-init-internal-images', true);
+ this.folderFullNameRaw = '';
+ this.uid = '';
+ this.hash = '';
+ this.requestHash = '';
+ this.subject('');
+ this.subjectPrefix('');
+ this.subjectSuffix('');
+ this.size(0);
+ this.dateTimeStampInUTC(0);
+ this.priority(Enums.MessagePriority.Normal);
- bLazy = Utils.isUnd(bLazy) ? false : bLazy;
+ this.proxy = false;
- var self = this;
+ this.fromEmailString('');
+ this.fromClearEmailString('');
+ this.toEmailsString('');
+ this.toClearEmailsString('');
+ this.senderEmailsString('');
+ this.senderClearEmailsString('');
- $('[data-x-src-cid]', this.body).each(function () {
+ this.emails = [];
- var oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-cid'));
- if (oAttachment && oAttachment.download)
- {
- if (bLazy && $(this).is('img'))
- {
- $(this)
- .addClass('lazy')
- .attr('data-original', oAttachment.linkPreview());
- }
- else
- {
- $(this).attr('src', oAttachment.linkPreview());
- }
- }
- });
+ this.from = [];
+ this.to = [];
+ this.cc = [];
+ this.bcc = [];
+ this.replyTo = [];
+ this.deliveredTo = [];
- $('[data-x-src-location]', this.body).each(function () {
+ this.newForAnimation(false);
- var oAttachment = self.findAttachmentByContentLocation($(this).attr('data-x-src-location'));
- if (!oAttachment)
- {
- oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-location'));
- }
+ this.deleted(false);
+ this.unseen(false);
+ this.flagged(false);
+ this.answered(false);
+ this.forwarded(false);
+ this.isReadReceipt(false);
- if (oAttachment && oAttachment.download)
- {
- if (bLazy && $(this).is('img'))
- {
- $(this)
- .addClass('lazy')
- .attr('data-original', oAttachment.linkPreview());
- }
- else
- {
- $(this).attr('src', oAttachment.linkPreview());
- }
- }
- });
+ this.selected(false);
+ this.checked(false);
+ this.hasAttachments(false);
+ this.attachmentsMainType('');
- $('[data-x-style-cid]', this.body).each(function () {
+ this.body = null;
+ this.isHtml(false);
+ this.hasImages(false);
+ this.attachments([]);
- var
- sStyle = '',
- sName = '',
- oAttachment = self.findAttachmentByCid($(this).attr('data-x-style-cid'))
- ;
+ this.isPgpSigned(false);
+ this.isPgpEncrypted(false);
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
+ this.pgpSignedVerifyUser('');
- if (oAttachment && oAttachment.linkPreview)
- {
- sName = $(this).attr('data-x-style-cid-name');
- if ('' !== sName)
- {
- sStyle = Utils.trim($(this).attr('style'));
- sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
- $(this).attr('style', sStyle + sName + ': url(\'' + oAttachment.linkPreview() + '\')');
- }
- }
- });
+ this.priority(Enums.MessagePriority.Normal);
+ this.readReceipt('');
+ this.aDraftInfo = [];
+ this.sMessageId = '';
+ this.sInReplyTo = '';
+ this.sReferences = '';
- if (bLazy)
- {
- (function ($oImg, oContainer) {
- _.delay(function () {
- $oImg.addClass('lazy-inited').lazyload({
- 'threshold' : 400,
- 'effect' : 'fadeIn',
- 'skip_invisible' : false,
- 'container': oContainer
- });
- }, 300);
- }($('img.lazy', self.body), $('.RL-MailMessageView .messageView .messageItem .content')[0]));
- }
+ this.parentUid(0);
+ this.threads([]);
+ this.threadsLen(0);
+ this.hasUnseenSubMessage(false);
+ this.hasFlaggedSubMessage(false);
- Utils.windowResize(500);
- }
-};
+ this.lastInCollapsedThread(false);
+ this.lastInCollapsedThreadLoading(false);
+ };
-MessageModel.prototype.storeDataToDom = function ()
-{
- if (this.body)
+ MessageModel.prototype.computeSenderEmail = function ()
{
- this.body.data('rl-is-html', !!this.isHtml());
- this.body.data('rl-has-images', !!this.hasImages());
+ var
+ sSent = RL.data().sentFolder(),
+ sDraft = RL.data().draftFolder()
+ ;
- this.body.data('rl-plain-raw', this.plainRaw);
+ this.senderEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ?
+ this.toEmailsString() : this.fromEmailString());
- if (RL.data().capaOpenPGP())
- {
- this.body.data('rl-plain-pgp-signed', !!this.isPgpSigned());
- this.body.data('rl-plain-pgp-encrypted', !!this.isPgpEncrypted());
- this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus());
- this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser());
- }
- }
-};
+ this.senderClearEmailsString(this.folderFullNameRaw === sSent || this.folderFullNameRaw === sDraft ?
+ this.toClearEmailsString() : this.fromClearEmailString());
+ };
-MessageModel.prototype.storePgpVerifyDataToDom = function ()
-{
- if (this.body && RL.data().capaOpenPGP())
+ /**
+ * @param {AjaxJsonMessage} oJsonMessage
+ * @return {boolean}
+ */
+ MessageModel.prototype.initByJson = function (oJsonMessage)
{
- this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus());
- this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser());
- }
-};
+ var bResult = false;
+ if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
+ {
+ this.folderFullNameRaw = oJsonMessage.Folder;
+ this.uid = oJsonMessage.Uid;
+ this.hash = oJsonMessage.Hash;
+ this.requestHash = oJsonMessage.RequestHash;
-MessageModel.prototype.fetchDataToDom = function ()
-{
- if (this.body)
+ this.proxy = !!oJsonMessage.ExternalProxy;
+
+ this.size(Utils.pInt(oJsonMessage.Size));
+
+ this.from = MessageModel.initEmailsFromJson(oJsonMessage.From);
+ this.to = MessageModel.initEmailsFromJson(oJsonMessage.To);
+ this.cc = MessageModel.initEmailsFromJson(oJsonMessage.Cc);
+ this.bcc = MessageModel.initEmailsFromJson(oJsonMessage.Bcc);
+ this.replyTo = MessageModel.initEmailsFromJson(oJsonMessage.ReplyTo);
+ this.deliveredTo = MessageModel.initEmailsFromJson(oJsonMessage.DeliveredTo);
+
+ this.subject(oJsonMessage.Subject);
+ if (Utils.isArray(oJsonMessage.SubjectParts))
+ {
+ this.subjectPrefix(oJsonMessage.SubjectParts[0]);
+ this.subjectSuffix(oJsonMessage.SubjectParts[1]);
+ }
+ else
+ {
+ this.subjectPrefix('');
+ this.subjectSuffix(this.subject());
+ }
+
+ this.dateTimeStampInUTC(Utils.pInt(oJsonMessage.DateTimeStampInUTC));
+ this.hasAttachments(!!oJsonMessage.HasAttachments);
+ this.attachmentsMainType(oJsonMessage.AttachmentsMainType);
+
+ this.fromEmailString(MessageModel.emailsToLine(this.from, true));
+ this.fromClearEmailString(MessageModel.emailsToLineClear(this.from));
+ this.toEmailsString(MessageModel.emailsToLine(this.to, true));
+ this.toClearEmailsString(MessageModel.emailsToLineClear(this.to));
+
+ this.parentUid(Utils.pInt(oJsonMessage.ParentThread));
+ this.threads(Utils.isArray(oJsonMessage.Threads) ? oJsonMessage.Threads : []);
+ this.threadsLen(Utils.pInt(oJsonMessage.ThreadsLen));
+
+ this.initFlagsByJson(oJsonMessage);
+ this.computeSenderEmail();
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @param {AjaxJsonMessage} oJsonMessage
+ * @return {boolean}
+ */
+ MessageModel.prototype.initUpdateByMessageJson = function (oJsonMessage)
{
- this.isHtml(!!this.body.data('rl-is-html'));
- this.hasImages(!!this.body.data('rl-has-images'));
+ var
+ bResult = false,
+ iPriority = Enums.MessagePriority.Normal
+ ;
- this.plainRaw = Utils.pString(this.body.data('rl-plain-raw'));
+ if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
+ {
+ iPriority = Utils.pInt(oJsonMessage.Priority);
+ this.priority(-1 < Utils.inArray(iPriority, [Enums.MessagePriority.High, Enums.MessagePriority.Low]) ?
+ iPriority : Enums.MessagePriority.Normal);
- if (RL.data().capaOpenPGP())
- {
- this.isPgpSigned(!!this.body.data('rl-plain-pgp-signed'));
- this.isPgpEncrypted(!!this.body.data('rl-plain-pgp-encrypted'));
- this.pgpSignedVerifyStatus(this.body.data('rl-pgp-verify-status'));
- this.pgpSignedVerifyUser(this.body.data('rl-pgp-verify-user'));
- }
- else
- {
- this.isPgpSigned(false);
- this.isPgpEncrypted(false);
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
- this.pgpSignedVerifyUser('');
- }
- }
-};
+ this.aDraftInfo = oJsonMessage.DraftInfo;
-MessageModel.prototype.verifyPgpSignedClearMessage = function ()
-{
- if (this.isPgpSigned())
+ this.sMessageId = oJsonMessage.MessageId;
+ this.sInReplyTo = oJsonMessage.InReplyTo;
+ this.sReferences = oJsonMessage.References;
+
+ this.proxy = !!oJsonMessage.ExternalProxy;
+
+ if (RL.data().capaOpenPGP()) // TODO cjs
+ {
+ this.isPgpSigned(!!oJsonMessage.PgpSigned);
+ this.isPgpEncrypted(!!oJsonMessage.PgpEncrypted);
+ }
+
+ this.hasAttachments(!!oJsonMessage.HasAttachments);
+ this.attachmentsMainType(oJsonMessage.AttachmentsMainType);
+
+ this.foundedCIDs = Utils.isArray(oJsonMessage.FoundedCIDs) ? oJsonMessage.FoundedCIDs : [];
+ this.attachments(this.initAttachmentsFromJson(oJsonMessage.Attachments));
+
+ this.readReceipt(oJsonMessage.ReadReceipt || '');
+
+ this.computeSenderEmail();
+
+ bResult = true;
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @param {(AjaxJsonAttachment|null)} oJsonAttachments
+ * @return {Array}
+ */
+ MessageModel.prototype.initAttachmentsFromJson = function (oJsonAttachments)
{
- var
- aRes = [],
- mPgpMessage = null,
- sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
- aPublicKeys = RL.data().findPublicKeysByEmail(sFrom),
- oValidKey = null,
- oValidSysKey = null,
- sPlain = ''
- ;
+ var
+ iIndex = 0,
+ iLen = 0,
+ oAttachmentModel = null,
+ aResult = []
+ ;
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error);
- this.pgpSignedVerifyUser('');
+ if (oJsonAttachments && 'Collection/AttachmentCollection' === oJsonAttachments['@Object'] &&
+ Utils.isNonEmptyArray(oJsonAttachments['@Collection']))
+ {
+ for (iIndex = 0, iLen = oJsonAttachments['@Collection'].length; iIndex < iLen; iIndex++)
+ {
+ oAttachmentModel = AttachmentModel.newInstanceFromJson(oJsonAttachments['@Collection'][iIndex]);
+ if (oAttachmentModel)
+ {
+ if ('' !== oAttachmentModel.cidWithOutTags && 0 < this.foundedCIDs.length &&
+ 0 <= Utils.inArray(oAttachmentModel.cidWithOutTags, this.foundedCIDs))
+ {
+ oAttachmentModel.isLinked = true;
+ }
- try
- {
- mPgpMessage = window.openpgp.cleartext.readArmored(this.plainRaw);
- if (mPgpMessage && mPgpMessage.getText)
- {
- this.pgpSignedVerifyStatus(
- aPublicKeys.length ? Enums.SignedVerifyStatus.Unverified : Enums.SignedVerifyStatus.UnknownPublicKeys);
+ aResult.push(oAttachmentModel);
+ }
+ }
+ }
- aRes = mPgpMessage.verify(aPublicKeys);
- if (aRes && 0 < aRes.length)
- {
- oValidKey = _.find(aRes, function (oItem) {
- return oItem && oItem.keyid && oItem.valid;
- });
+ return aResult;
+ };
- if (oValidKey)
- {
- oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex());
- if (oValidSysKey)
- {
- sPlain = mPgpMessage.getText();
-
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
- this.pgpSignedVerifyUser(oValidSysKey.user);
-
- sPlain =
- $proxyDiv.empty().append(
- $('').text(sPlain)
- ).html()
- ;
-
- $proxyDiv.empty();
-
- this.replacePlaneTextBody(sPlain);
- }
- }
- }
- }
- }
- catch (oExc) {}
-
- this.storePgpVerifyDataToDom();
- }
-};
-
-MessageModel.prototype.decryptPgpEncryptedMessage = function (sPassword)
-{
- if (this.isPgpEncrypted())
+ /**
+ * @param {AjaxJsonMessage} oJsonMessage
+ * @return {boolean}
+ */
+ MessageModel.prototype.initFlagsByJson = function (oJsonMessage)
{
- var
- aRes = [],
- mPgpMessage = null,
- mPgpMessageDecrypted = null,
- sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
- aPublicKey = RL.data().findPublicKeysByEmail(sFrom),
- oPrivateKey = RL.data().findSelfPrivateKey(sPassword),
- oValidKey = null,
- oValidSysKey = null,
- sPlain = ''
- ;
+ var bResult = false;
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error);
- this.pgpSignedVerifyUser('');
+ if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
+ {
+ this.unseen(!oJsonMessage.IsSeen);
+ this.flagged(!!oJsonMessage.IsFlagged);
+ this.answered(!!oJsonMessage.IsAnswered);
+ this.forwarded(!!oJsonMessage.IsForwarded);
+ this.isReadReceipt(!!oJsonMessage.IsReadReceipt);
- if (!oPrivateKey)
- {
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.UnknownPrivateKey);
- }
+ bResult = true;
+ }
- try
- {
- mPgpMessage = window.openpgp.message.readArmored(this.plainRaw);
- if (mPgpMessage && oPrivateKey && mPgpMessage.decrypt)
- {
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Unverified);
+ return bResult;
+ };
- mPgpMessageDecrypted = mPgpMessage.decrypt(oPrivateKey);
- if (mPgpMessageDecrypted)
- {
- aRes = mPgpMessageDecrypted.verify(aPublicKey);
- if (aRes && 0 < aRes.length)
- {
- oValidKey = _.find(aRes, function (oItem) {
- return oItem && oItem.keyid && oItem.valid;
- });
-
- if (oValidKey)
- {
- oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex());
- if (oValidSysKey)
- {
- this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
- this.pgpSignedVerifyUser(oValidSysKey.user);
- }
- }
- }
-
- sPlain = mPgpMessageDecrypted.getText();
-
- sPlain =
- $proxyDiv.empty().append(
- $('').text(sPlain)
- ).html()
- ;
-
- $proxyDiv.empty();
-
- this.replacePlaneTextBody(sPlain);
- }
- }
- }
- catch (oExc) {}
-
- this.storePgpVerifyDataToDom();
- }
-};
-
-MessageModel.prototype.replacePlaneTextBody = function (sPlain)
-{
- if (this.body)
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @return {string}
+ */
+ MessageModel.prototype.fromToLine = function (bFriendlyView, bWrapWithLink)
{
- this.body.html(sPlain).addClass('b-text-part plain');
- }
-};
+ return MessageModel.emailsToLine(this.from, bFriendlyView, bWrapWithLink);
+ };
-/**
- * @return {string}
- */
-MessageModel.prototype.flagHash = function ()
-{
- return [this.deleted(), this.unseen(), this.flagged(), this.answered(), this.forwarded(),
- this.isReadReceipt()].join('');
-};
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @return {string}
+ */
+ MessageModel.prototype.toToLine = function (bFriendlyView, bWrapWithLink)
+ {
+ return MessageModel.emailsToLine(this.to, bFriendlyView, bWrapWithLink);
+ };
+
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @return {string}
+ */
+ MessageModel.prototype.ccToLine = function (bFriendlyView, bWrapWithLink)
+ {
+ return MessageModel.emailsToLine(this.cc, bFriendlyView, bWrapWithLink);
+ };
+
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @return {string}
+ */
+ MessageModel.prototype.bccToLine = function (bFriendlyView, bWrapWithLink)
+ {
+ return MessageModel.emailsToLine(this.bcc, bFriendlyView, bWrapWithLink);
+ };
+
+ /**
+ * @return string
+ */
+ MessageModel.prototype.lineAsCcc = function ()
+ {
+ var aResult = [];
+ if (this.deleted())
+ {
+ aResult.push('deleted');
+ }
+ if (this.selected())
+ {
+ aResult.push('selected');
+ }
+ if (this.checked())
+ {
+ aResult.push('checked');
+ }
+ if (this.flagged())
+ {
+ aResult.push('flagged');
+ }
+ if (this.unseen())
+ {
+ aResult.push('unseen');
+ }
+ if (this.answered())
+ {
+ aResult.push('answered');
+ }
+ if (this.forwarded())
+ {
+ aResult.push('forwarded');
+ }
+ if (this.focused())
+ {
+ aResult.push('focused');
+ }
+ if (this.hasAttachments())
+ {
+ aResult.push('withAttachments');
+ switch (this.attachmentsMainType())
+ {
+ case 'image':
+ aResult.push('imageOnlyAttachments');
+ break;
+ case 'archive':
+ aResult.push('archiveOnlyAttachments');
+ break;
+ }
+ }
+ if (this.newForAnimation())
+ {
+ aResult.push('new');
+ }
+ if ('' === this.subject())
+ {
+ aResult.push('emptySubject');
+ }
+ if (0 < this.parentUid())
+ {
+ aResult.push('hasParentMessage');
+ }
+ if (0 < this.threadsLen() && 0 === this.parentUid())
+ {
+ aResult.push('hasChildrenMessage');
+ }
+ if (this.hasUnseenSubMessage())
+ {
+ aResult.push('hasUnseenSubMessage');
+ }
+ if (this.hasFlaggedSubMessage())
+ {
+ aResult.push('hasFlaggedSubMessage');
+ }
+
+ return aResult.join(' ');
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MessageModel.prototype.hasVisibleAttachments = function ()
+ {
+ return !!_.find(this.attachments(), function (oAttachment) {
+ return !oAttachment.isLinked;
+ });
+ };
+
+ /**
+ * @param {string} sCid
+ * @return {*}
+ */
+ MessageModel.prototype.findAttachmentByCid = function (sCid)
+ {
+ var
+ oResult = null,
+ aAttachments = this.attachments()
+ ;
+
+ if (Utils.isNonEmptyArray(aAttachments))
+ {
+ sCid = sCid.replace(/^<+/, '').replace(/>+$/, '');
+ oResult = _.find(aAttachments, function (oAttachment) {
+ return sCid === oAttachment.cidWithOutTags;
+ });
+ }
+
+ return oResult || null;
+ };
+
+ /**
+ * @param {string} sContentLocation
+ * @return {*}
+ */
+ MessageModel.prototype.findAttachmentByContentLocation = function (sContentLocation)
+ {
+ var
+ oResult = null,
+ aAttachments = this.attachments()
+ ;
+
+ if (Utils.isNonEmptyArray(aAttachments))
+ {
+ oResult = _.find(aAttachments, function (oAttachment) {
+ return sContentLocation === oAttachment.contentLocation;
+ });
+ }
+
+ return oResult || null;
+ };
+
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.messageId = function ()
+ {
+ return this.sMessageId;
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.inReplyTo = function ()
+ {
+ return this.sInReplyTo;
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.references = function ()
+ {
+ return this.sReferences;
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.fromAsSingleEmail = function ()
+ {
+ return Utils.isArray(this.from) && this.from[0] ? this.from[0].email : '';
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.viewLink = function ()
+ {
+ return RL.link().messageViewLink(this.requestHash);// TODO cjs
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.downloadLink = function ()
+ {
+ return RL.link().messageDownloadLink(this.requestHash);// TODO cjs
+ };
+
+ /**
+ * @param {Object} oExcludeEmails
+ * @return {Array}
+ */
+ MessageModel.prototype.replyEmails = function (oExcludeEmails)
+ {
+ var
+ aResult = [],
+ oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
+ ;
+
+ MessageModel.replyHelper(this.replyTo, oUnic, aResult);
+ if (0 === aResult.length)
+ {
+ MessageModel.replyHelper(this.from, oUnic, aResult);
+ }
+
+ return aResult;
+ };
+
+ /**
+ * @param {Object} oExcludeEmails
+ * @return {Array.}
+ */
+ MessageModel.prototype.replyAllEmails = function (oExcludeEmails)
+ {
+ var
+ aToResult = [],
+ aCcResult = [],
+ oUnic = Utils.isUnd(oExcludeEmails) ? {} : oExcludeEmails
+ ;
+
+ MessageModel.replyHelper(this.replyTo, oUnic, aToResult);
+ if (0 === aToResult.length)
+ {
+ MessageModel.replyHelper(this.from, oUnic, aToResult);
+ }
+
+ MessageModel.replyHelper(this.to, oUnic, aToResult);
+ MessageModel.replyHelper(this.cc, oUnic, aCcResult);
+
+ return [aToResult, aCcResult];
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.textBodyToString = function ()
+ {
+ return this.body ? this.body.html() : '';
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.attachmentsToStringLine = function ()
+ {
+ var aAttachLines = _.map(this.attachments(), function (oItem) {
+ return oItem.fileName + ' (' + oItem.friendlySize + ')';
+ });
+
+ return aAttachLines && 0 < aAttachLines.length ? aAttachLines.join(', ') : '';
+ };
+
+ /**
+ * @return {Object}
+ */
+ MessageModel.prototype.getDataForWindowPopup = function ()
+ {
+ return {
+ 'popupFrom': this.fromToLine(false),
+ 'popupTo': this.toToLine(false),
+ 'popupCc': this.ccToLine(false),
+ 'popupBcc': this.bccToLine(false),
+ 'popupSubject': this.subject(),
+ 'popupDate': this.fullFormatDateValue(),
+ 'popupAttachments': this.attachmentsToStringLine(),
+ 'popupBody': this.textBodyToString()
+ };
+ };
+
+ /**
+ * @param {boolean=} bPrint = false
+ */
+ MessageModel.prototype.viewPopupMessage = function (bPrint)
+ {
+ Utils.windowPopupKnockout(this.getDataForWindowPopup(), 'PopupsWindowSimpleMessage', this.subject(), function (oPopupWin) {
+ if (oPopupWin && oPopupWin.document && oPopupWin.document.body)
+ {
+ $('img.lazy', oPopupWin.document.body).each(function (iIndex, oImg) {
+
+ var
+ $oImg = $(oImg),
+ sOrig = $oImg.data('original'),
+ sSrc = $oImg.attr('src')
+ ;
+
+ if (0 <= iIndex && sOrig && !sSrc)
+ {
+ $oImg.attr('src', sOrig);
+ }
+ });
+
+ if (bPrint)
+ {
+ window.setTimeout(function () {
+ oPopupWin.print();
+ }, 100);
+ }
+ }
+ });
+ };
+
+ MessageModel.prototype.printMessage = function ()
+ {
+ this.viewPopupMessage(true);
+ };
+
+ /**
+ * @returns {string}
+ */
+ MessageModel.prototype.generateUid = function ()
+ {
+ return this.folderFullNameRaw + '/' + this.uid;
+ };
+
+ /**
+ * @param {MessageModel} oMessage
+ * @return {MessageModel}
+ */
+ MessageModel.prototype.populateByMessageListItem = function (oMessage)
+ {
+ this.folderFullNameRaw = oMessage.folderFullNameRaw;
+ this.uid = oMessage.uid;
+ this.hash = oMessage.hash;
+ this.requestHash = oMessage.requestHash;
+ this.subject(oMessage.subject());
+ this.subjectPrefix(this.subjectPrefix());
+ this.subjectSuffix(this.subjectSuffix());
+
+ this.size(oMessage.size());
+ this.dateTimeStampInUTC(oMessage.dateTimeStampInUTC());
+ this.priority(oMessage.priority());
+
+ this.proxy = oMessage.proxy;
+
+ this.fromEmailString(oMessage.fromEmailString());
+ this.fromClearEmailString(oMessage.fromClearEmailString());
+ this.toEmailsString(oMessage.toEmailsString());
+ this.toClearEmailsString(oMessage.toClearEmailsString());
+
+ this.emails = oMessage.emails;
+
+ this.from = oMessage.from;
+ this.to = oMessage.to;
+ this.cc = oMessage.cc;
+ this.bcc = oMessage.bcc;
+ this.replyTo = oMessage.replyTo;
+ this.deliveredTo = oMessage.deliveredTo;
+
+ this.unseen(oMessage.unseen());
+ this.flagged(oMessage.flagged());
+ this.answered(oMessage.answered());
+ this.forwarded(oMessage.forwarded());
+ this.isReadReceipt(oMessage.isReadReceipt());
+
+ this.selected(oMessage.selected());
+ this.checked(oMessage.checked());
+ this.hasAttachments(oMessage.hasAttachments());
+ this.attachmentsMainType(oMessage.attachmentsMainType());
+
+ this.moment(oMessage.moment());
+
+ this.body = null;
+
+ this.priority(Enums.MessagePriority.Normal);
+ this.aDraftInfo = [];
+ this.sMessageId = '';
+ this.sInReplyTo = '';
+ this.sReferences = '';
+
+ this.parentUid(oMessage.parentUid());
+ this.threads(oMessage.threads());
+ this.threadsLen(oMessage.threadsLen());
+
+ this.computeSenderEmail();
+
+ return this;
+ };
+
+ MessageModel.prototype.showExternalImages = function (bLazy)
+ {
+ if (this.body && this.body.data('rl-has-images'))
+ {
+ var sAttr = '';
+ bLazy = Utils.isUnd(bLazy) ? false : bLazy;
+
+ this.hasImages(false);
+ this.body.data('rl-has-images', false);
+
+ sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src';
+ $('[' + sAttr + ']', this.body).each(function () {
+ if (bLazy && $(this).is('img'))
+ {
+ $(this)
+ .addClass('lazy')
+ .attr('data-original', $(this).attr(sAttr))
+ .removeAttr(sAttr)
+ ;
+ }
+ else
+ {
+ $(this).attr('src', $(this).attr(sAttr)).removeAttr(sAttr);
+ }
+ });
+
+ sAttr = this.proxy ? 'data-x-additional-style-url' : 'data-x-style-url';
+ $('[' + sAttr + ']', this.body).each(function () {
+ var sStyle = Utils.trim($(this).attr('style'));
+ sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
+ $(this).attr('style', sStyle + $(this).attr(sAttr)).removeAttr(sAttr);
+ });
+
+ if (bLazy)
+ {
+ $('img.lazy', this.body).addClass('lazy-inited').lazyload({
+ 'threshold' : 400,
+ 'effect' : 'fadeIn',
+ 'skip_invisible' : false,
+ 'container': $('.RL-MailMessageView .messageView .messageItem .content')[0]
+ });
+
+ $window.resize();
+ }
+
+ Utils.windowResize(500);
+ }
+ };
+
+ MessageModel.prototype.showInternalImages = function (bLazy)
+ {
+ if (this.body && !this.body.data('rl-init-internal-images'))
+ {
+ this.body.data('rl-init-internal-images', true);
+
+ bLazy = Utils.isUnd(bLazy) ? false : bLazy;
+
+ var self = this;
+
+ $('[data-x-src-cid]', this.body).each(function () {
+
+ var oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-cid'));
+ if (oAttachment && oAttachment.download)
+ {
+ if (bLazy && $(this).is('img'))
+ {
+ $(this)
+ .addClass('lazy')
+ .attr('data-original', oAttachment.linkPreview());
+ }
+ else
+ {
+ $(this).attr('src', oAttachment.linkPreview());
+ }
+ }
+ });
+
+ $('[data-x-src-location]', this.body).each(function () {
+
+ var oAttachment = self.findAttachmentByContentLocation($(this).attr('data-x-src-location'));
+ if (!oAttachment)
+ {
+ oAttachment = self.findAttachmentByCid($(this).attr('data-x-src-location'));
+ }
+
+ if (oAttachment && oAttachment.download)
+ {
+ if (bLazy && $(this).is('img'))
+ {
+ $(this)
+ .addClass('lazy')
+ .attr('data-original', oAttachment.linkPreview());
+ }
+ else
+ {
+ $(this).attr('src', oAttachment.linkPreview());
+ }
+ }
+ });
+
+ $('[data-x-style-cid]', this.body).each(function () {
+
+ var
+ sStyle = '',
+ sName = '',
+ oAttachment = self.findAttachmentByCid($(this).attr('data-x-style-cid'))
+ ;
+
+ if (oAttachment && oAttachment.linkPreview)
+ {
+ sName = $(this).attr('data-x-style-cid-name');
+ if ('' !== sName)
+ {
+ sStyle = Utils.trim($(this).attr('style'));
+ sStyle = '' === sStyle ? '' : (';' === sStyle.substr(-1) ? sStyle + ' ' : sStyle + '; ');
+ $(this).attr('style', sStyle + sName + ': url(\'' + oAttachment.linkPreview() + '\')');
+ }
+ }
+ });
+
+ if (bLazy)
+ {
+ (function ($oImg, oContainer) {
+ _.delay(function () {
+ $oImg.addClass('lazy-inited').lazyload({
+ 'threshold' : 400,
+ 'effect' : 'fadeIn',
+ 'skip_invisible' : false,
+ 'container': oContainer
+ });
+ }, 300);
+ }($('img.lazy', self.body), $('.RL-MailMessageView .messageView .messageItem .content')[0]));
+ }
+
+ Utils.windowResize(500);
+ }
+ };
+
+ MessageModel.prototype.storeDataToDom = function ()
+ {
+ if (this.body)
+ {
+ this.body.data('rl-is-html', !!this.isHtml());
+ this.body.data('rl-has-images', !!this.hasImages());
+
+ this.body.data('rl-plain-raw', this.plainRaw);
+
+ if (RL.data().capaOpenPGP()) // TODO cjs
+ {
+ this.body.data('rl-plain-pgp-signed', !!this.isPgpSigned());
+ this.body.data('rl-plain-pgp-encrypted', !!this.isPgpEncrypted());
+ this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus());
+ this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser());
+ }
+ }
+ };
+
+ MessageModel.prototype.storePgpVerifyDataToDom = function ()
+ {
+ if (this.body && RL.data().capaOpenPGP()) // TODO cjs
+ {
+ this.body.data('rl-pgp-verify-status', this.pgpSignedVerifyStatus());
+ this.body.data('rl-pgp-verify-user', this.pgpSignedVerifyUser());
+ }
+ };
+
+ MessageModel.prototype.fetchDataToDom = function ()
+ {
+ if (this.body)
+ {
+ this.isHtml(!!this.body.data('rl-is-html'));
+ this.hasImages(!!this.body.data('rl-has-images'));
+
+ this.plainRaw = Utils.pString(this.body.data('rl-plain-raw'));
+
+ if (RL.data().capaOpenPGP()) // TODO cjs
+ {
+ this.isPgpSigned(!!this.body.data('rl-plain-pgp-signed'));
+ this.isPgpEncrypted(!!this.body.data('rl-plain-pgp-encrypted'));
+ this.pgpSignedVerifyStatus(this.body.data('rl-pgp-verify-status'));
+ this.pgpSignedVerifyUser(this.body.data('rl-pgp-verify-user'));
+ }
+ else
+ {
+ this.isPgpSigned(false);
+ this.isPgpEncrypted(false);
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
+ this.pgpSignedVerifyUser('');
+ }
+ }
+ };
+
+ MessageModel.prototype.verifyPgpSignedClearMessage = function ()
+ {
+ if (this.isPgpSigned())
+ {
+ var
+ aRes = [],
+ mPgpMessage = null,
+ sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
+ aPublicKeys = RL.data().findPublicKeysByEmail(sFrom), // TODO cjs
+ oValidKey = null,
+ oValidSysKey = null,
+ sPlain = ''
+ ;
+
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error);
+ this.pgpSignedVerifyUser('');
+
+ try
+ {
+ mPgpMessage = window.openpgp.cleartext.readArmored(this.plainRaw);
+ if (mPgpMessage && mPgpMessage.getText)
+ {
+ this.pgpSignedVerifyStatus(
+ aPublicKeys.length ? Enums.SignedVerifyStatus.Unverified : Enums.SignedVerifyStatus.UnknownPublicKeys);
+
+ aRes = mPgpMessage.verify(aPublicKeys);
+ if (aRes && 0 < aRes.length)
+ {
+ oValidKey = _.find(aRes, function (oItem) {
+ return oItem && oItem.keyid && oItem.valid;
+ });
+
+ if (oValidKey)
+ {
+ oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex()); // TODO cjs
+ if (oValidSysKey)
+ {
+ sPlain = mPgpMessage.getText();
+
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
+ this.pgpSignedVerifyUser(oValidSysKey.user);
+
+ sPlain =
+ $div.empty().append(
+ $('').text(sPlain)
+ ).html()
+ ;
+
+ $div.empty();
+
+ this.replacePlaneTextBody(sPlain);
+ }
+ }
+ }
+ }
+ }
+ catch (oExc) {}
+
+ this.storePgpVerifyDataToDom();
+ }
+ };
+
+ MessageModel.prototype.decryptPgpEncryptedMessage = function (sPassword)
+ {
+ if (this.isPgpEncrypted())
+ {
+ var
+ aRes = [],
+ mPgpMessage = null,
+ mPgpMessageDecrypted = null,
+ sFrom = this.from && this.from[0] && this.from[0].email ? this.from[0].email : '',
+ aPublicKey = RL.data().findPublicKeysByEmail(sFrom), // TODO cjs
+ oPrivateKey = RL.data().findSelfPrivateKey(sPassword), // TODO cjs
+ oValidKey = null,
+ oValidSysKey = null,
+ sPlain = ''
+ ;
+
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Error);
+ this.pgpSignedVerifyUser('');
+
+ if (!oPrivateKey)
+ {
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.UnknownPrivateKey);
+ }
+
+ try
+ {
+ mPgpMessage = window.openpgp.message.readArmored(this.plainRaw);
+ if (mPgpMessage && oPrivateKey && mPgpMessage.decrypt)
+ {
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Unverified);
+
+ mPgpMessageDecrypted = mPgpMessage.decrypt(oPrivateKey);
+ if (mPgpMessageDecrypted)
+ {
+ aRes = mPgpMessageDecrypted.verify(aPublicKey);
+ if (aRes && 0 < aRes.length)
+ {
+ oValidKey = _.find(aRes, function (oItem) {
+ return oItem && oItem.keyid && oItem.valid;
+ });
+
+ if (oValidKey)
+ {
+ oValidSysKey = RL.data().findPublicKeyByHex(oValidKey.keyid.toHex()); // TODO cjs
+ if (oValidSysKey)
+ {
+ this.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.Success);
+ this.pgpSignedVerifyUser(oValidSysKey.user);
+ }
+ }
+ }
+
+ sPlain = mPgpMessageDecrypted.getText();
+
+ sPlain =
+ $div.empty().append(
+ $('').text(sPlain)
+ ).html()
+ ;
+
+ $div.empty();
+
+ this.replacePlaneTextBody(sPlain);
+ }
+ }
+ }
+ catch (oExc) {}
+
+ this.storePgpVerifyDataToDom();
+ }
+ };
+
+ MessageModel.prototype.replacePlaneTextBody = function (sPlain)
+ {
+ if (this.body)
+ {
+ this.body.html(sPlain).addClass('b-text-part plain');
+ }
+ };
+
+ /**
+ * @return {string}
+ */
+ MessageModel.prototype.flagHash = function ()
+ {
+ return [this.deleted(), this.unseen(), this.flagged(), this.answered(), this.forwarded(),
+ this.isReadReceipt()].join('');
+ };
+
+ module.exports = MessageModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Models/OpenPgpKeyModel.js b/dev/Models/OpenPgpKeyModel.js
index 7c1bc0096..ba517bfa5 100644
--- a/dev/Models/OpenPgpKeyModel.js
+++ b/dev/Models/OpenPgpKeyModel.js
@@ -1,32 +1,44 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {string} iIndex
- * @param {string} sGuID
- * @param {string} sID
- * @param {string} sUserID
- * @param {string} sEmail
- * @param {boolean} bIsPrivate
- * @param {string} sArmor
- * @constructor
- */
-function OpenPgpKeyModel(iIndex, sGuID, sID, sUserID, sEmail, bIsPrivate, sArmor)
-{
- this.index = iIndex;
- this.id = sID;
- this.guid = sGuID;
- this.user = sUserID;
- this.email = sEmail;
- this.armor = sArmor;
- this.isPrivate = !!bIsPrivate;
-
- this.deleteAccess = ko.observable(false);
-}
+(function (module) {
-OpenPgpKeyModel.prototype.index = 0;
-OpenPgpKeyModel.prototype.id = '';
-OpenPgpKeyModel.prototype.guid = '';
-OpenPgpKeyModel.prototype.user = '';
-OpenPgpKeyModel.prototype.email = '';
-OpenPgpKeyModel.prototype.armor = '';
-OpenPgpKeyModel.prototype.isPrivate = false;
+ 'use strict';
+
+ var
+ ko = require('./ko.js')
+ ;
+
+ /**
+ * @param {string} iIndex
+ * @param {string} sGuID
+ * @param {string} sID
+ * @param {string} sUserID
+ * @param {string} sEmail
+ * @param {boolean} bIsPrivate
+ * @param {string} sArmor
+ * @constructor
+ */
+ function OpenPgpKeyModel(iIndex, sGuID, sID, sUserID, sEmail, bIsPrivate, sArmor)
+ {
+ this.index = iIndex;
+ this.id = sID;
+ this.guid = sGuID;
+ this.user = sUserID;
+ this.email = sEmail;
+ this.armor = sArmor;
+ this.isPrivate = !!bIsPrivate;
+
+ this.deleteAccess = ko.observable(false);
+ }
+
+ OpenPgpKeyModel.prototype.index = 0;
+ OpenPgpKeyModel.prototype.id = '';
+ OpenPgpKeyModel.prototype.guid = '';
+ OpenPgpKeyModel.prototype.user = '';
+ OpenPgpKeyModel.prototype.email = '';
+ OpenPgpKeyModel.prototype.armor = '';
+ OpenPgpKeyModel.prototype.isPrivate = false;
+
+ module.exports = OpenPgpKeyModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/RL.js b/dev/RL.js
new file mode 100644
index 000000000..85a86f65d
--- /dev/null
+++ b/dev/RL.js
@@ -0,0 +1,7 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = function () {
+ return require('./Knoin/Knoin.js').rl();
+};
\ No newline at end of file
diff --git a/dev/RainLoopBoot.js b/dev/RainLoopBoot.js
new file mode 100644
index 000000000..3467fd945
--- /dev/null
+++ b/dev/RainLoopBoot.js
@@ -0,0 +1,10 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+var
+ kn = require('./Knoin/Knoin.js'),
+ RL = require('./Boots/RainLoopApp.js')
+;
+
+kn.bootstart(RL);
\ No newline at end of file
diff --git a/dev/Screens/AbstractSettings.js b/dev/Screens/AbstractSettings.js
index b8f8f1c5c..61fc66d9e 100644
--- a/dev/Screens/AbstractSettings.js
+++ b/dev/Screens/AbstractSettings.js
@@ -1,181 +1,199 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {Array} aViewModels
- * @constructor
- * @extends KnoinAbstractScreen
- */
-function AbstractSettings(aViewModels)
-{
- KnoinAbstractScreen.call(this, 'settings', aViewModels);
-
- this.menu = ko.observableArray([]);
+(function (module) {
- this.oCurrentSubScreen = null;
- this.oViewModelPlace = null;
-}
+ 'use strict';
-_.extend(AbstractSettings.prototype, KnoinAbstractScreen.prototype);
-
-AbstractSettings.prototype.onRoute = function (sSubName)
-{
var
- self = this,
- oSettingsScreen = null,
- RoutedSettingsViewModel = null,
- oViewModelPlace = null,
- oViewModelDom = null
+ $ = require('./External/jquery.js'),
+ _ = require('./External/underscore.js'),
+ ko = require('./External/ko.js'),
+ Globals = require('./Common/Globals.js'),
+ Utils = require('./Common/Utils.js'),
+ kn = require('./Knoin/Knoin.js'),
+ KnoinAbstractScreen = require('./Knoin/KnoinAbstractScreen.js')
;
- RoutedSettingsViewModel = _.find(ViewModels['settings'], function (SettingsViewModel) {
- return SettingsViewModel && SettingsViewModel.__rlSettingsData &&
- sSubName === SettingsViewModel.__rlSettingsData.Route;
- });
-
- if (RoutedSettingsViewModel)
+ /**
+ * @param {Array} aViewModels
+ * @constructor
+ * @extends KnoinAbstractScreen
+ */
+ function AbstractSettings(aViewModels)
{
- if (_.find(ViewModels['settings-removed'], function (DisabledSettingsViewModel) {
- return DisabledSettingsViewModel && DisabledSettingsViewModel === RoutedSettingsViewModel;
- }))
- {
- RoutedSettingsViewModel = null;
- }
-
- if (RoutedSettingsViewModel && _.find(ViewModels['settings-disabled'], function (DisabledSettingsViewModel) {
- return DisabledSettingsViewModel && DisabledSettingsViewModel === RoutedSettingsViewModel;
- }))
- {
- RoutedSettingsViewModel = null;
- }
+ KnoinAbstractScreen.call(this, 'settings', aViewModels);
+
+ this.menu = ko.observableArray([]);
+
+ this.oCurrentSubScreen = null;
+ this.oViewModelPlace = null;
}
- if (RoutedSettingsViewModel)
+ _.extend(AbstractSettings.prototype, KnoinAbstractScreen.prototype);
+
+ AbstractSettings.prototype.onRoute = function (sSubName)
{
- if (RoutedSettingsViewModel.__builded && RoutedSettingsViewModel.__vm)
+ var
+ self = this,
+ oSettingsScreen = null,
+ RoutedSettingsViewModel = null,
+ oViewModelPlace = null,
+ oViewModelDom = null
+ ;
+
+ RoutedSettingsViewModel = _.find(Globals.aViewModels['settings'], function (SettingsViewModel) {
+ return SettingsViewModel && SettingsViewModel.__rlSettingsData &&
+ sSubName === SettingsViewModel.__rlSettingsData.Route;
+ });
+
+ if (RoutedSettingsViewModel)
{
- oSettingsScreen = RoutedSettingsViewModel.__vm;
- }
- else
- {
- oViewModelPlace = this.oViewModelPlace;
- if (oViewModelPlace && 1 === oViewModelPlace.length)
+ if (_.find(Globals.aViewModels['settings-removed'], function (DisabledSettingsViewModel) {
+ return DisabledSettingsViewModel && DisabledSettingsViewModel === RoutedSettingsViewModel;
+ }))
{
- RoutedSettingsViewModel = /** @type {?Function} */ RoutedSettingsViewModel;
- oSettingsScreen = new RoutedSettingsViewModel();
+ RoutedSettingsViewModel = null;
+ }
- oViewModelDom = $('').addClass('rl-settings-view-model').hide();
- oViewModelDom.appendTo(oViewModelPlace);
-
- oSettingsScreen.data = RL.data();
- oSettingsScreen.viewModelDom = oViewModelDom;
-
- oSettingsScreen.__rlSettingsData = RoutedSettingsViewModel.__rlSettingsData;
-
- RoutedSettingsViewModel.__dom = oViewModelDom;
- RoutedSettingsViewModel.__builded = true;
- RoutedSettingsViewModel.__vm = oSettingsScreen;
-
- ko.applyBindingAccessorsToNode(oViewModelDom[0], {
- 'i18nInit': true,
- 'template': function () { return {'name': RoutedSettingsViewModel.__rlSettingsData.Template}; }
- }, oSettingsScreen);
+ if (RoutedSettingsViewModel && _.find(Globals.aViewModels['settings-disabled'], function (DisabledSettingsViewModel) {
+ return DisabledSettingsViewModel && DisabledSettingsViewModel === RoutedSettingsViewModel;
+ }))
+ {
+ RoutedSettingsViewModel = null;
+ }
+ }
- Utils.delegateRun(oSettingsScreen, 'onBuild', [oViewModelDom]);
+ if (RoutedSettingsViewModel)
+ {
+ if (RoutedSettingsViewModel.__builded && RoutedSettingsViewModel.__vm)
+ {
+ oSettingsScreen = RoutedSettingsViewModel.__vm;
}
else
{
- Utils.log('Cannot find sub settings view model position: SettingsSubScreen');
+ oViewModelPlace = this.oViewModelPlace;
+ if (oViewModelPlace && 1 === oViewModelPlace.length)
+ {
+ RoutedSettingsViewModel = /** @type {?Function} */ RoutedSettingsViewModel;
+ oSettingsScreen = new RoutedSettingsViewModel();
+
+ oViewModelDom = $('').addClass('rl-settings-view-model').hide();
+ oViewModelDom.appendTo(oViewModelPlace);
+
+ oSettingsScreen.data = RL.data(); // TODO cjs
+ oSettingsScreen.viewModelDom = oViewModelDom;
+
+ oSettingsScreen.__rlSettingsData = RoutedSettingsViewModel.__rlSettingsData;
+
+ RoutedSettingsViewModel.__dom = oViewModelDom;
+ RoutedSettingsViewModel.__builded = true;
+ RoutedSettingsViewModel.__vm = oSettingsScreen;
+
+ ko.applyBindingAccessorsToNode(oViewModelDom[0], {
+ 'i18nInit': true,
+ 'template': function () { return {'name': RoutedSettingsViewModel.__rlSettingsData.Template}; }
+ }, oSettingsScreen);
+
+ Utils.delegateRun(oSettingsScreen, 'onBuild', [oViewModelDom]);
+ }
+ else
+ {
+ Utils.log('Cannot find sub settings view model position: SettingsSubScreen');
+ }
+ }
+
+ if (oSettingsScreen)
+ {
+ _.defer(function () {
+ // hide
+ if (self.oCurrentSubScreen)
+ {
+ Utils.delegateRun(self.oCurrentSubScreen, 'onHide');
+ self.oCurrentSubScreen.viewModelDom.hide();
+ }
+ // --
+
+ self.oCurrentSubScreen = oSettingsScreen;
+
+ // show
+ if (self.oCurrentSubScreen)
+ {
+ self.oCurrentSubScreen.viewModelDom.show();
+ Utils.delegateRun(self.oCurrentSubScreen, 'onShow');
+ Utils.delegateRun(self.oCurrentSubScreen, 'onFocus', [], 200);
+
+ _.each(self.menu(), function (oItem) {
+ oItem.selected(oSettingsScreen && oSettingsScreen.__rlSettingsData && oItem.route === oSettingsScreen.__rlSettingsData.Route);
+ });
+
+ $('#rl-content .b-settings .b-content .content').scrollTop(0);
+ }
+ // --
+
+ Utils.windowResize();
+ });
}
}
-
- if (oSettingsScreen)
+ else
{
- _.defer(function () {
- // hide
- if (self.oCurrentSubScreen)
- {
- Utils.delegateRun(self.oCurrentSubScreen, 'onHide');
- self.oCurrentSubScreen.viewModelDom.hide();
- }
- // --
-
- self.oCurrentSubScreen = oSettingsScreen;
-
- // show
- if (self.oCurrentSubScreen)
- {
- self.oCurrentSubScreen.viewModelDom.show();
- Utils.delegateRun(self.oCurrentSubScreen, 'onShow');
- Utils.delegateRun(self.oCurrentSubScreen, 'onFocus', [], 200);
-
- _.each(self.menu(), function (oItem) {
- oItem.selected(oSettingsScreen && oSettingsScreen.__rlSettingsData && oItem.route === oSettingsScreen.__rlSettingsData.Route);
- });
-
- $('#rl-content .b-settings .b-content .content').scrollTop(0);
- }
- // --
-
- Utils.windowResize();
- });
+ kn.setHash(RL.link().settings(), false, true); // TODO cjs
}
- }
- else
- {
- kn.setHash(RL.link().settings(), false, true);
- }
-};
+ };
-AbstractSettings.prototype.onHide = function ()
-{
- if (this.oCurrentSubScreen && this.oCurrentSubScreen.viewModelDom)
+ AbstractSettings.prototype.onHide = function ()
{
- Utils.delegateRun(this.oCurrentSubScreen, 'onHide');
- this.oCurrentSubScreen.viewModelDom.hide();
- }
-};
-
-AbstractSettings.prototype.onBuild = function ()
-{
- _.each(ViewModels['settings'], function (SettingsViewModel) {
- if (SettingsViewModel && SettingsViewModel.__rlSettingsData &&
- !_.find(ViewModels['settings-removed'], function (RemoveSettingsViewModel) {
- return RemoveSettingsViewModel && RemoveSettingsViewModel === SettingsViewModel;
- }))
+ if (this.oCurrentSubScreen && this.oCurrentSubScreen.viewModelDom)
{
- this.menu.push({
- 'route': SettingsViewModel.__rlSettingsData.Route,
- 'label': SettingsViewModel.__rlSettingsData.Label,
- 'selected': ko.observable(false),
- 'disabled': !!_.find(ViewModels['settings-disabled'], function (DisabledSettingsViewModel) {
- return DisabledSettingsViewModel && DisabledSettingsViewModel === SettingsViewModel;
- })
- });
+ Utils.delegateRun(this.oCurrentSubScreen, 'onHide');
+ this.oCurrentSubScreen.viewModelDom.hide();
}
- }, this);
+ };
- this.oViewModelPlace = $('#rl-content #rl-settings-subscreen');
-};
-
-AbstractSettings.prototype.routes = function ()
-{
- var
- DefaultViewModel = _.find(ViewModels['settings'], function (SettingsViewModel) {
- return SettingsViewModel && SettingsViewModel.__rlSettingsData && SettingsViewModel.__rlSettingsData['IsDefault'];
- }),
- sDefaultRoute = DefaultViewModel ? DefaultViewModel.__rlSettingsData['Route'] : 'general',
- oRules = {
- 'subname': /^(.*)$/,
- 'normalize_': function (oRequest, oVals) {
- oVals.subname = Utils.isUnd(oVals.subname) ? sDefaultRoute : Utils.pString(oVals.subname);
- return [oVals.subname];
+ AbstractSettings.prototype.onBuild = function ()
+ {
+ _.each(Globals.aViewModels['settings'], function (SettingsViewModel) {
+ if (SettingsViewModel && SettingsViewModel.__rlSettingsData &&
+ !_.find(Globals.aViewModels['settings-removed'], function (RemoveSettingsViewModel) {
+ return RemoveSettingsViewModel && RemoveSettingsViewModel === SettingsViewModel;
+ }))
+ {
+ this.menu.push({
+ 'route': SettingsViewModel.__rlSettingsData.Route,
+ 'label': SettingsViewModel.__rlSettingsData.Label,
+ 'selected': ko.observable(false),
+ 'disabled': !!_.find(Globals.aViewModels['settings-disabled'], function (DisabledSettingsViewModel) {
+ return DisabledSettingsViewModel && DisabledSettingsViewModel === SettingsViewModel;
+ })
+ });
}
- }
- ;
+ }, this);
- return [
- ['{subname}/', oRules],
- ['{subname}', oRules],
- ['', oRules]
- ];
-};
+ this.oViewModelPlace = $('#rl-content #rl-settings-subscreen');
+ };
+
+ AbstractSettings.prototype.routes = function ()
+ {
+ var
+ DefaultViewModel = _.find(Globals.aViewModels['settings'], function (SettingsViewModel) {
+ return SettingsViewModel && SettingsViewModel.__rlSettingsData && SettingsViewModel.__rlSettingsData['IsDefault'];
+ }),
+ sDefaultRoute = DefaultViewModel ? DefaultViewModel.__rlSettingsData['Route'] : 'general',
+ oRules = {
+ 'subname': /^(.*)$/,
+ 'normalize_': function (oRequest, oVals) {
+ oVals.subname = Utils.isUnd(oVals.subname) ? sDefaultRoute : Utils.pString(oVals.subname);
+ return [oVals.subname];
+ }
+ }
+ ;
+
+ return [
+ ['{subname}/', oRules],
+ ['{subname}', oRules],
+ ['', oRules]
+ ];
+ };
+
+ module.exports = AbstractSettings;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Screens/AdminLogin.js b/dev/Screens/AdminLogin.js
index a1ad92095..94ebf35c4 100644
--- a/dev/Screens/AdminLogin.js
+++ b/dev/Screens/AdminLogin.js
@@ -1,17 +1,31 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends KnoinAbstractScreen
- */
-function AdminLoginScreen()
-{
- KnoinAbstractScreen.call(this, 'login', [AdminLoginViewModel]);
-}
+(function (module) {
-_.extend(AdminLoginScreen.prototype, KnoinAbstractScreen.prototype);
+ 'use strict';
-AdminLoginScreen.prototype.onShow = function ()
-{
- RL.setTitle('');
-};
\ No newline at end of file
+ var
+ _ = require('./External/underscore.js'),
+ KnoinAbstractScreen = require('./Knoin/KnoinAbstractScreen.js'),
+ AdminLoginViewModel = require('./ViewModels/AdminLoginViewModel.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends KnoinAbstractScreen
+ */
+ function AdminLoginScreen()
+ {
+ KnoinAbstractScreen.call(this, 'login', [AdminLoginViewModel]);
+ }
+
+ _.extend(AdminLoginScreen.prototype, KnoinAbstractScreen.prototype);
+
+ AdminLoginScreen.prototype.onShow = function ()
+ {
+ RL.setTitle(''); // TODO cjs
+ };
+
+ module.exports = AdminLoginScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Screens/AdminSettings.js b/dev/Screens/AdminSettings.js
index c3e3ca254..57696532b 100644
--- a/dev/Screens/AdminSettings.js
+++ b/dev/Screens/AdminSettings.js
@@ -1,20 +1,35 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends AbstractSettings
- */
-function AdminSettingsScreen()
-{
- AbstractSettings.call(this, [
- AdminMenuViewModel,
- AdminPaneViewModel
- ]);
-}
+(function (module) {
-_.extend(AdminSettingsScreen.prototype, AbstractSettings.prototype);
+ 'use strict';
-AdminSettingsScreen.prototype.onShow = function ()
-{
- RL.setTitle('');
-};
\ No newline at end of file
+ var
+ _ = require('./External/underscore.js'),
+ AbstractSettings = require('./Screens/AbstractSettings.js'),
+ AdminMenuViewModel = require('./ViewModels/AdminMenuViewModel.js'),
+ AdminPaneViewModel = require('./ViewModels/AdminPaneViewModel.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractSettings
+ */
+ function AdminSettingsScreen()
+ {
+ AbstractSettings.call(this, [
+ AdminMenuViewModel,
+ AdminPaneViewModel
+ ]);
+ }
+
+ _.extend(AdminSettingsScreen.prototype, AbstractSettings.prototype);
+
+ AdminSettingsScreen.prototype.onShow = function ()
+ {
+ RL.setTitle(''); // TODO cjs
+ };
+
+ module.exports = AdminSettingsScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Screens/Login.js b/dev/Screens/Login.js
index efee34c7d..f366939cb 100644
--- a/dev/Screens/Login.js
+++ b/dev/Screens/Login.js
@@ -1,17 +1,31 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends KnoinAbstractScreen
- */
-function LoginScreen()
-{
- KnoinAbstractScreen.call(this, 'login', [LoginViewModel]);
-}
+(function (module) {
-_.extend(LoginScreen.prototype, KnoinAbstractScreen.prototype);
+ 'use strict';
-LoginScreen.prototype.onShow = function ()
-{
- RL.setTitle('');
-};
\ No newline at end of file
+ var
+ _ = require('./External/underscore.js'),
+ KnoinAbstractScreen = require('./Knoin/KnoinAbstractScreen.js'),
+ LoginViewModel = require('./ViewModels/LoginViewModel.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends KnoinAbstractScreen
+ */
+ function LoginScreen()
+ {
+ KnoinAbstractScreen.call(this, 'login', [LoginViewModel]);
+ }
+
+ _.extend(LoginScreen.prototype, KnoinAbstractScreen.prototype);
+
+ LoginScreen.prototype.onShow = function ()
+ {
+ RL.setTitle(''); // TODO cjs
+ };
+
+ module.exports = LoginScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Screens/MailBox.js b/dev/Screens/MailBox.js
index 11f813a6c..5b9cd0a4b 100644
--- a/dev/Screens/MailBox.js
+++ b/dev/Screens/MailBox.js
@@ -1,171 +1,191 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends KnoinAbstractScreen
- */
-function MailBoxScreen()
-{
- KnoinAbstractScreen.call(this, 'mailbox', [
- MailBoxSystemDropDownViewModel,
- MailBoxFolderListViewModel,
- MailBoxMessageListViewModel,
- MailBoxMessageViewViewModel
- ]);
+(function (module) {
- this.oLastRoute = {};
-}
+ 'use strict';
-_.extend(MailBoxScreen.prototype, KnoinAbstractScreen.prototype);
-
-/**
- * @type {Object}
- */
-MailBoxScreen.prototype.oLastRoute = {};
-
-MailBoxScreen.prototype.setNewTitle = function ()
-{
var
- sEmail = RL.data().accountEmail(),
- ifoldersInboxUnreadCount = RL.data().foldersInboxUnreadCount()
+ _ = require('./External/underscore.js'),
+ $html = require('./External/$html.js'),
+ Enums = require('./Common/Enums.js'),
+ Utils = require('./Common/Utils.js'),
+ KnoinAbstractScreen = require('./Knoin/KnoinAbstractScreen.js'),
+ MailBoxSystemDropDownViewModel = require('./ViewModels/MailBoxSystemDropDownViewModel.js'),
+ MailBoxFolderListViewModel = require('./ViewModels/MailBoxFolderListViewModel.js'),
+ MailBoxMessageListViewModel = require('./ViewModels/MailBoxMessageListViewModel.js'),
+ MailBoxMessageViewViewModel = require('./ViewModels/MailBoxMessageViewViewModel.js')
;
- RL.setTitle(('' === sEmail ? '' :
- (0 < ifoldersInboxUnreadCount ? '(' + ifoldersInboxUnreadCount + ') ' : ' ') + sEmail + ' - ') + Utils.i18n('TITLES/MAILBOX'));
-};
-
-MailBoxScreen.prototype.onShow = function ()
-{
- this.setNewTitle();
- RL.data().keyScope(Enums.KeyState.MessageList);
-};
-
-/**
- * @param {string} sFolderHash
- * @param {number} iPage
- * @param {string} sSearch
- * @param {boolean=} bPreview = false
- */
-MailBoxScreen.prototype.onRoute = function (sFolderHash, iPage, sSearch, bPreview)
-{
- if (Utils.isUnd(bPreview) ? false : !!bPreview)
+ /**
+ * @constructor
+ * @extends KnoinAbstractScreen
+ */
+ function MailBoxScreen()
{
- if (Enums.Layout.NoPreview === RL.data().layout() && !RL.data().message())
- {
- RL.historyBack();
- }
+ KnoinAbstractScreen.call(this, 'mailbox', [
+ MailBoxSystemDropDownViewModel,
+ MailBoxFolderListViewModel,
+ MailBoxMessageListViewModel,
+ MailBoxMessageViewViewModel
+ ]);
+
+ this.oLastRoute = {};
}
- else
+
+ _.extend(MailBoxScreen.prototype, KnoinAbstractScreen.prototype);
+
+ /**
+ * @type {Object}
+ */
+ MailBoxScreen.prototype.oLastRoute = {};
+
+ MailBoxScreen.prototype.setNewTitle = function ()
{
var
- oData = RL.data(),
- sFolderFullNameRaw = RL.cache().getFolderFullNameRaw(sFolderHash),
- oFolder = RL.cache().getFolderFromCacheList(sFolderFullNameRaw)
+ sEmail = RL.data().accountEmail(), // TODO cjs
+ ifoldersInboxUnreadCount = RL.data().foldersInboxUnreadCount() // TODO cjs
;
+ // TODO cjs
+ RL.setTitle(('' === sEmail ? '' :
+ (0 < ifoldersInboxUnreadCount ? '(' + ifoldersInboxUnreadCount + ') ' : ' ') + sEmail + ' - ') + Utils.i18n('TITLES/MAILBOX'));
+ };
- if (oFolder)
+ MailBoxScreen.prototype.onShow = function ()
+ {
+ this.setNewTitle();
+ RL.data().keyScope(Enums.KeyState.MessageList);// TODO cjs
+ };
+
+ /**
+ * @param {string} sFolderHash
+ * @param {number} iPage
+ * @param {string} sSearch
+ * @param {boolean=} bPreview = false
+ */
+ MailBoxScreen.prototype.onRoute = function (sFolderHash, iPage, sSearch, bPreview)
+ {
+ if (Utils.isUnd(bPreview) ? false : !!bPreview)
{
- oData
- .currentFolder(oFolder)
- .messageListPage(iPage)
- .messageListSearch(sSearch)
+ if (Enums.Layout.NoPreview === RL.data().layout() && !RL.data().message())// TODO cjs
+ {
+ RL.historyBack();// TODO cjs
+ }
+ }
+ else
+ {
+ var
+ oData = RL.data(),// TODO cjs
+ sFolderFullNameRaw = RL.cache().getFolderFullNameRaw(sFolderHash),// TODO cjs
+ oFolder = RL.cache().getFolderFromCacheList(sFolderFullNameRaw)// TODO cjs
;
- if (Enums.Layout.NoPreview === oData.layout() && oData.message())
+ if (oFolder)
{
- oData.message(null);
+ oData
+ .currentFolder(oFolder)
+ .messageListPage(iPage)
+ .messageListSearch(sSearch)
+ ;
+
+ if (Enums.Layout.NoPreview === oData.layout() && oData.message())
+ {
+ oData.message(null);
+ }
+
+ RL.reloadMessageList();// TODO cjs
}
-
- RL.reloadMessageList();
}
- }
-};
+ };
-MailBoxScreen.prototype.onStart = function ()
-{
- var
- oData = RL.data(),
- fResizeFunction = function () {
- Utils.windowResize();
- }
- ;
-
- if (RL.capa(Enums.Capa.AdditionalAccounts) || RL.capa(Enums.Capa.AdditionalIdentities))
+ MailBoxScreen.prototype.onStart = function ()
{
- RL.accountsAndIdentities();
- }
+ var
+ oData = RL.data(),// TODO cjs
+ fResizeFunction = function () {
+ Utils.windowResize();
+ }
+ ;
- _.delay(function () {
- if ('INBOX' !== oData.currentFolderFullNameRaw())
+ if (RL.capa(Enums.Capa.AdditionalAccounts) || RL.capa(Enums.Capa.AdditionalIdentities))// TODO cjs
{
- RL.folderInformation('INBOX');
+ RL.accountsAndIdentities();// TODO cjs
}
- }, 1000);
- _.delay(function () {
- RL.quota();
- }, 5000);
-
- _.delay(function () {
- RL.remote().appDelayStart(Utils.emptyFunction);
- }, 35000);
-
- $html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === oData.layout());
-
- oData.folderList.subscribe(fResizeFunction);
- oData.messageList.subscribe(fResizeFunction);
- oData.message.subscribe(fResizeFunction);
-
- oData.layout.subscribe(function (nValue) {
- $html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === nValue);
- });
-
- oData.foldersInboxUnreadCount.subscribe(function () {
- this.setNewTitle();
- }, this);
-};
-
-/**
- * @return {Array}
- */
-MailBoxScreen.prototype.routes = function ()
-{
- var
- fNormP = function () {
- return ['Inbox', 1, '', true];
- },
- fNormS = function (oRequest, oVals) {
- oVals[0] = Utils.pString(oVals[0]);
- oVals[1] = Utils.pInt(oVals[1]);
- oVals[1] = 0 >= oVals[1] ? 1 : oVals[1];
- oVals[2] = Utils.pString(oVals[2]);
-
- if ('' === oRequest)
+ _.delay(function () {
+ if ('INBOX' !== oData.currentFolderFullNameRaw())
{
- oVals[0] = 'Inbox';
- oVals[1] = 1;
+ RL.folderInformation('INBOX');// TODO cjs
}
+ }, 1000);
- return [decodeURI(oVals[0]), oVals[1], decodeURI(oVals[2]), false];
- },
- fNormD = function (oRequest, oVals) {
- oVals[0] = Utils.pString(oVals[0]);
- oVals[1] = Utils.pString(oVals[1]);
+ _.delay(function () {
+ RL.quota();// TODO cjs
+ }, 5000);
- if ('' === oRequest)
- {
- oVals[0] = 'Inbox';
+ _.delay(function () {
+ RL.remote().appDelayStart(Utils.emptyFunction);// TODO cjs
+ }, 35000);
+
+ $html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === oData.layout());
+
+ oData.folderList.subscribe(fResizeFunction);
+ oData.messageList.subscribe(fResizeFunction);
+ oData.message.subscribe(fResizeFunction);
+
+ oData.layout.subscribe(function (nValue) {
+ $html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === nValue);
+ });
+
+ oData.foldersInboxUnreadCount.subscribe(function () {
+ this.setNewTitle();
+ }, this);
+ };
+
+ /**
+ * @return {Array}
+ */
+ MailBoxScreen.prototype.routes = function ()
+ {
+ var
+ fNormP = function () {
+ return ['Inbox', 1, '', true];
+ },
+ fNormS = function (oRequest, oVals) {
+ oVals[0] = Utils.pString(oVals[0]);
+ oVals[1] = Utils.pInt(oVals[1]);
+ oVals[1] = 0 >= oVals[1] ? 1 : oVals[1];
+ oVals[2] = Utils.pString(oVals[2]);
+
+ if ('' === oRequest)
+ {
+ oVals[0] = 'Inbox';
+ oVals[1] = 1;
+ }
+
+ return [decodeURI(oVals[0]), oVals[1], decodeURI(oVals[2]), false];
+ },
+ fNormD = function (oRequest, oVals) {
+ oVals[0] = Utils.pString(oVals[0]);
+ oVals[1] = Utils.pString(oVals[1]);
+
+ if ('' === oRequest)
+ {
+ oVals[0] = 'Inbox';
+ }
+
+ return [decodeURI(oVals[0]), 1, decodeURI(oVals[1]), false];
}
+ ;
- return [decodeURI(oVals[0]), 1, decodeURI(oVals[1]), false];
- }
- ;
+ return [
+ [/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)\/(.+)\/?$/, {'normalize_': fNormS}],
+ [/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)$/, {'normalize_': fNormS}],
+ [/^([a-zA-Z0-9]+)\/(.+)\/?$/, {'normalize_': fNormD}],
+ [/^message-preview$/, {'normalize_': fNormP}],
+ [/^([^\/]*)$/, {'normalize_': fNormS}]
+ ];
+ };
- return [
- [/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)\/(.+)\/?$/, {'normalize_': fNormS}],
- [/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)$/, {'normalize_': fNormS}],
- [/^([a-zA-Z0-9]+)\/(.+)\/?$/, {'normalize_': fNormD}],
- [/^message-preview$/, {'normalize_': fNormP}],
- [/^([^\/]*)$/, {'normalize_': fNormS}]
- ];
-};
+ module.exports = MailBoxScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Screens/Settings.js b/dev/Screens/Settings.js
index bbc3c2ae1..32a5c2cb8 100644
--- a/dev/Screens/Settings.js
+++ b/dev/Screens/Settings.js
@@ -1,28 +1,46 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends AbstractSettings
- */
-function SettingsScreen()
-{
- AbstractSettings.call(this, [
- SettingsSystemDropDownViewModel,
- SettingsMenuViewModel,
- SettingsPaneViewModel
- ]);
+(function (module) {
- Utils.initOnStartOrLangChange(function () {
- this.sSettingsTitle = Utils.i18n('TITLES/SETTINGS');
- }, this, function () {
- RL.setTitle(this.sSettingsTitle);
- });
-}
+ 'use strict';
-_.extend(SettingsScreen.prototype, AbstractSettings.prototype);
+ var
+ _ = require('./External/underscore.js'),
+ Enums = require('./Common/Enums.js'),
+ Utils = require('./Common/Utils.js'),
+ AbstractSettings = require('./Screens/AbstractSettings.js'),
+ SettingsSystemDropDownViewModel = require('./ViewModels/SettingsSystemDropDownViewModel.js'),
+ SettingsMenuViewModel = require('./ViewModels/SettingsMenuViewModel.js'),
+ SettingsPaneViewModel = require('./ViewModels/SettingsPaneViewModel.js')
+ ;
-SettingsScreen.prototype.onShow = function ()
-{
- RL.setTitle(this.sSettingsTitle);
- RL.data().keyScope(Enums.KeyState.Settings);
-};
+ /**
+ * @constructor
+ * @extends AbstractSettings
+ */
+ function SettingsScreen()
+ {
+ AbstractSettings.call(this, [
+ SettingsSystemDropDownViewModel,
+ SettingsMenuViewModel,
+ SettingsPaneViewModel
+ ]);
+
+ Utils.initOnStartOrLangChange(function () {
+ this.sSettingsTitle = Utils.i18n('TITLES/SETTINGS');
+ }, this, function () {
+ RL.setTitle(this.sSettingsTitle); // TODO cjs
+ });
+ }
+
+ _.extend(SettingsScreen.prototype, AbstractSettings.prototype);
+
+ SettingsScreen.prototype.onShow = function ()
+ {
+ RL.setTitle(this.sSettingsTitle); // TODO cjs
+ RL.data().keyScope(Enums.KeyState.Settings); // TODO cjs
+ };
+
+ module.exports = SettingsScreen;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Settings/General.js b/dev/Settings/General.js
index de9fc9d70..cd3e7669b 100644
--- a/dev/Settings/General.js
+++ b/dev/Settings/General.js
@@ -68,7 +68,7 @@ SettingsGeneral.prototype.onBuild = function ()
'dataType': 'script',
'cache': true
}).done(function() {
- Utils.i18nToDoc();
+ Utils.i18nReload();
self.languageTrigger(Enums.SaveSettingsStep.TrueResult);
}).fail(function() {
self.languageTrigger(Enums.SaveSettingsStep.FalseResult);
diff --git a/dev/Storages/AbstractAjaxRemote.js b/dev/Storages/AbstractAjaxRemote.js
deleted file mode 100644
index cdb2af486..000000000
--- a/dev/Storages/AbstractAjaxRemote.js
+++ /dev/null
@@ -1,283 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- */
-function AbstractAjaxRemoteStorage()
-{
- this.oRequests = {};
-}
-
-AbstractAjaxRemoteStorage.prototype.oRequests = {};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sRequestAction
- * @param {string} sType
- * @param {?AjaxJsonDefaultResponse} oData
- * @param {boolean} bCached
- * @param {*=} oRequestParameters
- */
-AbstractAjaxRemoteStorage.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters)
-{
- var
- fCall = function () {
- if (Enums.StorageResultType.Success !== sType && Globals.bUnload)
- {
- sType = Enums.StorageResultType.Unload;
- }
-
- if (Enums.StorageResultType.Success === sType && oData && !oData.Result)
- {
- if (oData && -1 < Utils.inArray(oData.ErrorCode, [
- Enums.Notification.AuthError, Enums.Notification.AccessError,
- Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed,
- Enums.Notification.MailServerError, Enums.Notification.UnknownNotification, Enums.Notification.UnknownError
- ]))
- {
- Globals.iAjaxErrorCount++;
- }
-
- if (oData && Enums.Notification.InvalidToken === oData.ErrorCode)
- {
- Globals.iTokenErrorCount++;
- }
-
- if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
- {
- RL.loginAndLogoutReload(true);
- }
-
- if (oData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
- {
- if (window.__rlah_clear)
- {
- window.__rlah_clear();
- }
-
- RL.loginAndLogoutReload(true);
- }
- }
- else if (Enums.StorageResultType.Success === sType && oData && oData.Result)
- {
- Globals.iAjaxErrorCount = 0;
- Globals.iTokenErrorCount = 0;
- }
-
- if (fCallback)
- {
- Plugins.runHook('ajax-default-response', [sRequestAction, Enums.StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);
-
- fCallback(
- sType,
- Enums.StorageResultType.Success === sType ? oData : null,
- bCached,
- sRequestAction,
- oRequestParameters
- );
- }
- }
- ;
-
- switch (sType)
- {
- case 'success':
- sType = Enums.StorageResultType.Success;
- break;
- case 'abort':
- sType = Enums.StorageResultType.Abort;
- break;
- default:
- sType = Enums.StorageResultType.Error;
- break;
- }
-
- if (Enums.StorageResultType.Error === sType)
- {
- _.delay(fCall, 300);
- }
- else
- {
- fCall();
- }
-};
-
-/**
- * @param {?Function} fResultCallback
- * @param {Object} oParameters
- * @param {?number=} iTimeOut = 20000
- * @param {string=} sGetAdd = ''
- * @param {Array=} aAbortActions = []
- * @return {jQuery.jqXHR}
- */
-AbstractAjaxRemoteStorage.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions)
-{
- var
- self = this,
- bPost = '' === sGetAdd,
- oHeaders = {},
- iStart = (new window.Date()).getTime(),
- oDefAjax = null,
- sAction = ''
- ;
-
- oParameters = oParameters || {};
- iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : 20000;
- sGetAdd = Utils.isUnd(sGetAdd) ? '' : Utils.pString(sGetAdd);
- aAbortActions = Utils.isArray(aAbortActions) ? aAbortActions : [];
-
- sAction = oParameters.Action || '';
-
- if (sAction && 0 < aAbortActions.length)
- {
- _.each(aAbortActions, function (sActionToAbort) {
- if (self.oRequests[sActionToAbort])
- {
- self.oRequests[sActionToAbort].__aborted = true;
- if (self.oRequests[sActionToAbort].abort)
- {
- self.oRequests[sActionToAbort].abort();
- }
- self.oRequests[sActionToAbort] = null;
- }
- });
- }
-
- if (bPost)
- {
- oParameters['XToken'] = RL.settingsGet('Token');
- }
-
- oDefAjax = $.ajax({
- 'type': bPost ? 'POST' : 'GET',
- 'url': RL.link().ajax(sGetAdd),
- 'async': true,
- 'dataType': 'json',
- 'data': bPost ? oParameters : {},
- 'headers': oHeaders,
- 'timeout': iTimeOut,
- 'global': true
- });
-
- oDefAjax.always(function (oData, sType) {
-
- var bCached = false;
- if (oData && oData['Time'])
- {
- bCached = Utils.pInt(oData['Time']) > (new window.Date()).getTime() - iStart;
- }
-
- if (sAction && self.oRequests[sAction])
- {
- if (self.oRequests[sAction].__aborted)
- {
- sType = 'abort';
- }
-
- self.oRequests[sAction] = null;
- }
-
- self.defaultResponse(fResultCallback, sAction, sType, oData, bCached, oParameters);
- });
-
- if (sAction && 0 < aAbortActions.length && -1 < Utils.inArray(sAction, aAbortActions))
- {
- if (this.oRequests[sAction])
- {
- this.oRequests[sAction].__aborted = true;
- if (this.oRequests[sAction].abort)
- {
- this.oRequests[sAction].abort();
- }
- this.oRequests[sAction] = null;
- }
-
- this.oRequests[sAction] = oDefAjax;
- }
-
- return oDefAjax;
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sAction
- * @param {Object=} oParameters
- * @param {?number=} iTimeout
- * @param {string=} sGetAdd = ''
- * @param {Array=} aAbortActions = []
- */
-AbstractAjaxRemoteStorage.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
-{
- oParameters = oParameters || {};
- oParameters.Action = sAction;
-
- sGetAdd = Utils.pString(sGetAdd);
-
- Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
-
- this.ajaxRequest(fCallback, oParameters,
- Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
-};
-
-/**
- * @param {?Function} fCallback
- */
-AbstractAjaxRemoteStorage.prototype.noop = function (fCallback)
-{
- this.defaultRequest(fCallback, 'Noop');
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sMessage
- * @param {string} sFileName
- * @param {number} iLineNo
- * @param {string} sLocation
- * @param {string} sHtmlCapa
- * @param {number} iTime
- */
-AbstractAjaxRemoteStorage.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime)
-{
- this.defaultRequest(fCallback, 'JsError', {
- 'Message': sMessage,
- 'FileName': sFileName,
- 'LineNo': iLineNo,
- 'Location': sLocation,
- 'HtmlCapa': sHtmlCapa,
- 'TimeOnPage': iTime
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sType
- * @param {Array=} mData = null
- * @param {boolean=} bIsError = false
- */
-AbstractAjaxRemoteStorage.prototype.jsInfo = function (fCallback, sType, mData, bIsError)
-{
- this.defaultRequest(fCallback, 'JsInfo', {
- 'Type': sType,
- 'Data': mData,
- 'IsError': (Utils.isUnd(bIsError) ? false : !!bIsError) ? '1' : '0'
- });
-};
-
-/**
- * @param {?Function} fCallback
- */
-AbstractAjaxRemoteStorage.prototype.getPublicKey = function (fCallback)
-{
- this.defaultRequest(fCallback, 'GetPublicKey');
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sVersion
- */
-AbstractAjaxRemoteStorage.prototype.jsVersion = function (fCallback, sVersion)
-{
- this.defaultRequest(fCallback, 'Version', {
- 'Version': sVersion
- });
-};
diff --git a/dev/Storages/AbstractAjaxRemoteStorage.js b/dev/Storages/AbstractAjaxRemoteStorage.js
new file mode 100644
index 000000000..e42771189
--- /dev/null
+++ b/dev/Storages/AbstractAjaxRemoteStorage.js
@@ -0,0 +1,301 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ window = require('./External/window.js'),
+ $ = require('./External/jquery.js'),
+ Consts = require('./Common/Consts.js'),
+ Enums = require('./Common/Enums.js'),
+ Globals = require('./Common/Globals.js'),
+ Utils = require('./Common/Utils.js'),
+ Plugins = require('./Common/Plugins.js')
+ ;
+
+ /**
+ * @constructor
+ */
+ function AbstractAjaxRemoteStorage()
+ {
+ this.oRequests = {};
+ }
+
+ AbstractAjaxRemoteStorage.prototype.oRequests = {};
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sRequestAction
+ * @param {string} sType
+ * @param {?AjaxJsonDefaultResponse} oData
+ * @param {boolean} bCached
+ * @param {*=} oRequestParameters
+ */
+ AbstractAjaxRemoteStorage.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters)
+ {
+ var
+ fCall = function () {
+ if (Enums.StorageResultType.Success !== sType && Globals.bUnload)
+ {
+ sType = Enums.StorageResultType.Unload;
+ }
+
+ if (Enums.StorageResultType.Success === sType && oData && !oData.Result)
+ {
+ if (oData && -1 < Utils.inArray(oData.ErrorCode, [
+ Enums.Notification.AuthError, Enums.Notification.AccessError,
+ Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed,
+ Enums.Notification.MailServerError, Enums.Notification.UnknownNotification, Enums.Notification.UnknownError
+ ]))
+ {
+ Globals.iAjaxErrorCount++;
+ }
+
+ if (oData && Enums.Notification.InvalidToken === oData.ErrorCode)
+ {
+ Globals.iTokenErrorCount++;
+ }
+
+ if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
+ {
+ RL.loginAndLogoutReload(true); // TODO cjs
+ }
+
+ if (oData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
+ {
+ if (window.__rlah_clear)
+ {
+ window.__rlah_clear();
+ }
+
+ RL.loginAndLogoutReload(true); // TODO cjs
+ }
+ }
+ else if (Enums.StorageResultType.Success === sType && oData && oData.Result)
+ {
+ Globals.iAjaxErrorCount = 0;
+ Globals.iTokenErrorCount = 0;
+ }
+
+ if (fCallback)
+ {
+ Plugins.runHook('ajax-default-response', [sRequestAction, Enums.StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);
+
+ fCallback(
+ sType,
+ Enums.StorageResultType.Success === sType ? oData : null,
+ bCached,
+ sRequestAction,
+ oRequestParameters
+ );
+ }
+ }
+ ;
+
+ switch (sType)
+ {
+ case 'success':
+ sType = Enums.StorageResultType.Success;
+ break;
+ case 'abort':
+ sType = Enums.StorageResultType.Abort;
+ break;
+ default:
+ sType = Enums.StorageResultType.Error;
+ break;
+ }
+
+ if (Enums.StorageResultType.Error === sType)
+ {
+ _.delay(fCall, 300);
+ }
+ else
+ {
+ fCall();
+ }
+ };
+
+ /**
+ * @param {?Function} fResultCallback
+ * @param {Object} oParameters
+ * @param {?number=} iTimeOut = 20000
+ * @param {string=} sGetAdd = ''
+ * @param {Array=} aAbortActions = []
+ * @return {jQuery.jqXHR}
+ */
+ AbstractAjaxRemoteStorage.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions)
+ {
+ var
+ self = this,
+ bPost = '' === sGetAdd,
+ oHeaders = {},
+ iStart = (new window.Date()).getTime(),
+ oDefAjax = null,
+ sAction = ''
+ ;
+
+ oParameters = oParameters || {};
+ iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : 20000;
+ sGetAdd = Utils.isUnd(sGetAdd) ? '' : Utils.pString(sGetAdd);
+ aAbortActions = Utils.isArray(aAbortActions) ? aAbortActions : [];
+
+ sAction = oParameters.Action || '';
+
+ if (sAction && 0 < aAbortActions.length)
+ {
+ _.each(aAbortActions, function (sActionToAbort) {
+ if (self.oRequests[sActionToAbort])
+ {
+ self.oRequests[sActionToAbort].__aborted = true;
+ if (self.oRequests[sActionToAbort].abort)
+ {
+ self.oRequests[sActionToAbort].abort();
+ }
+ self.oRequests[sActionToAbort] = null;
+ }
+ });
+ }
+
+ if (bPost)
+ {
+ oParameters['XToken'] = RL.settingsGet('Token'); // TODO cjs
+ }
+
+ oDefAjax = $.ajax({
+ 'type': bPost ? 'POST' : 'GET',
+ 'url': RL.link().ajax(sGetAdd), // TODO cjs
+ 'async': true,
+ 'dataType': 'json',
+ 'data': bPost ? oParameters : {},
+ 'headers': oHeaders,
+ 'timeout': iTimeOut,
+ 'global': true
+ });
+
+ oDefAjax.always(function (oData, sType) {
+
+ var bCached = false;
+ if (oData && oData['Time'])
+ {
+ bCached = Utils.pInt(oData['Time']) > (new window.Date()).getTime() - iStart;
+ }
+
+ if (sAction && self.oRequests[sAction])
+ {
+ if (self.oRequests[sAction].__aborted)
+ {
+ sType = 'abort';
+ }
+
+ self.oRequests[sAction] = null;
+ }
+
+ self.defaultResponse(fResultCallback, sAction, sType, oData, bCached, oParameters);
+ });
+
+ if (sAction && 0 < aAbortActions.length && -1 < Utils.inArray(sAction, aAbortActions))
+ {
+ if (this.oRequests[sAction])
+ {
+ this.oRequests[sAction].__aborted = true;
+ if (this.oRequests[sAction].abort)
+ {
+ this.oRequests[sAction].abort();
+ }
+ this.oRequests[sAction] = null;
+ }
+
+ this.oRequests[sAction] = oDefAjax;
+ }
+
+ return oDefAjax;
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sAction
+ * @param {Object=} oParameters
+ * @param {?number=} iTimeout
+ * @param {string=} sGetAdd = ''
+ * @param {Array=} aAbortActions = []
+ */
+ AbstractAjaxRemoteStorage.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
+ {
+ oParameters = oParameters || {};
+ oParameters.Action = sAction;
+
+ sGetAdd = Utils.pString(sGetAdd);
+
+ Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
+
+ this.ajaxRequest(fCallback, oParameters,
+ Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AbstractAjaxRemoteStorage.prototype.noop = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'Noop');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sMessage
+ * @param {string} sFileName
+ * @param {number} iLineNo
+ * @param {string} sLocation
+ * @param {string} sHtmlCapa
+ * @param {number} iTime
+ */
+ AbstractAjaxRemoteStorage.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime)
+ {
+ this.defaultRequest(fCallback, 'JsError', {
+ 'Message': sMessage,
+ 'FileName': sFileName,
+ 'LineNo': iLineNo,
+ 'Location': sLocation,
+ 'HtmlCapa': sHtmlCapa,
+ 'TimeOnPage': iTime
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sType
+ * @param {Array=} mData = null
+ * @param {boolean=} bIsError = false
+ */
+ AbstractAjaxRemoteStorage.prototype.jsInfo = function (fCallback, sType, mData, bIsError)
+ {
+ this.defaultRequest(fCallback, 'JsInfo', {
+ 'Type': sType,
+ 'Data': mData,
+ 'IsError': (Utils.isUnd(bIsError) ? false : !!bIsError) ? '1' : '0'
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AbstractAjaxRemoteStorage.prototype.getPublicKey = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'GetPublicKey');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sVersion
+ */
+ AbstractAjaxRemoteStorage.prototype.jsVersion = function (fCallback, sVersion)
+ {
+ this.defaultRequest(fCallback, 'Version', {
+ 'Version': sVersion
+ });
+ };
+
+ module.exports = AbstractAjaxRemoteStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/AbstractCache.js b/dev/Storages/AbstractCache.js
deleted file mode 100644
index aecbbdaed..000000000
--- a/dev/Storages/AbstractCache.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- */
-function AbstractCacheStorage()
-{
- this.bCapaGravatar = RL.capa(Enums.Capa.Gravatar);
-}
-
-/**
- * @type {Object}
- */
-AbstractCacheStorage.prototype.oServices = {};
-
-/**
- * @type {boolean}
- */
-AbstractCacheStorage.prototype.bCapaGravatar = false;
-
-AbstractCacheStorage.prototype.clear = function ()
-{
- this.bCapaGravatar = !!this.bCapaGravatar; // TODO
-};
-
-/**
- * @param {string} sEmail
- * @return {string}
- */
-AbstractCacheStorage.prototype.getUserPic = function (sEmail, fCallback)
-{
- sEmail = Utils.trim(sEmail);
- fCallback(this.bCapaGravatar && '' !== sEmail ? RL.link().avatarLink(sEmail) : '', sEmail);
-};
diff --git a/dev/Storages/AbstractCacheStorage.js b/dev/Storages/AbstractCacheStorage.js
new file mode 100644
index 000000000..1fd364064
--- /dev/null
+++ b/dev/Storages/AbstractCacheStorage.js
@@ -0,0 +1,48 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ Enums = require('./Common/Enums.js'),
+ Utils = require('./Common/Utils.js'),
+ RL = require('./RL.js')
+ ;
+
+ /**
+ * @constructor
+ */
+ function AbstractCacheStorage()
+ {
+ this.bCapaGravatar = RL().capa(Enums.Capa.Gravatar);
+ }
+
+ /**
+ * @type {Object}
+ */
+ AbstractCacheStorage.prototype.oServices = {};
+
+ /**
+ * @type {boolean}
+ */
+ AbstractCacheStorage.prototype.bCapaGravatar = false;
+
+ AbstractCacheStorage.prototype.clear = function ()
+ {
+ this.bCapaGravatar = !!this.bCapaGravatar; // TODO
+ };
+
+ /**
+ * @param {string} sEmail
+ * @return {string}
+ */
+ AbstractCacheStorage.prototype.getUserPic = function (sEmail, fCallback)
+ {
+ sEmail = Utils.trim(sEmail);
+ fCallback(this.bCapaGravatar && '' !== sEmail ? RL().link().avatarLink(sEmail) : '', sEmail);
+ };
+
+ module.exports = AbstractCacheStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/AbstractData.js b/dev/Storages/AbstractData.js
index 4afd05795..a373dfa76 100644
--- a/dev/Storages/AbstractData.js
+++ b/dev/Storages/AbstractData.js
@@ -1,134 +1,150 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function AbstractData()
-{
- this.leftPanelDisabled = ko.observable(false);
- this.useKeyboardShortcuts = ko.observable(true);
+(function (module) {
- this.keyScopeReal = ko.observable(Enums.KeyState.All);
- this.keyScopeFake = ko.observable(Enums.KeyState.All);
+ 'use strict';
- this.keyScope = ko.computed({
- 'owner': this,
- 'read': function () {
- return this.keyScopeFake();
- },
- 'write': function (sValue) {
-
- if (Enums.KeyState.Menu !== sValue)
- {
- if (Enums.KeyState.Compose === sValue)
- {
- Utils.disableKeyFilter();
- }
- else
- {
- Utils.restoreKeyFilter();
- }
-
- this.keyScopeFake(sValue);
- if (Globals.dropdownVisibility())
- {
- sValue = Enums.KeyState.Menu;
- }
- }
-
- this.keyScopeReal(sValue);
- }
- });
-
- this.keyScopeReal.subscribe(function (sValue) {
-// window.console.log(sValue);
- key.setScope(sValue);
- });
-
- this.leftPanelDisabled.subscribe(function (bValue) {
- RL.pub('left-panel.' + (bValue ? 'off' : 'on'));
- });
-
- Globals.dropdownVisibility.subscribe(function (bValue) {
- if (bValue)
- {
- Globals.tooltipTrigger(!Globals.tooltipTrigger());
- this.keyScope(Enums.KeyState.Menu);
- }
- else if (Enums.KeyState.Menu === key.getScope())
- {
- this.keyScope(this.keyScopeFake());
- }
- }, this);
-
- Utils.initDataConstructorBySettings(this);
-}
-
-AbstractData.prototype.populateDataOnStart = function()
-{
var
- mLayout = Utils.pInt(RL.settingsGet('Layout')),
- aLanguages = RL.settingsGet('Languages'),
- aThemes = RL.settingsGet('Themes')
+ ko = require('./External/ko.js'),
+ key = require('./External/key.js'),
+ Enums = require('./Common/Enums.js'),
+ Globals = require('./Common/Globals.js'),
+ Utils = require('./Common/Utils.js')
;
-
- if (Utils.isArray(aLanguages))
+
+ /**
+ * @constructor
+ */
+ function AbstractData()
{
- this.languages(aLanguages);
+ this.leftPanelDisabled = ko.observable(false);
+ this.useKeyboardShortcuts = ko.observable(true);
+
+ this.keyScopeReal = ko.observable(Enums.KeyState.All);
+ this.keyScopeFake = ko.observable(Enums.KeyState.All);
+
+ this.keyScope = ko.computed({
+ 'owner': this,
+ 'read': function () {
+ return this.keyScopeFake();
+ },
+ 'write': function (sValue) {
+
+ if (Enums.KeyState.Menu !== sValue)
+ {
+ if (Enums.KeyState.Compose === sValue)
+ {
+ Utils.disableKeyFilter();
+ }
+ else
+ {
+ Utils.restoreKeyFilter();
+ }
+
+ this.keyScopeFake(sValue);
+ if (Globals.dropdownVisibility())
+ {
+ sValue = Enums.KeyState.Menu;
+ }
+ }
+
+ this.keyScopeReal(sValue);
+ }
+ });
+
+ this.keyScopeReal.subscribe(function (sValue) {
+ // window.console.log(sValue);
+ key.setScope(sValue);
+ });
+
+ this.leftPanelDisabled.subscribe(function (bValue) {
+ RL.pub('left-panel.' + (bValue ? 'off' : 'on')); // TODO cjs
+ });
+
+ Globals.dropdownVisibility.subscribe(function (bValue) {
+ if (bValue)
+ {
+ Globals.tooltipTrigger(!Globals.tooltipTrigger());
+ this.keyScope(Enums.KeyState.Menu);
+ }
+ else if (Enums.KeyState.Menu === key.getScope())
+ {
+ this.keyScope(this.keyScopeFake());
+ }
+ }, this);
+
+ Utils.initDataConstructorBySettings(this);
}
- if (Utils.isArray(aThemes))
+ AbstractData.prototype.populateDataOnStart = function()
{
- this.themes(aThemes);
- }
+ var
+ mLayout = Utils.pInt(RL.settingsGet('Layout')), // TODO cjs
+ aLanguages = RL.settingsGet('Languages'),
+ aThemes = RL.settingsGet('Themes')
+ ;
- this.mainLanguage(RL.settingsGet('Language'));
- this.mainTheme(RL.settingsGet('Theme'));
+ if (Utils.isArray(aLanguages))
+ {
+ this.languages(aLanguages);
+ }
- this.capaAdditionalAccounts(RL.capa(Enums.Capa.AdditionalAccounts));
- this.capaAdditionalIdentities(RL.capa(Enums.Capa.AdditionalIdentities));
- this.capaGravatar(RL.capa(Enums.Capa.Gravatar));
- this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
- this.determineUserDomain(!!RL.settingsGet('DetermineUserDomain'));
+ if (Utils.isArray(aThemes))
+ {
+ this.themes(aThemes);
+ }
- this.capaThemes(RL.capa(Enums.Capa.Themes));
- this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
- this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));
- this.useLocalProxyForExternalImages(!!RL.settingsGet('UseLocalProxyForExternalImages'));
+ this.mainLanguage(RL.settingsGet('Language'));
+ this.mainTheme(RL.settingsGet('Theme'));
- this.editorDefaultType(RL.settingsGet('EditorDefaultType'));
- this.showImages(!!RL.settingsGet('ShowImages'));
- this.contactsAutosave(!!RL.settingsGet('ContactsAutosave'));
- this.interfaceAnimation(RL.settingsGet('InterfaceAnimation'));
+ this.capaAdditionalAccounts(RL.capa(Enums.Capa.AdditionalAccounts));
+ this.capaAdditionalIdentities(RL.capa(Enums.Capa.AdditionalIdentities));
+ this.capaGravatar(RL.capa(Enums.Capa.Gravatar));
+ this.determineUserLanguage(!!RL.settingsGet('DetermineUserLanguage'));
+ this.determineUserDomain(!!RL.settingsGet('DetermineUserDomain'));
- this.mainMessagesPerPage(RL.settingsGet('MPP'));
+ this.capaThemes(RL.capa(Enums.Capa.Themes));
+ this.allowLanguagesOnLogin(!!RL.settingsGet('AllowLanguagesOnLogin'));
+ this.allowLanguagesOnSettings(!!RL.settingsGet('AllowLanguagesOnSettings'));
+ this.useLocalProxyForExternalImages(!!RL.settingsGet('UseLocalProxyForExternalImages'));
- this.desktopNotifications(!!RL.settingsGet('DesktopNotifications'));
- this.useThreads(!!RL.settingsGet('UseThreads'));
- this.replySameFolder(!!RL.settingsGet('ReplySameFolder'));
- this.useCheckboxesInList(!!RL.settingsGet('UseCheckboxesInList'));
+ this.editorDefaultType(RL.settingsGet('EditorDefaultType'));
+ this.showImages(!!RL.settingsGet('ShowImages'));
+ this.contactsAutosave(!!RL.settingsGet('ContactsAutosave'));
+ this.interfaceAnimation(RL.settingsGet('InterfaceAnimation'));
- this.layout(Enums.Layout.SidePreview);
- if (-1 < Utils.inArray(mLayout, [Enums.Layout.NoPreview, Enums.Layout.SidePreview, Enums.Layout.BottomPreview]))
- {
- this.layout(mLayout);
- }
- this.facebookSupported(!!RL.settingsGet('SupportedFacebookSocial'));
- this.facebookEnable(!!RL.settingsGet('AllowFacebookSocial'));
- this.facebookAppID(RL.settingsGet('FacebookAppID'));
- this.facebookAppSecret(RL.settingsGet('FacebookAppSecret'));
+ this.mainMessagesPerPage(RL.settingsGet('MPP'));
- this.twitterEnable(!!RL.settingsGet('AllowTwitterSocial'));
- this.twitterConsumerKey(RL.settingsGet('TwitterConsumerKey'));
- this.twitterConsumerSecret(RL.settingsGet('TwitterConsumerSecret'));
+ this.desktopNotifications(!!RL.settingsGet('DesktopNotifications'));
+ this.useThreads(!!RL.settingsGet('UseThreads'));
+ this.replySameFolder(!!RL.settingsGet('ReplySameFolder'));
+ this.useCheckboxesInList(!!RL.settingsGet('UseCheckboxesInList'));
- this.googleEnable(!!RL.settingsGet('AllowGoogleSocial'));
- this.googleClientID(RL.settingsGet('GoogleClientID'));
- this.googleClientSecret(RL.settingsGet('GoogleClientSecret'));
- this.googleApiKey(RL.settingsGet('GoogleApiKey'));
+ this.layout(Enums.Layout.SidePreview);
+ if (-1 < Utils.inArray(mLayout, [Enums.Layout.NoPreview, Enums.Layout.SidePreview, Enums.Layout.BottomPreview]))
+ {
+ this.layout(mLayout);
+ }
+ this.facebookSupported(!!RL.settingsGet('SupportedFacebookSocial'));
+ this.facebookEnable(!!RL.settingsGet('AllowFacebookSocial'));
+ this.facebookAppID(RL.settingsGet('FacebookAppID'));
+ this.facebookAppSecret(RL.settingsGet('FacebookAppSecret'));
- this.dropboxEnable(!!RL.settingsGet('AllowDropboxSocial'));
- this.dropboxApiKey(RL.settingsGet('DropboxApiKey'));
+ this.twitterEnable(!!RL.settingsGet('AllowTwitterSocial'));
+ this.twitterConsumerKey(RL.settingsGet('TwitterConsumerKey'));
+ this.twitterConsumerSecret(RL.settingsGet('TwitterConsumerSecret'));
- this.contactsIsAllowed(!!RL.settingsGet('ContactsIsAllowed'));
-};
+ this.googleEnable(!!RL.settingsGet('AllowGoogleSocial'));
+ this.googleClientID(RL.settingsGet('GoogleClientID'));
+ this.googleClientSecret(RL.settingsGet('GoogleClientSecret'));
+ this.googleApiKey(RL.settingsGet('GoogleApiKey'));
+
+ this.dropboxEnable(!!RL.settingsGet('AllowDropboxSocial'));
+ this.dropboxApiKey(RL.settingsGet('DropboxApiKey'));
+
+ this.contactsIsAllowed(!!RL.settingsGet('ContactsIsAllowed'));
+ };
+
+ module.exports = AbstractData;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/AdminAjaxRemote.js b/dev/Storages/AdminAjaxRemote.js
deleted file mode 100644
index fd5730f4f..000000000
--- a/dev/Storages/AdminAjaxRemote.js
+++ /dev/null
@@ -1,262 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- * @extends AbstractAjaxRemoteStorage
- */
-function AdminAjaxRemoteStorage()
-{
- AbstractAjaxRemoteStorage.call(this);
-
- this.oRequests = {};
-}
-
-_.extend(AdminAjaxRemoteStorage.prototype, AbstractAjaxRemoteStorage.prototype);
-
-/**
- * @param {?Function} fCallback
- * @param {string} sLogin
- * @param {string} sPassword
- */
-AdminAjaxRemoteStorage.prototype.adminLogin = function (fCallback, sLogin, sPassword)
-{
- this.defaultRequest(fCallback, 'AdminLogin', {
- 'Login': sLogin,
- 'Password': sPassword
- });
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.adminLogout = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminLogout');
-};
-
-/**
- * @param {?Function} fCallback
- * @param {?} oData
- */
-AdminAjaxRemoteStorage.prototype.saveAdminConfig = function (fCallback, oData)
-{
- this.defaultRequest(fCallback, 'AdminSettingsUpdate', oData);
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.domainList = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminDomainList');
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.pluginList = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminPluginList');
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.packagesList = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminPackagesList');
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.coreData = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminCoreData');
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.updateCoreData = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminUpdateCoreData', {}, 90000);
-};
-
-/**
- * @param {?Function} fCallback
- * @param {Object} oPackage
- */
-AdminAjaxRemoteStorage.prototype.packageInstall = function (fCallback, oPackage)
-{
- this.defaultRequest(fCallback, 'AdminPackageInstall', {
- 'Id': oPackage.id,
- 'Type': oPackage.type,
- 'File': oPackage.file
- }, 60000);
-};
-
-/**
- * @param {?Function} fCallback
- * @param {Object} oPackage
- */
-AdminAjaxRemoteStorage.prototype.packageDelete = function (fCallback, oPackage)
-{
- this.defaultRequest(fCallback, 'AdminPackageDelete', {
- 'Id': oPackage.id
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sName
- */
-AdminAjaxRemoteStorage.prototype.domain = function (fCallback, sName)
-{
- this.defaultRequest(fCallback, 'AdminDomainLoad', {
- 'Name': sName
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sName
- */
-AdminAjaxRemoteStorage.prototype.plugin = function (fCallback, sName)
-{
- this.defaultRequest(fCallback, 'AdminPluginLoad', {
- 'Name': sName
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sName
- */
-AdminAjaxRemoteStorage.prototype.domainDelete = function (fCallback, sName)
-{
- this.defaultRequest(fCallback, 'AdminDomainDelete', {
- 'Name': sName
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sName
- * @param {boolean} bDisabled
- */
-AdminAjaxRemoteStorage.prototype.domainDisable = function (fCallback, sName, bDisabled)
-{
- return this.defaultRequest(fCallback, 'AdminDomainDisable', {
- 'Name': sName,
- 'Disabled': !!bDisabled ? '1' : '0'
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {Object} oConfig
- */
-AdminAjaxRemoteStorage.prototype.pluginSettingsUpdate = function (fCallback, oConfig)
-{
- return this.defaultRequest(fCallback, 'AdminPluginSettingsUpdate', oConfig);
-};
-
-/**
- * @param {?Function} fCallback
- * @param {boolean} bForce
- */
-AdminAjaxRemoteStorage.prototype.licensing = function (fCallback, bForce)
-{
- return this.defaultRequest(fCallback, 'AdminLicensing', {
- 'Force' : bForce ? '1' : '0'
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sDomain
- * @param {string} sKey
- */
-AdminAjaxRemoteStorage.prototype.licensingActivate = function (fCallback, sDomain, sKey)
-{
- return this.defaultRequest(fCallback, 'AdminLicensingActivate', {
- 'Domain' : sDomain,
- 'Key' : sKey
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {string} sName
- * @param {boolean} bDisabled
- */
-AdminAjaxRemoteStorage.prototype.pluginDisable = function (fCallback, sName, bDisabled)
-{
- return this.defaultRequest(fCallback, 'AdminPluginDisable', {
- 'Name': sName,
- 'Disabled': !!bDisabled ? '1' : '0'
- });
-};
-
-AdminAjaxRemoteStorage.prototype.createOrUpdateDomain = function (fCallback,
- bCreate, sName, sIncHost, iIncPort, sIncSecure, bIncShortLogin,
- sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, sWhiteList)
-{
- this.defaultRequest(fCallback, 'AdminDomainSave', {
- 'Create': bCreate ? '1' : '0',
- 'Name': sName,
- 'IncHost': sIncHost,
- 'IncPort': iIncPort,
- 'IncSecure': sIncSecure,
- 'IncShortLogin': bIncShortLogin ? '1' : '0',
- 'OutHost': sOutHost,
- 'OutPort': iOutPort,
- 'OutSecure': sOutSecure,
- 'OutShortLogin': bOutShortLogin ? '1' : '0',
- 'OutAuth': bOutAuth ? '1' : '0',
- 'WhiteList': sWhiteList
- });
-};
-
-AdminAjaxRemoteStorage.prototype.testConnectionForDomain = function (fCallback, sName,
- sIncHost, iIncPort, sIncSecure,
- sOutHost, iOutPort, sOutSecure, bOutAuth)
-{
- this.defaultRequest(fCallback, 'AdminDomainTest', {
- 'Name': sName,
- 'IncHost': sIncHost,
- 'IncPort': iIncPort,
- 'IncSecure': sIncSecure,
- 'OutHost': sOutHost,
- 'OutPort': iOutPort,
- 'OutSecure': sOutSecure,
- 'OutAuth': bOutAuth ? '1' : '0'
- });
-};
-
-/**
- * @param {?Function} fCallback
- * @param {?} oData
- */
-AdminAjaxRemoteStorage.prototype.testContacts = function (fCallback, oData)
-{
- this.defaultRequest(fCallback, 'AdminContactsTest', oData);
-};
-
-/**
- * @param {?Function} fCallback
- * @param {?} oData
- */
-AdminAjaxRemoteStorage.prototype.saveNewAdminPassword = function (fCallback, oData)
-{
- this.defaultRequest(fCallback, 'AdminPasswordUpdate', oData);
-};
-
-/**
- * @param {?Function} fCallback
- */
-AdminAjaxRemoteStorage.prototype.adminPing = function (fCallback)
-{
- this.defaultRequest(fCallback, 'AdminPing');
-};
diff --git a/dev/Storages/AdminAjaxRemoteStorage.js b/dev/Storages/AdminAjaxRemoteStorage.js
new file mode 100644
index 000000000..094d9ba6f
--- /dev/null
+++ b/dev/Storages/AdminAjaxRemoteStorage.js
@@ -0,0 +1,275 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ _ = require('./External/underscore.js'),
+ AbstractAjaxRemoteStorage = require('./Storages/AbstractAjaxRemoteStorage.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractAjaxRemoteStorage
+ */
+ function AdminAjaxRemoteStorage()
+ {
+ AbstractAjaxRemoteStorage.call(this);
+
+ this.oRequests = {};
+ }
+
+ _.extend(AdminAjaxRemoteStorage.prototype, AbstractAjaxRemoteStorage.prototype);
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sLogin
+ * @param {string} sPassword
+ */
+ AdminAjaxRemoteStorage.prototype.adminLogin = function (fCallback, sLogin, sPassword)
+ {
+ this.defaultRequest(fCallback, 'AdminLogin', {
+ 'Login': sLogin,
+ 'Password': sPassword
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.adminLogout = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminLogout');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {?} oData
+ */
+ AdminAjaxRemoteStorage.prototype.saveAdminConfig = function (fCallback, oData)
+ {
+ this.defaultRequest(fCallback, 'AdminSettingsUpdate', oData);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.domainList = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminDomainList');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.pluginList = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminPluginList');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.packagesList = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminPackagesList');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.coreData = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminCoreData');
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.updateCoreData = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminUpdateCoreData', {}, 90000);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {Object} oPackage
+ */
+ AdminAjaxRemoteStorage.prototype.packageInstall = function (fCallback, oPackage)
+ {
+ this.defaultRequest(fCallback, 'AdminPackageInstall', {
+ 'Id': oPackage.id,
+ 'Type': oPackage.type,
+ 'File': oPackage.file
+ }, 60000);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {Object} oPackage
+ */
+ AdminAjaxRemoteStorage.prototype.packageDelete = function (fCallback, oPackage)
+ {
+ this.defaultRequest(fCallback, 'AdminPackageDelete', {
+ 'Id': oPackage.id
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sName
+ */
+ AdminAjaxRemoteStorage.prototype.domain = function (fCallback, sName)
+ {
+ this.defaultRequest(fCallback, 'AdminDomainLoad', {
+ 'Name': sName
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sName
+ */
+ AdminAjaxRemoteStorage.prototype.plugin = function (fCallback, sName)
+ {
+ this.defaultRequest(fCallback, 'AdminPluginLoad', {
+ 'Name': sName
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sName
+ */
+ AdminAjaxRemoteStorage.prototype.domainDelete = function (fCallback, sName)
+ {
+ this.defaultRequest(fCallback, 'AdminDomainDelete', {
+ 'Name': sName
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sName
+ * @param {boolean} bDisabled
+ */
+ AdminAjaxRemoteStorage.prototype.domainDisable = function (fCallback, sName, bDisabled)
+ {
+ return this.defaultRequest(fCallback, 'AdminDomainDisable', {
+ 'Name': sName,
+ 'Disabled': !!bDisabled ? '1' : '0'
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {Object} oConfig
+ */
+ AdminAjaxRemoteStorage.prototype.pluginSettingsUpdate = function (fCallback, oConfig)
+ {
+ return this.defaultRequest(fCallback, 'AdminPluginSettingsUpdate', oConfig);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {boolean} bForce
+ */
+ AdminAjaxRemoteStorage.prototype.licensing = function (fCallback, bForce)
+ {
+ return this.defaultRequest(fCallback, 'AdminLicensing', {
+ 'Force' : bForce ? '1' : '0'
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sDomain
+ * @param {string} sKey
+ */
+ AdminAjaxRemoteStorage.prototype.licensingActivate = function (fCallback, sDomain, sKey)
+ {
+ return this.defaultRequest(fCallback, 'AdminLicensingActivate', {
+ 'Domain' : sDomain,
+ 'Key' : sKey
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {string} sName
+ * @param {boolean} bDisabled
+ */
+ AdminAjaxRemoteStorage.prototype.pluginDisable = function (fCallback, sName, bDisabled)
+ {
+ return this.defaultRequest(fCallback, 'AdminPluginDisable', {
+ 'Name': sName,
+ 'Disabled': !!bDisabled ? '1' : '0'
+ });
+ };
+
+ AdminAjaxRemoteStorage.prototype.createOrUpdateDomain = function (fCallback,
+ bCreate, sName, sIncHost, iIncPort, sIncSecure, bIncShortLogin,
+ sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, sWhiteList)
+ {
+ this.defaultRequest(fCallback, 'AdminDomainSave', {
+ 'Create': bCreate ? '1' : '0',
+ 'Name': sName,
+ 'IncHost': sIncHost,
+ 'IncPort': iIncPort,
+ 'IncSecure': sIncSecure,
+ 'IncShortLogin': bIncShortLogin ? '1' : '0',
+ 'OutHost': sOutHost,
+ 'OutPort': iOutPort,
+ 'OutSecure': sOutSecure,
+ 'OutShortLogin': bOutShortLogin ? '1' : '0',
+ 'OutAuth': bOutAuth ? '1' : '0',
+ 'WhiteList': sWhiteList
+ });
+ };
+
+ AdminAjaxRemoteStorage.prototype.testConnectionForDomain = function (fCallback, sName,
+ sIncHost, iIncPort, sIncSecure,
+ sOutHost, iOutPort, sOutSecure, bOutAuth)
+ {
+ this.defaultRequest(fCallback, 'AdminDomainTest', {
+ 'Name': sName,
+ 'IncHost': sIncHost,
+ 'IncPort': iIncPort,
+ 'IncSecure': sIncSecure,
+ 'OutHost': sOutHost,
+ 'OutPort': iOutPort,
+ 'OutSecure': sOutSecure,
+ 'OutAuth': bOutAuth ? '1' : '0'
+ });
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {?} oData
+ */
+ AdminAjaxRemoteStorage.prototype.testContacts = function (fCallback, oData)
+ {
+ this.defaultRequest(fCallback, 'AdminContactsTest', oData);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ * @param {?} oData
+ */
+ AdminAjaxRemoteStorage.prototype.saveNewAdminPassword = function (fCallback, oData)
+ {
+ this.defaultRequest(fCallback, 'AdminPasswordUpdate', oData);
+ };
+
+ /**
+ * @param {?Function} fCallback
+ */
+ AdminAjaxRemoteStorage.prototype.adminPing = function (fCallback)
+ {
+ this.defaultRequest(fCallback, 'AdminPing');
+ };
+
+ module.exports = AdminAjaxRemoteStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/AdminCache.js b/dev/Storages/AdminCache.js
deleted file mode 100644
index 152e99ab7..000000000
--- a/dev/Storages/AdminCache.js
+++ /dev/null
@@ -1,12 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- * @extends AbstractCacheStorage
- */
-function AdminCacheStorage()
-{
- AbstractCacheStorage.call(this);
-}
-
-_.extend(AdminCacheStorage.prototype, AbstractCacheStorage.prototype);
diff --git a/dev/Storages/AdminCacheStorage.js b/dev/Storages/AdminCacheStorage.js
new file mode 100644
index 000000000..c24d74ad3
--- /dev/null
+++ b/dev/Storages/AdminCacheStorage.js
@@ -0,0 +1,25 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ _ = require('./External/underscore.js'),
+ AbstractCacheStorage = require('./Storages/AbstractCacheStorage.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractCacheStorage
+ */
+ function AdminCacheStorage()
+ {
+ AbstractCacheStorage.call(this);
+ }
+
+ _.extend(AdminCacheStorage.prototype, AbstractCacheStorage.prototype);
+
+ module.exports = AdminCacheStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/AdminData.js b/dev/Storages/AdminData.js
deleted file mode 100644
index 6d0cf6126..000000000
--- a/dev/Storages/AdminData.js
+++ /dev/null
@@ -1,53 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- * @extends AbstractData
- */
-function AdminDataStorage()
-{
- AbstractData.call(this);
-
- this.domainsLoading = ko.observable(false).extend({'throttle': 100});
- this.domains = ko.observableArray([]);
-
- this.pluginsLoading = ko.observable(false).extend({'throttle': 100});
- this.plugins = ko.observableArray([]);
-
- this.packagesReal = ko.observable(true);
- this.packagesMainUpdatable = ko.observable(true);
- this.packagesLoading = ko.observable(false).extend({'throttle': 100});
- this.packages = ko.observableArray([]);
-
- this.coreReal = ko.observable(true);
- this.coreUpdatable = ko.observable(true);
- this.coreAccess = ko.observable(true);
- this.coreChecking = ko.observable(false).extend({'throttle': 100});
- this.coreUpdating = ko.observable(false).extend({'throttle': 100});
- this.coreRemoteVersion = ko.observable('');
- this.coreRemoteRelease = ko.observable('');
- this.coreVersionCompare = ko.observable(-2);
-
- this.licensing = ko.observable(false);
- this.licensingProcess = ko.observable(false);
- this.licenseValid = ko.observable(false);
- this.licenseExpired = ko.observable(0);
- this.licenseError = ko.observable('');
-
- this.licenseTrigger = ko.observable(false);
-
- this.adminManLoading = ko.computed(function () {
- return '000' !== [this.domainsLoading() ? '1' : '0', this.pluginsLoading() ? '1' : '0', this.packagesLoading() ? '1' : '0'].join('');
- }, this);
-
- this.adminManLoadingVisibility = ko.computed(function () {
- return this.adminManLoading() ? 'visible' : 'hidden';
- }, this).extend({'rateLimit': 300});
-}
-
-_.extend(AdminDataStorage.prototype, AbstractData.prototype);
-
-AdminDataStorage.prototype.populateDataOnStart = function()
-{
- AbstractData.prototype.populateDataOnStart.call(this);
-};
\ No newline at end of file
diff --git a/dev/Storages/AdminDataStorage.js b/dev/Storages/AdminDataStorage.js
new file mode 100644
index 000000000..e4b1f4a81
--- /dev/null
+++ b/dev/Storages/AdminDataStorage.js
@@ -0,0 +1,67 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ _ = require('./External/underscore.js'),
+ ko = require('./External/ko.js'),
+ AbstractData = require('./Storages/AbstractData.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractData
+ */
+ function AdminDataStorage()
+ {
+ AbstractData.call(this);
+
+ this.domainsLoading = ko.observable(false).extend({'throttle': 100});
+ this.domains = ko.observableArray([]);
+
+ this.pluginsLoading = ko.observable(false).extend({'throttle': 100});
+ this.plugins = ko.observableArray([]);
+
+ this.packagesReal = ko.observable(true);
+ this.packagesMainUpdatable = ko.observable(true);
+ this.packagesLoading = ko.observable(false).extend({'throttle': 100});
+ this.packages = ko.observableArray([]);
+
+ this.coreReal = ko.observable(true);
+ this.coreUpdatable = ko.observable(true);
+ this.coreAccess = ko.observable(true);
+ this.coreChecking = ko.observable(false).extend({'throttle': 100});
+ this.coreUpdating = ko.observable(false).extend({'throttle': 100});
+ this.coreRemoteVersion = ko.observable('');
+ this.coreRemoteRelease = ko.observable('');
+ this.coreVersionCompare = ko.observable(-2);
+
+ this.licensing = ko.observable(false);
+ this.licensingProcess = ko.observable(false);
+ this.licenseValid = ko.observable(false);
+ this.licenseExpired = ko.observable(0);
+ this.licenseError = ko.observable('');
+
+ this.licenseTrigger = ko.observable(false);
+
+ this.adminManLoading = ko.computed(function () {
+ return '000' !== [this.domainsLoading() ? '1' : '0', this.pluginsLoading() ? '1' : '0', this.packagesLoading() ? '1' : '0'].join('');
+ }, this);
+
+ this.adminManLoadingVisibility = ko.computed(function () {
+ return this.adminManLoading() ? 'visible' : 'hidden';
+ }, this).extend({'rateLimit': 300});
+ }
+
+ _.extend(AdminDataStorage.prototype, AbstractData.prototype);
+
+ AdminDataStorage.prototype.populateDataOnStart = function()
+ {
+ AbstractData.prototype.populateDataOnStart.call(this);
+ };
+
+ module.exports = AdminDataStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/LocalStorage.js b/dev/Storages/LocalStorage.js
index 988460812..b78fb8899 100644
--- a/dev/Storages/LocalStorage.js
+++ b/dev/Storages/LocalStorage.js
@@ -1,44 +1,54 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function LocalStorage()
-{
+(function (module) {
+
+ 'use strict';
+
var
- sStorages = [
- LocalStorageDriver,
- CookieDriver
- ],
- NextStorageDriver = _.find(sStorages, function (NextStorageDriver) {
- return NextStorageDriver.supported();
- })
+ _ = require('./External/underscore.js'),
+ CookieDriver = require('./Storages/LocalStorages/CookieDriver.js'),
+ LocalStorageDriver = require('./Storages/LocalStorages/LocalStorageDriver.js')
;
- if (NextStorageDriver)
+ /**
+ * @constructor
+ */
+ function LocalStorage()
{
- NextStorageDriver = /** @type {?Function} */ NextStorageDriver;
- this.oDriver = new NextStorageDriver();
+ var
+ NextStorageDriver = _.find([LocalStorageDriver, CookieDriver], function (NextStorageDriver) {
+ return NextStorageDriver.supported();
+ })
+ ;
+
+ if (NextStorageDriver)
+ {
+ NextStorageDriver = /** @type {?Function} */ NextStorageDriver;
+ this.oDriver = new NextStorageDriver();
+ }
}
-}
-LocalStorage.prototype.oDriver = null;
+ LocalStorage.prototype.oDriver = null;
-/**
- * @param {number} iKey
- * @param {*} mData
- * @return {boolean}
- */
-LocalStorage.prototype.set = function (iKey, mData)
-{
- return this.oDriver ? this.oDriver.set('p' + iKey, mData) : false;
-};
+ /**
+ * @param {number} iKey
+ * @param {*} mData
+ * @return {boolean}
+ */
+ LocalStorage.prototype.set = function (iKey, mData)
+ {
+ return this.oDriver ? this.oDriver.set('p' + iKey, mData) : false;
+ };
-/**
- * @param {number} iKey
- * @return {*}
- */
-LocalStorage.prototype.get = function (iKey)
-{
- return this.oDriver ? this.oDriver.get('p' + iKey) : null;
-};
+ /**
+ * @param {number} iKey
+ * @return {*}
+ */
+ LocalStorage.prototype.get = function (iKey)
+ {
+ return this.oDriver ? this.oDriver.get('p' + iKey) : null;
+ };
+
+ module.exports = LocalStorage;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/LocalStorages/CookieDriver.js b/dev/Storages/LocalStorages/CookieDriver.js
index fb4f46698..5cc4bbf87 100644
--- a/dev/Storages/LocalStorages/CookieDriver.js
+++ b/dev/Storages/LocalStorages/CookieDriver.js
@@ -1,75 +1,90 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function CookieDriver()
-{
+(function (module) {
-}
+ 'use strict';
-CookieDriver.supported = function ()
-{
- return true;
-};
-
-/**
- * @param {string} sKey
- * @param {*} mData
- * @returns {boolean}
- */
-CookieDriver.prototype.set = function (sKey, mData)
-{
var
- mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
- bResult = false,
- mResult = null
+ $ = require('./External/jquery.js'),
+ JSON = require('./External/JSON.js'),
+ Consts = require('./Common/Consts.js'),
+ Utils = require('./Common/Utils.js')
;
- try
+ /**
+ * @constructor
+ */
+ function CookieDriver()
{
- mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
- if (!mResult)
- {
- mResult = {};
- }
- mResult[sKey] = mData;
- $.cookie(Consts.Values.ClientSideCookieIndexName, JSON.stringify(mResult), {
- 'expires': 30
- });
-
- bResult = true;
}
- catch (oException) {}
- return bResult;
-};
-
-/**
- * @param {string} sKey
- * @returns {*}
- */
-CookieDriver.prototype.get = function (sKey)
-{
- var
- mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
- mResult = null
- ;
-
- try
+ CookieDriver.supported = function ()
{
- mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
- if (mResult && !Utils.isUnd(mResult[sKey]))
- {
- mResult = mResult[sKey];
- }
- else
- {
- mResult = null;
- }
- }
- catch (oException) {}
+ return true;
+ };
- return mResult;
-};
+ /**
+ * @param {string} sKey
+ * @param {*} mData
+ * @returns {boolean}
+ */
+ CookieDriver.prototype.set = function (sKey, mData)
+ {
+ var
+ mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
+ bResult = false,
+ mResult = null
+ ;
+
+ try
+ {
+ mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
+ if (!mResult)
+ {
+ mResult = {};
+ }
+
+ mResult[sKey] = mData;
+ $.cookie(Consts.Values.ClientSideCookieIndexName, JSON.stringify(mResult), {
+ 'expires': 30
+ });
+
+ bResult = true;
+ }
+ catch (oException) {}
+
+ return bResult;
+ };
+
+ /**
+ * @param {string} sKey
+ * @returns {*}
+ */
+ CookieDriver.prototype.get = function (sKey)
+ {
+ var
+ mCokieValue = $.cookie(Consts.Values.ClientSideCookieIndexName),
+ mResult = null
+ ;
+
+ try
+ {
+ mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
+ if (mResult && !Utils.isUnd(mResult[sKey]))
+ {
+ mResult = mResult[sKey];
+ }
+ else
+ {
+ mResult = null;
+ }
+ }
+ catch (oException) {}
+
+ return mResult;
+ };
+
+ module.exports = CookieDriver;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/LocalStorages/LocalStorageDriver.js b/dev/Storages/LocalStorages/LocalStorageDriver.js
index e6c26891e..36864d3ca 100644
--- a/dev/Storages/LocalStorages/LocalStorageDriver.js
+++ b/dev/Storages/LocalStorages/LocalStorageDriver.js
@@ -1,72 +1,87 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- */
-function LocalStorageDriver()
-{
-}
+(function (module) {
-LocalStorageDriver.supported = function ()
-{
- return !!window.localStorage;
-};
+ 'use strict';
-/**
- * @param {string} sKey
- * @param {*} mData
- * @returns {boolean}
- */
-LocalStorageDriver.prototype.set = function (sKey, mData)
-{
var
- mCookieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
- bResult = false,
- mResult = null
+ window = require('./External/window.js'),
+ JSON = require('./External/JSON.js'),
+ Consts = require('./Common/Consts.js'),
+ Utils = require('./Common/Utils.js')
;
- try
+ /**
+ * @constructor
+ */
+ function LocalStorageDriver()
{
- mResult = null === mCookieValue ? null : JSON.parse(mCookieValue);
- if (!mResult)
- {
- mResult = {};
- }
-
- mResult[sKey] = mData;
- window.localStorage[Consts.Values.ClientSideCookieIndexName] = JSON.stringify(mResult);
-
- bResult = true;
}
- catch (oException) {}
- return bResult;
-};
-
-/**
- * @param {string} sKey
- * @returns {*}
- */
-LocalStorageDriver.prototype.get = function (sKey)
-{
- var
- mCokieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
- mResult = null
- ;
-
- try
+ LocalStorageDriver.supported = function ()
{
- mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
- if (mResult && !Utils.isUnd(mResult[sKey]))
- {
- mResult = mResult[sKey];
- }
- else
- {
- mResult = null;
- }
- }
- catch (oException) {}
+ return !!window.localStorage;
+ };
- return mResult;
-};
+ /**
+ * @param {string} sKey
+ * @param {*} mData
+ * @returns {boolean}
+ */
+ LocalStorageDriver.prototype.set = function (sKey, mData)
+ {
+ var
+ mCookieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
+ bResult = false,
+ mResult = null
+ ;
+
+ try
+ {
+ mResult = null === mCookieValue ? null : JSON.parse(mCookieValue);
+ if (!mResult)
+ {
+ mResult = {};
+ }
+
+ mResult[sKey] = mData;
+ window.localStorage[Consts.Values.ClientSideCookieIndexName] = JSON.stringify(mResult);
+
+ bResult = true;
+ }
+ catch (oException) {}
+
+ return bResult;
+ };
+
+ /**
+ * @param {string} sKey
+ * @returns {*}
+ */
+ LocalStorageDriver.prototype.get = function (sKey)
+ {
+ var
+ mCokieValue = window.localStorage[Consts.Values.ClientSideCookieIndexName] || null,
+ mResult = null
+ ;
+
+ try
+ {
+ mResult = null === mCokieValue ? null : JSON.parse(mCokieValue);
+ if (mResult && !Utils.isUnd(mResult[sKey]))
+ {
+ mResult = mResult[sKey];
+ }
+ else
+ {
+ mResult = null;
+ }
+ }
+ catch (oException) {}
+
+ return mResult;
+ };
+
+ module.exports = LocalStorageDriver;
+
+}(module));
\ No newline at end of file
diff --git a/dev/Storages/WebMailAjaxRemote.js b/dev/Storages/WebMailAjaxRemoteStorage.js
similarity index 100%
rename from dev/Storages/WebMailAjaxRemote.js
rename to dev/Storages/WebMailAjaxRemoteStorage.js
diff --git a/dev/Storages/WebMailCache.js b/dev/Storages/WebMailCacheStorage.js
similarity index 100%
rename from dev/Storages/WebMailCache.js
rename to dev/Storages/WebMailCacheStorage.js
diff --git a/dev/Storages/WebMailData.js b/dev/Storages/WebMailData.js
deleted file mode 100644
index c9b440585..000000000
--- a/dev/Storages/WebMailData.js
+++ /dev/null
@@ -1,1259 +0,0 @@
-/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-
-/**
- * @constructor
- * @extends AbstractData
- */
-function WebMailDataStorage()
-{
- AbstractData.call(this);
-
- var
- fRemoveSystemFolderType = function (observable) {
- return function () {
- var oFolder = RL.cache().getFolderFromCacheList(observable());
- if (oFolder)
- {
- oFolder.type(Enums.FolderType.User);
- }
- };
- },
- fSetSystemFolderType = function (iType) {
- return function (sValue) {
- var oFolder = RL.cache().getFolderFromCacheList(sValue);
- if (oFolder)
- {
- oFolder.type(iType);
- }
- };
- }
- ;
-
- this.devEmail = '';
- this.devPassword = '';
-
- this.accountEmail = ko.observable('');
- this.accountIncLogin = ko.observable('');
- this.accountOutLogin = ko.observable('');
- this.projectHash = ko.observable('');
- this.threading = ko.observable(false);
-
- this.lastFoldersHash = '';
- this.remoteSuggestions = false;
-
- // system folders
- this.sentFolder = ko.observable('');
- this.draftFolder = ko.observable('');
- this.spamFolder = ko.observable('');
- this.trashFolder = ko.observable('');
- this.archiveFolder = ko.observable('');
-
- this.sentFolder.subscribe(fRemoveSystemFolderType(this.sentFolder), this, 'beforeChange');
- this.draftFolder.subscribe(fRemoveSystemFolderType(this.draftFolder), this, 'beforeChange');
- this.spamFolder.subscribe(fRemoveSystemFolderType(this.spamFolder), this, 'beforeChange');
- this.trashFolder.subscribe(fRemoveSystemFolderType(this.trashFolder), this, 'beforeChange');
- this.archiveFolder.subscribe(fRemoveSystemFolderType(this.archiveFolder), this, 'beforeChange');
-
- this.sentFolder.subscribe(fSetSystemFolderType(Enums.FolderType.SentItems), this);
- this.draftFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Draft), this);
- this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
- this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
- this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this);
-
- this.draftFolderNotEnabled = ko.computed(function () {
- return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
- }, this);
-
- // personal
- this.displayName = ko.observable('');
- this.signature = ko.observable('');
- this.signatureToAll = ko.observable(false);
- this.replyTo = ko.observable('');
-
- // security
- this.enableTwoFactor = ko.observable(false);
-
- // accounts
- this.accounts = ko.observableArray([]);
- this.accountsLoading = ko.observable(false).extend({'throttle': 100});
-
- // identities
- this.defaultIdentityID = ko.observable('');
- this.identities = ko.observableArray([]);
- this.identitiesLoading = ko.observable(false).extend({'throttle': 100});
-
- // contacts
- this.contactTags = ko.observableArray([]);
- this.contacts = ko.observableArray([]);
- this.contacts.loading = ko.observable(false).extend({'throttle': 200});
- this.contacts.importing = ko.observable(false).extend({'throttle': 200});
- this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
- this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
- this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
-
- this.allowContactsSync = ko.observable(false);
- this.enableContactsSync = ko.observable(false);
- this.contactsSyncUrl = ko.observable('');
- this.contactsSyncUser = ko.observable('');
- this.contactsSyncPass = ko.observable('');
-
- this.allowContactsSync = ko.observable(!!RL.settingsGet('ContactsSyncIsAllowed'));
- this.enableContactsSync = ko.observable(!!RL.settingsGet('EnableContactsSync'));
- this.contactsSyncUrl = ko.observable(RL.settingsGet('ContactsSyncUrl'));
- this.contactsSyncUser = ko.observable(RL.settingsGet('ContactsSyncUser'));
- this.contactsSyncPass = ko.observable(RL.settingsGet('ContactsSyncPassword'));
-
- // folders
- this.namespace = '';
- this.folderList = ko.observableArray([]);
- this.folderList.focused = ko.observable(false);
-
- this.foldersListError = ko.observable('');
-
- this.foldersLoading = ko.observable(false);
- this.foldersCreating = ko.observable(false);
- this.foldersDeleting = ko.observable(false);
- this.foldersRenaming = ko.observable(false);
-
- this.foldersChanging = ko.computed(function () {
- var
- bLoading = this.foldersLoading(),
- bCreating = this.foldersCreating(),
- bDeleting = this.foldersDeleting(),
- bRenaming = this.foldersRenaming()
- ;
- return bLoading || bCreating || bDeleting || bRenaming;
- }, this);
-
- this.foldersInboxUnreadCount = ko.observable(0);
-
- this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
- function (oPrev) {
- if (oPrev)
- {
- oPrev.selected(false);
- }
- }, function (oNext) {
- if (oNext)
- {
- oNext.selected(true);
- }
- }
- ]});
-
- this.currentFolderFullNameRaw = ko.computed(function () {
- return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
- }, this);
-
- this.currentFolderFullName = ko.computed(function () {
- return this.currentFolder() ? this.currentFolder().fullName : '';
- }, this);
-
- this.currentFolderFullNameHash = ko.computed(function () {
- return this.currentFolder() ? this.currentFolder().fullNameHash : '';
- }, this);
-
- this.currentFolderName = ko.computed(function () {
- return this.currentFolder() ? this.currentFolder().name() : '';
- }, this);
-
- this.folderListSystemNames = ko.computed(function () {
-
- var
- aList = ['INBOX'],
- aFolders = this.folderList(),
- sSentFolder = this.sentFolder(),
- sDraftFolder = this.draftFolder(),
- sSpamFolder = this.spamFolder(),
- sTrashFolder = this.trashFolder(),
- sArchiveFolder = this.archiveFolder()
- ;
-
- if (Utils.isArray(aFolders) && 0 < aFolders.length)
- {
- if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
- {
- aList.push(sSentFolder);
- }
- if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
- {
- aList.push(sDraftFolder);
- }
- if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
- {
- aList.push(sSpamFolder);
- }
- if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
- {
- aList.push(sTrashFolder);
- }
- if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
- {
- aList.push(sArchiveFolder);
- }
- }
-
- return aList;
-
- }, this);
-
- this.folderListSystem = ko.computed(function () {
- return _.compact(_.map(this.folderListSystemNames(), function (sName) {
- return RL.cache().getFolderFromCacheList(sName);
- }));
- }, this);
-
- this.folderMenuForMove = ko.computed(function () {
- return RL.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [
- this.currentFolderFullNameRaw()
- ], null, null, null, null, function (oItem) {
- return oItem ? oItem.localName() : '';
- });
- }, this);
-
- // message list
- this.staticMessageList = [];
-
- this.messageList = ko.observableArray([]).extend({'rateLimit': 0});
-
- this.messageListCount = ko.observable(0);
- this.messageListSearch = ko.observable('');
- this.messageListPage = ko.observable(1);
-
- this.messageListThreadFolder = ko.observable('');
- this.messageListThreadUids = ko.observableArray([]);
-
- this.messageListThreadFolder.subscribe(function () {
- this.messageListThreadUids([]);
- }, this);
-
- this.messageListEndFolder = ko.observable('');
- this.messageListEndSearch = ko.observable('');
- this.messageListEndPage = ko.observable(1);
-
- this.messageListEndHash = ko.computed(function () {
- return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage();
- }, this);
-
- this.messageListPageCount = ko.computed(function () {
- var iPage = Math.ceil(this.messageListCount() / this.messagesPerPage());
- return 0 >= iPage ? 1 : iPage;
- }, this);
-
- this.mainMessageListSearch = ko.computed({
- 'read': this.messageListSearch,
- 'write': function (sValue) {
- kn.setHash(RL.link().mailBox(
- this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
- ));
- },
- 'owner': this
- });
-
- this.messageListError = ko.observable('');
-
- this.messageListLoading = ko.observable(false);
- this.messageListIsNotCompleted = ko.observable(false);
- this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
-
- this.messageListCompleteLoading = ko.computed(function () {
- var
- bOne = this.messageListLoading(),
- bTwo = this.messageListIsNotCompleted()
- ;
- return bOne || bTwo;
- }, this);
-
- this.messageListCompleteLoading.subscribe(function (bValue) {
- this.messageListCompleteLoadingThrottle(bValue);
- }, this);
-
- this.messageList.subscribe(_.debounce(function (aList) {
- _.each(aList, function (oItem) {
- if (oItem.newForAnimation())
- {
- oItem.newForAnimation(false);
- }
- });
- }, 500));
-
- // message preview
- this.staticMessageList = new MessageModel();
- this.message = ko.observable(null);
- this.messageLoading = ko.observable(false);
- this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
-
- this.message.focused = ko.observable(false);
-
- this.message.subscribe(function (oMessage) {
- if (!oMessage)
- {
- this.message.focused(false);
- this.messageFullScreenMode(false);
- this.hideMessageBodies();
-
- if (Enums.Layout.NoPreview === RL.data().layout() &&
- -1 < window.location.hash.indexOf('message-preview'))
- {
- RL.historyBack();
- }
- }
- else if (Enums.Layout.NoPreview === this.layout())
- {
- this.message.focused(true);
- }
- }, this);
-
- this.message.focused.subscribe(function (bValue) {
- if (bValue)
- {
- this.folderList.focused(false);
- this.keyScope(Enums.KeyState.MessageView);
- }
- else if (Enums.KeyState.MessageView === RL.data().keyScope())
- {
- if (Enums.Layout.NoPreview === RL.data().layout() && this.message())
- {
- this.keyScope(Enums.KeyState.MessageView);
- }
- else
- {
- this.keyScope(Enums.KeyState.MessageList);
- }
- }
- }, this);
-
- this.folderList.focused.subscribe(function (bValue) {
- if (bValue)
- {
- RL.data().keyScope(Enums.KeyState.FolderList);
- }
- else if (Enums.KeyState.FolderList === RL.data().keyScope())
- {
- RL.data().keyScope(Enums.KeyState.MessageList);
- }
- });
-
- this.messageLoading.subscribe(function (bValue) {
- this.messageLoadingThrottle(bValue);
- }, this);
-
- this.messageFullScreenMode = ko.observable(false);
-
- this.messageError = ko.observable('');
-
- this.messagesBodiesDom = ko.observable(null);
-
- this.messagesBodiesDom.subscribe(function (oDom) {
- if (oDom && !(oDom instanceof jQuery))
- {
- this.messagesBodiesDom($(oDom));
- }
- }, this);
-
- this.messageActiveDom = ko.observable(null);
-
- this.isMessageSelected = ko.computed(function () {
- return null !== this.message();
- }, this);
-
- this.currentMessage = ko.observable(null);
-
- this.messageListChecked = ko.computed(function () {
- return _.filter(this.messageList(), function (oItem) {
- return oItem.checked();
- });
- }, this).extend({'rateLimit': 0});
-
- this.hasCheckedMessages = ko.computed(function () {
- return 0 < this.messageListChecked().length;
- }, this).extend({'rateLimit': 0});
-
- this.messageListCheckedOrSelected = ko.computed(function () {
-
- var
- aChecked = this.messageListChecked(),
- oSelectedMessage = this.currentMessage()
- ;
-
- return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
-
- }, this);
-
- this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
- var aList = [];
- _.each(this.messageListCheckedOrSelected(), function (oMessage) {
- if (oMessage)
- {
- aList.push(oMessage.uid);
- if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
- {
- aList = _.union(aList, oMessage.threads());
- }
- }
- });
- return aList;
- }, this);
-
- // quota
- this.userQuota = ko.observable(0);
- this.userUsageSize = ko.observable(0);
- this.userUsageProc = ko.computed(function () {
-
- var
- iQuota = this.userQuota(),
- iUsed = this.userUsageSize()
- ;
-
- return 0 < iQuota ? Math.ceil((iUsed / iQuota) * 100) : 0;
-
- }, this);
-
- // other
- this.capaOpenPGP = ko.observable(false);
- this.openpgpkeys = ko.observableArray([]);
- this.openpgpKeyring = null;
-
- this.openpgpkeysPublic = this.openpgpkeys.filter(function (oItem) {
- return !!(oItem && !oItem.isPrivate);
- });
-
- this.openpgpkeysPrivate = this.openpgpkeys.filter(function (oItem) {
- return !!(oItem && oItem.isPrivate);
- });
-
- // google
- this.googleActions = ko.observable(false);
- this.googleLoggined = ko.observable(false);
- this.googleUserName = ko.observable('');
-
- // facebook
- this.facebookActions = ko.observable(false);
- this.facebookLoggined = ko.observable(false);
- this.facebookUserName = ko.observable('');
-
- // twitter
- this.twitterActions = ko.observable(false);
- this.twitterLoggined = ko.observable(false);
- this.twitterUserName = ko.observable('');
-
- this.customThemeType = ko.observable(Enums.CustomThemeType.Light);
-
- this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
-}
-
-_.extend(WebMailDataStorage.prototype, AbstractData.prototype);
-
-WebMailDataStorage.prototype.purgeMessageBodyCache = function()
-{
- var
- iCount = 0,
- oMessagesBodiesDom = null,
- iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
- ;
-
- if (0 < iEnd)
- {
- oMessagesBodiesDom = this.messagesBodiesDom();
- if (oMessagesBodiesDom)
- {
- oMessagesBodiesDom.find('.rl-cache-class').each(function () {
- var oItem = $(this);
- if (iEnd > oItem.data('rl-cache-count'))
- {
- oItem.addClass('rl-cache-purge');
- iCount++;
- }
- });
-
- if (0 < iCount)
- {
- _.delay(function () {
- oMessagesBodiesDom.find('.rl-cache-purge').remove();
- }, 300);
- }
- }
- }
-};
-
-WebMailDataStorage.prototype.populateDataOnStart = function()
-{
- AbstractData.prototype.populateDataOnStart.call(this);
-
- this.accountEmail(RL.settingsGet('Email'));
- this.accountIncLogin(RL.settingsGet('IncLogin'));
- this.accountOutLogin(RL.settingsGet('OutLogin'));
- this.projectHash(RL.settingsGet('ProjectHash'));
-
- this.defaultIdentityID(RL.settingsGet('DefaultIdentityID'));
-
- this.displayName(RL.settingsGet('DisplayName'));
- this.replyTo(RL.settingsGet('ReplyTo'));
- this.signature(RL.settingsGet('Signature'));
- this.signatureToAll(!!RL.settingsGet('SignatureToAll'));
- this.enableTwoFactor(!!RL.settingsGet('EnableTwoFactor'));
-
- this.lastFoldersHash = RL.local().get(Enums.ClientSideKeyName.FoldersLashHash) || '';
-
- this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');
-
- this.devEmail = RL.settingsGet('DevEmail');
- this.devPassword = RL.settingsGet('DevPassword');
-};
-
-WebMailDataStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
-{
- if ('INBOX' === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
- {
- if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
- {
- var
- oCache = RL.cache(),
- iIndex = 0,
- iLen = aNewMessages.length,
- fNotificationHelper = function (sImageSrc, sTitle, sText)
- {
- var oNotification = null;
- if (NotificationClass && RL.data().useDesktopNotifications())
- {
- oNotification = new NotificationClass(sTitle, {
- 'body': sText,
- 'icon': sImageSrc
- });
-
- if (oNotification)
- {
- if (oNotification.show)
- {
- oNotification.show();
- }
-
- window.setTimeout((function (oLocalNotifications) {
- return function () {
- if (oLocalNotifications.cancel)
- {
- oLocalNotifications.cancel();
- }
- else if (oLocalNotifications.close)
- {
- oLocalNotifications.close();
- }
- };
- }(oNotification)), 7000);
- }
- }
- }
- ;
-
- _.each(aNewMessages, function (oItem) {
- oCache.addNewMessageCache(sFolder, oItem.Uid);
- });
-
- if (3 < iLen)
- {
- fNotificationHelper(
- RL.link().notificationMailIcon(),
- RL.data().accountEmail(),
- Utils.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
- 'COUNT': iLen
- })
- );
- }
- else
- {
- for (; iIndex < iLen; iIndex++)
- {
- fNotificationHelper(
- RL.link().notificationMailIcon(),
- MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),
- aNewMessages[iIndex].Subject
- );
- }
- }
- }
-
- RL.cache().setFolderUidNext(sFolder, sUidNext);
- }
-};
-
-/**
- * @param {string} sNamespace
- * @param {Array} aFolders
- * @return {Array}
- */
-WebMailDataStorage.prototype.folderResponseParseRec = function (sNamespace, aFolders)
-{
- var
- iIndex = 0,
- iLen = 0,
- oFolder = null,
- oCacheFolder = null,
- sFolderFullNameRaw = '',
- aSubFolders = [],
- aList = []
- ;
-
- for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
- {
- oFolder = aFolders[iIndex];
- if (oFolder)
- {
- sFolderFullNameRaw = oFolder.FullNameRaw;
-
- oCacheFolder = RL.cache().getFolderFromCacheList(sFolderFullNameRaw);
- if (!oCacheFolder)
- {
- oCacheFolder = FolderModel.newInstanceFromJson(oFolder);
- if (oCacheFolder)
- {
- RL.cache().setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);
- RL.cache().setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw);
- }
- }
-
- if (oCacheFolder)
- {
- oCacheFolder.collapsed(!Utils.isFolderExpanded(oCacheFolder.fullNameHash));
-
- if (oFolder.Extended)
- {
- if (oFolder.Extended.Hash)
- {
- RL.cache().setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash);
- }
-
- if (Utils.isNormal(oFolder.Extended.MessageCount))
- {
- oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
- }
-
- if (Utils.isNormal(oFolder.Extended.MessageUnseenCount))
- {
- oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
- }
- }
-
- aSubFolders = oFolder['SubFolders'];
- if (aSubFolders && 'Collection/FolderCollection' === aSubFolders['@Object'] &&
- aSubFolders['@Collection'] && Utils.isArray(aSubFolders['@Collection']))
- {
- oCacheFolder.subFolders(
- this.folderResponseParseRec(sNamespace, aSubFolders['@Collection']));
- }
-
- aList.push(oCacheFolder);
- }
- }
- }
-
- return aList;
-};
-
-/**
- * @param {*} oData
- */
-WebMailDataStorage.prototype.setFolders = function (oData)
-{
- var
- aList = [],
- bUpdate = false,
- oRLData = RL.data(),
- fNormalizeFolder = function (sFolderFullNameRaw) {
- return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
- null !== RL.cache().getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';
- }
- ;
-
- if (oData && oData.Result && 'Collection/FolderCollection' === oData.Result['@Object'] &&
- oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
- {
- if (!Utils.isUnd(oData.Result.Namespace))
- {
- oRLData.namespace = oData.Result.Namespace;
- }
-
- this.threading(!!RL.settingsGet('UseImapThread') && oData.Result.IsThreadsSupported && true);
-
- aList = this.folderResponseParseRec(oRLData.namespace, oData.Result['@Collection']);
- oRLData.folderList(aList);
-
- if (oData.Result['SystemFolders'] &&
- '' === '' + RL.settingsGet('SentFolder') + RL.settingsGet('DraftFolder') +
- RL.settingsGet('SpamFolder') + RL.settingsGet('TrashFolder') + RL.settingsGet('ArchiveFolder') +
- RL.settingsGet('NullFolder'))
- {
- // TODO Magic Numbers
- RL.settingsSet('SentFolder', oData.Result['SystemFolders'][2] || null);
- RL.settingsSet('DraftFolder', oData.Result['SystemFolders'][3] || null);
- RL.settingsSet('SpamFolder', oData.Result['SystemFolders'][4] || null);
- RL.settingsSet('TrashFolder', oData.Result['SystemFolders'][5] || null);
- RL.settingsSet('ArchiveFolder', oData.Result['SystemFolders'][12] || null);
-
- bUpdate = true;
- }
-
- oRLData.sentFolder(fNormalizeFolder(RL.settingsGet('SentFolder')));
- oRLData.draftFolder(fNormalizeFolder(RL.settingsGet('DraftFolder')));
- oRLData.spamFolder(fNormalizeFolder(RL.settingsGet('SpamFolder')));
- oRLData.trashFolder(fNormalizeFolder(RL.settingsGet('TrashFolder')));
- oRLData.archiveFolder(fNormalizeFolder(RL.settingsGet('ArchiveFolder')));
-
- if (bUpdate)
- {
- RL.remote().saveSystemFolders(Utils.emptyFunction, {
- 'SentFolder': oRLData.sentFolder(),
- 'DraftFolder': oRLData.draftFolder(),
- 'SpamFolder': oRLData.spamFolder(),
- 'TrashFolder': oRLData.trashFolder(),
- 'ArchiveFolder': oRLData.archiveFolder(),
- 'NullFolder': 'NullFolder'
- });
- }
-
- RL.local().set(Enums.ClientSideKeyName.FoldersLashHash, oData.Result.FoldersHash);
- }
-};
-
-WebMailDataStorage.prototype.hideMessageBodies = function ()
-{
- var oMessagesBodiesDom = this.messagesBodiesDom();
- if (oMessagesBodiesDom)
- {
- oMessagesBodiesDom.find('.b-text-part').hide();
- }
-};
-
-/**
- * @param {boolean=} bBoot = false
- * @returns {Array}
- */
-WebMailDataStorage.prototype.getNextFolderNames = function (bBoot)
-{
- bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;
-
- var
- aResult = [],
- iLimit = 10,
- iUtc = moment().unix(),
- iTimeout = iUtc - 60 * 5,
- aTimeouts = [],
- fSearchFunction = function (aList) {
- _.each(aList, function (oFolder) {
- if (oFolder && 'INBOX' !== oFolder.fullNameRaw &&
- oFolder.selectable && oFolder.existen &&
- iTimeout > oFolder.interval &&
- (!bBoot || oFolder.subScribed()))
- {
- aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]);
- }
-
- if (oFolder && 0 < oFolder.subFolders().length)
- {
- fSearchFunction(oFolder.subFolders());
- }
- });
- }
- ;
-
- fSearchFunction(this.folderList());
-
- aTimeouts.sort(function(a, b) {
- if (a[0] < b[0])
- {
- return -1;
- }
- else if (a[0] > b[0])
- {
- return 1;
- }
-
- return 0;
- });
-
- _.find(aTimeouts, function (aItem) {
- var oFolder = RL.cache().getFolderFromCacheList(aItem[1]);
- if (oFolder)
- {
- oFolder.interval = iUtc;
- aResult.push(aItem[1]);
- }
-
- return iLimit <= aResult.length;
- });
-
- return _.uniq(aResult);
-};
-
-/**
- * @param {string} sFromFolderFullNameRaw
- * @param {Array} aUidForRemove
- * @param {string=} sToFolderFullNameRaw = ''
- * @param {bCopy=} bCopy = false
- */
-WebMailDataStorage.prototype.removeMessagesFromList = function (
- sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
-{
- sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
- bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;
-
- aUidForRemove = _.map(aUidForRemove, function (mValue) {
- return Utils.pInt(mValue);
- });
-
- var
- iUnseenCount = 0,
- oData = RL.data(),
- oCache = RL.cache(),
- aMessageList = oData.messageList(),
- oFromFolder = RL.cache().getFolderFromCacheList(sFromFolderFullNameRaw),
- oToFolder = '' === sToFolderFullNameRaw ? null : oCache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
- sCurrentFolderFullNameRaw = oData.currentFolderFullNameRaw(),
- oCurrentMessage = oData.message(),
- aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) {
- return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove);
- }) : []
- ;
-
- _.each(aMessages, function (oMessage) {
- if (oMessage && oMessage.unseen())
- {
- iUnseenCount++;
- }
- });
-
- if (oFromFolder && !bCopy)
- {
- oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
- oFromFolder.messageCountAll() - aUidForRemove.length : 0);
-
- if (0 < iUnseenCount)
- {
- oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
- oFromFolder.messageCountUnread() - iUnseenCount : 0);
- }
- }
-
- if (oToFolder)
- {
- oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
- if (0 < iUnseenCount)
- {
- oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
- }
-
- oToFolder.actionBlink(true);
- }
-
- if (0 < aMessages.length)
- {
- if (bCopy)
- {
- _.each(aMessages, function (oMessage) {
- oMessage.checked(false);
- });
- }
- else
- {
- oData.messageListIsNotCompleted(true);
-
- _.each(aMessages, function (oMessage) {
- if (oCurrentMessage && oCurrentMessage.hash === oMessage.hash)
- {
- oCurrentMessage = null;
- oData.message(null);
- }
-
- oMessage.deleted(true);
- });
-
- _.delay(function () {
- _.each(aMessages, function (oMessage) {
- oData.messageList.remove(oMessage);
- });
- }, 400);
- }
- }
-
- if ('' !== sFromFolderFullNameRaw)
- {
- oCache.setFolderHash(sFromFolderFullNameRaw, '');
- }
-
- if ('' !== sToFolderFullNameRaw)
- {
- oCache.setFolderHash(sToFolderFullNameRaw, '');
- }
-};
-
-WebMailDataStorage.prototype.setMessage = function (oData, bCached)
-{
- var
- bIsHtml = false,
- bHasExternals = false,
- bHasInternals = false,
- oBody = null,
- oTextBody = null,
- sId = '',
- sResultHtml = '',
- bPgpSigned = false,
- bPgpEncrypted = false,
- oMessagesBodiesDom = this.messagesBodiesDom(),
- oMessage = this.message()
- ;
-
- if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
- oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
- {
- this.messageError('');
-
- oMessage.initUpdateByMessageJson(oData.Result);
- RL.cache().addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);
-
- if (!bCached)
- {
- oMessage.initFlagsByJson(oData.Result);
- }
-
- oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
- if (oMessagesBodiesDom)
- {
- sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
- oTextBody = oMessagesBodiesDom.find('#' + sId);
- if (!oTextBody || !oTextBody[0])
- {
- bHasExternals = !!oData.Result.HasExternals;
- bHasInternals = !!oData.Result.HasInternals;
-
- oBody = $('').hide().addClass('rl-cache-class');
- oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
-
- if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
- {
- bIsHtml = true;
- sResultHtml = oData.Result.Html.toString();
- }
- else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
- {
- bIsHtml = false;
- sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false);
-
- if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && RL.data().capaOpenPGP())
- {
- oMessage.plainRaw = Utils.pString(oData.Result.Plain);
-
- bPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(oMessage.plainRaw);
- if (!bPgpEncrypted)
- {
- bPgpSigned = /-----BEGIN PGP SIGNED MESSAGE-----/.test(oMessage.plainRaw) &&
- /-----BEGIN PGP SIGNATURE-----/.test(oMessage.plainRaw);
- }
-
- $proxyDiv.empty();
- if (bPgpSigned && oMessage.isPgpSigned())
- {
- sResultHtml =
- $proxyDiv.append(
- $('').text(oMessage.plainRaw)
- ).html()
- ;
- }
- else if (bPgpEncrypted && oMessage.isPgpEncrypted())
- {
- sResultHtml =
- $proxyDiv.append(
- $('').text(oMessage.plainRaw)
- ).html()
- ;
- }
-
- $proxyDiv.empty();
-
- oMessage.isPgpSigned(bPgpSigned);
- oMessage.isPgpEncrypted(bPgpEncrypted);
- }
- }
- else
- {
- bIsHtml = false;
- }
-
- oBody
- .html(Utils.linkify(sResultHtml))
- .addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'))
- ;
-
- oMessage.isHtml(!!bIsHtml);
- oMessage.hasImages(!!bHasExternals);
- oMessage.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
- oMessage.pgpSignedVerifyUser('');
-
- oMessage.body = oBody;
- if (oMessage.body)
- {
- oMessagesBodiesDom.append(oMessage.body);
- }
-
- oMessage.storeDataToDom();
-
- if (bHasInternals)
- {
- oMessage.showInternalImages(true);
- }
-
- if (oMessage.hasImages() && this.showImages())
- {
- oMessage.showExternalImages(true);
- }
-
- this.purgeMessageBodyCacheThrottle();
- }
- else
- {
- oMessage.body = oTextBody;
- if (oMessage.body)
- {
- oMessage.body.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
- oMessage.fetchDataToDom();
- }
- }
-
- this.messageActiveDom(oMessage.body);
-
- this.hideMessageBodies();
- oMessage.body.show();
-
- if (oBody)
- {
- Utils.initBlockquoteSwitcher(oBody);
- }
- }
-
- RL.cache().initMessageFlagsFromCache(oMessage);
- if (oMessage.unseen())
- {
- RL.setMessageSeen(oMessage);
- }
-
- Utils.windowResize();
- }
-};
-
-/**
- * @param {Array} aList
- * @returns {string}
- */
-WebMailDataStorage.prototype.calculateMessageListHash = function (aList)
-{
- return _.map(aList, function (oMessage) {
- return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
- }).join('|');
-};
-
-WebMailDataStorage.prototype.setMessageList = function (oData, bCached)
-{
- if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
- oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
- {
- var
- oRainLoopData = RL.data(),
- oCache = RL.cache(),
- mLastCollapsedThreadUids = null,
- iIndex = 0,
- iLen = 0,
- iCount = 0,
- iOffset = 0,
- aList = [],
- iUtc = moment().unix(),
- aStaticList = oRainLoopData.staticMessageList,
- oJsonMessage = null,
- oMessage = null,
- oFolder = null,
- iNewCount = 0,
- bUnreadCountChange = false
- ;
-
- iCount = Utils.pInt(oData.Result.MessageResultCount);
- iOffset = Utils.pInt(oData.Result.Offset);
-
- if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
- {
- mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
- }
-
- oFolder = RL.cache().getFolderFromCacheList(
- Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
-
- if (oFolder && !bCached)
- {
- oFolder.interval = iUtc;
-
- RL.cache().setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
-
- if (Utils.isNormal(oData.Result.MessageCount))
- {
- oFolder.messageCountAll(oData.Result.MessageCount);
- }
-
- if (Utils.isNormal(oData.Result.MessageUnseenCount))
- {
- if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
- {
- bUnreadCountChange = true;
- }
-
- oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
- }
-
- this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
- }
-
- if (bUnreadCountChange && oFolder)
- {
- RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
- }
-
- for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
- {
- oJsonMessage = oData.Result['@Collection'][iIndex];
- if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
- {
- oMessage = aStaticList[iIndex];
- if (!oMessage || !oMessage.initByJson(oJsonMessage))
- {
- oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
- }
-
- if (oMessage)
- {
- if (oCache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
- {
- iNewCount++;
- oMessage.newForAnimation(true);
- }
-
- oMessage.deleted(false);
-
- if (bCached)
- {
- RL.cache().initMessageFlagsFromCache(oMessage);
- }
- else
- {
- RL.cache().storeMessageFlagsToCache(oMessage);
- }
-
- oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);
-
- aList.push(oMessage);
- }
- }
- }
-
- oRainLoopData.messageListCount(iCount);
- oRainLoopData.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
- oRainLoopData.messageListPage(Math.ceil((iOffset / oRainLoopData.messagesPerPage()) + 1));
- oRainLoopData.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
- oRainLoopData.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
- oRainLoopData.messageListEndPage(oRainLoopData.messageListPage());
-
- oRainLoopData.messageList(aList);
- oRainLoopData.messageListIsNotCompleted(false);
-
- if (aStaticList.length < aList.length)
- {
- oRainLoopData.staticMessageList = aList;
- }
-
- oCache.clearNewMessageCache();
-
- if (oFolder && (bCached || bUnreadCountChange || RL.data().useThreads()))
- {
- RL.folderInformation(oFolder.fullNameRaw, aList);
- }
- }
- else
- {
- RL.data().messageListCount(0);
- RL.data().messageList([]);
- RL.data().messageListError(Utils.getNotification(
- oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
- ));
- }
-};
-
-WebMailDataStorage.prototype.findPublicKeyByHex = function (sHash)
-{
- return _.find(this.openpgpkeysPublic(), function (oItem) {
- return oItem && sHash === oItem.id;
- });
-};
-
-WebMailDataStorage.prototype.findPublicKeysByEmail = function (sEmail)
-{
- return _.compact(_.map(this.openpgpkeysPublic(), function (oItem) {
-
- var oKey = null;
- if (oItem && sEmail === oItem.email)
- {
- try
- {
- oKey = window.openpgp.key.readArmored(oItem.armor);
- if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
- {
- return oKey.keys[0];
- }
- }
- catch (e) {}
- }
-
- return null;
-
- }));
-};
-
-/**
- * @param {string} sEmail
- * @param {string=} sPassword
- * @returns {?}
- */
-WebMailDataStorage.prototype.findPrivateKeyByEmail = function (sEmail, sPassword)
-{
- var
- oPrivateKey = null,
- oKey = _.find(this.openpgpkeysPrivate(), function (oItem) {
- return oItem && sEmail === oItem.email;
- })
- ;
-
- if (oKey)
- {
- try
- {
- oPrivateKey = window.openpgp.key.readArmored(oKey.armor);
- if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0])
- {
- oPrivateKey = oPrivateKey.keys[0];
- oPrivateKey.decrypt(Utils.pString(sPassword));
- }
- else
- {
- oPrivateKey = null;
- }
- }
- catch (e)
- {
- oPrivateKey = null;
- }
- }
-
- return oPrivateKey;
-};
-
-/**
- * @param {string=} sPassword
- * @returns {?}
- */
-WebMailDataStorage.prototype.findSelfPrivateKey = function (sPassword)
-{
- return this.findPrivateKeyByEmail(this.accountEmail(), sPassword);
-};
diff --git a/dev/Storages/WebMailDataStorage.js b/dev/Storages/WebMailDataStorage.js
new file mode 100644
index 000000000..a6ed96345
--- /dev/null
+++ b/dev/Storages/WebMailDataStorage.js
@@ -0,0 +1,1287 @@
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ window = require('./External/window.js'),
+ $ = require('./External/jquery.js'),
+ _ = require('./External/underscore.js'),
+ ko = require('./External/ko.js'),
+ moment = require('./External/moment.js'),
+ $div = require('./External/$div.js'),
+ NotificationClass = require('./External/NotificationClass.js'),
+ Consts = require('./Common/Consts.js'),
+ Enums = require('./Common/Enums.js'),
+ Globals = require('./Common/Globals.js'),
+ Utils = require('./Common/Utils.js'),
+ kn = require('./Knoin/Knoin.js'),
+ AbstractData = require('./Storages/AbstractData.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractData
+ */
+ function WebMailDataStorage()
+ {
+ AbstractData.call(this);
+
+ var
+ fRemoveSystemFolderType = function (observable) {
+ return function () {
+ var oFolder = RL.cache().getFolderFromCacheList(observable()); // TODO cjs
+ if (oFolder)
+ {
+ oFolder.type(Enums.FolderType.User);
+ }
+ };
+ },
+ fSetSystemFolderType = function (iType) {
+ return function (sValue) {
+ var oFolder = RL.cache().getFolderFromCacheList(sValue); // TODO cjs
+ if (oFolder)
+ {
+ oFolder.type(iType);
+ }
+ };
+ }
+ ;
+
+ this.devEmail = '';
+ this.devPassword = '';
+
+ this.accountEmail = ko.observable('');
+ this.accountIncLogin = ko.observable('');
+ this.accountOutLogin = ko.observable('');
+ this.projectHash = ko.observable('');
+ this.threading = ko.observable(false);
+
+ this.lastFoldersHash = '';
+ this.remoteSuggestions = false;
+
+ // system folders
+ this.sentFolder = ko.observable('');
+ this.draftFolder = ko.observable('');
+ this.spamFolder = ko.observable('');
+ this.trashFolder = ko.observable('');
+ this.archiveFolder = ko.observable('');
+
+ this.sentFolder.subscribe(fRemoveSystemFolderType(this.sentFolder), this, 'beforeChange');
+ this.draftFolder.subscribe(fRemoveSystemFolderType(this.draftFolder), this, 'beforeChange');
+ this.spamFolder.subscribe(fRemoveSystemFolderType(this.spamFolder), this, 'beforeChange');
+ this.trashFolder.subscribe(fRemoveSystemFolderType(this.trashFolder), this, 'beforeChange');
+ this.archiveFolder.subscribe(fRemoveSystemFolderType(this.archiveFolder), this, 'beforeChange');
+
+ this.sentFolder.subscribe(fSetSystemFolderType(Enums.FolderType.SentItems), this);
+ this.draftFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Draft), this);
+ this.spamFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Spam), this);
+ this.trashFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Trash), this);
+ this.archiveFolder.subscribe(fSetSystemFolderType(Enums.FolderType.Archive), this);
+
+ this.draftFolderNotEnabled = ko.computed(function () {
+ return '' === this.draftFolder() || Consts.Values.UnuseOptionValue === this.draftFolder();
+ }, this);
+
+ // personal
+ this.displayName = ko.observable('');
+ this.signature = ko.observable('');
+ this.signatureToAll = ko.observable(false);
+ this.replyTo = ko.observable('');
+
+ // security
+ this.enableTwoFactor = ko.observable(false);
+
+ // accounts
+ this.accounts = ko.observableArray([]);
+ this.accountsLoading = ko.observable(false).extend({'throttle': 100});
+
+ // identities
+ this.defaultIdentityID = ko.observable('');
+ this.identities = ko.observableArray([]);
+ this.identitiesLoading = ko.observable(false).extend({'throttle': 100});
+
+ // contacts
+ this.contactTags = ko.observableArray([]);
+ this.contacts = ko.observableArray([]);
+ this.contacts.loading = ko.observable(false).extend({'throttle': 200});
+ this.contacts.importing = ko.observable(false).extend({'throttle': 200});
+ this.contacts.syncing = ko.observable(false).extend({'throttle': 200});
+ this.contacts.exportingVcf = ko.observable(false).extend({'throttle': 200});
+ this.contacts.exportingCsv = ko.observable(false).extend({'throttle': 200});
+
+ this.allowContactsSync = ko.observable(false);
+ this.enableContactsSync = ko.observable(false);
+ this.contactsSyncUrl = ko.observable('');
+ this.contactsSyncUser = ko.observable('');
+ this.contactsSyncPass = ko.observable('');
+
+ this.allowContactsSync = ko.observable(!!RL.settingsGet('ContactsSyncIsAllowed')); // TODO cjs
+ this.enableContactsSync = ko.observable(!!RL.settingsGet('EnableContactsSync'));
+ this.contactsSyncUrl = ko.observable(RL.settingsGet('ContactsSyncUrl'));
+ this.contactsSyncUser = ko.observable(RL.settingsGet('ContactsSyncUser'));
+ this.contactsSyncPass = ko.observable(RL.settingsGet('ContactsSyncPassword'));
+
+ // folders
+ this.namespace = '';
+ this.folderList = ko.observableArray([]);
+ this.folderList.focused = ko.observable(false);
+
+ this.foldersListError = ko.observable('');
+
+ this.foldersLoading = ko.observable(false);
+ this.foldersCreating = ko.observable(false);
+ this.foldersDeleting = ko.observable(false);
+ this.foldersRenaming = ko.observable(false);
+
+ this.foldersChanging = ko.computed(function () {
+ var
+ bLoading = this.foldersLoading(),
+ bCreating = this.foldersCreating(),
+ bDeleting = this.foldersDeleting(),
+ bRenaming = this.foldersRenaming()
+ ;
+ return bLoading || bCreating || bDeleting || bRenaming;
+ }, this);
+
+ this.foldersInboxUnreadCount = ko.observable(0);
+
+ this.currentFolder = ko.observable(null).extend({'toggleSubscribe': [null,
+ function (oPrev) {
+ if (oPrev)
+ {
+ oPrev.selected(false);
+ }
+ }, function (oNext) {
+ if (oNext)
+ {
+ oNext.selected(true);
+ }
+ }
+ ]});
+
+ this.currentFolderFullNameRaw = ko.computed(function () {
+ return this.currentFolder() ? this.currentFolder().fullNameRaw : '';
+ }, this);
+
+ this.currentFolderFullName = ko.computed(function () {
+ return this.currentFolder() ? this.currentFolder().fullName : '';
+ }, this);
+
+ this.currentFolderFullNameHash = ko.computed(function () {
+ return this.currentFolder() ? this.currentFolder().fullNameHash : '';
+ }, this);
+
+ this.currentFolderName = ko.computed(function () {
+ return this.currentFolder() ? this.currentFolder().name() : '';
+ }, this);
+
+ this.folderListSystemNames = ko.computed(function () {
+
+ var
+ aList = ['INBOX'],
+ aFolders = this.folderList(),
+ sSentFolder = this.sentFolder(),
+ sDraftFolder = this.draftFolder(),
+ sSpamFolder = this.spamFolder(),
+ sTrashFolder = this.trashFolder(),
+ sArchiveFolder = this.archiveFolder()
+ ;
+
+ if (Utils.isArray(aFolders) && 0 < aFolders.length)
+ {
+ if ('' !== sSentFolder && Consts.Values.UnuseOptionValue !== sSentFolder)
+ {
+ aList.push(sSentFolder);
+ }
+ if ('' !== sDraftFolder && Consts.Values.UnuseOptionValue !== sDraftFolder)
+ {
+ aList.push(sDraftFolder);
+ }
+ if ('' !== sSpamFolder && Consts.Values.UnuseOptionValue !== sSpamFolder)
+ {
+ aList.push(sSpamFolder);
+ }
+ if ('' !== sTrashFolder && Consts.Values.UnuseOptionValue !== sTrashFolder)
+ {
+ aList.push(sTrashFolder);
+ }
+ if ('' !== sArchiveFolder && Consts.Values.UnuseOptionValue !== sArchiveFolder)
+ {
+ aList.push(sArchiveFolder);
+ }
+ }
+
+ return aList;
+
+ }, this);
+
+ this.folderListSystem = ko.computed(function () {
+ return _.compact(_.map(this.folderListSystemNames(), function (sName) {
+ return RL.cache().getFolderFromCacheList(sName); // TODO cjs
+ }));
+ }, this);
+
+ this.folderMenuForMove = ko.computed(function () {
+ return RL.folderListOptionsBuilder(this.folderListSystem(), this.folderList(), [// TODO cjs
+ this.currentFolderFullNameRaw()
+ ], null, null, null, null, function (oItem) {
+ return oItem ? oItem.localName() : '';
+ });
+ }, this);
+
+ // message list
+ this.staticMessageList = [];
+
+ this.messageList = ko.observableArray([]).extend({'rateLimit': 0});
+
+ this.messageListCount = ko.observable(0);
+ this.messageListSearch = ko.observable('');
+ this.messageListPage = ko.observable(1);
+
+ this.messageListThreadFolder = ko.observable('');
+ this.messageListThreadUids = ko.observableArray([]);
+
+ this.messageListThreadFolder.subscribe(function () {
+ this.messageListThreadUids([]);
+ }, this);
+
+ this.messageListEndFolder = ko.observable('');
+ this.messageListEndSearch = ko.observable('');
+ this.messageListEndPage = ko.observable(1);
+
+ this.messageListEndHash = ko.computed(function () {
+ return this.messageListEndFolder() + '|' + this.messageListEndSearch() + '|' + this.messageListEndPage();
+ }, this);
+
+ this.messageListPageCount = ko.computed(function () {
+ var iPage = window.Math.ceil(this.messageListCount() / this.messagesPerPage());
+ return 0 >= iPage ? 1 : iPage;
+ }, this);
+
+ this.mainMessageListSearch = ko.computed({
+ 'read': this.messageListSearch,
+ 'write': function (sValue) {
+ kn.setHash(RL.link().mailBox( // TODO cjs
+ this.currentFolderFullNameHash(), 1, Utils.trim(sValue.toString())
+ ));
+ },
+ 'owner': this
+ });
+
+ this.messageListError = ko.observable('');
+
+ this.messageListLoading = ko.observable(false);
+ this.messageListIsNotCompleted = ko.observable(false);
+ this.messageListCompleteLoadingThrottle = ko.observable(false).extend({'throttle': 200});
+
+ this.messageListCompleteLoading = ko.computed(function () {
+ var
+ bOne = this.messageListLoading(),
+ bTwo = this.messageListIsNotCompleted()
+ ;
+ return bOne || bTwo;
+ }, this);
+
+ this.messageListCompleteLoading.subscribe(function (bValue) {
+ this.messageListCompleteLoadingThrottle(bValue);
+ }, this);
+
+ this.messageList.subscribe(_.debounce(function (aList) {
+ _.each(aList, function (oItem) {
+ if (oItem.newForAnimation())
+ {
+ oItem.newForAnimation(false);
+ }
+ });
+ }, 500));
+
+ // message preview
+ this.staticMessageList = new MessageModel();// TODO cjs
+ this.message = ko.observable(null);
+ this.messageLoading = ko.observable(false);
+ this.messageLoadingThrottle = ko.observable(false).extend({'throttle': 50});
+
+ this.message.focused = ko.observable(false);
+
+ this.message.subscribe(function (oMessage) {
+ if (!oMessage)
+ {
+ this.message.focused(false);
+ this.messageFullScreenMode(false);
+ this.hideMessageBodies();
+
+ if (Enums.Layout.NoPreview === RL.data().layout() &&// TODO cjs
+ -1 < window.location.hash.indexOf('message-preview'))
+ {
+ RL.historyBack();// TODO cjs
+ }
+ }
+ else if (Enums.Layout.NoPreview === this.layout())
+ {
+ this.message.focused(true);
+ }
+ }, this);
+
+ this.message.focused.subscribe(function (bValue) {
+ if (bValue)
+ {
+ this.folderList.focused(false);
+ this.keyScope(Enums.KeyState.MessageView);
+ }
+ else if (Enums.KeyState.MessageView === RL.data().keyScope())// TODO cjs
+ {
+ if (Enums.Layout.NoPreview === RL.data().layout() && this.message())// TODO cjs
+ {
+ this.keyScope(Enums.KeyState.MessageView);
+ }
+ else
+ {
+ this.keyScope(Enums.KeyState.MessageList);
+ }
+ }
+ }, this);
+
+ this.folderList.focused.subscribe(function (bValue) {
+ if (bValue)
+ {
+ RL.data().keyScope(Enums.KeyState.FolderList);// TODO cjs
+ }
+ else if (Enums.KeyState.FolderList === RL.data().keyScope())// TODO cjs
+ {
+ RL.data().keyScope(Enums.KeyState.MessageList);// TODO cjs
+ }
+ });
+
+ this.messageLoading.subscribe(function (bValue) {
+ this.messageLoadingThrottle(bValue);
+ }, this);
+
+ this.messageFullScreenMode = ko.observable(false);
+
+ this.messageError = ko.observable('');
+
+ this.messagesBodiesDom = ko.observable(null);
+
+ this.messagesBodiesDom.subscribe(function (oDom) {
+ if (oDom && !(oDom instanceof $))
+ {
+ this.messagesBodiesDom($(oDom));
+ }
+ }, this);
+
+ this.messageActiveDom = ko.observable(null);
+
+ this.isMessageSelected = ko.computed(function () {
+ return null !== this.message();
+ }, this);
+
+ this.currentMessage = ko.observable(null);
+
+ this.messageListChecked = ko.computed(function () {
+ return _.filter(this.messageList(), function (oItem) {
+ return oItem.checked();
+ });
+ }, this).extend({'rateLimit': 0});
+
+ this.hasCheckedMessages = ko.computed(function () {
+ return 0 < this.messageListChecked().length;
+ }, this).extend({'rateLimit': 0});
+
+ this.messageListCheckedOrSelected = ko.computed(function () {
+
+ var
+ aChecked = this.messageListChecked(),
+ oSelectedMessage = this.currentMessage()
+ ;
+
+ return _.union(aChecked, oSelectedMessage ? [oSelectedMessage] : []);
+
+ }, this);
+
+ this.messageListCheckedOrSelectedUidsWithSubMails = ko.computed(function () {
+ var aList = [];
+ _.each(this.messageListCheckedOrSelected(), function (oMessage) {
+ if (oMessage)
+ {
+ aList.push(oMessage.uid);
+ if (0 < oMessage.threadsLen() && 0 === oMessage.parentUid() && oMessage.lastInCollapsedThread())
+ {
+ aList = _.union(aList, oMessage.threads());
+ }
+ }
+ });
+ return aList;
+ }, this);
+
+ // quota
+ this.userQuota = ko.observable(0);
+ this.userUsageSize = ko.observable(0);
+ this.userUsageProc = ko.computed(function () {
+
+ var
+ iQuota = this.userQuota(),
+ iUsed = this.userUsageSize()
+ ;
+
+ return 0 < iQuota ? window.Math.ceil((iUsed / iQuota) * 100) : 0;
+
+ }, this);
+
+ // other
+ this.capaOpenPGP = ko.observable(false);
+ this.openpgpkeys = ko.observableArray([]);
+ this.openpgpKeyring = null;
+
+ this.openpgpkeysPublic = this.openpgpkeys.filter(function (oItem) {
+ return !!(oItem && !oItem.isPrivate);
+ });
+
+ this.openpgpkeysPrivate = this.openpgpkeys.filter(function (oItem) {
+ return !!(oItem && oItem.isPrivate);
+ });
+
+ // google
+ this.googleActions = ko.observable(false);
+ this.googleLoggined = ko.observable(false);
+ this.googleUserName = ko.observable('');
+
+ // facebook
+ this.facebookActions = ko.observable(false);
+ this.facebookLoggined = ko.observable(false);
+ this.facebookUserName = ko.observable('');
+
+ // twitter
+ this.twitterActions = ko.observable(false);
+ this.twitterLoggined = ko.observable(false);
+ this.twitterUserName = ko.observable('');
+
+ this.customThemeType = ko.observable(Enums.CustomThemeType.Light);
+
+ this.purgeMessageBodyCacheThrottle = _.throttle(this.purgeMessageBodyCache, 1000 * 30);
+ }
+
+ _.extend(WebMailDataStorage.prototype, AbstractData.prototype);
+
+ WebMailDataStorage.prototype.purgeMessageBodyCache = function()
+ {
+ var
+ iCount = 0,
+ oMessagesBodiesDom = null,
+ iEnd = Globals.iMessageBodyCacheCount - Consts.Values.MessageBodyCacheLimit
+ ;
+
+ if (0 < iEnd)
+ {
+ oMessagesBodiesDom = this.messagesBodiesDom();
+ if (oMessagesBodiesDom)
+ {
+ oMessagesBodiesDom.find('.rl-cache-class').each(function () {
+ var oItem = $(this);
+ if (iEnd > oItem.data('rl-cache-count'))
+ {
+ oItem.addClass('rl-cache-purge');
+ iCount++;
+ }
+ });
+
+ if (0 < iCount)
+ {
+ _.delay(function () {
+ oMessagesBodiesDom.find('.rl-cache-purge').remove();
+ }, 300);
+ }
+ }
+ }
+ };
+
+ WebMailDataStorage.prototype.populateDataOnStart = function()
+ {
+ AbstractData.prototype.populateDataOnStart.call(this);
+
+ this.accountEmail(RL.settingsGet('Email'));// TODO cjs
+ this.accountIncLogin(RL.settingsGet('IncLogin'));
+ this.accountOutLogin(RL.settingsGet('OutLogin'));
+ this.projectHash(RL.settingsGet('ProjectHash'));
+
+ this.defaultIdentityID(RL.settingsGet('DefaultIdentityID'));
+
+ this.displayName(RL.settingsGet('DisplayName'));
+ this.replyTo(RL.settingsGet('ReplyTo'));
+ this.signature(RL.settingsGet('Signature'));
+ this.signatureToAll(!!RL.settingsGet('SignatureToAll'));
+ this.enableTwoFactor(!!RL.settingsGet('EnableTwoFactor'));
+
+ this.lastFoldersHash = RL.local().get(Enums.ClientSideKeyName.FoldersLashHash) || '';
+
+ this.remoteSuggestions = !!RL.settingsGet('RemoteSuggestions');
+
+ this.devEmail = RL.settingsGet('DevEmail');
+ this.devPassword = RL.settingsGet('DevPassword');
+ };
+
+ WebMailDataStorage.prototype.initUidNextAndNewMessages = function (sFolder, sUidNext, aNewMessages)
+ {
+ if ('INBOX' === sFolder && Utils.isNormal(sUidNext) && sUidNext !== '')
+ {
+ if (Utils.isArray(aNewMessages) && 0 < aNewMessages.length)
+ {
+ var
+ oCache = RL.cache(),// TODO cjs
+ iIndex = 0,
+ iLen = aNewMessages.length,
+ fNotificationHelper = function (sImageSrc, sTitle, sText)
+ {
+ var oNotification = null;
+ if (NotificationClass && RL.data().useDesktopNotifications())
+ {
+ oNotification = new NotificationClass(sTitle, {
+ 'body': sText,
+ 'icon': sImageSrc
+ });
+
+ if (oNotification)
+ {
+ if (oNotification.show)
+ {
+ oNotification.show();
+ }
+
+ window.setTimeout((function (oLocalNotifications) {
+ return function () {
+ if (oLocalNotifications.cancel)
+ {
+ oLocalNotifications.cancel();
+ }
+ else if (oLocalNotifications.close)
+ {
+ oLocalNotifications.close();
+ }
+ };
+ }(oNotification)), 7000);
+ }
+ }
+ }
+ ;
+
+ _.each(aNewMessages, function (oItem) {
+ oCache.addNewMessageCache(sFolder, oItem.Uid);
+ });
+
+ if (3 < iLen)
+ {
+ fNotificationHelper(
+ RL.link().notificationMailIcon(),// TODO cjs
+ RL.data().accountEmail(),
+ Utils.i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
+ 'COUNT': iLen
+ })
+ );
+ }
+ else
+ {
+ for (; iIndex < iLen; iIndex++)
+ {
+ fNotificationHelper(
+ RL.link().notificationMailIcon(),// TODO cjs
+ MessageModel.emailsToLine(MessageModel.initEmailsFromJson(aNewMessages[iIndex].From), false),// TODO cjs
+ aNewMessages[iIndex].Subject
+ );
+ }
+ }
+ }
+
+ RL.cache().setFolderUidNext(sFolder, sUidNext);// TODO cjs
+ }
+ };
+
+ /**
+ * @param {string} sNamespace
+ * @param {Array} aFolders
+ * @return {Array}
+ */
+ WebMailDataStorage.prototype.folderResponseParseRec = function (sNamespace, aFolders)
+ {
+ var
+ iIndex = 0,
+ iLen = 0,
+ oFolder = null,
+ oCacheFolder = null,
+ sFolderFullNameRaw = '',
+ aSubFolders = [],
+ aList = []
+ ;
+
+ for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
+ {
+ oFolder = aFolders[iIndex];
+ if (oFolder)
+ {
+ sFolderFullNameRaw = oFolder.FullNameRaw;
+
+ oCacheFolder = RL.cache().getFolderFromCacheList(sFolderFullNameRaw);// TODO cjs
+ if (!oCacheFolder)
+ {
+ oCacheFolder = FolderModel.newInstanceFromJson(oFolder);// TODO cjs
+ if (oCacheFolder)
+ {
+ RL.cache().setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);// TODO cjs
+ RL.cache().setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw);// TODO cjs
+ }
+ }
+
+ if (oCacheFolder)
+ {
+ oCacheFolder.collapsed(!Utils.isFolderExpanded(oCacheFolder.fullNameHash));
+
+ if (oFolder.Extended)
+ {
+ if (oFolder.Extended.Hash)
+ {
+ RL.cache().setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash);// TODO cjs
+ }
+
+ if (Utils.isNormal(oFolder.Extended.MessageCount))
+ {
+ oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
+ }
+
+ if (Utils.isNormal(oFolder.Extended.MessageUnseenCount))
+ {
+ oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
+ }
+ }
+
+ aSubFolders = oFolder['SubFolders'];
+ if (aSubFolders && 'Collection/FolderCollection' === aSubFolders['@Object'] &&
+ aSubFolders['@Collection'] && Utils.isArray(aSubFolders['@Collection']))
+ {
+ oCacheFolder.subFolders(
+ this.folderResponseParseRec(sNamespace, aSubFolders['@Collection']));
+ }
+
+ aList.push(oCacheFolder);
+ }
+ }
+ }
+
+ return aList;
+ };
+
+ /**
+ * @param {*} oData
+ */
+ WebMailDataStorage.prototype.setFolders = function (oData)
+ {
+ var
+ aList = [],
+ bUpdate = false,
+ oRLData = RL.data(),// TODO cjs
+ fNormalizeFolder = function (sFolderFullNameRaw) {
+ return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
+ null !== RL.cache().getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';// TODO cjs
+ }
+ ;
+
+ if (oData && oData.Result && 'Collection/FolderCollection' === oData.Result['@Object'] &&
+ oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
+ {
+ if (!Utils.isUnd(oData.Result.Namespace))
+ {
+ oRLData.namespace = oData.Result.Namespace;
+ }
+
+ this.threading(!!RL.settingsGet('UseImapThread') && oData.Result.IsThreadsSupported && true);// TODO cjs
+
+ aList = this.folderResponseParseRec(oRLData.namespace, oData.Result['@Collection']);
+ oRLData.folderList(aList);
+
+ // TODO cjs
+ if (oData.Result['SystemFolders'] &&
+ '' === '' + RL.settingsGet('SentFolder') + RL.settingsGet('DraftFolder') +
+ RL.settingsGet('SpamFolder') + RL.settingsGet('TrashFolder') + RL.settingsGet('ArchiveFolder') +
+ RL.settingsGet('NullFolder'))
+ {
+ // TODO Magic Numbers
+ RL.settingsSet('SentFolder', oData.Result['SystemFolders'][2] || null);
+ RL.settingsSet('DraftFolder', oData.Result['SystemFolders'][3] || null);
+ RL.settingsSet('SpamFolder', oData.Result['SystemFolders'][4] || null);
+ RL.settingsSet('TrashFolder', oData.Result['SystemFolders'][5] || null);
+ RL.settingsSet('ArchiveFolder', oData.Result['SystemFolders'][12] || null);
+
+ bUpdate = true;
+ }
+
+ // TODO cjs
+ oRLData.sentFolder(fNormalizeFolder(RL.settingsGet('SentFolder')));
+ oRLData.draftFolder(fNormalizeFolder(RL.settingsGet('DraftFolder')));
+ oRLData.spamFolder(fNormalizeFolder(RL.settingsGet('SpamFolder')));
+ oRLData.trashFolder(fNormalizeFolder(RL.settingsGet('TrashFolder')));
+ oRLData.archiveFolder(fNormalizeFolder(RL.settingsGet('ArchiveFolder')));
+
+ if (bUpdate)
+ {
+ // TODO cjs
+ RL.remote().saveSystemFolders(Utils.emptyFunction, {
+ 'SentFolder': oRLData.sentFolder(),
+ 'DraftFolder': oRLData.draftFolder(),
+ 'SpamFolder': oRLData.spamFolder(),
+ 'TrashFolder': oRLData.trashFolder(),
+ 'ArchiveFolder': oRLData.archiveFolder(),
+ 'NullFolder': 'NullFolder'
+ });
+ }
+
+ // TODO cjs
+ RL.local().set(Enums.ClientSideKeyName.FoldersLashHash, oData.Result.FoldersHash);
+ }
+ };
+
+ WebMailDataStorage.prototype.hideMessageBodies = function ()
+ {
+ var oMessagesBodiesDom = this.messagesBodiesDom();
+ if (oMessagesBodiesDom)
+ {
+ oMessagesBodiesDom.find('.b-text-part').hide();
+ }
+ };
+
+ /**
+ * @param {boolean=} bBoot = false
+ * @returns {Array}
+ */
+ WebMailDataStorage.prototype.getNextFolderNames = function (bBoot)
+ {
+ bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;
+
+ var
+ aResult = [],
+ iLimit = 10,
+ iUtc = moment().unix(),
+ iTimeout = iUtc - 60 * 5,
+ aTimeouts = [],
+ fSearchFunction = function (aList) {
+ _.each(aList, function (oFolder) {
+ if (oFolder && 'INBOX' !== oFolder.fullNameRaw &&
+ oFolder.selectable && oFolder.existen &&
+ iTimeout > oFolder.interval &&
+ (!bBoot || oFolder.subScribed()))
+ {
+ aTimeouts.push([oFolder.interval, oFolder.fullNameRaw]);
+ }
+
+ if (oFolder && 0 < oFolder.subFolders().length)
+ {
+ fSearchFunction(oFolder.subFolders());
+ }
+ });
+ }
+ ;
+
+ fSearchFunction(this.folderList());
+
+ aTimeouts.sort(function(a, b) {
+ if (a[0] < b[0])
+ {
+ return -1;
+ }
+ else if (a[0] > b[0])
+ {
+ return 1;
+ }
+
+ return 0;
+ });
+
+ _.find(aTimeouts, function (aItem) {
+ var oFolder = RL.cache().getFolderFromCacheList(aItem[1]);// TODO cjs
+ if (oFolder)
+ {
+ oFolder.interval = iUtc;
+ aResult.push(aItem[1]);
+ }
+
+ return iLimit <= aResult.length;
+ });
+
+ return _.uniq(aResult);
+ };
+
+ /**
+ * @param {string} sFromFolderFullNameRaw
+ * @param {Array} aUidForRemove
+ * @param {string=} sToFolderFullNameRaw = ''
+ * @param {bCopy=} bCopy = false
+ */
+ WebMailDataStorage.prototype.removeMessagesFromList = function (
+ sFromFolderFullNameRaw, aUidForRemove, sToFolderFullNameRaw, bCopy)
+ {
+ sToFolderFullNameRaw = Utils.isNormal(sToFolderFullNameRaw) ? sToFolderFullNameRaw : '';
+ bCopy = Utils.isUnd(bCopy) ? false : !!bCopy;
+
+ aUidForRemove = _.map(aUidForRemove, function (mValue) {
+ return Utils.pInt(mValue);
+ });
+
+ var
+ iUnseenCount = 0,
+ oData = RL.data(),// TODO cjs
+ oCache = RL.cache(),// TODO cjs
+ aMessageList = oData.messageList(),
+ oFromFolder = RL.cache().getFolderFromCacheList(sFromFolderFullNameRaw),
+ oToFolder = '' === sToFolderFullNameRaw ? null : oCache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
+ sCurrentFolderFullNameRaw = oData.currentFolderFullNameRaw(),
+ oCurrentMessage = oData.message(),
+ aMessages = sCurrentFolderFullNameRaw === sFromFolderFullNameRaw ? _.filter(aMessageList, function (oMessage) {
+ return oMessage && -1 < Utils.inArray(Utils.pInt(oMessage.uid), aUidForRemove);
+ }) : []
+ ;
+
+ _.each(aMessages, function (oMessage) {
+ if (oMessage && oMessage.unseen())
+ {
+ iUnseenCount++;
+ }
+ });
+
+ if (oFromFolder && !bCopy)
+ {
+ oFromFolder.messageCountAll(0 <= oFromFolder.messageCountAll() - aUidForRemove.length ?
+ oFromFolder.messageCountAll() - aUidForRemove.length : 0);
+
+ if (0 < iUnseenCount)
+ {
+ oFromFolder.messageCountUnread(0 <= oFromFolder.messageCountUnread() - iUnseenCount ?
+ oFromFolder.messageCountUnread() - iUnseenCount : 0);
+ }
+ }
+
+ if (oToFolder)
+ {
+ oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
+ if (0 < iUnseenCount)
+ {
+ oToFolder.messageCountUnread(oToFolder.messageCountUnread() + iUnseenCount);
+ }
+
+ oToFolder.actionBlink(true);
+ }
+
+ if (0 < aMessages.length)
+ {
+ if (bCopy)
+ {
+ _.each(aMessages, function (oMessage) {
+ oMessage.checked(false);
+ });
+ }
+ else
+ {
+ oData.messageListIsNotCompleted(true);
+
+ _.each(aMessages, function (oMessage) {
+ if (oCurrentMessage && oCurrentMessage.hash === oMessage.hash)
+ {
+ oCurrentMessage = null;
+ oData.message(null);
+ }
+
+ oMessage.deleted(true);
+ });
+
+ _.delay(function () {
+ _.each(aMessages, function (oMessage) {
+ oData.messageList.remove(oMessage);
+ });
+ }, 400);
+ }
+ }
+
+ if ('' !== sFromFolderFullNameRaw)
+ {
+ oCache.setFolderHash(sFromFolderFullNameRaw, '');
+ }
+
+ if ('' !== sToFolderFullNameRaw)
+ {
+ oCache.setFolderHash(sToFolderFullNameRaw, '');
+ }
+ };
+
+ WebMailDataStorage.prototype.setMessage = function (oData, bCached)
+ {
+ var
+ bIsHtml = false,
+ bHasExternals = false,
+ bHasInternals = false,
+ oBody = null,
+ oTextBody = null,
+ sId = '',
+ sResultHtml = '',
+ bPgpSigned = false,
+ bPgpEncrypted = false,
+ oMessagesBodiesDom = this.messagesBodiesDom(),
+ oMessage = this.message()
+ ;
+
+ if (oData && oMessage && oData.Result && 'Object/Message' === oData.Result['@Object'] &&
+ oMessage.folderFullNameRaw === oData.Result.Folder && oMessage.uid === oData.Result.Uid)
+ {
+ this.messageError('');
+
+ oMessage.initUpdateByMessageJson(oData.Result);
+ RL.cache().addRequestedMessage(oMessage.folderFullNameRaw, oMessage.uid);// TODO cjs
+
+ if (!bCached)
+ {
+ oMessage.initFlagsByJson(oData.Result);
+ }
+
+ oMessagesBodiesDom = oMessagesBodiesDom && oMessagesBodiesDom[0] ? oMessagesBodiesDom : null;
+ if (oMessagesBodiesDom)
+ {
+ sId = 'rl-mgs-' + oMessage.hash.replace(/[^a-zA-Z0-9]/g, '');
+ oTextBody = oMessagesBodiesDom.find('#' + sId);
+ if (!oTextBody || !oTextBody[0])
+ {
+ bHasExternals = !!oData.Result.HasExternals;
+ bHasInternals = !!oData.Result.HasInternals;
+
+ oBody = $('').hide().addClass('rl-cache-class');
+ oBody.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
+
+ if (Utils.isNormal(oData.Result.Html) && '' !== oData.Result.Html)
+ {
+ bIsHtml = true;
+ sResultHtml = oData.Result.Html.toString();
+ }
+ else if (Utils.isNormal(oData.Result.Plain) && '' !== oData.Result.Plain)
+ {
+ bIsHtml = false;
+ sResultHtml = Utils.plainToHtml(oData.Result.Plain.toString(), false);
+
+ if ((oMessage.isPgpSigned() || oMessage.isPgpEncrypted()) && RL.data().capaOpenPGP())
+ {
+ oMessage.plainRaw = Utils.pString(oData.Result.Plain);
+
+ bPgpEncrypted = /---BEGIN PGP MESSAGE---/.test(oMessage.plainRaw);
+ if (!bPgpEncrypted)
+ {
+ bPgpSigned = /-----BEGIN PGP SIGNED MESSAGE-----/.test(oMessage.plainRaw) &&
+ /-----BEGIN PGP SIGNATURE-----/.test(oMessage.plainRaw);
+ }
+
+ $div.empty();
+ if (bPgpSigned && oMessage.isPgpSigned())
+ {
+ sResultHtml =
+ $div.append(
+ $('').text(oMessage.plainRaw)
+ ).html()
+ ;
+ }
+ else if (bPgpEncrypted && oMessage.isPgpEncrypted())
+ {
+ sResultHtml =
+ $div.append(
+ $('').text(oMessage.plainRaw)
+ ).html()
+ ;
+ }
+
+ $div.empty();
+
+ oMessage.isPgpSigned(bPgpSigned);
+ oMessage.isPgpEncrypted(bPgpEncrypted);
+ }
+ }
+ else
+ {
+ bIsHtml = false;
+ }
+
+ oBody
+ .html(Utils.linkify(sResultHtml))
+ .addClass('b-text-part ' + (bIsHtml ? 'html' : 'plain'))
+ ;
+
+ oMessage.isHtml(!!bIsHtml);
+ oMessage.hasImages(!!bHasExternals);
+ oMessage.pgpSignedVerifyStatus(Enums.SignedVerifyStatus.None);
+ oMessage.pgpSignedVerifyUser('');
+
+ oMessage.body = oBody;
+ if (oMessage.body)
+ {
+ oMessagesBodiesDom.append(oMessage.body);
+ }
+
+ oMessage.storeDataToDom();
+
+ if (bHasInternals)
+ {
+ oMessage.showInternalImages(true);
+ }
+
+ if (oMessage.hasImages() && this.showImages())
+ {
+ oMessage.showExternalImages(true);
+ }
+
+ this.purgeMessageBodyCacheThrottle();
+ }
+ else
+ {
+ oMessage.body = oTextBody;
+ if (oMessage.body)
+ {
+ oMessage.body.data('rl-cache-count', ++Globals.iMessageBodyCacheCount);
+ oMessage.fetchDataToDom();
+ }
+ }
+
+ this.messageActiveDom(oMessage.body);
+
+ this.hideMessageBodies();
+ oMessage.body.show();
+
+ if (oBody)
+ {
+ Utils.initBlockquoteSwitcher(oBody);
+ }
+ }
+
+ RL.cache().initMessageFlagsFromCache(oMessage);
+ if (oMessage.unseen())
+ {
+ RL.setMessageSeen(oMessage);
+ }
+
+ Utils.windowResize();
+ }
+ };
+
+ /**
+ * @param {Array} aList
+ * @returns {string}
+ */
+ WebMailDataStorage.prototype.calculateMessageListHash = function (aList)
+ {
+ return _.map(aList, function (oMessage) {
+ return '' + oMessage.hash + '_' + oMessage.threadsLen() + '_' + oMessage.flagHash();
+ }).join('|');
+ };
+
+ WebMailDataStorage.prototype.setMessageList = function (oData, bCached)
+ {
+ if (oData && oData.Result && 'Collection/MessageCollection' === oData.Result['@Object'] &&
+ oData.Result['@Collection'] && Utils.isArray(oData.Result['@Collection']))
+ {
+ var
+ oRainLoopData = RL.data(),
+ oCache = RL.cache(),
+ mLastCollapsedThreadUids = null,
+ iIndex = 0,
+ iLen = 0,
+ iCount = 0,
+ iOffset = 0,
+ aList = [],
+ iUtc = moment().unix(),
+ aStaticList = oRainLoopData.staticMessageList,
+ oJsonMessage = null,
+ oMessage = null,
+ oFolder = null,
+ iNewCount = 0,
+ bUnreadCountChange = false
+ ;
+
+ iCount = Utils.pInt(oData.Result.MessageResultCount);
+ iOffset = Utils.pInt(oData.Result.Offset);
+
+ if (Utils.isNonEmptyArray(oData.Result.LastCollapsedThreadUids))
+ {
+ mLastCollapsedThreadUids = oData.Result.LastCollapsedThreadUids;
+ }
+
+ oFolder = RL.cache().getFolderFromCacheList(
+ Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
+
+ if (oFolder && !bCached)
+ {
+ oFolder.interval = iUtc;
+
+ RL.cache().setFolderHash(oData.Result.Folder, oData.Result.FolderHash);
+
+ if (Utils.isNormal(oData.Result.MessageCount))
+ {
+ oFolder.messageCountAll(oData.Result.MessageCount);
+ }
+
+ if (Utils.isNormal(oData.Result.MessageUnseenCount))
+ {
+ if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
+ {
+ bUnreadCountChange = true;
+ }
+
+ oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
+ }
+
+ this.initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
+ }
+
+ if (bUnreadCountChange && oFolder)
+ {
+ RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
+ }
+
+ for (iIndex = 0, iLen = oData.Result['@Collection'].length; iIndex < iLen; iIndex++)
+ {
+ oJsonMessage = oData.Result['@Collection'][iIndex];
+ if (oJsonMessage && 'Object/Message' === oJsonMessage['@Object'])
+ {
+ oMessage = aStaticList[iIndex];
+ if (!oMessage || !oMessage.initByJson(oJsonMessage))
+ {
+ oMessage = MessageModel.newInstanceFromJson(oJsonMessage);
+ }
+
+ if (oMessage)
+ {
+ if (oCache.hasNewMessageAndRemoveFromCache(oMessage.folderFullNameRaw, oMessage.uid) && 5 >= iNewCount)
+ {
+ iNewCount++;
+ oMessage.newForAnimation(true);
+ }
+
+ oMessage.deleted(false);
+
+ if (bCached)
+ {
+ RL.cache().initMessageFlagsFromCache(oMessage);
+ }
+ else
+ {
+ RL.cache().storeMessageFlagsToCache(oMessage);
+ }
+
+ oMessage.lastInCollapsedThread(mLastCollapsedThreadUids && -1 < Utils.inArray(Utils.pInt(oMessage.uid), mLastCollapsedThreadUids) ? true : false);
+
+ aList.push(oMessage);
+ }
+ }
+ }
+
+ oRainLoopData.messageListCount(iCount);
+ oRainLoopData.messageListSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
+ oRainLoopData.messageListPage(Math.ceil((iOffset / oRainLoopData.messagesPerPage()) + 1));
+ oRainLoopData.messageListEndFolder(Utils.isNormal(oData.Result.Folder) ? oData.Result.Folder : '');
+ oRainLoopData.messageListEndSearch(Utils.isNormal(oData.Result.Search) ? oData.Result.Search : '');
+ oRainLoopData.messageListEndPage(oRainLoopData.messageListPage());
+
+ oRainLoopData.messageList(aList);
+ oRainLoopData.messageListIsNotCompleted(false);
+
+ if (aStaticList.length < aList.length)
+ {
+ oRainLoopData.staticMessageList = aList;
+ }
+
+ oCache.clearNewMessageCache();
+
+ if (oFolder && (bCached || bUnreadCountChange || RL.data().useThreads()))
+ {
+ RL.folderInformation(oFolder.fullNameRaw, aList);
+ }
+ }
+ else
+ {
+ RL.data().messageListCount(0);
+ RL.data().messageList([]);
+ RL.data().messageListError(Utils.getNotification(
+ oData && oData.ErrorCode ? oData.ErrorCode : Enums.Notification.CantGetMessageList
+ ));
+ }
+ };
+
+ WebMailDataStorage.prototype.findPublicKeyByHex = function (sHash)
+ {
+ return _.find(this.openpgpkeysPublic(), function (oItem) {
+ return oItem && sHash === oItem.id;
+ });
+ };
+
+ WebMailDataStorage.prototype.findPublicKeysByEmail = function (sEmail)
+ {
+ return _.compact(_.map(this.openpgpkeysPublic(), function (oItem) {
+
+ var oKey = null;
+ if (oItem && sEmail === oItem.email)
+ {
+ try
+ {
+ oKey = window.openpgp.key.readArmored(oItem.armor);
+ if (oKey && !oKey.err && oKey.keys && oKey.keys[0])
+ {
+ return oKey.keys[0];
+ }
+ }
+ catch (e) {}
+ }
+
+ return null;
+
+ }));
+ };
+
+ /**
+ * @param {string} sEmail
+ * @param {string=} sPassword
+ * @returns {?}
+ */
+ WebMailDataStorage.prototype.findPrivateKeyByEmail = function (sEmail, sPassword)
+ {
+ var
+ oPrivateKey = null,
+ oKey = _.find(this.openpgpkeysPrivate(), function (oItem) {
+ return oItem && sEmail === oItem.email;
+ })
+ ;
+
+ if (oKey)
+ {
+ try
+ {
+ oPrivateKey = window.openpgp.key.readArmored(oKey.armor);
+ if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0])
+ {
+ oPrivateKey = oPrivateKey.keys[0];
+ oPrivateKey.decrypt(Utils.pString(sPassword));
+ }
+ else
+ {
+ oPrivateKey = null;
+ }
+ }
+ catch (e)
+ {
+ oPrivateKey = null;
+ }
+ }
+
+ return oPrivateKey;
+ };
+
+ /**
+ * @param {string=} sPassword
+ * @returns {?}
+ */
+ WebMailDataStorage.prototype.findSelfPrivateKey = function (sPassword)
+ {
+ return this.findPrivateKeyByEmail(this.accountEmail(), sPassword);
+ };
+
+ module.exports = WebMailDataStorage;
+
+}(module));
diff --git a/dev/ViewModels/LoginViewModel.js b/dev/ViewModels/LoginViewModel.js
index 474d79ac4..c7f2828b0 100644
--- a/dev/ViewModels/LoginViewModel.js
+++ b/dev/ViewModels/LoginViewModel.js
@@ -320,7 +320,7 @@ LoginViewModel.prototype.onBuild = function ()
'cache': true
}).done(function() {
self.bSendLanguage = true;
- Utils.i18nToDoc();
+ Utils.i18nReload();
$.cookie('rllang', RL.data().language(), {'expires': 30});
}).always(function() {
self.langRequest(false);
diff --git a/dev/ViewModels/MailBoxMessageViewViewModel.js b/dev/ViewModels/MailBoxMessageViewViewModel.js
index 178ece78d..02f59df50 100644
--- a/dev/ViewModels/MailBoxMessageViewViewModel.js
+++ b/dev/ViewModels/MailBoxMessageViewViewModel.js
@@ -1,693 +1,712 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends KnoinAbstractViewModel
- */
-function MailBoxMessageViewViewModel()
-{
- KnoinAbstractViewModel.call(this, 'Right', 'MailMessageView');
+(function (module) {
+
+ 'use strict';
var
- self = this,
- sLastEmail = '',
- oData = RL.data(),
- createCommandHelper = function (sType) {
- return Utils.createCommand(self, function () {
- this.replyOrforward(sType);
- }, self.canBeRepliedOrForwarded);
- }
+ ko = require('../External/ko.js'),
+ key = require('../External/key.js'),
+ $html = require('../External/$html.js'),
+ Consts = require('../Common/Consts.js'),
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js'),
+ kn = require('../Knoin/Knoin.js'),
+ KnoinAbstractViewModel = require('../Knoin/KnoinAbstractViewModel.js')
;
- this.oMessageScrollerDom = null;
+ /**
+ * @constructor
+ * @extends KnoinAbstractViewModel
+ */
+ function MailBoxMessageViewViewModel()
+ {
+ KnoinAbstractViewModel.call(this, 'Right', 'MailMessageView');
- this.keyScope = oData.keyScope;
- this.message = oData.message;
- this.currentMessage = oData.currentMessage;
- this.messageListChecked = oData.messageListChecked;
- this.hasCheckedMessages = oData.hasCheckedMessages;
- this.messageListCheckedOrSelectedUidsWithSubMails = oData.messageListCheckedOrSelectedUidsWithSubMails;
- this.messageLoading = oData.messageLoading;
- this.messageLoadingThrottle = oData.messageLoadingThrottle;
- this.messagesBodiesDom = oData.messagesBodiesDom;
- this.useThreads = oData.useThreads;
- this.replySameFolder = oData.replySameFolder;
- this.layout = oData.layout;
- this.usePreviewPane = oData.usePreviewPane;
- this.isMessageSelected = oData.isMessageSelected;
- this.messageActiveDom = oData.messageActiveDom;
- this.messageError = oData.messageError;
-
- this.fullScreenMode = oData.messageFullScreenMode;
-
- this.showFullInfo = ko.observable(false);
- this.moreDropdownTrigger = ko.observable(false);
- this.messageDomFocused = ko.observable(false).extend({'rateLimit': 0});
-
- this.messageVisibility = ko.computed(function () {
- return !this.messageLoadingThrottle() && !!this.message();
- }, this);
-
- this.message.subscribe(function (oMessage) {
- if (!oMessage)
- {
- this.currentMessage(null);
- }
- }, this);
-
- this.canBeRepliedOrForwarded = this.messageVisibility;
-
- // commands
- this.closeMessage = Utils.createCommand(this, function () {
- oData.message(null);
- });
-
- this.replyCommand = createCommandHelper(Enums.ComposeType.Reply);
- this.replyAllCommand = createCommandHelper(Enums.ComposeType.ReplyAll);
- this.forwardCommand = createCommandHelper(Enums.ComposeType.Forward);
- this.forwardAsAttachmentCommand = createCommandHelper(Enums.ComposeType.ForwardAsAttachment);
- this.editAsNewCommand = createCommandHelper(Enums.ComposeType.EditAsNew);
-
- this.messageVisibilityCommand = Utils.createCommand(this, Utils.emptyFunction, this.messageVisibility);
-
- this.messageEditCommand = Utils.createCommand(this, function () {
- this.editMessage();
- }, this.messageVisibility);
-
- this.deleteCommand = Utils.createCommand(this, function () {
- if (this.message())
- {
- RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
- this.message().folderFullNameRaw,
- [this.message().uid], true);
- }
- }, this.messageVisibility);
-
- this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
- if (this.message())
- {
- RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
- RL.data().currentFolderFullNameRaw(),
- [this.message().uid], false);
- }
- }, this.messageVisibility);
-
- this.archiveCommand = Utils.createCommand(this, function () {
- if (this.message())
- {
- RL.deleteMessagesFromFolder(Enums.FolderType.Archive,
- this.message().folderFullNameRaw,
- [this.message().uid], true);
- }
- }, this.messageVisibility);
-
- this.spamCommand = Utils.createCommand(this, function () {
- if (this.message())
- {
- RL.deleteMessagesFromFolder(Enums.FolderType.Spam,
- this.message().folderFullNameRaw,
- [this.message().uid], true);
- }
- }, this.messageVisibility);
-
- this.notSpamCommand = Utils.createCommand(this, function () {
- if (this.message())
- {
- RL.deleteMessagesFromFolder(Enums.FolderType.NotSpam,
- this.message().folderFullNameRaw,
- [this.message().uid], true);
- }
- }, this.messageVisibility);
-
- // viewer
- this.viewHash = '';
- this.viewSubject = ko.observable('');
- this.viewFromShort = ko.observable('');
- this.viewToShort = ko.observable('');
- this.viewFrom = ko.observable('');
- this.viewTo = ko.observable('');
- this.viewCc = ko.observable('');
- this.viewBcc = ko.observable('');
- this.viewDate = ko.observable('');
- this.viewMoment = ko.observable('');
- this.viewLineAsCcc = ko.observable('');
- this.viewViewLink = ko.observable('');
- this.viewDownloadLink = ko.observable('');
- this.viewUserPic = ko.observable(Consts.DataImages.UserDotPic);
- this.viewUserPicVisible = ko.observable(false);
-
- this.viewPgpPassword = ko.observable('');
- this.viewPgpSignedVerifyStatus = ko.computed(function () {
- return this.message() ? this.message().pgpSignedVerifyStatus() : Enums.SignedVerifyStatus.None;
- }, this);
-
- this.viewPgpSignedVerifyUser = ko.computed(function () {
- return this.message() ? this.message().pgpSignedVerifyUser() : '';
- }, this);
-
- this.message.subscribe(function (oMessage) {
-
- this.messageActiveDom(null);
-
- this.viewPgpPassword('');
-
- if (oMessage)
- {
- if (this.viewHash !== oMessage.hash)
- {
- this.scrollMessageToTop();
+ var
+ self = this,
+ sLastEmail = '',
+ oData = RL.data(),
+ createCommandHelper = function (sType) {
+ return Utils.createCommand(self, function () {
+ this.replyOrforward(sType);
+ }, self.canBeRepliedOrForwarded);
}
+ ;
- this.viewHash = oMessage.hash;
- this.viewSubject(oMessage.subject());
- this.viewFromShort(oMessage.fromToLine(true, true));
- this.viewToShort(oMessage.toToLine(true, true));
- this.viewFrom(oMessage.fromToLine(false));
- this.viewTo(oMessage.toToLine(false));
- this.viewCc(oMessage.ccToLine(false));
- this.viewBcc(oMessage.bccToLine(false));
- this.viewDate(oMessage.fullFormatDateValue());
- this.viewMoment(oMessage.momentDate());
- this.viewLineAsCcc(oMessage.lineAsCcc());
- this.viewViewLink(oMessage.viewLink());
- this.viewDownloadLink(oMessage.downloadLink());
+ this.oMessageScrollerDom = null;
- sLastEmail = oMessage.fromAsSingleEmail();
- RL.cache().getUserPic(sLastEmail, function (sPic, $sEmail) {
- if (sPic !== self.viewUserPic() && sLastEmail === $sEmail)
+ this.keyScope = oData.keyScope;
+ this.message = oData.message;
+ this.currentMessage = oData.currentMessage;
+ this.messageListChecked = oData.messageListChecked;
+ this.hasCheckedMessages = oData.hasCheckedMessages;
+ this.messageListCheckedOrSelectedUidsWithSubMails = oData.messageListCheckedOrSelectedUidsWithSubMails;
+ this.messageLoading = oData.messageLoading;
+ this.messageLoadingThrottle = oData.messageLoadingThrottle;
+ this.messagesBodiesDom = oData.messagesBodiesDom;
+ this.useThreads = oData.useThreads;
+ this.replySameFolder = oData.replySameFolder;
+ this.layout = oData.layout;
+ this.usePreviewPane = oData.usePreviewPane;
+ this.isMessageSelected = oData.isMessageSelected;
+ this.messageActiveDom = oData.messageActiveDom;
+ this.messageError = oData.messageError;
+
+ this.fullScreenMode = oData.messageFullScreenMode;
+
+ this.showFullInfo = ko.observable(false);
+ this.moreDropdownTrigger = ko.observable(false);
+ this.messageDomFocused = ko.observable(false).extend({'rateLimit': 0});
+
+ this.messageVisibility = ko.computed(function () {
+ return !this.messageLoadingThrottle() && !!this.message();
+ }, this);
+
+ this.message.subscribe(function (oMessage) {
+ if (!oMessage)
+ {
+ this.currentMessage(null);
+ }
+ }, this);
+
+ this.canBeRepliedOrForwarded = this.messageVisibility;
+
+ // commands
+ this.closeMessage = Utils.createCommand(this, function () {
+ oData.message(null);
+ });
+
+ this.replyCommand = createCommandHelper(Enums.ComposeType.Reply);
+ this.replyAllCommand = createCommandHelper(Enums.ComposeType.ReplyAll);
+ this.forwardCommand = createCommandHelper(Enums.ComposeType.Forward);
+ this.forwardAsAttachmentCommand = createCommandHelper(Enums.ComposeType.ForwardAsAttachment);
+ this.editAsNewCommand = createCommandHelper(Enums.ComposeType.EditAsNew);
+
+ this.messageVisibilityCommand = Utils.createCommand(this, Utils.emptyFunction, this.messageVisibility);
+
+ this.messageEditCommand = Utils.createCommand(this, function () {
+ this.editMessage();
+ }, this.messageVisibility);
+
+ this.deleteCommand = Utils.createCommand(this, function () {
+ if (this.message())
+ {
+ RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
+ this.message().folderFullNameRaw,
+ [this.message().uid], true);
+ }
+ }, this.messageVisibility);
+
+ this.deleteWithoutMoveCommand = Utils.createCommand(this, function () {
+ if (this.message())
+ {
+ RL.deleteMessagesFromFolder(Enums.FolderType.Trash,
+ RL.data().currentFolderFullNameRaw(),
+ [this.message().uid], false);
+ }
+ }, this.messageVisibility);
+
+ this.archiveCommand = Utils.createCommand(this, function () {
+ if (this.message())
+ {
+ RL.deleteMessagesFromFolder(Enums.FolderType.Archive,
+ this.message().folderFullNameRaw,
+ [this.message().uid], true);
+ }
+ }, this.messageVisibility);
+
+ this.spamCommand = Utils.createCommand(this, function () {
+ if (this.message())
+ {
+ RL.deleteMessagesFromFolder(Enums.FolderType.Spam,
+ this.message().folderFullNameRaw,
+ [this.message().uid], true);
+ }
+ }, this.messageVisibility);
+
+ this.notSpamCommand = Utils.createCommand(this, function () {
+ if (this.message())
+ {
+ RL.deleteMessagesFromFolder(Enums.FolderType.NotSpam,
+ this.message().folderFullNameRaw,
+ [this.message().uid], true);
+ }
+ }, this.messageVisibility);
+
+ // viewer
+ this.viewHash = '';
+ this.viewSubject = ko.observable('');
+ this.viewFromShort = ko.observable('');
+ this.viewToShort = ko.observable('');
+ this.viewFrom = ko.observable('');
+ this.viewTo = ko.observable('');
+ this.viewCc = ko.observable('');
+ this.viewBcc = ko.observable('');
+ this.viewDate = ko.observable('');
+ this.viewMoment = ko.observable('');
+ this.viewLineAsCcc = ko.observable('');
+ this.viewViewLink = ko.observable('');
+ this.viewDownloadLink = ko.observable('');
+ this.viewUserPic = ko.observable(Consts.DataImages.UserDotPic);
+ this.viewUserPicVisible = ko.observable(false);
+
+ this.viewPgpPassword = ko.observable('');
+ this.viewPgpSignedVerifyStatus = ko.computed(function () {
+ return this.message() ? this.message().pgpSignedVerifyStatus() : Enums.SignedVerifyStatus.None;
+ }, this);
+
+ this.viewPgpSignedVerifyUser = ko.computed(function () {
+ return this.message() ? this.message().pgpSignedVerifyUser() : '';
+ }, this);
+
+ this.message.subscribe(function (oMessage) {
+
+ this.messageActiveDom(null);
+
+ this.viewPgpPassword('');
+
+ if (oMessage)
+ {
+ if (this.viewHash !== oMessage.hash)
{
- self.viewUserPicVisible(false);
- self.viewUserPic(Consts.DataImages.UserDotPic);
- if ('' !== sPic)
- {
- self.viewUserPicVisible(true);
- self.viewUserPic(sPic);
- }
+ this.scrollMessageToTop();
}
- });
- }
- else
- {
- this.viewHash = '';
- this.scrollMessageToTop();
- }
- }, this);
+ this.viewHash = oMessage.hash;
+ this.viewSubject(oMessage.subject());
+ this.viewFromShort(oMessage.fromToLine(true, true));
+ this.viewToShort(oMessage.toToLine(true, true));
+ this.viewFrom(oMessage.fromToLine(false));
+ this.viewTo(oMessage.toToLine(false));
+ this.viewCc(oMessage.ccToLine(false));
+ this.viewBcc(oMessage.bccToLine(false));
+ this.viewDate(oMessage.fullFormatDateValue());
+ this.viewMoment(oMessage.momentDate());
+ this.viewLineAsCcc(oMessage.lineAsCcc());
+ this.viewViewLink(oMessage.viewLink());
+ this.viewDownloadLink(oMessage.downloadLink());
- this.fullScreenMode.subscribe(function (bValue) {
- if (bValue)
- {
- $html.addClass('rl-message-fullscreen');
- }
- else
- {
- $html.removeClass('rl-message-fullscreen');
- }
-
- Utils.windowResize();
- });
-
- this.messageLoadingThrottle.subscribe(function (bV) {
- if (bV)
- {
- Utils.windowResize();
- }
- });
-
- this.goUpCommand = Utils.createCommand(this, function () {
- RL.pub('mailbox.message-list.selector.go-up');
- });
-
- this.goDownCommand = Utils.createCommand(this, function () {
- RL.pub('mailbox.message-list.selector.go-down');
- });
-
- Knoin.constructorEnd(this);
-}
-
-Utils.extendAsViewModel('MailBoxMessageViewViewModel', MailBoxMessageViewViewModel);
-
-MailBoxMessageViewViewModel.prototype.isPgpActionVisible = function ()
-{
- return Enums.SignedVerifyStatus.Success !== this.viewPgpSignedVerifyStatus();
-};
-
-MailBoxMessageViewViewModel.prototype.isPgpStatusVerifyVisible = function ()
-{
- return Enums.SignedVerifyStatus.None !== this.viewPgpSignedVerifyStatus();
-};
-
-MailBoxMessageViewViewModel.prototype.isPgpStatusVerifySuccess = function ()
-{
- return Enums.SignedVerifyStatus.Success === this.viewPgpSignedVerifyStatus();
-};
-
-MailBoxMessageViewViewModel.prototype.pgpStatusVerifyMessage = function ()
-{
- var sResult = '';
- switch (this.viewPgpSignedVerifyStatus())
- {
- case Enums.SignedVerifyStatus.UnknownPublicKeys:
- sResult = Utils.i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND');
- break;
- case Enums.SignedVerifyStatus.UnknownPrivateKey:
- sResult = Utils.i18n('PGP_NOTIFICATIONS/NO_PRIVATE_KEY_FOUND');
- break;
- case Enums.SignedVerifyStatus.Unverified:
- sResult = Utils.i18n('PGP_NOTIFICATIONS/UNVERIFIRED_SIGNATURE');
- break;
- case Enums.SignedVerifyStatus.Error:
- sResult = Utils.i18n('PGP_NOTIFICATIONS/DECRYPTION_ERROR');
- break;
- case Enums.SignedVerifyStatus.Success:
- sResult = Utils.i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', {
- 'USER': this.viewPgpSignedVerifyUser()
- });
- break;
- }
-
- return sResult;
-};
-
-MailBoxMessageViewViewModel.prototype.scrollToTop = function ()
-{
- var oCont = $('.messageItem.nano .content', this.viewModelDom);
- if (oCont && oCont[0])
- {
-// oCont.animate({'scrollTop': 0}, 300);
- oCont.scrollTop(0);
- }
- else
- {
-// $('.messageItem', this.viewModelDom).animate({'scrollTop': 0}, 300);
- $('.messageItem', this.viewModelDom).scrollTop(0);
- }
-
- Utils.windowResize();
-};
-
-MailBoxMessageViewViewModel.prototype.fullScreen = function ()
-{
- this.fullScreenMode(true);
- Utils.windowResize();
-};
-
-MailBoxMessageViewViewModel.prototype.unFullScreen = function ()
-{
- this.fullScreenMode(false);
- Utils.windowResize();
-};
-
-MailBoxMessageViewViewModel.prototype.toggleFullScreen = function ()
-{
- Utils.removeSelection();
-
- this.fullScreenMode(!this.fullScreenMode());
- Utils.windowResize();
-};
-
-/**
- * @param {string} sType
- */
-MailBoxMessageViewViewModel.prototype.replyOrforward = function (sType)
-{
- kn.showScreenPopup(PopupsComposeViewModel, [sType, RL.data().message()]);
-};
-
-MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
-{
- var
- self = this,
- oData = RL.data()
- ;
-
- this.fullScreenMode.subscribe(function (bValue) {
- if (bValue)
- {
- self.message.focused(true);
- }
- }, this);
-
- $('.attachmentsPlace', oDom).magnificPopup({
- 'delegate': '.magnificPopupImage:visible',
- 'type': 'image',
- 'gallery': {
- 'enabled': true,
- 'preload': [1, 1],
- 'navigateByImgClick': true
- },
- 'callbacks': {
- 'open': function() {
- oData.useKeyboardShortcuts(false);
- },
- 'close': function() {
- oData.useKeyboardShortcuts(true);
- }
- },
- 'mainClass': 'mfp-fade',
- 'removalDelay': 400
- });
-
- oDom
- .on('click', '.messageView .messageItem .messageItemHeader', function () {
- if (oData.useKeyboardShortcuts() && self.message())
- {
- self.message.focused(true);
- }
- })
- .on('click', 'a', function (oEvent) {
- // setup maito protocol
- return !(!!oEvent && 3 !== oEvent['which'] && RL.mailToHelper($(this).attr('href')));
- })
- .on('click', '.attachmentsPlace .attachmentPreview', function (oEvent) {
- if (oEvent && oEvent.stopPropagation)
- {
- oEvent.stopPropagation();
- }
- })
- .on('click', '.attachmentsPlace .attachmentItem', function () {
-
- var
- oAttachment = ko.dataFor(this)
- ;
-
- if (oAttachment && oAttachment.download)
- {
- RL.download(oAttachment.linkDownload());
- }
- })
- ;
-
- this.message.focused.subscribe(function (bValue) {
- if (bValue && !Utils.inFocus()) {
- this.messageDomFocused(true);
- } else {
- this.messageDomFocused(false);
- }
- }, this);
-
- this.messageDomFocused.subscribe(function (bValue) {
- if (!bValue && Enums.KeyState.MessageView === this.keyScope())
- {
- this.message.focused(false);
- }
- }, this);
-
- this.keyScope.subscribe(function (sValue) {
- if (Enums.KeyState.MessageView === sValue && this.message.focused())
- {
- this.messageDomFocused(true);
- }
- }, this);
-
- this.oMessageScrollerDom = oDom.find('.messageItem .content');
- this.oMessageScrollerDom = this.oMessageScrollerDom && this.oMessageScrollerDom[0] ? this.oMessageScrollerDom : null;
-
- this.initShortcuts();
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.escShortcuts = function ()
-{
- if (this.viewModelVisibility() && this.message())
- {
- if (this.fullScreenMode())
- {
- this.fullScreenMode(false);
- }
- else if (Enums.Layout.NoPreview === RL.data().layout())
- {
- this.message(null);
- }
- else
- {
- this.message.focused(false);
- }
-
- return false;
- }
-};
-
-MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
-{
- var
- self = this,
- oData = RL.data()
- ;
-
- // exit fullscreen, back
- key('esc', Enums.KeyState.MessageView, _.bind(this.escShortcuts, this));
-
- // fullscreen
- key('enter', Enums.KeyState.MessageView, function () {
- self.toggleFullScreen();
- return false;
- });
-
- key('enter', Enums.KeyState.MessageList, function () {
- if (Enums.Layout.NoPreview !== oData.layout() && self.message())
- {
- self.toggleFullScreen();
- return false;
- }
- });
-
- // TODO // more toggle
-// key('', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
-// self.moreDropdownTrigger(true);
-// return false;
-// });
-
- // reply
- key('r', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
- if (oData.message())
- {
- self.replyCommand();
- return false;
- }
- });
-
- // replaAll
- key('a', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
- if (oData.message())
- {
- self.replyAllCommand();
- return false;
- }
- });
-
- // forward
- key('f', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
- if (oData.message())
- {
- self.forwardCommand();
- return false;
- }
- });
-
- // message information
-// key('i', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
-// if (oData.message())
-// {
-// self.showFullInfo(!self.showFullInfo());
-// return false;
-// }
-// });
-
- // toggle message blockquotes
- key('b', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
- if (oData.message() && oData.message().body)
- {
- Utils.toggleMessageBlockquote(oData.message().body);
- return false;
- }
- });
-
- key('ctrl+left, command+left, ctrl+up, command+up', Enums.KeyState.MessageView, function () {
- self.goUpCommand();
- return false;
- });
-
- key('ctrl+right, command+right, ctrl+down, command+down', Enums.KeyState.MessageView, function () {
- self.goDownCommand();
- return false;
- });
-
- // print
- key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
- if (self.message())
- {
- self.message().printMessage();
- }
-
- return false;
- });
-
- // delete
- key('delete, shift+delete', Enums.KeyState.MessageView, function (event, handler) {
- if (event)
- {
- if (handler && 'shift+delete' === handler.shortcut)
- {
- self.deleteWithoutMoveCommand();
+ sLastEmail = oMessage.fromAsSingleEmail();
+ RL.cache().getUserPic(sLastEmail, function (sPic, $sEmail) {
+ if (sPic !== self.viewUserPic() && sLastEmail === $sEmail)
+ {
+ self.viewUserPicVisible(false);
+ self.viewUserPic(Consts.DataImages.UserDotPic);
+ if ('' !== sPic)
+ {
+ self.viewUserPicVisible(true);
+ self.viewUserPic(sPic);
+ }
+ }
+ });
}
else
{
- self.deleteCommand();
+ this.viewHash = '';
+ this.scrollMessageToTop();
+ }
+
+ }, this);
+
+ this.fullScreenMode.subscribe(function (bValue) {
+ if (bValue)
+ {
+ $html.addClass('rl-message-fullscreen');
+ }
+ else
+ {
+ $html.removeClass('rl-message-fullscreen');
+ }
+
+ Utils.windowResize();
+ });
+
+ this.messageLoadingThrottle.subscribe(function (bV) {
+ if (bV)
+ {
+ Utils.windowResize();
+ }
+ });
+
+ this.goUpCommand = Utils.createCommand(this, function () {
+ RL.pub('mailbox.message-list.selector.go-up');
+ });
+
+ this.goDownCommand = Utils.createCommand(this, function () {
+ RL.pub('mailbox.message-list.selector.go-down');
+ });
+
+ kn.constructorEnd(this);
+ }
+
+ Utils.extendAsViewModel('MailBoxMessageViewViewModel', MailBoxMessageViewViewModel);
+
+ MailBoxMessageViewViewModel.prototype.isPgpActionVisible = function ()
+ {
+ return Enums.SignedVerifyStatus.Success !== this.viewPgpSignedVerifyStatus();
+ };
+
+ MailBoxMessageViewViewModel.prototype.isPgpStatusVerifyVisible = function ()
+ {
+ return Enums.SignedVerifyStatus.None !== this.viewPgpSignedVerifyStatus();
+ };
+
+ MailBoxMessageViewViewModel.prototype.isPgpStatusVerifySuccess = function ()
+ {
+ return Enums.SignedVerifyStatus.Success === this.viewPgpSignedVerifyStatus();
+ };
+
+ MailBoxMessageViewViewModel.prototype.pgpStatusVerifyMessage = function ()
+ {
+ var sResult = '';
+ switch (this.viewPgpSignedVerifyStatus())
+ {
+ case Enums.SignedVerifyStatus.UnknownPublicKeys:
+ sResult = Utils.i18n('PGP_NOTIFICATIONS/NO_PUBLIC_KEYS_FOUND');
+ break;
+ case Enums.SignedVerifyStatus.UnknownPrivateKey:
+ sResult = Utils.i18n('PGP_NOTIFICATIONS/NO_PRIVATE_KEY_FOUND');
+ break;
+ case Enums.SignedVerifyStatus.Unverified:
+ sResult = Utils.i18n('PGP_NOTIFICATIONS/UNVERIFIRED_SIGNATURE');
+ break;
+ case Enums.SignedVerifyStatus.Error:
+ sResult = Utils.i18n('PGP_NOTIFICATIONS/DECRYPTION_ERROR');
+ break;
+ case Enums.SignedVerifyStatus.Success:
+ sResult = Utils.i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', {
+ 'USER': this.viewPgpSignedVerifyUser()
+ });
+ break;
+ }
+
+ return sResult;
+ };
+
+ MailBoxMessageViewViewModel.prototype.scrollToTop = function ()
+ {
+ var oCont = $('.messageItem.nano .content', this.viewModelDom);
+ if (oCont && oCont[0])
+ {
+ // oCont.animate({'scrollTop': 0}, 300);
+ oCont.scrollTop(0);
+ }
+ else
+ {
+ // $('.messageItem', this.viewModelDom).animate({'scrollTop': 0}, 300);
+ $('.messageItem', this.viewModelDom).scrollTop(0);
+ }
+
+ Utils.windowResize();
+ };
+
+ MailBoxMessageViewViewModel.prototype.fullScreen = function ()
+ {
+ this.fullScreenMode(true);
+ Utils.windowResize();
+ };
+
+ MailBoxMessageViewViewModel.prototype.unFullScreen = function ()
+ {
+ this.fullScreenMode(false);
+ Utils.windowResize();
+ };
+
+ MailBoxMessageViewViewModel.prototype.toggleFullScreen = function ()
+ {
+ Utils.removeSelection();
+
+ this.fullScreenMode(!this.fullScreenMode());
+ Utils.windowResize();
+ };
+
+ /**
+ * @param {string} sType
+ */
+ MailBoxMessageViewViewModel.prototype.replyOrforward = function (sType)
+ {
+ kn.showScreenPopup(PopupsComposeViewModel, [sType, RL.data().message()]);
+ };
+
+ MailBoxMessageViewViewModel.prototype.onBuild = function (oDom)
+ {
+ var
+ self = this,
+ oData = RL.data()
+ ;
+
+ this.fullScreenMode.subscribe(function (bValue) {
+ if (bValue)
+ {
+ self.message.focused(true);
+ }
+ }, this);
+
+ $('.attachmentsPlace', oDom).magnificPopup({
+ 'delegate': '.magnificPopupImage:visible',
+ 'type': 'image',
+ 'gallery': {
+ 'enabled': true,
+ 'preload': [1, 1],
+ 'navigateByImgClick': true
+ },
+ 'callbacks': {
+ 'open': function() {
+ oData.useKeyboardShortcuts(false);
+ },
+ 'close': function() {
+ oData.useKeyboardShortcuts(true);
+ }
+ },
+ 'mainClass': 'mfp-fade',
+ 'removalDelay': 400
+ });
+
+ oDom
+ .on('click', '.messageView .messageItem .messageItemHeader', function () {
+ if (oData.useKeyboardShortcuts() && self.message())
+ {
+ self.message.focused(true);
+ }
+ })
+ .on('click', 'a', function (oEvent) {
+ // setup maito protocol
+ return !(!!oEvent && 3 !== oEvent['which'] && RL.mailToHelper($(this).attr('href')));
+ })
+ .on('click', '.attachmentsPlace .attachmentPreview', function (oEvent) {
+ if (oEvent && oEvent.stopPropagation)
+ {
+ oEvent.stopPropagation();
+ }
+ })
+ .on('click', '.attachmentsPlace .attachmentItem', function () {
+
+ var
+ oAttachment = ko.dataFor(this)
+ ;
+
+ if (oAttachment && oAttachment.download)
+ {
+ RL.download(oAttachment.linkDownload());
+ }
+ })
+ ;
+
+ this.message.focused.subscribe(function (bValue) {
+ if (bValue && !Utils.inFocus()) {
+ this.messageDomFocused(true);
+ } else {
+ this.messageDomFocused(false);
+ }
+ }, this);
+
+ this.messageDomFocused.subscribe(function (bValue) {
+ if (!bValue && Enums.KeyState.MessageView === this.keyScope())
+ {
+ this.message.focused(false);
+ }
+ }, this);
+
+ this.keyScope.subscribe(function (sValue) {
+ if (Enums.KeyState.MessageView === sValue && this.message.focused())
+ {
+ this.messageDomFocused(true);
+ }
+ }, this);
+
+ this.oMessageScrollerDom = oDom.find('.messageItem .content');
+ this.oMessageScrollerDom = this.oMessageScrollerDom && this.oMessageScrollerDom[0] ? this.oMessageScrollerDom : null;
+
+ this.initShortcuts();
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.escShortcuts = function ()
+ {
+ if (this.viewModelVisibility() && this.message())
+ {
+ if (this.fullScreenMode())
+ {
+ this.fullScreenMode(false);
+ }
+ else if (Enums.Layout.NoPreview === RL.data().layout())
+ {
+ this.message(null);
+ }
+ else
+ {
+ this.message.focused(false);
}
return false;
}
- });
+ };
- // change focused state
- key('tab, shift+tab, left', Enums.KeyState.MessageView, function () {
- if (!self.fullScreenMode() && self.message() && Enums.Layout.NoPreview !== oData.layout())
+ MailBoxMessageViewViewModel.prototype.initShortcuts = function ()
+ {
+ var
+ self = this,
+ oData = RL.data()
+ ;
+
+ // exit fullscreen, back
+ key('esc', Enums.KeyState.MessageView, _.bind(this.escShortcuts, this));
+
+ // fullscreen
+ key('enter', Enums.KeyState.MessageView, function () {
+ self.toggleFullScreen();
+ return false;
+ });
+
+ key('enter', Enums.KeyState.MessageList, function () {
+ if (Enums.Layout.NoPreview !== oData.layout() && self.message())
+ {
+ self.toggleFullScreen();
+ return false;
+ }
+ });
+
+ // TODO // more toggle
+ // key('', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ // self.moreDropdownTrigger(true);
+ // return false;
+ // });
+
+ // reply
+ key('r', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ if (oData.message())
+ {
+ self.replyCommand();
+ return false;
+ }
+ });
+
+ // replaAll
+ key('a', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ if (oData.message())
+ {
+ self.replyAllCommand();
+ return false;
+ }
+ });
+
+ // forward
+ key('f', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ if (oData.message())
+ {
+ self.forwardCommand();
+ return false;
+ }
+ });
+
+ // message information
+ // key('i', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ // if (oData.message())
+ // {
+ // self.showFullInfo(!self.showFullInfo());
+ // return false;
+ // }
+ // });
+
+ // toggle message blockquotes
+ key('b', [Enums.KeyState.MessageList, Enums.KeyState.MessageView], function () {
+ if (oData.message() && oData.message().body)
+ {
+ Utils.toggleMessageBlockquote(oData.message().body);
+ return false;
+ }
+ });
+
+ key('ctrl+left, command+left, ctrl+up, command+up', Enums.KeyState.MessageView, function () {
+ self.goUpCommand();
+ return false;
+ });
+
+ key('ctrl+right, command+right, ctrl+down, command+down', Enums.KeyState.MessageView, function () {
+ self.goDownCommand();
+ return false;
+ });
+
+ // print
+ key('ctrl+p, command+p', Enums.KeyState.MessageView, function () {
+ if (self.message())
+ {
+ self.message().printMessage();
+ }
+
+ return false;
+ });
+
+ // delete
+ key('delete, shift+delete', Enums.KeyState.MessageView, function (event, handler) {
+ if (event)
+ {
+ if (handler && 'shift+delete' === handler.shortcut)
+ {
+ self.deleteWithoutMoveCommand();
+ }
+ else
+ {
+ self.deleteCommand();
+ }
+
+ return false;
+ }
+ });
+
+ // change focused state
+ key('tab, shift+tab, left', Enums.KeyState.MessageView, function () {
+ if (!self.fullScreenMode() && self.message() && Enums.Layout.NoPreview !== oData.layout())
+ {
+ self.message.focused(false);
+ }
+
+ return false;
+ });
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isDraftFolder = function ()
+ {
+ return RL.data().message() && RL.data().draftFolder() === RL.data().message().folderFullNameRaw;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isSentFolder = function ()
+ {
+ return RL.data().message() && RL.data().sentFolder() === RL.data().message().folderFullNameRaw;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isSpamFolder = function ()
+ {
+ return RL.data().message() && RL.data().spamFolder() === RL.data().message().folderFullNameRaw;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isSpamDisabled = function ()
+ {
+ return RL.data().message() && RL.data().spamFolder() === Consts.Values.UnuseOptionValue;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isArchiveFolder = function ()
+ {
+ return RL.data().message() && RL.data().archiveFolder() === RL.data().message().folderFullNameRaw;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isArchiveDisabled = function ()
+ {
+ return RL.data().message() && RL.data().archiveFolder() === Consts.Values.UnuseOptionValue;
+ };
+
+ /**
+ * @return {boolean}
+ */
+ MailBoxMessageViewViewModel.prototype.isDraftOrSentFolder = function ()
+ {
+ return this.isDraftFolder() || this.isSentFolder();
+ };
+
+ MailBoxMessageViewViewModel.prototype.composeClick = function ()
+ {
+ kn.showScreenPopup(PopupsComposeViewModel);
+ };
+
+ MailBoxMessageViewViewModel.prototype.editMessage = function ()
+ {
+ if (RL.data().message())
{
- self.message.focused(false);
+ kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Draft, RL.data().message()]);
}
+ };
- return false;
- });
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isDraftFolder = function ()
-{
- return RL.data().message() && RL.data().draftFolder() === RL.data().message().folderFullNameRaw;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isSentFolder = function ()
-{
- return RL.data().message() && RL.data().sentFolder() === RL.data().message().folderFullNameRaw;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isSpamFolder = function ()
-{
- return RL.data().message() && RL.data().spamFolder() === RL.data().message().folderFullNameRaw;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isSpamDisabled = function ()
-{
- return RL.data().message() && RL.data().spamFolder() === Consts.Values.UnuseOptionValue;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isArchiveFolder = function ()
-{
- return RL.data().message() && RL.data().archiveFolder() === RL.data().message().folderFullNameRaw;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isArchiveDisabled = function ()
-{
- return RL.data().message() && RL.data().archiveFolder() === Consts.Values.UnuseOptionValue;
-};
-
-/**
- * @return {boolean}
- */
-MailBoxMessageViewViewModel.prototype.isDraftOrSentFolder = function ()
-{
- return this.isDraftFolder() || this.isSentFolder();
-};
-
-MailBoxMessageViewViewModel.prototype.composeClick = function ()
-{
- kn.showScreenPopup(PopupsComposeViewModel);
-};
-
-MailBoxMessageViewViewModel.prototype.editMessage = function ()
-{
- if (RL.data().message())
+ MailBoxMessageViewViewModel.prototype.scrollMessageToTop = function ()
{
- kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Draft, RL.data().message()]);
- }
-};
+ if (this.oMessageScrollerDom)
+ {
+ this.oMessageScrollerDom.scrollTop(0);
+ }
+ };
-MailBoxMessageViewViewModel.prototype.scrollMessageToTop = function ()
-{
- if (this.oMessageScrollerDom)
+ /**
+ * @param {MessageModel} oMessage
+ */
+ MailBoxMessageViewViewModel.prototype.showImages = function (oMessage)
{
- this.oMessageScrollerDom.scrollTop(0);
- }
-};
+ if (oMessage && oMessage.showExternalImages)
+ {
+ oMessage.showExternalImages(true);
+ }
+ };
-/**
- * @param {MessageModel} oMessage
- */
-MailBoxMessageViewViewModel.prototype.showImages = function (oMessage)
-{
- if (oMessage && oMessage.showExternalImages)
+ /**
+ * @returns {string}
+ */
+ MailBoxMessageViewViewModel.prototype.printableCheckedMessageCount = function ()
{
- oMessage.showExternalImages(true);
- }
-};
-
-/**
- * @returns {string}
- */
-MailBoxMessageViewViewModel.prototype.printableCheckedMessageCount = function ()
-{
- var iCnt = this.messageListCheckedOrSelectedUidsWithSubMails().length;
- return 0 < iCnt ? (100 > iCnt ? iCnt : '99+') : '';
-};
+ var iCnt = this.messageListCheckedOrSelectedUidsWithSubMails().length;
+ return 0 < iCnt ? (100 > iCnt ? iCnt : '99+') : '';
+ };
-/**
- * @param {MessageModel} oMessage
- */
-MailBoxMessageViewViewModel.prototype.verifyPgpSignedClearMessage = function (oMessage)
-{
- if (oMessage)
+ /**
+ * @param {MessageModel} oMessage
+ */
+ MailBoxMessageViewViewModel.prototype.verifyPgpSignedClearMessage = function (oMessage)
{
- oMessage.verifyPgpSignedClearMessage();
- }
-};
+ if (oMessage)
+ {
+ oMessage.verifyPgpSignedClearMessage();
+ }
+ };
-/**
- * @param {MessageModel} oMessage
- */
-MailBoxMessageViewViewModel.prototype.decryptPgpEncryptedMessage = function (oMessage)
-{
- if (oMessage)
+ /**
+ * @param {MessageModel} oMessage
+ */
+ MailBoxMessageViewViewModel.prototype.decryptPgpEncryptedMessage = function (oMessage)
{
- oMessage.decryptPgpEncryptedMessage(this.viewPgpPassword());
- }
-};
+ if (oMessage)
+ {
+ oMessage.decryptPgpEncryptedMessage(this.viewPgpPassword());
+ }
+ };
-/**
- * @param {MessageModel} oMessage
- */
-MailBoxMessageViewViewModel.prototype.readReceipt = function (oMessage)
-{
- if (oMessage && '' !== oMessage.readReceipt())
+ /**
+ * @param {MessageModel} oMessage
+ */
+ MailBoxMessageViewViewModel.prototype.readReceipt = function (oMessage)
{
- RL.remote().sendReadReceiptMessage(Utils.emptyFunction, oMessage.folderFullNameRaw, oMessage.uid,
- oMessage.readReceipt(),
- Utils.i18n('READ_RECEIPT/SUBJECT', {'SUBJECT': oMessage.subject()}),
- Utils.i18n('READ_RECEIPT/BODY', {'READ-RECEIPT': RL.data().accountEmail()}));
+ if (oMessage && '' !== oMessage.readReceipt())
+ {
+ RL.remote().sendReadReceiptMessage(Utils.emptyFunction, oMessage.folderFullNameRaw, oMessage.uid,
+ oMessage.readReceipt(),
+ Utils.i18n('READ_RECEIPT/SUBJECT', {'SUBJECT': oMessage.subject()}),
+ Utils.i18n('READ_RECEIPT/BODY', {'READ-RECEIPT': RL.data().accountEmail()}));
- oMessage.isReadReceipt(true);
+ oMessage.isReadReceipt(true);
- RL.cache().storeMessageFlagsToCache(oMessage);
- RL.reloadFlagsCurrentMessageListAndMessageFromCache();
- }
-};
+ RL.cache().storeMessageFlagsToCache(oMessage);
+ RL.reloadFlagsCurrentMessageListAndMessageFromCache();
+ }
+ };
+
+ module.exports = MailBoxMessageViewViewModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/ViewModels/MailBoxSystemDropDownViewModel.js b/dev/ViewModels/MailBoxSystemDropDownViewModel.js
index fdeb0f10c..0ed5aa0bf 100644
--- a/dev/ViewModels/MailBoxSystemDropDownViewModel.js
+++ b/dev/ViewModels/MailBoxSystemDropDownViewModel.js
@@ -1,13 +1,27 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends AbstractSystemDropDownViewModel
- */
-function MailBoxSystemDropDownViewModel()
-{
- AbstractSystemDropDownViewModel.call(this);
- Knoin.constructorEnd(this);
-}
+(function (module) {
-Utils.extendAsViewModel('MailBoxSystemDropDownViewModel', MailBoxSystemDropDownViewModel, AbstractSystemDropDownViewModel);
+ 'use strict';
+
+ var
+ Utils = require('../Common/Utils.js'),
+ kn = require('../Knoin/Knoin.js'),
+ AbstractSystemDropDownViewModel = require('./AbstractSystemDropDownViewModel.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractSystemDropDownViewModel
+ */
+ function MailBoxSystemDropDownViewModel()
+ {
+ AbstractSystemDropDownViewModel.call(this);
+ kn.constructorEnd(this);
+ }
+
+ Utils.extendAsViewModel('MailBoxSystemDropDownViewModel', MailBoxSystemDropDownViewModel, AbstractSystemDropDownViewModel);
+
+ module.exports = MailBoxSystemDropDownViewModel;
+
+}(module));
diff --git a/dev/ViewModels/SettingsMenuViewModel.js b/dev/ViewModels/SettingsMenuViewModel.js
index fc8c894e8..fd6fc8cab 100644
--- a/dev/ViewModels/SettingsMenuViewModel.js
+++ b/dev/ViewModels/SettingsMenuViewModel.js
@@ -1,30 +1,44 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @param {?} oScreen
- *
- * @constructor
- * @extends KnoinAbstractViewModel
- */
-function SettingsMenuViewModel(oScreen)
-{
- KnoinAbstractViewModel.call(this, 'Left', 'SettingsMenu');
+(function (module) {
- this.leftPanelDisabled = RL.data().leftPanelDisabled;
+ 'use strict';
- this.menu = oScreen.menu;
+ var
+ Utils = require('../Common/Utils.js'),
+ kn = require('../Knoin/Knoin.js'),
+ KnoinAbstractViewModel = require('../Knoin/KnoinAbstractViewModel.js')
+ ;
- Knoin.constructorEnd(this);
-}
+ /**
+ * @param {?} oScreen
+ *
+ * @constructor
+ * @extends KnoinAbstractViewModel
+ */
+ function SettingsMenuViewModel(oScreen)
+ {
+ KnoinAbstractViewModel.call(this, 'Left', 'SettingsMenu');
-Utils.extendAsViewModel('SettingsMenuViewModel', SettingsMenuViewModel);
+ this.leftPanelDisabled = RL.data().leftPanelDisabled; // TODO cjs
-SettingsMenuViewModel.prototype.link = function (sRoute)
-{
- return RL.link().settings(sRoute);
-};
+ this.menu = oScreen.menu;
-SettingsMenuViewModel.prototype.backToMailBoxClick = function ()
-{
- kn.setHash(RL.link().inbox());
-};
+ kn.constructorEnd(this);
+ }
+
+ Utils.extendAsViewModel('SettingsMenuViewModel', SettingsMenuViewModel);
+
+ SettingsMenuViewModel.prototype.link = function (sRoute)
+ {
+ return RL.link().settings(sRoute);// TODO cjs
+ };
+
+ SettingsMenuViewModel.prototype.backToMailBoxClick = function ()
+ {
+ kn.setHash(RL.link().inbox()); // TODO cjs
+ };
+
+ module.exports = SettingsMenuViewModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/ViewModels/SettingsPaneViewModel.js b/dev/ViewModels/SettingsPaneViewModel.js
index b6d5ee08c..6653ec34a 100644
--- a/dev/ViewModels/SettingsPaneViewModel.js
+++ b/dev/ViewModels/SettingsPaneViewModel.js
@@ -1,32 +1,48 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends KnoinAbstractViewModel
- */
-function SettingsPaneViewModel()
-{
- KnoinAbstractViewModel.call(this, 'Right', 'SettingsPane');
+(function (module) {
- Knoin.constructorEnd(this);
-}
+ 'use strict';
-Utils.extendAsViewModel('SettingsPaneViewModel', SettingsPaneViewModel);
+ var
+ key = require('../External/key.js'),
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js'),
+ kn = require('../Knoin/Knoin.js'),
+ KnoinAbstractViewModel = require('../Knoin/KnoinAbstractViewModel.js')
+ ;
-SettingsPaneViewModel.prototype.onBuild = function ()
-{
- var self = this;
- key('esc', Enums.KeyState.Settings, function () {
- self.backToMailBoxClick();
- });
-};
+ /**
+ * @constructor
+ * @extends KnoinAbstractViewModel
+ */
+ function SettingsPaneViewModel()
+ {
+ KnoinAbstractViewModel.call(this, 'Right', 'SettingsPane');
-SettingsPaneViewModel.prototype.onShow = function ()
-{
- RL.data().message(null);
-};
+ kn.constructorEnd(this);
+ }
-SettingsPaneViewModel.prototype.backToMailBoxClick = function ()
-{
- kn.setHash(RL.link().inbox());
-};
+ Utils.extendAsViewModel('SettingsPaneViewModel', SettingsPaneViewModel);
+
+ SettingsPaneViewModel.prototype.onBuild = function ()
+ {
+ var self = this;
+ key('esc', Enums.KeyState.Settings, function () {
+ self.backToMailBoxClick();
+ });
+ };
+
+ SettingsPaneViewModel.prototype.onShow = function ()
+ {
+ RL.data().message(null); // TODO cjs
+ };
+
+ SettingsPaneViewModel.prototype.backToMailBoxClick = function ()
+ {
+ kn.setHash(RL.link().inbox()); // TODO cjs
+ };
+
+ module.exports = SettingsPaneViewModel;
+
+}(module));
\ No newline at end of file
diff --git a/dev/ViewModels/SettingsSystemDropDownViewModel.js b/dev/ViewModels/SettingsSystemDropDownViewModel.js
index 2c102dc31..2e6c74b78 100644
--- a/dev/ViewModels/SettingsSystemDropDownViewModel.js
+++ b/dev/ViewModels/SettingsSystemDropDownViewModel.js
@@ -1,13 +1,27 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
-/**
- * @constructor
- * @extends AbstractSystemDropDownViewModel
- */
-function SettingsSystemDropDownViewModel()
-{
- AbstractSystemDropDownViewModel.call(this);
- Knoin.constructorEnd(this);
-}
+(function (module) {
-Utils.extendAsViewModel('SettingsSystemDropDownViewModel', SettingsSystemDropDownViewModel, AbstractSystemDropDownViewModel);
+ 'use strict';
+
+ var
+ Utils = require('../Common/Utils.js'),
+ kn = require('./Knoin/Knoin.js'),
+ AbstractSystemDropDownViewModel = require('./AbstractSystemDropDownViewModel.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractSystemDropDownViewModel
+ */
+ function SettingsSystemDropDownViewModel()
+ {
+ AbstractSystemDropDownViewModel.call(this);
+ kn.constructorEnd(this);
+ }
+
+ Utils.extendAsViewModel('SettingsSystemDropDownViewModel', SettingsSystemDropDownViewModel, AbstractSystemDropDownViewModel);
+
+ module.exports = SettingsSystemDropDownViewModel;
+
+}(module));
\ No newline at end of file
diff --git a/gulpfile.js b/gulpfile.js
index 8efd70083..4e6a18a5a 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -607,4 +607,19 @@ gulp.task('build+', ['rainloop+']);
gulp.task('b', ['rainloop']);
gulp.task('b+', ['rainloop+']);
-gulp.task('own', ['owncloud']);
\ No newline at end of file
+gulp.task('own', ['owncloud']);
+
+var browserify = require('browserify');
+var source = require('vinyl-source-stream');
+
+gulp.task('bro', function() {
+ return browserify({
+ 'basedir': './dev/',
+ 'detectGlobals': false,
+ 'debug': false
+ })
+ .add('./RainLoopBoot.js')
+ .bundle()
+ .pipe(source('bro.js'))
+ .pipe(gulp.dest(cfg.paths.staticJS));
+});
diff --git a/package.json b/package.json
index 66722b891..63308eb88 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,9 @@
"node-fs": "*",
"jshint-summary": "*",
+ "browserify": "*",
+ "vinyl-source-stream": "latest",
+
"gulp": "*",
"gulp-util": "*",
"gulp-uglify": "*",
diff --git a/rainloop/v/0.0.0/static/js/bro.js b/rainloop/v/0.0.0/static/js/bro.js
new file mode 100644
index 000000000..005e2b372
--- /dev/null
+++ b/rainloop/v/0.0.0/static/js/bro.js
@@ -0,0 +1,6484 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o').appendTo('body');
+
+ $window.on('error', function (oEvent) {
+ if (oEvent && oEvent.originalEvent && oEvent.originalEvent.message &&
+ -1 === Utils.inArray(oEvent.originalEvent.message, [
+ 'Script error.', 'Uncaught Error: Error calling method on NPObject.'
+ ]))
+ {
+ // TODO cjs
+ RL.remote().jsError(
+ Utils.emptyFunction,
+ oEvent.originalEvent.message,
+ oEvent.originalEvent.filename,
+ oEvent.originalEvent.lineno,
+ window.location && window.location.toString ? window.location.toString() : '',
+ $html.attr('class'),
+ Utils.microtime() - Globals.now
+ );
+ }
+ });
+
+ $doc.on('keydown', function (oEvent) {
+ if (oEvent && oEvent.ctrlKey)
+ {
+ $html.addClass('rl-ctrl-key-pressed');
+ }
+ }).on('keyup', function (oEvent) {
+ if (oEvent && !oEvent.ctrlKey)
+ {
+ $html.removeClass('rl-ctrl-key-pressed');
+ }
+ });
+ }
+
+ _.extend(AbstractApp.prototype, KnoinAbstractBoot.prototype);
+
+ AbstractApp.prototype.oSettings = null;
+ AbstractApp.prototype.oPlugins = null;
+ AbstractApp.prototype.oLocal = null;
+ AbstractApp.prototype.oLink = null;
+ AbstractApp.prototype.oSubs = {};
+
+ /**
+ * @param {string} sLink
+ * @return {boolean}
+ */
+ AbstractApp.prototype.download = function (sLink)
+ {
+ var
+ oE = null,
+ oLink = null,
+ sUserAgent = window.navigator.userAgent.toLowerCase()
+ ;
+
+ if (sUserAgent && (sUserAgent.indexOf('chrome') > -1 || sUserAgent.indexOf('chrome') > -1))
+ {
+ oLink = window.document.createElement('a');
+ oLink['href'] = sLink;
+
+ if (window.document['createEvent'])
+ {
+ oE = window.document['createEvent']('MouseEvents');
+ if (oE && oE['initEvent'] && oLink['dispatchEvent'])
+ {
+ oE['initEvent']('click', true, true);
+ oLink['dispatchEvent'](oE);
+ return true;
+ }
+ }
+ }
+
+ if (Globals.bMobileDevice)
+ {
+ window.open(sLink, '_self');
+ window.focus();
+ }
+ else
+ {
+ this.iframe.attr('src', sLink);
+ // window.document.location.href = sLink;
+ }
+
+ return true;
+ };
+
+ /**
+ * @return {LinkBuilder}
+ */
+ AbstractApp.prototype.link = function ()
+ {
+ if (null === this.oLink)
+ {
+ this.oLink = new LinkBuilder(); // TODO cjs
+ }
+
+ return this.oLink;
+ };
+
+ /**
+ * @return {LocalStorage}
+ */
+ AbstractApp.prototype.local = function ()
+ {
+ if (null === this.oLocal)
+ {
+ this.oLocal = new LocalStorage(); // TODO cjs
+ }
+
+ return this.oLocal;
+ };
+
+ /**
+ * @param {string} sName
+ * @return {?}
+ */
+ AbstractApp.prototype.settingsGet = function (sName)
+ {
+ if (null === this.oSettings)
+ {
+ this.oSettings = Utils.isNormal(AppData) ? AppData : {};
+ }
+
+ return Utils.isUnd(this.oSettings[sName]) ? null : this.oSettings[sName];
+ };
+
+ /**
+ * @param {string} sName
+ * @param {?} mValue
+ */
+ AbstractApp.prototype.settingsSet = function (sName, mValue)
+ {
+ if (null === this.oSettings)
+ {
+ this.oSettings = Utils.isNormal(AppData) ? AppData : {};
+ }
+
+ this.oSettings[sName] = mValue;
+ };
+
+ AbstractApp.prototype.setTitle = function (sTitle)
+ {
+ sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') +
+ RL.settingsGet('Title') || ''; // TODO cjs
+
+ window.document.title = '_';
+ window.document.title = sTitle;
+ };
+
+ /**
+ * @param {boolean=} bLogout = false
+ * @param {boolean=} bClose = false
+ */
+ AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose)
+ {
+ var
+ sCustomLogoutLink = Utils.pString(RL.settingsGet('CustomLogoutLink')),
+ bInIframe = !!RL.settingsGet('InIframe')
+ ;
+
+ // TODO cjs
+
+ bLogout = Utils.isUnd(bLogout) ? false : !!bLogout;
+ bClose = Utils.isUnd(bClose) ? false : !!bClose;
+
+ if (bLogout && bClose && window.close)
+ {
+ window.close();
+ }
+
+ if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink)
+ {
+ _.delay(function () {
+ if (bInIframe && window.parent)
+ {
+ window.parent.location.href = sCustomLogoutLink;
+ }
+ else
+ {
+ window.location.href = sCustomLogoutLink;
+ }
+ }, 100);
+ }
+ else
+ {
+ kn.routeOff();
+ kn.setHash(RL.link().root(), true);
+ kn.routeOff();
+
+ _.delay(function () {
+ if (bInIframe && window.parent)
+ {
+ window.parent.location.reload();
+ }
+ else
+ {
+ window.location.reload();
+ }
+ }, 100);
+ }
+ };
+
+ AbstractApp.prototype.historyBack = function ()
+ {
+ window.history.back();
+ };
+
+ /**
+ * @param {string} sQuery
+ * @param {Function} fCallback
+ */
+ AbstractApp.prototype.getAutocomplete = function (sQuery, fCallback)
+ {
+ fCallback([], sQuery);
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Function} fFunc
+ * @param {Object=} oContext
+ * @return {AbstractApp}
+ */
+ AbstractApp.prototype.sub = function (sName, fFunc, oContext)
+ {
+ if (Utils.isUnd(this.oSubs[sName]))
+ {
+ this.oSubs[sName] = [];
+ }
+
+ this.oSubs[sName].push([fFunc, oContext]);
+
+ return this;
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Array=} aArgs
+ * @return {AbstractApp}
+ */
+ AbstractApp.prototype.pub = function (sName, aArgs)
+ {
+ Plugins.runHook('rl-pub', [sName, aArgs]);
+ if (!Utils.isUnd(this.oSubs[sName]))
+ {
+ _.each(this.oSubs[sName], function (aItem) {
+ if (aItem[0])
+ {
+ aItem[0].apply(aItem[1] || null, aArgs || []);
+ }
+ });
+ }
+
+ return this;
+ };
+
+ /**
+ * @param {string} sName
+ * @return {boolean}
+ */
+ AbstractApp.prototype.capa = function (sName)
+ {
+ var mCapa = this.settingsGet('Capa');
+ return Utils.isArray(mCapa) && Utils.isNormal(sName) && -1 < Utils.inArray(sName, mCapa);
+ };
+
+ AbstractApp.prototype.bootstart = function ()
+ {
+ var ssm = require('../External/ssm.js');
+
+ Utils.initOnStartOrLangChange(function () {
+ Utils.initNotificationLanguage();
+ }, null);
+
+ _.delay(function () {
+ Utils.windowResize();
+ }, 1000);
+
+ ssm.addState({
+ 'id': 'mobile',
+ 'maxWidth': 767,
+ 'onEnter': function() {
+ $html.addClass('ssm-state-mobile');
+ RL.pub('ssm.mobile-enter');
+ },
+ 'onLeave': function() {
+ $html.removeClass('ssm-state-mobile');
+ RL.pub('ssm.mobile-leave');
+ }
+ });
+
+ ssm.addState({
+ 'id': 'tablet',
+ 'minWidth': 768,
+ 'maxWidth': 999,
+ 'onEnter': function() {
+ $html.addClass('ssm-state-tablet');
+ },
+ 'onLeave': function() {
+ $html.removeClass('ssm-state-tablet');
+ }
+ });
+
+ ssm.addState({
+ 'id': 'desktop',
+ 'minWidth': 1000,
+ 'maxWidth': 1400,
+ 'onEnter': function() {
+ $html.addClass('ssm-state-desktop');
+ },
+ 'onLeave': function() {
+ $html.removeClass('ssm-state-desktop');
+ }
+ });
+
+ ssm.addState({
+ 'id': 'desktop-large',
+ 'minWidth': 1400,
+ 'onEnter': function() {
+ $html.addClass('ssm-state-desktop-large');
+ },
+ 'onLeave': function() {
+ $html.removeClass('ssm-state-desktop-large');
+ }
+ });
+
+ RL.sub('ssm.mobile-enter', function () { // TODO cjs
+ RL.data().leftPanelDisabled(true);
+ });
+
+ RL.sub('ssm.mobile-leave', function () { // TODO cjs
+ RL.data().leftPanelDisabled(false);
+ });
+
+ RL.data().leftPanelDisabled.subscribe(function (bValue) { // TODO cjs
+ $html.toggleClass('rl-left-panel-disabled', bValue);
+ });
+
+ ssm.ready();
+ };
+
+ module.exports = AbstractApp;
+
+}(module));
+},{"../Common/Globals.js":6,"../Common/Utils.js":8,"../External/$doc.js":9,"../External/$html.js":10,"../External/$window.js":11,"../External/AppData.js":12,"../External/ko.js":17,"../External/ssm.js":18,"../External/underscore.js":19,"../External/window.js":20,"../Knoin/KnoinAbstractBoot.js":22}],3:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ window = require('../External/window.js'),
+ $ = require('../External/jquery.js'),
+ _ = require('../External/underscore.js'),
+ Enums = require('../Common/Enums.js'),
+ Globals = require('../Common/Globals.js'),
+ Consts = require('../Common/Consts.js'),
+ Plugins = require('../Common/Plugins.js'),
+ Utils = require('../Common/Utils.js'),
+ kn = require('../Knoin/Knoin.js'),
+ AbstractApp = require('./AbstractApp.js')
+ ;
+
+ /**
+ * @constructor
+ * @extends AbstractApp
+ */
+ function RainLoopApp()
+ {
+ AbstractApp.call(this);
+
+ this.oData = null;
+ this.oRemote = null;
+ this.oCache = null;
+ this.oMoveCache = {};
+
+ this.quotaDebounce = _.debounce(this.quota, 1000 * 30);
+ this.moveOrDeleteResponseHelper = _.bind(this.moveOrDeleteResponseHelper, this);
+
+ this.messagesMoveTrigger = _.debounce(this.messagesMoveTrigger, 500);
+
+ window.setInterval(function () {
+ RL.pub('interval.30s');
+ }, 30000);
+
+ window.setInterval(function () {
+ RL.pub('interval.1m');
+ }, 60000);
+
+ window.setInterval(function () {
+ RL.pub('interval.2m');
+ }, 60000 * 2);
+
+ window.setInterval(function () {
+ RL.pub('interval.3m');
+ }, 60000 * 3);
+
+ window.setInterval(function () {
+ RL.pub('interval.5m');
+ }, 60000 * 5);
+
+ window.setInterval(function () {
+ RL.pub('interval.10m');
+ }, 60000 * 10);
+
+ window.setTimeout(function () {
+ window.setInterval(function () {
+ RL.pub('interval.10m-after5m');
+ }, 60000 * 10);
+ }, 60000 * 5);
+
+ $.wakeUp(function () {
+ RL.remote().jsVersion(function (sResult, oData) {
+ if (Enums.StorageResultType.Success === sResult && oData && !oData.Result)
+ {
+ if (window.parent && !!RL.settingsGet('InIframe'))
+ {
+ window.parent.location.reload();
+ }
+ else
+ {
+ window.location.reload();
+ }
+ }
+ }, RL.settingsGet('Version'));
+ }, {}, 60 * 60 * 1000);
+ }
+
+ _.extend(RainLoopApp.prototype, AbstractApp.prototype);
+
+ RainLoopApp.prototype.oData = null;
+ RainLoopApp.prototype.oRemote = null;
+ RainLoopApp.prototype.oCache = null;
+
+ /**
+ * @return {WebMailDataStorage}
+ */
+ RainLoopApp.prototype.data = function ()
+ {
+ if (null === this.oData)
+ {
+ this.oData = new WebMailDataStorage();
+ }
+
+ return this.oData;
+ };
+
+ /**
+ * @return {WebMailAjaxRemoteStorage}
+ */
+ RainLoopApp.prototype.remote = function ()
+ {
+ if (null === this.oRemote)
+ {
+ this.oRemote = new WebMailAjaxRemoteStorage();
+ }
+
+ return this.oRemote;
+ };
+
+ /**
+ * @return {WebMailCacheStorage}
+ */
+ RainLoopApp.prototype.cache = function ()
+ {
+ if (null === this.oCache)
+ {
+ this.oCache = new WebMailCacheStorage();
+ }
+
+ return this.oCache;
+ };
+
+ RainLoopApp.prototype.reloadFlagsCurrentMessageListAndMessageFromCache = function ()
+ {
+ var oCache = RL.cache();
+ _.each(RL.data().messageList(), function (oMessage) {
+ oCache.initMessageFlagsFromCache(oMessage);
+ });
+
+ oCache.initMessageFlagsFromCache(RL.data().message());
+ };
+
+ /**
+ * @param {boolean=} bDropPagePosition = false
+ * @param {boolean=} bDropCurrenFolderCache = false
+ */
+ RainLoopApp.prototype.reloadMessageList = function (bDropPagePosition, bDropCurrenFolderCache)
+ {
+ var
+ oRLData = RL.data(),
+ iOffset = (oRLData.messageListPage() - 1) * oRLData.messagesPerPage()
+ ;
+
+ if (Utils.isUnd(bDropCurrenFolderCache) ? false : !!bDropCurrenFolderCache)
+ {
+ RL.cache().setFolderHash(oRLData.currentFolderFullNameRaw(), '');
+ }
+
+ if (Utils.isUnd(bDropPagePosition) ? false : !!bDropPagePosition)
+ {
+ oRLData.messageListPage(1);
+ iOffset = 0;
+ }
+
+ oRLData.messageListLoading(true);
+ RL.remote().messageList(function (sResult, oData, bCached) {
+
+ if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
+ {
+ oRLData.messageListError('');
+ oRLData.messageListLoading(false);
+ oRLData.setMessageList(oData, bCached);
+ }
+ else if (Enums.StorageResultType.Unload === sResult)
+ {
+ oRLData.messageListError('');
+ oRLData.messageListLoading(false);
+ }
+ else if (Enums.StorageResultType.Abort !== sResult)
+ {
+ oRLData.messageList([]);
+ oRLData.messageListLoading(false);
+ oRLData.messageListError(oData && oData.ErrorCode ?
+ Utils.getNotification(oData.ErrorCode) : Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST')
+ );
+ }
+
+ }, oRLData.currentFolderFullNameRaw(), iOffset, oRLData.messagesPerPage(), oRLData.messageListSearch());
+ };
+
+ RainLoopApp.prototype.recacheInboxMessageList = function ()
+ {
+ RL.remote().messageList(Utils.emptyFunction, 'INBOX', 0, RL.data().messagesPerPage(), '', true);
+ };
+
+ RainLoopApp.prototype.reloadMessageListHelper = function (bEmptyList)
+ {
+ RL.reloadMessageList(bEmptyList);
+ };
+
+ /**
+ * @param {Function} fResultFunc
+ * @returns {boolean}
+ */
+ RainLoopApp.prototype.contactsSync = function (fResultFunc)
+ {
+ var oContacts = RL.data().contacts;
+ if (oContacts.importing() || oContacts.syncing() || !RL.data().enableContactsSync() || !RL.data().allowContactsSync())
+ {
+ return false;
+ }
+
+ oContacts.syncing(true);
+
+ RL.remote().contactsSync(function (sResult, oData) {
+
+ oContacts.syncing(false);
+
+ if (fResultFunc)
+ {
+ fResultFunc(sResult, oData);
+ }
+ });
+
+ return true;
+ };
+
+ RainLoopApp.prototype.messagesMoveTrigger = function ()
+ {
+ var
+ self = this,
+ sSpamFolder = RL.data().spamFolder()
+ ;
+
+ _.each(this.oMoveCache, function (oItem) {
+
+ var
+ bSpam = sSpamFolder === oItem['To'],
+ bHam = !bSpam && sSpamFolder === oItem['From'] && 'INBOX' === oItem['To']
+ ;
+
+ RL.remote().messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'],
+ bSpam ? 'SPAM' : (bHam ? 'HAM' : ''));
+ });
+
+ this.oMoveCache = {};
+ };
+
+ RainLoopApp.prototype.messagesMoveHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForMove)
+ {
+ var sH = '$$' + sFromFolderFullNameRaw + '$$' + sToFolderFullNameRaw + '$$';
+ if (!this.oMoveCache[sH])
+ {
+ this.oMoveCache[sH] = {
+ 'From': sFromFolderFullNameRaw,
+ 'To': sToFolderFullNameRaw,
+ 'Uid': []
+ };
+ }
+
+ this.oMoveCache[sH]['Uid'] = _.union(this.oMoveCache[sH]['Uid'], aUidForMove);
+ this.messagesMoveTrigger();
+ };
+
+ RainLoopApp.prototype.messagesCopyHelper = function (sFromFolderFullNameRaw, sToFolderFullNameRaw, aUidForCopy)
+ {
+ RL.remote().messagesCopy(
+ this.moveOrDeleteResponseHelper,
+ sFromFolderFullNameRaw,
+ sToFolderFullNameRaw,
+ aUidForCopy
+ );
+ };
+
+ RainLoopApp.prototype.messagesDeleteHelper = function (sFromFolderFullNameRaw, aUidForRemove)
+ {
+ RL.remote().messagesDelete(
+ this.moveOrDeleteResponseHelper,
+ sFromFolderFullNameRaw,
+ aUidForRemove
+ );
+ };
+
+ RainLoopApp.prototype.moveOrDeleteResponseHelper = function (sResult, oData)
+ {
+ if (Enums.StorageResultType.Success === sResult && RL.data().currentFolder())
+ {
+ if (oData && Utils.isArray(oData.Result) && 2 === oData.Result.length)
+ {
+ RL.cache().setFolderHash(oData.Result[0], oData.Result[1]);
+ }
+ else
+ {
+ RL.cache().setFolderHash(RL.data().currentFolderFullNameRaw(), '');
+
+ if (oData && -1 < Utils.inArray(oData.ErrorCode,
+ [Enums.Notification.CantMoveMessage, Enums.Notification.CantCopyMessage]))
+ {
+ window.alert(Utils.getNotification(oData.ErrorCode));
+ }
+ }
+
+ RL.reloadMessageListHelper(0 === RL.data().messageList().length);
+ RL.quotaDebounce();
+ }
+ };
+
+ /**
+ * @param {string} sFromFolderFullNameRaw
+ * @param {Array} aUidForRemove
+ */
+ RainLoopApp.prototype.deleteMessagesFromFolderWithoutCheck = function (sFromFolderFullNameRaw, aUidForRemove)
+ {
+ this.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
+ RL.data().removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
+ };
+
+ /**
+ * @param {number} iDeleteType
+ * @param {string} sFromFolderFullNameRaw
+ * @param {Array} aUidForRemove
+ * @param {boolean=} bUseFolder = true
+ */
+ RainLoopApp.prototype.deleteMessagesFromFolder = function (iDeleteType, sFromFolderFullNameRaw, aUidForRemove, bUseFolder)
+ {
+ var
+ self = this,
+ oData = RL.data(),
+ oCache = RL.cache(),
+ oMoveFolder = null,
+ nSetSystemFoldersNotification = null
+ ;
+
+ switch (iDeleteType)
+ {
+ case Enums.FolderType.Spam:
+ oMoveFolder = oCache.getFolderFromCacheList(oData.spamFolder());
+ nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Spam;
+ break;
+ case Enums.FolderType.NotSpam:
+ oMoveFolder = oCache.getFolderFromCacheList('INBOX');
+ break;
+ case Enums.FolderType.Trash:
+ oMoveFolder = oCache.getFolderFromCacheList(oData.trashFolder());
+ nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Trash;
+ break;
+ case Enums.FolderType.Archive:
+ oMoveFolder = oCache.getFolderFromCacheList(oData.archiveFolder());
+ nSetSystemFoldersNotification = Enums.SetSystemFoldersNotification.Archive;
+ break;
+ }
+
+ bUseFolder = Utils.isUnd(bUseFolder) ? true : !!bUseFolder;
+ if (bUseFolder)
+ {
+ if ((Enums.FolderType.Spam === iDeleteType && Consts.Values.UnuseOptionValue === oData.spamFolder()) ||
+ (Enums.FolderType.Trash === iDeleteType && Consts.Values.UnuseOptionValue === oData.trashFolder()) ||
+ (Enums.FolderType.Archive === iDeleteType && Consts.Values.UnuseOptionValue === oData.archiveFolder()))
+ {
+ bUseFolder = false;
+ }
+ }
+
+ if (!oMoveFolder && bUseFolder)
+ {
+ kn.showScreenPopup(PopupsFolderSystemViewModel, [nSetSystemFoldersNotification]);
+ }
+ else if (!bUseFolder || (Enums.FolderType.Trash === iDeleteType &&
+ (sFromFolderFullNameRaw === oData.spamFolder() || sFromFolderFullNameRaw === oData.trashFolder())))
+ {
+ kn.showScreenPopup(PopupsAskViewModel, [Utils.i18n('POPUPS_ASK/DESC_WANT_DELETE_MESSAGES'), function () {
+
+ self.messagesDeleteHelper(sFromFolderFullNameRaw, aUidForRemove);
+ oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove);
+
+ }]);
+ }
+ else if (oMoveFolder)
+ {
+ this.messagesMoveHelper(sFromFolderFullNameRaw, oMoveFolder.fullNameRaw, aUidForRemove);
+ oData.removeMessagesFromList(sFromFolderFullNameRaw, aUidForRemove, oMoveFolder.fullNameRaw);
+ }
+ };
+
+ /**
+ * @param {string} sFromFolderFullNameRaw
+ * @param {Array} aUidForMove
+ * @param {string} sToFolderFullNameRaw
+ * @param {boolean=} bCopy = false
+ */
+ RainLoopApp.prototype.moveMessagesToFolder = function (sFromFolderFullNameRaw, aUidForMove, sToFolderFullNameRaw, bCopy)
+ {
+ if (sFromFolderFullNameRaw !== sToFolderFullNameRaw && Utils.isArray(aUidForMove) && 0 < aUidForMove.length)
+ {
+ var
+ oFromFolder = RL.cache().getFolderFromCacheList(sFromFolderFullNameRaw),
+ oToFolder = RL.cache().getFolderFromCacheList(sToFolderFullNameRaw)
+ ;
+
+ if (oFromFolder && oToFolder)
+ {
+ if (Utils.isUnd(bCopy) ? false : !!bCopy)
+ {
+ this.messagesCopyHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
+ }
+ else
+ {
+ this.messagesMoveHelper(oFromFolder.fullNameRaw, oToFolder.fullNameRaw, aUidForMove);
+ }
+
+ RL.data().removeMessagesFromList(oFromFolder.fullNameRaw, aUidForMove, oToFolder.fullNameRaw, bCopy);
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ /**
+ * @param {Function=} fCallback
+ */
+ RainLoopApp.prototype.folders = function (fCallback)
+ {
+ this.data().foldersLoading(true);
+ this.remote().folders(_.bind(function (sResult, oData) {
+
+ RL.data().foldersLoading(false);
+ if (Enums.StorageResultType.Success === sResult)
+ {
+ this.data().setFolders(oData);
+ if (fCallback)
+ {
+ fCallback(true);
+ }
+ }
+ else
+ {
+ if (fCallback)
+ {
+ fCallback(false);
+ }
+ }
+ }, this));
+ };
+
+ RainLoopApp.prototype.reloadOpenPgpKeys = function ()
+ {
+ if (RL.data().capaOpenPGP())
+ {
+ var
+ aKeys = [],
+ oEmail = new EmailModel(),
+ oOpenpgpKeyring = RL.data().openpgpKeyring,
+ oOpenpgpKeys = oOpenpgpKeyring ? oOpenpgpKeyring.getAllKeys() : []
+ ;
+
+ _.each(oOpenpgpKeys, function (oItem, iIndex) {
+ if (oItem && oItem.primaryKey)
+ {
+ var
+
+ oPrimaryUser = oItem.getPrimaryUser(),
+ sUser = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid
+ : (oItem.users && oItem.users[0] ? oItem.users[0].userId.userid : '')
+ ;
+
+ oEmail.clear();
+ oEmail.mailsoParse(sUser);
+
+ if (oEmail.validate())
+ {
+ aKeys.push(new OpenPgpKeyModel(
+ iIndex,
+ oItem.primaryKey.getFingerprint(),
+ oItem.primaryKey.getKeyId().toHex().toLowerCase(),
+ sUser,
+ oEmail.email,
+ oItem.isPrivate(),
+ oItem.armor())
+ );
+ }
+ }
+ });
+
+ RL.data().openpgpkeys(aKeys);
+ }
+ };
+
+ RainLoopApp.prototype.accountsAndIdentities = function ()
+ {
+ var oRainLoopData = RL.data();
+
+ oRainLoopData.accountsLoading(true);
+ oRainLoopData.identitiesLoading(true);
+
+ RL.remote().accountsAndIdentities(function (sResult, oData) {
+
+ oRainLoopData.accountsLoading(false);
+ oRainLoopData.identitiesLoading(false);
+
+ if (Enums.StorageResultType.Success === sResult && oData.Result)
+ {
+ var
+ sParentEmail = RL.settingsGet('ParentEmail'),
+ sAccountEmail = oRainLoopData.accountEmail()
+ ;
+
+ sParentEmail = '' === sParentEmail ? sAccountEmail : sParentEmail;
+
+ if (Utils.isArray(oData.Result['Accounts']))
+ {
+ oRainLoopData.accounts(_.map(oData.Result['Accounts'], function (sValue) {
+ return new AccountModel(sValue, sValue !== sParentEmail);
+ }));
+ }
+
+ if (Utils.isArray(oData.Result['Identities']))
+ {
+ oRainLoopData.identities(_.map(oData.Result['Identities'], function (oIdentityData) {
+
+ var
+ sId = Utils.pString(oIdentityData['Id']),
+ sEmail = Utils.pString(oIdentityData['Email']),
+ oIdentity = new IdentityModel(sId, sEmail, sId !== sAccountEmail)
+ ;
+
+ oIdentity.name(Utils.pString(oIdentityData['Name']));
+ oIdentity.replyTo(Utils.pString(oIdentityData['ReplyTo']));
+ oIdentity.bcc(Utils.pString(oIdentityData['Bcc']));
+
+ return oIdentity;
+ }));
+ }
+ }
+ });
+ };
+
+ RainLoopApp.prototype.quota = function ()
+ {
+ this.remote().quota(function (sResult, oData) {
+ if (Enums.StorageResultType.Success === sResult && oData && oData.Result &&
+ Utils.isArray(oData.Result) && 1 < oData.Result.length &&
+ Utils.isPosNumeric(oData.Result[0], true) && Utils.isPosNumeric(oData.Result[1], true))
+ {
+ RL.data().userQuota(Utils.pInt(oData.Result[1]) * 1024);
+ RL.data().userUsageSize(Utils.pInt(oData.Result[0]) * 1024);
+ }
+ });
+ };
+
+ /**
+ * @param {string} sFolder
+ * @param {Array=} aList = []
+ */
+ RainLoopApp.prototype.folderInformation = function (sFolder, aList)
+ {
+ if ('' !== Utils.trim(sFolder))
+ {
+ this.remote().folderInformation(function (sResult, oData) {
+ if (Enums.StorageResultType.Success === sResult)
+ {
+ if (oData && oData.Result && oData.Result.Hash && oData.Result.Folder)
+ {
+ var
+ iUtc = moment().unix(),
+ sHash = RL.cache().getFolderHash(oData.Result.Folder),
+ oFolder = RL.cache().getFolderFromCacheList(oData.Result.Folder),
+ bCheck = false,
+ sUid = '',
+ aList = [],
+ bUnreadCountChange = false,
+ oFlags = null
+ ;
+
+ if (oFolder)
+ {
+ oFolder.interval = iUtc;
+
+ if (oData.Result.Hash)
+ {
+ RL.cache().setFolderHash(oData.Result.Folder, oData.Result.Hash);
+ }
+
+ if (Utils.isNormal(oData.Result.MessageCount))
+ {
+ oFolder.messageCountAll(oData.Result.MessageCount);
+ }
+
+ if (Utils.isNormal(oData.Result.MessageUnseenCount))
+ {
+ if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oData.Result.MessageUnseenCount))
+ {
+ bUnreadCountChange = true;
+ }
+
+ oFolder.messageCountUnread(oData.Result.MessageUnseenCount);
+ }
+
+ if (bUnreadCountChange)
+ {
+ RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
+ }
+
+ if (oData.Result.Flags)
+ {
+ for (sUid in oData.Result.Flags)
+ {
+ if (oData.Result.Flags.hasOwnProperty(sUid))
+ {
+ bCheck = true;
+ oFlags = oData.Result.Flags[sUid];
+ RL.cache().storeMessageFlagsToCacheByFolderAndUid(oFolder.fullNameRaw, sUid.toString(), [
+ !oFlags['IsSeen'], !!oFlags['IsFlagged'], !!oFlags['IsAnswered'], !!oFlags['IsForwarded'], !!oFlags['IsReadReceipt']
+ ]);
+ }
+ }
+
+ if (bCheck)
+ {
+ RL.reloadFlagsCurrentMessageListAndMessageFromCache();
+ }
+ }
+
+ RL.data().initUidNextAndNewMessages(oFolder.fullNameRaw, oData.Result.UidNext, oData.Result.NewMessages);
+
+ if (oData.Result.Hash !== sHash || '' === sHash)
+ {
+ if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
+ {
+ RL.reloadMessageList();
+ }
+ else if ('INBOX' === oFolder.fullNameRaw)
+ {
+ RL.recacheInboxMessageList();
+ }
+ }
+ else if (bUnreadCountChange)
+ {
+ if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
+ {
+ aList = RL.data().messageList();
+ if (Utils.isNonEmptyArray(aList))
+ {
+ RL.folderInformation(oFolder.fullNameRaw, aList);
+ }
+ }
+ }
+ }
+ }
+ }
+ }, sFolder, aList);
+ }
+ };
+
+ /**
+ * @param {boolean=} bBoot = false
+ */
+ RainLoopApp.prototype.folderInformationMultiply = function (bBoot)
+ {
+ bBoot = Utils.isUnd(bBoot) ? false : !!bBoot;
+
+ var
+ iUtc = moment().unix(),
+ aFolders = RL.data().getNextFolderNames(bBoot)
+ ;
+
+ if (Utils.isNonEmptyArray(aFolders))
+ {
+ this.remote().folderInformationMultiply(function (sResult, oData) {
+ if (Enums.StorageResultType.Success === sResult)
+ {
+ if (oData && oData.Result && oData.Result.List && Utils.isNonEmptyArray(oData.Result.List))
+ {
+ _.each(oData.Result.List, function (oItem) {
+
+ var
+ aList = [],
+ sHash = RL.cache().getFolderHash(oItem.Folder),
+ oFolder = RL.cache().getFolderFromCacheList(oItem.Folder),
+ bUnreadCountChange = false
+ ;
+
+ if (oFolder)
+ {
+ oFolder.interval = iUtc;
+
+ if (oItem.Hash)
+ {
+ RL.cache().setFolderHash(oItem.Folder, oItem.Hash);
+ }
+
+ if (Utils.isNormal(oItem.MessageCount))
+ {
+ oFolder.messageCountAll(oItem.MessageCount);
+ }
+
+ if (Utils.isNormal(oItem.MessageUnseenCount))
+ {
+ if (Utils.pInt(oFolder.messageCountUnread()) !== Utils.pInt(oItem.MessageUnseenCount))
+ {
+ bUnreadCountChange = true;
+ }
+
+ oFolder.messageCountUnread(oItem.MessageUnseenCount);
+ }
+
+ if (bUnreadCountChange)
+ {
+ RL.cache().clearMessageFlagsFromCacheByFolder(oFolder.fullNameRaw);
+ }
+
+ if (oItem.Hash !== sHash || '' === sHash)
+ {
+ if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
+ {
+ RL.reloadMessageList();
+ }
+ }
+ else if (bUnreadCountChange)
+ {
+ if (oFolder.fullNameRaw === RL.data().currentFolderFullNameRaw())
+ {
+ aList = RL.data().messageList();
+ if (Utils.isNonEmptyArray(aList))
+ {
+ RL.folderInformation(oFolder.fullNameRaw, aList);
+ }
+ }
+ }
+ }
+ });
+
+ if (bBoot)
+ {
+ RL.folderInformationMultiply(true);
+ }
+ }
+ }
+ }, aFolders);
+ }
+ };
+
+ RainLoopApp.prototype.setMessageSeen = function (oMessage)
+ {
+ if (oMessage.unseen())
+ {
+ oMessage.unseen(false);
+
+ var oFolder = RL.cache().getFolderFromCacheList(oMessage.folderFullNameRaw);
+ if (oFolder)
+ {
+ oFolder.messageCountUnread(0 <= oFolder.messageCountUnread() - 1 ?
+ oFolder.messageCountUnread() - 1 : 0);
+ }
+
+ RL.cache().storeMessageFlagsToCache(oMessage);
+ RL.reloadFlagsCurrentMessageListAndMessageFromCache();
+ }
+
+ RL.remote().messageSetSeen(Utils.emptyFunction, oMessage.folderFullNameRaw, [oMessage.uid], true);
+ };
+
+ RainLoopApp.prototype.googleConnect = function ()
+ {
+ window.open(RL.link().socialGoogle(), 'Google', 'left=200,top=100,width=650,height=600,menubar=no,status=no,resizable=yes,scrollbars=yes');
+ };
+
+ RainLoopApp.prototype.twitterConnect = function ()
+ {
+ window.open(RL.link().socialTwitter(), 'Twitter', 'left=200,top=100,width=650,height=350,menubar=no,status=no,resizable=yes,scrollbars=yes');
+ };
+
+ RainLoopApp.prototype.facebookConnect = function ()
+ {
+ window.open(RL.link().socialFacebook(), 'Facebook', 'left=200,top=100,width=650,height=335,menubar=no,status=no,resizable=yes,scrollbars=yes');
+ };
+
+ /**
+ * @param {boolean=} bFireAllActions
+ */
+ RainLoopApp.prototype.socialUsers = function (bFireAllActions)
+ {
+ var oRainLoopData = RL.data();
+
+ if (bFireAllActions)
+ {
+ oRainLoopData.googleActions(true);
+ oRainLoopData.facebookActions(true);
+ oRainLoopData.twitterActions(true);
+ }
+
+ RL.remote().socialUsers(function (sResult, oData) {
+
+ if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
+ {
+ oRainLoopData.googleUserName(oData.Result['Google'] || '');
+ oRainLoopData.facebookUserName(oData.Result['Facebook'] || '');
+ oRainLoopData.twitterUserName(oData.Result['Twitter'] || '');
+ }
+ else
+ {
+ oRainLoopData.googleUserName('');
+ oRainLoopData.facebookUserName('');
+ oRainLoopData.twitterUserName('');
+ }
+
+ oRainLoopData.googleLoggined('' !== oRainLoopData.googleUserName());
+ oRainLoopData.facebookLoggined('' !== oRainLoopData.facebookUserName());
+ oRainLoopData.twitterLoggined('' !== oRainLoopData.twitterUserName());
+
+ oRainLoopData.googleActions(false);
+ oRainLoopData.facebookActions(false);
+ oRainLoopData.twitterActions(false);
+ });
+ };
+
+ RainLoopApp.prototype.googleDisconnect = function ()
+ {
+ RL.data().googleActions(true);
+ RL.remote().googleDisconnect(function () {
+ RL.socialUsers();
+ });
+ };
+
+ RainLoopApp.prototype.facebookDisconnect = function ()
+ {
+ RL.data().facebookActions(true);
+ RL.remote().facebookDisconnect(function () {
+ RL.socialUsers();
+ });
+ };
+
+ RainLoopApp.prototype.twitterDisconnect = function ()
+ {
+ RL.data().twitterActions(true);
+ RL.remote().twitterDisconnect(function () {
+ RL.socialUsers();
+ });
+ };
+
+ /**
+ * @param {Array} aSystem
+ * @param {Array} aList
+ * @param {Array=} aDisabled
+ * @param {Array=} aHeaderLines
+ * @param {?number=} iUnDeep
+ * @param {Function=} fDisableCallback
+ * @param {Function=} fVisibleCallback
+ * @param {Function=} fRenameCallback
+ * @param {boolean=} bSystem
+ * @param {boolean=} bBuildUnvisible
+ * @return {Array}
+ */
+ RainLoopApp.prototype.folderListOptionsBuilder = function (aSystem, aList, aDisabled, aHeaderLines, iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible)
+ {
+ var
+ iIndex = 0,
+ iLen = 0,
+ /**
+ * @type {?FolderModel}
+ */
+ oItem = null,
+ bSep = false,
+ sDeepPrefix = '\u00A0\u00A0\u00A0',
+ aResult = []
+ ;
+
+ bSystem = !Utils.isNormal(bSystem) ? 0 < aSystem.length : bSystem;
+ bBuildUnvisible = Utils.isUnd(bBuildUnvisible) ? false : !!bBuildUnvisible;
+ iUnDeep = !Utils.isNormal(iUnDeep) ? 0 : iUnDeep;
+ fDisableCallback = Utils.isNormal(fDisableCallback) ? fDisableCallback : null;
+ fVisibleCallback = Utils.isNormal(fVisibleCallback) ? fVisibleCallback : null;
+ fRenameCallback = Utils.isNormal(fRenameCallback) ? fRenameCallback : null;
+
+ if (!Utils.isArray(aDisabled))
+ {
+ aDisabled = [];
+ }
+
+ if (!Utils.isArray(aHeaderLines))
+ {
+ aHeaderLines = [];
+ }
+
+ for (iIndex = 0, iLen = aHeaderLines.length; iIndex < iLen; iIndex++)
+ {
+ aResult.push({
+ 'id': aHeaderLines[iIndex][0],
+ 'name': aHeaderLines[iIndex][1],
+ 'system': false,
+ 'seporator': false,
+ 'disabled': false
+ });
+ }
+
+ bSep = true;
+ for (iIndex = 0, iLen = aSystem.length; iIndex < iLen; iIndex++)
+ {
+ oItem = aSystem[iIndex];
+ if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true)
+ {
+ if (bSep && 0 < aResult.length)
+ {
+ aResult.push({
+ 'id': '---',
+ 'name': '---',
+ 'system': false,
+ 'seporator': true,
+ 'disabled': true
+ });
+ }
+
+ bSep = false;
+ aResult.push({
+ 'id': oItem.fullNameRaw,
+ 'name': fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name(),
+ 'system': true,
+ 'seporator': false,
+ 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) ||
+ (fDisableCallback ? fDisableCallback.call(null, oItem) : false)
+ });
+ }
+ }
+
+ bSep = true;
+ for (iIndex = 0, iLen = aList.length; iIndex < iLen; iIndex++)
+ {
+ oItem = aList[iIndex];
+ if (oItem.subScribed() || !oItem.existen)
+ {
+ if (fVisibleCallback ? fVisibleCallback.call(null, oItem) : true)
+ {
+ if (Enums.FolderType.User === oItem.type() || !bSystem || 0 < oItem.subFolders().length)
+ {
+ if (bSep && 0 < aResult.length)
+ {
+ aResult.push({
+ 'id': '---',
+ 'name': '---',
+ 'system': false,
+ 'seporator': true,
+ 'disabled': true
+ });
+ }
+
+ bSep = false;
+ aResult.push({
+ 'id': oItem.fullNameRaw,
+ 'name': (new window.Array(oItem.deep + 1 - iUnDeep)).join(sDeepPrefix) +
+ (fRenameCallback ? fRenameCallback.call(null, oItem) : oItem.name()),
+ 'system': false,
+ 'seporator': false,
+ 'disabled': !oItem.selectable || -1 < Utils.inArray(oItem.fullNameRaw, aDisabled) ||
+ (fDisableCallback ? fDisableCallback.call(null, oItem) : false)
+ });
+ }
+ }
+ }
+
+ if (oItem.subScribed() && 0 < oItem.subFolders().length)
+ {
+ aResult = aResult.concat(RL.folderListOptionsBuilder([], oItem.subFolders(), aDisabled, [],
+ iUnDeep, fDisableCallback, fVisibleCallback, fRenameCallback, bSystem, bBuildUnvisible));
+ }
+ }
+
+ return aResult;
+ };
+
+ /**
+ * @param {string} sQuery
+ * @param {Function} fCallback
+ */
+ RainLoopApp.prototype.getAutocomplete = function (sQuery, fCallback)
+ {
+ var
+ aData = []
+ ;
+
+ RL.remote().suggestions(function (sResult, oData) {
+ if (Enums.StorageResultType.Success === sResult && oData && Utils.isArray(oData.Result))
+ {
+ aData = _.map(oData.Result, function (aItem) {
+ return aItem && aItem[0] ? new EmailModel(aItem[0], aItem[1]) : null;
+ });
+
+ fCallback(_.compact(aData));
+ }
+ else if (Enums.StorageResultType.Abort !== sResult)
+ {
+ fCallback([]);
+ }
+
+ }, sQuery);
+ };
+
+ /**
+ * @param {string} sQuery
+ * @param {Function} fCallback
+ */
+ RainLoopApp.prototype.getContactTagsAutocomplete = function (sQuery, fCallback)
+ {
+ fCallback(_.filter(RL.data().contactTags(), function (oContactTag) {
+ return oContactTag && oContactTag.filterHelper(sQuery);
+ }));
+ };
+
+ /**
+ * @param {string} sMailToUrl
+ * @returns {boolean}
+ */
+ RainLoopApp.prototype.mailToHelper = function (sMailToUrl)
+ {
+ if (sMailToUrl && 'mailto:' === sMailToUrl.toString().substr(0, 7).toLowerCase())
+ {
+ sMailToUrl = sMailToUrl.toString().substr(7);
+
+ var
+ oParams = {},
+ oEmailModel = null,
+ sEmail = sMailToUrl.replace(/\?.+$/, ''),
+ sQueryString = sMailToUrl.replace(/^[^\?]*\?/, '')
+ ;
+
+ oEmailModel = new EmailModel();
+ oEmailModel.parse(window.decodeURIComponent(sEmail));
+
+ if (oEmailModel && oEmailModel.email)
+ {
+ oParams = Utils.simpleQueryParser(sQueryString);
+ kn.showScreenPopup(PopupsComposeViewModel, [Enums.ComposeType.Empty, null, [oEmailModel],
+ Utils.isUnd(oParams.subject) ? null : Utils.pString(oParams.subject),
+ Utils.isUnd(oParams.body) ? null : Utils.plainToHtml(Utils.pString(oParams.body))
+ ]);
+ }
+
+ return true;
+ }
+
+ return false;
+ };
+
+ RainLoopApp.prototype.bootstart = function ()
+ {
+ RL.pub('rl.bootstart');
+ AbstractApp.prototype.bootstart.call(this);
+
+ RL.data().populateDataOnStart();
+
+ var
+ sCustomLoginLink = '',
+ sJsHash = RL.settingsGet('JsHash'),
+ iContactsSyncInterval = Utils.pInt(RL.settingsGet('ContactsSyncInterval')),
+ bGoogle = RL.settingsGet('AllowGoogleSocial'),
+ bFacebook = RL.settingsGet('AllowFacebookSocial'),
+ bTwitter = RL.settingsGet('AllowTwitterSocial')
+ ;
+
+ if (!RL.settingsGet('ChangePasswordIsAllowed'))
+ {
+ Utils.removeSettingsViewModel(SettingsChangePasswordScreen);
+ }
+
+ if (!RL.settingsGet('ContactsIsAllowed'))
+ {
+ Utils.removeSettingsViewModel(SettingsContacts);
+ }
+
+ if (!RL.capa(Enums.Capa.AdditionalAccounts))
+ {
+ Utils.removeSettingsViewModel(SettingsAccounts);
+ }
+
+ if (RL.capa(Enums.Capa.AdditionalIdentities))
+ {
+ Utils.removeSettingsViewModel(SettingsIdentity);
+ }
+ else
+ {
+ Utils.removeSettingsViewModel(SettingsIdentities);
+ }
+
+ if (!RL.capa(Enums.Capa.OpenPGP))
+ {
+ Utils.removeSettingsViewModel(SettingsOpenPGP);
+ }
+
+ if (!RL.capa(Enums.Capa.TwoFactor))
+ {
+ Utils.removeSettingsViewModel(SettingsSecurity);
+ }
+
+ if (!RL.capa(Enums.Capa.Themes))
+ {
+ Utils.removeSettingsViewModel(SettingsThemes);
+ }
+
+ if (!RL.capa(Enums.Capa.Filters))
+ {
+ Utils.removeSettingsViewModel(SettingsFilters);
+ }
+
+ if (!bGoogle && !bFacebook && !bTwitter)
+ {
+ Utils.removeSettingsViewModel(SettingsSocialScreen);
+ }
+
+ Utils.initOnStartOrLangChange(function () {
+
+ $.extend(true, $.magnificPopup.defaults, {
+ 'tClose': Utils.i18n('MAGNIFIC_POPUP/CLOSE'),
+ 'tLoading': Utils.i18n('MAGNIFIC_POPUP/LOADING'),
+ 'gallery': {
+ 'tPrev': Utils.i18n('MAGNIFIC_POPUP/GALLERY_PREV'),
+ 'tNext': Utils.i18n('MAGNIFIC_POPUP/GALLERY_NEXT'),
+ 'tCounter': Utils.i18n('MAGNIFIC_POPUP/GALLERY_COUNTER')
+ },
+ 'image': {
+ 'tError': Utils.i18n('MAGNIFIC_POPUP/IMAGE_ERROR')
+ },
+ 'ajax': {
+ 'tError': Utils.i18n('MAGNIFIC_POPUP/AJAX_ERROR')
+ }
+ });
+
+ }, this);
+
+ if (window.SimplePace)
+ {
+ window.SimplePace.set(70);
+ window.SimplePace.sleep();
+ }
+
+ if (!!RL.settingsGet('Auth'))
+ {
+ this.setTitle(Utils.i18n('TITLES/LOADING'));
+
+ this.folders(_.bind(function (bValue) {
+
+ kn.hideLoading();
+
+ if (bValue)
+ {
+ if (window.$LAB && window.crypto && window.crypto.getRandomValues && RL.capa(Enums.Capa.OpenPGP))
+ {
+ window.$LAB.script(window.openpgp ? '' : RL.link().openPgpJs()).wait(function () {
+ if (window.openpgp)
+ {
+ RL.data().openpgpKeyring = new window.openpgp.Keyring();
+ RL.data().capaOpenPGP(true);
+
+ RL.pub('openpgp.init');
+
+ RL.reloadOpenPgpKeys();
+ }
+ });
+ }
+ else
+ {
+ RL.data().capaOpenPGP(false);
+ }
+
+ kn.startScreens([MailBoxScreen, SettingsScreen]);
+
+ if (bGoogle || bFacebook || bTwitter)
+ {
+ RL.socialUsers(true);
+ }
+
+ RL.sub('interval.2m', function () {
+ RL.folderInformation('INBOX');
+ });
+
+ RL.sub('interval.2m', function () {
+ var sF = RL.data().currentFolderFullNameRaw();
+ if ('INBOX' !== sF)
+ {
+ RL.folderInformation(sF);
+ }
+ });
+
+ RL.sub('interval.3m', function () {
+ RL.folderInformationMultiply();
+ });
+
+ RL.sub('interval.5m', function () {
+ RL.quota();
+ });
+
+ RL.sub('interval.10m', function () {
+ RL.folders();
+ });
+
+ iContactsSyncInterval = 5 <= iContactsSyncInterval ? iContactsSyncInterval : 20;
+ iContactsSyncInterval = 320 >= iContactsSyncInterval ? iContactsSyncInterval : 320;
+
+ window.setInterval(function () {
+ RL.contactsSync();
+ }, iContactsSyncInterval * 60000 + 5000);
+
+ _.delay(function () {
+ RL.contactsSync();
+ }, 5000);
+
+ _.delay(function () {
+ RL.folderInformationMultiply(true);
+ }, 500);
+
+ Plugins.runHook('rl-start-user-screens');
+ RL.pub('rl.bootstart-user-screens');
+
+ if (!!RL.settingsGet('AccountSignMe') && window.navigator.registerProtocolHandler)
+ {
+ _.delay(function () {
+ try {
+ window.navigator.registerProtocolHandler('mailto',
+ window.location.protocol + '//' + window.location.host + window.location.pathname + '?mailto&to=%s',
+ '' + (RL.settingsGet('Title') || 'RainLoop'));
+ } catch(e) {}
+
+ if (RL.settingsGet('MailToEmail'))
+ {
+ RL.mailToHelper(RL.settingsGet('MailToEmail'));
+ }
+ }, 500);
+ }
+ }
+ else
+ {
+ kn.startScreens([LoginScreen]);
+
+ Plugins.runHook('rl-start-login-screens');
+ RL.pub('rl.bootstart-login-screens');
+ }
+
+ if (window.SimplePace)
+ {
+ window.SimplePace.set(100);
+ }
+
+ if (!Globals.bMobileDevice)
+ {
+ _.defer(function () {
+ Utils.initLayoutResizer('#rl-left', '#rl-right', Enums.ClientSideKeyName.FolderListSize);
+ });
+ }
+
+ }, this));
+ }
+ else
+ {
+ sCustomLoginLink = Utils.pString(RL.settingsGet('CustomLoginLink'));
+ if (!sCustomLoginLink)
+ {
+ kn.hideLoading();
+ kn.startScreens([LoginScreen]);
+
+ Plugins.runHook('rl-start-login-screens');
+ RL.pub('rl.bootstart-login-screens');
+
+ if (window.SimplePace)
+ {
+ window.SimplePace.set(100);
+ }
+ }
+ else
+ {
+ kn.routeOff();
+ kn.setHash(RL.link().root(), true);
+ kn.routeOff();
+
+ _.defer(function () {
+ window.location.href = sCustomLoginLink;
+ });
+ }
+ }
+
+ if (bGoogle)
+ {
+ window['rl_' + sJsHash + '_google_service'] = function () {
+ RL.data().googleActions(true);
+ RL.socialUsers();
+ };
+ }
+
+ if (bFacebook)
+ {
+ window['rl_' + sJsHash + '_facebook_service'] = function () {
+ RL.data().facebookActions(true);
+ RL.socialUsers();
+ };
+ }
+
+ if (bTwitter)
+ {
+ window['rl_' + sJsHash + '_twitter_service'] = function () {
+ RL.data().twitterActions(true);
+ RL.socialUsers();
+ };
+ }
+
+ RL.sub('interval.1m', function () {
+ Globals.momentTrigger(!Globals.momentTrigger());
+ });
+
+ Plugins.runHook('rl-start-screens');
+ RL.pub('rl.bootstart-end');
+ };
+
+ module.exports = new RainLoopApp();
+
+}(module));
+},{"../Common/Consts.js":4,"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/Plugins.js":7,"../Common/Utils.js":8,"../External/jquery.js":16,"../External/underscore.js":19,"../External/window.js":20,"../Knoin/Knoin.js":21,"./AbstractApp.js":2}],4:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var Consts = {};
+
+ Consts.Values = {};
+ Consts.DataImages = {};
+ Consts.Defaults = {};
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.MessagesPerPage = 20;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.ContactsPerPage = 50;
+
+ /**
+ * @const
+ * @type {Array}
+ */
+ Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/];
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.DefaultAjaxTimeout = 30000;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.SearchAjaxTimeout = 300000;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.SendMessageAjaxTimeout = 300000;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.SaveMessageAjaxTimeout = 200000;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Defaults.ContactsSyncAjaxTimeout = 200000;
+
+ /**
+ * @const
+ * @type {string}
+ */
+ Consts.Values.UnuseOptionValue = '__UNUSE__';
+
+ /**
+ * @const
+ * @type {string}
+ */
+ Consts.Values.ClientSideCookieIndexName = 'rlcsc';
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.ImapDefaulPort = 143;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.ImapDefaulSecurePort = 993;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.SmtpDefaulPort = 25;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.SmtpDefaulSecurePort = 465;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.MessageBodyCacheLimit = 15;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.AjaxErrorLimit = 7;
+
+ /**
+ * @const
+ * @type {number}
+ */
+ Consts.Values.TokenErrorLimit = 10;
+
+ /**
+ * @const
+ * @type {string}
+ */
+ Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=';
+
+ /**
+ * @const
+ * @type {string}
+ */
+ Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=';
+
+ module.exports = Consts;
+
+}(module));
+},{}],5:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var Enums = {};
+
+ /**
+ * @enum {string}
+ */
+ Enums.StorageResultType = {
+ 'Success': 'success',
+ 'Abort': 'abort',
+ 'Error': 'error',
+ 'Unload': 'unload'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.State = {
+ 'Empty': 10,
+ 'Login': 20,
+ 'Auth': 30
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.StateType = {
+ 'Webmail': 0,
+ 'Admin': 1
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.Capa = {
+ 'Prem': 'PREM',
+ 'TwoFactor': 'TWO_FACTOR',
+ 'OpenPGP': 'OPEN_PGP',
+ 'Prefetch': 'PREFETCH',
+ 'Gravatar': 'GRAVATAR',
+ 'Themes': 'THEMES',
+ 'Filters': 'FILTERS',
+ 'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
+ 'AdditionalIdentities': 'ADDITIONAL_IDENTITIES'
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.KeyState = {
+ 'All': 'all',
+ 'None': 'none',
+ 'ContactList': 'contact-list',
+ 'MessageList': 'message-list',
+ 'FolderList': 'folder-list',
+ 'MessageView': 'message-view',
+ 'Compose': 'compose',
+ 'Settings': 'settings',
+ 'Menu': 'menu',
+ 'PopupComposeOpenPGP': 'compose-open-pgp',
+ 'PopupKeyboardShortcutsHelp': 'popup-keyboard-shortcuts-help',
+ 'PopupAsk': 'popup-ask'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.FolderType = {
+ 'Inbox': 10,
+ 'SentItems': 11,
+ 'Draft': 12,
+ 'Trash': 13,
+ 'Spam': 14,
+ 'Archive': 15,
+ 'NotSpam': 80,
+ 'User': 99
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.LoginSignMeTypeAsString = {
+ 'DefaultOff': 'defaultoff',
+ 'DefaultOn': 'defaulton',
+ 'Unused': 'unused'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.LoginSignMeType = {
+ 'DefaultOff': 0,
+ 'DefaultOn': 1,
+ 'Unused': 2
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.ComposeType = {
+ 'Empty': 'empty',
+ 'Reply': 'reply',
+ 'ReplyAll': 'replyall',
+ 'Forward': 'forward',
+ 'ForwardAsAttachment': 'forward-as-attachment',
+ 'Draft': 'draft',
+ 'EditAsNew': 'editasnew'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.UploadErrorCode = {
+ 'Normal': 0,
+ 'FileIsTooBig': 1,
+ 'FilePartiallyUploaded': 2,
+ 'FileNoUploaded': 3,
+ 'MissingTempFolder': 4,
+ 'FileOnSaveingError': 5,
+ 'FileType': 98,
+ 'Unknown': 99
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.SetSystemFoldersNotification = {
+ 'None': 0,
+ 'Sent': 1,
+ 'Draft': 2,
+ 'Spam': 3,
+ 'Trash': 4,
+ 'Archive': 5
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.ClientSideKeyName = {
+ 'FoldersLashHash': 0,
+ 'MessagesInboxLastHash': 1,
+ 'MailBoxListSize': 2,
+ 'ExpandedFolders': 3,
+ 'FolderListSize': 4
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.EventKeyCode = {
+ 'Backspace': 8,
+ 'Tab': 9,
+ 'Enter': 13,
+ 'Esc': 27,
+ 'PageUp': 33,
+ 'PageDown': 34,
+ 'Left': 37,
+ 'Right': 39,
+ 'Up': 38,
+ 'Down': 40,
+ 'End': 35,
+ 'Home': 36,
+ 'Space': 32,
+ 'Insert': 45,
+ 'Delete': 46,
+ 'A': 65,
+ 'S': 83
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.MessageSetAction = {
+ 'SetSeen': 0,
+ 'UnsetSeen': 1,
+ 'SetFlag': 2,
+ 'UnsetFlag': 3
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.MessageSelectAction = {
+ 'All': 0,
+ 'None': 1,
+ 'Invert': 2,
+ 'Unseen': 3,
+ 'Seen': 4,
+ 'Flagged': 5,
+ 'Unflagged': 6
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.DesktopNotifications = {
+ 'Allowed': 0,
+ 'NotAllowed': 1,
+ 'Denied': 2,
+ 'NotSupported': 9
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.MessagePriority = {
+ 'Low': 5,
+ 'Normal': 3,
+ 'High': 1
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.EditorDefaultType = {
+ 'Html': 'Html',
+ 'Plain': 'Plain'
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.CustomThemeType = {
+ 'Light': 'Light',
+ 'Dark': 'Dark'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.ServerSecure = {
+ 'None': 0,
+ 'SSL': 1,
+ 'TLS': 2
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.SearchDateType = {
+ 'All': -1,
+ 'Days3': 3,
+ 'Days7': 7,
+ 'Month': 30
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.EmailType = {
+ 'Defailt': 0,
+ 'Facebook': 1,
+ 'Google': 2
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.SaveSettingsStep = {
+ 'Animate': -2,
+ 'Idle': -1,
+ 'TrueResult': 1,
+ 'FalseResult': 0
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.InterfaceAnimation = {
+ 'None': 'None',
+ 'Normal': 'Normal',
+ 'Full': 'Full'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.Layout = {
+ 'NoPreview': 0,
+ 'SidePreview': 1,
+ 'BottomPreview': 2
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.FilterConditionField = {
+ 'From': 'From',
+ 'To': 'To',
+ 'Recipient': 'Recipient',
+ 'Subject': 'Subject'
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.FilterConditionType = {
+ 'Contains': 'Contains',
+ 'NotContains': 'NotContains',
+ 'EqualTo': 'EqualTo',
+ 'NotEqualTo': 'NotEqualTo'
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.FiltersAction = {
+ 'None': 'None',
+ 'Move': 'Move',
+ 'Discard': 'Discard',
+ 'Forward': 'Forward',
+ };
+
+ /**
+ * @enum {string}
+ */
+ Enums.FilterRulesType = {
+ 'And': 'And',
+ 'Or': 'Or'
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.SignedVerifyStatus = {
+ 'UnknownPublicKeys': -4,
+ 'UnknownPrivateKey': -3,
+ 'Unverified': -2,
+ 'Error': -1,
+ 'None': 0,
+ 'Success': 1
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.ContactPropertyType = {
+
+ 'Unknown': 0,
+
+ 'FullName': 10,
+
+ 'FirstName': 15,
+ 'LastName': 16,
+ 'MiddleName': 16,
+ 'Nick': 18,
+
+ 'NamePrefix': 20,
+ 'NameSuffix': 21,
+
+ 'Email': 30,
+ 'Phone': 31,
+ 'Web': 32,
+
+ 'Birthday': 40,
+
+ 'Facebook': 90,
+ 'Skype': 91,
+ 'GitHub': 92,
+
+ 'Note': 110,
+
+ 'Custom': 250
+ };
+
+ /**
+ * @enum {number}
+ */
+ Enums.Notification = {
+ 'InvalidToken': 101,
+ 'AuthError': 102,
+ 'AccessError': 103,
+ 'ConnectionError': 104,
+ 'CaptchaError': 105,
+ 'SocialFacebookLoginAccessDisable': 106,
+ 'SocialTwitterLoginAccessDisable': 107,
+ 'SocialGoogleLoginAccessDisable': 108,
+ 'DomainNotAllowed': 109,
+ 'AccountNotAllowed': 110,
+
+ 'AccountTwoFactorAuthRequired': 120,
+ 'AccountTwoFactorAuthError': 121,
+
+ 'CouldNotSaveNewPassword': 130,
+ 'CurrentPasswordIncorrect': 131,
+ 'NewPasswordShort': 132,
+ 'NewPasswordWeak': 133,
+ 'NewPasswordForbidden': 134,
+
+ 'ContactsSyncError': 140,
+
+ 'CantGetMessageList': 201,
+ 'CantGetMessage': 202,
+ 'CantDeleteMessage': 203,
+ 'CantMoveMessage': 204,
+ 'CantCopyMessage': 205,
+
+ 'CantSaveMessage': 301,
+ 'CantSendMessage': 302,
+ 'InvalidRecipients': 303,
+
+ 'CantCreateFolder': 400,
+ 'CantRenameFolder': 401,
+ 'CantDeleteFolder': 402,
+ 'CantSubscribeFolder': 403,
+ 'CantUnsubscribeFolder': 404,
+ 'CantDeleteNonEmptyFolder': 405,
+
+ 'CantSaveSettings': 501,
+ 'CantSavePluginSettings': 502,
+
+ 'DomainAlreadyExists': 601,
+
+ 'CantInstallPackage': 701,
+ 'CantDeletePackage': 702,
+ 'InvalidPluginPackage': 703,
+ 'UnsupportedPluginPackage': 704,
+
+ 'LicensingServerIsUnavailable': 710,
+ 'LicensingExpired': 711,
+ 'LicensingBanned': 712,
+
+ 'DemoSendMessageError': 750,
+
+ 'AccountAlreadyExists': 801,
+
+ 'MailServerError': 901,
+ 'ClientViewError': 902,
+ 'InvalidInputArgument': 903,
+ 'UnknownNotification': 999,
+ 'UnknownError': 999
+ };
+
+ module.exports = Enums;
+
+}(module));
+},{}],6:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ Globals = {},
+ window = require('../External/window.js'),
+ ko = require('../External/ko.js'),
+ $html = require('../External/$html.js')
+ ;
+
+ /**
+ * @type {?}
+ */
+ Globals.now = (new window.Date()).getTime();
+
+ /**
+ * @type {?}
+ */
+ Globals.momentTrigger = ko.observable(true);
+
+ /**
+ * @type {?}
+ */
+ Globals.dropdownVisibility = ko.observable(false).extend({'rateLimit': 0});
+
+ /**
+ * @type {?}
+ */
+ Globals.tooltipTrigger = ko.observable(false).extend({'rateLimit': 0});
+
+ /**
+ * @type {?}
+ */
+ Globals.langChangeTrigger = ko.observable(true);
+
+ /**
+ * @type {number}
+ */
+ Globals.iAjaxErrorCount = 0;
+
+ /**
+ * @type {number}
+ */
+ Globals.iTokenErrorCount = 0;
+
+ /**
+ * @type {number}
+ */
+ Globals.iMessageBodyCacheCount = 0;
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bUnload = false;
+
+ /**
+ * @type {string}
+ */
+ Globals.sUserAgent = (window.navigator.userAgent || '').toLowerCase();
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad');
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android');
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice;
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bDisableNanoScroll = Globals.bMobileDevice;
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bAllowPdfPreview = !Globals.bMobileDevice;
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bAnimationSupported = !Globals.bMobileDevice && $html.hasClass('csstransitions');
+
+ /**
+ * @type {boolean}
+ */
+ Globals.bXMLHttpRequestSupported = !!window.XMLHttpRequest;
+
+ /**
+ * @type {string}
+ */
+ Globals.sAnimationType = '';
+
+ /**
+ * @type {Object}
+ */
+ Globals.oHtmlEditorDefaultConfig = {
+ 'title': false,
+ 'stylesSet': false,
+ 'customConfig': '',
+ 'contentsCss': '',
+ 'toolbarGroups': [
+ {name: 'spec'},
+ {name: 'styles'},
+ {name: 'basicstyles', groups: ['basicstyles', 'cleanup']},
+ {name: 'colors'},
+ {name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align']},
+ {name: 'links'},
+ {name: 'insert'},
+ {name: 'others'}
+ // {name: 'document', groups: ['mode', 'document', 'doctools']}
+ ],
+
+ 'removePlugins': 'contextmenu', //blockquote
+ 'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll',
+ 'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced',
+
+ 'extraPlugins': 'plain',
+
+ 'allowedContent': true,
+ 'autoParagraph': false,
+
+ 'font_defaultLabel': 'Arial',
+ 'fontSize_defaultLabel': '13',
+ 'fontSize_sizes': '10/10px;12/12px;13/13px;14/14px;16/16px;18/18px;20/20px;24/24px;28/28px;36/36px;48/48px'
+ };
+
+ /**
+ * @type {Object}
+ */
+ Globals.oHtmlEditorLangsMap = {
+ 'de': 'de',
+ 'es': 'es',
+ 'fr': 'fr',
+ 'hu': 'hu',
+ 'is': 'is',
+ 'it': 'it',
+ 'ko': 'ko',
+ 'ko-kr': 'ko',
+ 'lv': 'lv',
+ 'nl': 'nl',
+ 'no': 'no',
+ 'pl': 'pl',
+ 'pt': 'pt',
+ 'pt-pt': 'pt',
+ 'pt-br': 'pt-br',
+ 'ru': 'ru',
+ 'ro': 'ro',
+ 'zh': 'zh',
+ 'zh-cn': 'zh-cn'
+ };
+
+ if (Globals.bAllowPdfPreview && window.navigator && window.navigator.mimeTypes)
+ {
+ Globals.bAllowPdfPreview = !!_.find(window.navigator.mimeTypes, function (oType) {
+ return oType && 'application/pdf' === oType.type;
+ });
+ }
+
+ Globals.oI18N = {},
+
+ Globals.oNotificationI18N = {},
+
+ Globals.aBootstrapDropdowns = [],
+
+ Globals.aViewModels = {
+ 'settings': [],
+ 'settings-removed': [],
+ 'settings-disabled': []
+ };
+
+ module.exports = Globals;
+
+}(module));
+},{"../External/$html.js":10,"../External/ko.js":17,"../External/window.js":20}],7:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ Plugins = {},
+ Utils = require('./Utils.js')
+ ;
+
+ /**
+ * @type {Object}
+ */
+ Plugins.oViewModelsHooks = {};
+
+ /**
+ * @type {Object}
+ */
+ Plugins.oSimpleHooks = {};
+
+ /**
+ * @param {string} sName
+ * @param {Function} ViewModel
+ */
+ Plugins.regViewModelHook = function (sName, ViewModel)
+ {
+ if (ViewModel)
+ {
+ ViewModel.__hookName = sName;
+ }
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Function} fCallback
+ */
+ Plugins.addHook = function (sName, fCallback)
+ {
+ if (Utils.isFunc(fCallback))
+ {
+ if (!Utils.isArray(Plugins.oSimpleHooks[sName]))
+ {
+ Plugins.oSimpleHooks[sName] = [];
+ }
+
+ Plugins.oSimpleHooks[sName].push(fCallback);
+ }
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Array=} aArguments
+ */
+ Plugins.runHook = function (sName, aArguments)
+ {
+ if (Utils.isArray(Plugins.oSimpleHooks[sName]))
+ {
+ aArguments = aArguments || [];
+
+ _.each(Plugins.oSimpleHooks[sName], function (fCallback) {
+ fCallback.apply(null, aArguments);
+ });
+ }
+ };
+
+ /**
+ * @param {string} sName
+ * @return {?}
+ */
+ Plugins.mainSettingsGet = function (sName)
+ {
+ return RL ? RL.settingsGet(sName) : null; // TODO cjs
+ };
+
+ /**
+ * @param {Function} fCallback
+ * @param {string} sAction
+ * @param {Object=} oParameters
+ * @param {?number=} iTimeout
+ * @param {string=} sGetAdd = ''
+ * @param {Array=} aAbortActions = []
+ */
+ Plugins.remoteRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
+ {
+ if (RL) // TODO cjs
+ {
+ RL.remote().defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions); // TODO cjs
+ }
+ };
+
+ /**
+ * @param {string} sPluginSection
+ * @param {string} sName
+ * @return {?}
+ */
+ Plugins.settingsGet = function (sPluginSection, sName)
+ {
+ var oPlugin = Plugins.mainSettingsGet('Plugins');
+ oPlugin = oPlugin && Utils.isUnd(oPlugin[sPluginSection]) ? null : oPlugin[sPluginSection];
+ return oPlugin ? (Utils.isUnd(oPlugin[sName]) ? null : oPlugin[sName]) : null;
+ };
+
+ module.exports = Plugins;
+
+}(module));
+},{"./Utils.js":8}],8:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ Utils = {},
+ $ = require('../External/jquery.js'),
+ _ = require('../External/underscore.js'),
+ ko = require('../External/ko.js'),
+ window = require('../External/window.js'),
+ $window = require('../External/$window.js'),
+ $doc = require('../External/$doc.js'),
+ NotificationClass = require('../External/NotificationClass.js'),
+ Enums = require('./Enums.js'),
+ Globals = require('./Globals.js')
+ ;
+
+ Utils.trim = $.trim;
+ Utils.inArray = $.inArray;
+ Utils.isArray = _.isArray;
+ Utils.isFunc = _.isFunction;
+ Utils.isUnd = _.isUndefined;
+ Utils.isNull = _.isNull;
+ Utils.emptyFunction = function () {};
+
+ /**
+ * @param {*} oValue
+ * @return {boolean}
+ */
+ Utils.isNormal = function (oValue)
+ {
+ return !Utils.isUnd(oValue) && !Utils.isNull(oValue);
+ };
+
+ Utils.windowResize = _.debounce(function (iTimeout) {
+ if (Utils.isUnd(iTimeout))
+ {
+ $window.resize();
+ }
+ else
+ {
+ window.setTimeout(function () {
+ $window.resize();
+ }, iTimeout);
+ }
+ }, 50);
+
+ /**
+ * @param {(string|number)} mValue
+ * @param {boolean=} bIncludeZero
+ * @return {boolean}
+ */
+ Utils.isPosNumeric = function (mValue, bIncludeZero)
+ {
+ return Utils.isNormal(mValue) ?
+ ((Utils.isUnd(bIncludeZero) ? true : !!bIncludeZero) ?
+ (/^[0-9]*$/).test(mValue.toString()) :
+ (/^[1-9]+[0-9]*$/).test(mValue.toString())) :
+ false;
+ };
+
+ /**
+ * @param {*} iValue
+ * @param {number=} iDefault = 0
+ * @return {number}
+ */
+ Utils.pInt = function (iValue, iDefault)
+ {
+ var iResult = Utils.isNormal(iValue) && '' !== iValue ? window.parseInt(iValue, 10) : (iDefault || 0);
+ return window.isNaN(iResult) ? (iDefault || 0) : iResult;
+ };
+
+ /**
+ * @param {*} mValue
+ * @return {string}
+ */
+ Utils.pString = function (mValue)
+ {
+ return Utils.isNormal(mValue) ? '' + mValue : '';
+ };
+
+ /**
+ * @param {*} aValue
+ * @return {boolean}
+ */
+ Utils.isNonEmptyArray = function (aValue)
+ {
+ return Utils.isArray(aValue) && 0 < aValue.length;
+ };
+
+ /**
+ * @param {string} sQueryString
+ * @return {Object}
+ */
+ Utils.simpleQueryParser = function (sQueryString)
+ {
+ var
+ oParams = {},
+ aQueries = [],
+ aTemp = [],
+ iIndex = 0,
+ iLen = 0
+ ;
+
+ aQueries = sQueryString.split('&');
+ for (iIndex = 0, iLen = aQueries.length; iIndex < iLen; iIndex++)
+ {
+ aTemp = aQueries[iIndex].split('=');
+ oParams[window.decodeURIComponent(aTemp[0])] = window.decodeURIComponent(aTemp[1]);
+ }
+
+ return oParams;
+ };
+
+ /**
+ * @param {string} aValue
+ * @param {string} sKey
+ * @param {string} sLongKey
+ * @return {string|boolean}
+ */
+ Utils.rsaEncode = function (sValue, sHash, sKey, sLongKey)
+ {
+ if (window.crypto && window.crypto.getRandomValues && window.RSAKey && sHash && sKey && sLongKey)
+ {
+ var oRsa = new window.RSAKey();
+ oRsa.setPublic(sLongKey, sKey);
+
+ sValue = oRsa.encrypt(Utils.fakeMd5() + ':' + sValue + ':' + Utils.fakeMd5());
+ if (false !== sValue)
+ {
+ return 'rsa:' + sHash + ':' + sValue;
+ }
+ }
+
+ return false;
+ };
+
+ Utils.rsaEncode.supported = !!(window.crypto && window.crypto.getRandomValues && window.RSAKey);
+
+ /**
+ * @param {string} sPath
+ * @param {*=} oObject
+ * @param {Object=} oObjectToExportTo
+ */
+ Utils.exportPath = function (sPath, oObject, oObjectToExportTo)
+ {
+ var
+ part = null,
+ parts = sPath.split('.'),
+ cur = oObjectToExportTo || window
+ ;
+
+ for (; parts.length && (part = parts.shift());)
+ {
+ if (!parts.length && !Utils.isUnd(oObject))
+ {
+ cur[part] = oObject;
+ }
+ else if (cur[part])
+ {
+ cur = cur[part];
+ }
+ else
+ {
+ cur = cur[part] = {};
+ }
+ }
+ };
+
+ /**
+ * @param {Object} oObject
+ * @param {string} sName
+ * @param {*} mValue
+ */
+ Utils.pImport = function (oObject, sName, mValue)
+ {
+ oObject[sName] = mValue;
+ };
+
+ /**
+ * @param {Object} oObject
+ * @param {string} sName
+ * @param {*} mDefault
+ * @return {*}
+ */
+ Utils.pExport = function (oObject, sName, mDefault)
+ {
+ return Utils.isUnd(oObject[sName]) ? mDefault : oObject[sName];
+ };
+
+ /**
+ * @param {string} sText
+ * @return {string}
+ */
+ Utils.encodeHtml = function (sText)
+ {
+ return Utils.isNormal(sText) ? sText.toString()
+ .replace(/&/g, '&').replace(//g, '>')
+ .replace(/"/g, '"').replace(/'/g, ''') : '';
+ };
+
+ /**
+ * @param {string} sText
+ * @param {number=} iLen
+ * @return {string}
+ */
+ Utils.splitPlainText = function (sText, iLen)
+ {
+ var
+ sPrefix = '',
+ sSubText = '',
+ sResult = sText,
+ iSpacePos = 0,
+ iNewLinePos = 0
+ ;
+
+ iLen = Utils.isUnd(iLen) ? 100 : iLen;
+
+ while (sResult.length > iLen)
+ {
+ sSubText = sResult.substring(0, iLen);
+ iSpacePos = sSubText.lastIndexOf(' ');
+ iNewLinePos = sSubText.lastIndexOf('\n');
+
+ if (-1 !== iNewLinePos)
+ {
+ iSpacePos = iNewLinePos;
+ }
+
+ if (-1 === iSpacePos)
+ {
+ iSpacePos = iLen;
+ }
+
+ sPrefix += sSubText.substring(0, iSpacePos) + '\n';
+ sResult = sResult.substring(iSpacePos + 1);
+ }
+
+ return sPrefix + sResult;
+ };
+
+ Utils.timeOutAction = (function () {
+
+ var
+ oTimeOuts = {}
+ ;
+
+ return function (sAction, fFunction, iTimeOut)
+ {
+ if (Utils.isUnd(oTimeOuts[sAction]))
+ {
+ oTimeOuts[sAction] = 0;
+ }
+
+ window.clearTimeout(oTimeOuts[sAction]);
+ oTimeOuts[sAction] = window.setTimeout(fFunction, iTimeOut);
+ };
+ }());
+
+ Utils.timeOutActionSecond = (function () {
+
+ var
+ oTimeOuts = {}
+ ;
+
+ return function (sAction, fFunction, iTimeOut)
+ {
+ if (!oTimeOuts[sAction])
+ {
+ oTimeOuts[sAction] = window.setTimeout(function () {
+ fFunction();
+ oTimeOuts[sAction] = 0;
+ }, iTimeOut);
+ }
+ };
+ }());
+
+ Utils.audio = (function () {
+
+ var
+ oAudio = false
+ ;
+
+ return function (sMp3File, sOggFile) {
+
+ if (false === oAudio)
+ {
+ if (Globals.bIsiOSDevice)
+ {
+ oAudio = null;
+ }
+ else
+ {
+ var
+ bCanPlayMp3 = false,
+ bCanPlayOgg = false,
+ oAudioLocal = window.Audio ? new window.Audio() : null
+ ;
+
+ if (oAudioLocal && oAudioLocal.canPlayType && oAudioLocal.play)
+ {
+ bCanPlayMp3 = '' !== oAudioLocal.canPlayType('audio/mpeg; codecs="mp3"');
+ if (!bCanPlayMp3)
+ {
+ bCanPlayOgg = '' !== oAudioLocal.canPlayType('audio/ogg; codecs="vorbis"');
+ }
+
+ if (bCanPlayMp3 || bCanPlayOgg)
+ {
+ oAudio = oAudioLocal;
+ oAudio.preload = 'none';
+ oAudio.loop = false;
+ oAudio.autoplay = false;
+ oAudio.muted = false;
+ oAudio.src = bCanPlayMp3 ? sMp3File : sOggFile;
+ }
+ else
+ {
+ oAudio = null;
+ }
+ }
+ else
+ {
+ oAudio = null;
+ }
+ }
+ }
+
+ return oAudio;
+ };
+ }());
+
+ /**
+ * @param {(Object|null|undefined)} oObject
+ * @param {string} sProp
+ * @return {boolean}
+ */
+ Utils.hos = function (oObject, sProp)
+ {
+ return oObject && window.Object && window.Object.hasOwnProperty ? window.Object.hasOwnProperty.call(oObject, sProp) : false;
+ };
+
+ /**
+ * @param {string} sKey
+ * @param {Object=} oValueList
+ * @param {string=} sDefaulValue
+ * @return {string}
+ */
+ Utils.i18n = function (sKey, oValueList, sDefaulValue)
+ {
+ var
+ sValueName = '',
+ sResult = Utils.isUnd(Globals.oI18N[sKey]) ? (Utils.isUnd(sDefaulValue) ? sKey : sDefaulValue) : Globals.oI18N[sKey]
+ ;
+
+ if (!Utils.isUnd(oValueList) && !Utils.isNull(oValueList))
+ {
+ for (sValueName in oValueList)
+ {
+ if (Utils.hos(oValueList, sValueName))
+ {
+ sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]);
+ }
+ }
+ }
+
+ return sResult;
+ };
+
+ /**
+ * @param {Object} oElement
+ */
+ Utils.i18nToNode = function (oElement)
+ {
+ _.defer(function () {
+ $('.i18n', oElement).each(function () {
+ var
+ jqThis = $(this),
+ sKey = ''
+ ;
+
+ sKey = jqThis.data('i18n-text');
+ if (sKey)
+ {
+ jqThis.text(Utils.i18n(sKey));
+ }
+ else
+ {
+ sKey = jqThis.data('i18n-html');
+ if (sKey)
+ {
+ jqThis.html(Utils.i18n(sKey));
+ }
+
+ sKey = jqThis.data('i18n-placeholder');
+ if (sKey)
+ {
+ jqThis.attr('placeholder', Utils.i18n(sKey));
+ }
+
+ sKey = jqThis.data('i18n-title');
+ if (sKey)
+ {
+ jqThis.attr('title', Utils.i18n(sKey));
+ }
+ }
+ });
+ });
+ };
+
+ Utils.i18nReload = function ()
+ {
+ if (window['rainloopI18N'])
+ {
+ Globals.oI18N = window['rainloopI18N'] || {};
+
+ Utils.i18nToNode($doc);
+
+ Globals.langChangeTrigger(!Globals.langChangeTrigger());
+ }
+
+ window['rainloopI18N'] = null;
+ };
+
+ /**
+ * @param {Function} fCallback
+ * @param {Object} oScope
+ * @param {Function=} fLangCallback
+ */
+ Utils.initOnStartOrLangChange = function (fCallback, oScope, fLangCallback)
+ {
+ if (fCallback)
+ {
+ fCallback.call(oScope);
+ }
+
+ if (fLangCallback)
+ {
+ Globals.langChangeTrigger.subscribe(function () {
+ if (fCallback)
+ {
+ fCallback.call(oScope);
+ }
+
+ fLangCallback.call(oScope);
+ });
+ }
+ else if (fCallback)
+ {
+ Globals.langChangeTrigger.subscribe(fCallback, oScope);
+ }
+ };
+
+ /**
+ * @return {boolean}
+ */
+ Utils.inFocus = function ()
+ {
+ if (document.activeElement)
+ {
+ if (Utils.isUnd(document.activeElement.__inFocusCache))
+ {
+ document.activeElement.__inFocusCache = $(document.activeElement).is('input,textarea,iframe,.cke_editable');
+ }
+
+ return !!document.activeElement.__inFocusCache;
+ }
+
+ return false;
+ };
+
+ Utils.removeInFocus = function ()
+ {
+ if (document && document.activeElement && document.activeElement.blur)
+ {
+ var oA = $(document.activeElement);
+ if (oA.is('input,textarea'))
+ {
+ document.activeElement.blur();
+ }
+ }
+ };
+
+ Utils.removeSelection = function ()
+ {
+ if (window && window.getSelection)
+ {
+ var oSel = window.getSelection();
+ if (oSel && oSel.removeAllRanges)
+ {
+ oSel.removeAllRanges();
+ }
+ }
+ else if (document && document.selection && document.selection.empty)
+ {
+ document.selection.empty();
+ }
+ };
+
+ /**
+ * @param {string} sPrefix
+ * @param {string} sSubject
+ * @return {string}
+ */
+ Utils.replySubjectAdd = function (sPrefix, sSubject)
+ {
+ sPrefix = Utils.trim(sPrefix.toUpperCase());
+ sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' '));
+
+ var
+ iIndex = 0,
+ sResult = '',
+ bDrop = false,
+ sTrimmedPart = '',
+ aSubject = [],
+ aParts = [],
+ bRe = 'RE' === sPrefix,
+ bFwd = 'FWD' === sPrefix,
+ bPrefixIsRe = !bFwd
+ ;
+
+ if ('' !== sSubject)
+ {
+ bDrop = false;
+
+ aParts = sSubject.split(':');
+ for (iIndex = 0; iIndex < aParts.length; iIndex++)
+ {
+ sTrimmedPart = Utils.trim(aParts[iIndex]);
+ if (!bDrop &&
+ (/^(RE|FWD)$/i.test(sTrimmedPart) || /^(RE|FWD)[\[\(][\d]+[\]\)]$/i.test(sTrimmedPart))
+ )
+ {
+ if (!bRe)
+ {
+ bRe = !!(/^RE/i.test(sTrimmedPart));
+ }
+
+ if (!bFwd)
+ {
+ bFwd = !!(/^FWD/i.test(sTrimmedPart));
+ }
+ }
+ else
+ {
+ aSubject.push(aParts[iIndex]);
+ bDrop = true;
+ }
+ }
+
+ if (0 < aSubject.length)
+ {
+ sResult = Utils.trim(aSubject.join(':'));
+ }
+ }
+
+ if (bPrefixIsRe)
+ {
+ bRe = false;
+ }
+ else
+ {
+ bFwd = false;
+ }
+
+ return Utils.trim(
+ (bPrefixIsRe ? 'Re: ' : 'Fwd: ') +
+ (bRe ? 'Re: ' : '') +
+ (bFwd ? 'Fwd: ' : '') +
+ sResult
+ );
+ };
+
+
+ /**
+ * @param {string} sSubject
+ * @return {string}
+ */
+ Utils.fixLongSubject = function (sSubject)
+ {
+ var
+ iLimit = 30,
+ mReg = /^Re([\[\(]([\d]+)[\]\)]|):[\s]{0,3}Re([\[\(]([\d]+)[\]\)]|):/ig,
+ oMatch = null
+ ;
+
+ sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' '));
+
+ do
+ {
+ iLimit--;
+
+ oMatch = mReg.exec(sSubject);
+ if (!oMatch || Utils.isUnd(oMatch[0]))
+ {
+ oMatch = null;
+ }
+
+ if (oMatch)
+ {
+ sSubject = sSubject.replace(mReg, 'Re:');
+ }
+ }
+ while (oMatch || 0 < iLimit);
+
+ return sSubject.replace(/[\s]+/, ' ');
+ };
+
+ /**
+ * @deprecated
+ * @param {string} sPrefix
+ * @param {string} sSubject
+ * @param {boolean=} bFixLongSubject = true
+ * @return {string}
+ */
+ Utils._replySubjectAdd_ = function (sPrefix, sSubject, bFixLongSubject)
+ {
+ var
+ oMatch = null,
+ sResult = Utils.trim(sSubject)
+ ;
+
+ if (null !== (oMatch = (new window.RegExp('^' + sPrefix + '[\\s]?\\:(.*)$', 'gi')).exec(sSubject)) && !Utils.isUnd(oMatch[1]))
+ {
+ sResult = sPrefix + '[2]: ' + oMatch[1];
+ }
+ else if (null !== (oMatch = (new window.RegExp('^(' + sPrefix + '[\\s]?[\\[\\(]?)([\\d]+)([\\]\\)]?[\\s]?\\:.*)$', 'gi')).exec(sSubject)) &&
+ !Utils.isUnd(oMatch[1]) && !Utils.isUnd(oMatch[2]) && !Utils.isUnd(oMatch[3]))
+ {
+ sResult = oMatch[1] + (Utils.pInt(oMatch[2]) + 1) + oMatch[3];
+ }
+ else
+ {
+ sResult = sPrefix + ': ' + sSubject;
+ }
+
+ sResult = sResult.replace(/[\s]+/g, ' ');
+ sResult = (Utils.isUnd(bFixLongSubject) ? true : bFixLongSubject) ? Utils.fixLongSubject(sResult) : sResult;
+ // sResult = sResult.replace(/^(Re|Fwd)[\s]?\[[\d]+\]:/ig, '$1:');
+ return sResult;
+ };
+
+ /**
+ * @deprecated
+ * @param {string} sSubject
+ * @return {string}
+ */
+ Utils._fixLongSubject_ = function (sSubject)
+ {
+ var
+ iCounter = 0,
+ oMatch = null
+ ;
+
+ sSubject = Utils.trim(sSubject.replace(/[\s]+/, ' '));
+
+ do
+ {
+ oMatch = /^Re(\[([\d]+)\]|):[\s]{0,3}Re(\[([\d]+)\]|):/ig.exec(sSubject);
+ if (!oMatch || Utils.isUnd(oMatch[0]))
+ {
+ oMatch = null;
+ }
+
+ if (oMatch)
+ {
+ iCounter = 0;
+ iCounter += Utils.isUnd(oMatch[2]) ? 1 : 0 + Utils.pInt(oMatch[2]);
+ iCounter += Utils.isUnd(oMatch[4]) ? 1 : 0 + Utils.pInt(oMatch[4]);
+
+ sSubject = sSubject.replace(/^Re(\[[\d]+\]|):[\s]{0,3}Re(\[[\d]+\]|):/gi, 'Re' + (0 < iCounter ? '[' + iCounter + ']' : '') + ':');
+ }
+
+ }
+ while (oMatch);
+
+ sSubject = sSubject.replace(/[\s]+/, ' ');
+ return sSubject;
+ };
+
+ /**
+ * @param {number} iNum
+ * @param {number} iDec
+ * @return {number}
+ */
+ Utils.roundNumber = function (iNum, iDec)
+ {
+ return Math.round(iNum * Math.pow(10, iDec)) / Math.pow(10, iDec);
+ };
+
+ /**
+ * @param {(number|string)} iSizeInBytes
+ * @return {string}
+ */
+ Utils.friendlySize = function (iSizeInBytes)
+ {
+ iSizeInBytes = Utils.pInt(iSizeInBytes);
+
+ if (iSizeInBytes >= 1073741824)
+ {
+ return Utils.roundNumber(iSizeInBytes / 1073741824, 1) + 'GB';
+ }
+ else if (iSizeInBytes >= 1048576)
+ {
+ return Utils.roundNumber(iSizeInBytes / 1048576, 1) + 'MB';
+ }
+ else if (iSizeInBytes >= 1024)
+ {
+ return Utils.roundNumber(iSizeInBytes / 1024, 0) + 'KB';
+ }
+
+ return iSizeInBytes + 'B';
+ };
+
+ /**
+ * @param {string} sDesc
+ */
+ Utils.log = function (sDesc)
+ {
+ if (window.console && window.console.log)
+ {
+ window.console.log(sDesc);
+ }
+ };
+
+ /**
+ * @param {number} iCode
+ * @param {*=} mMessage = ''
+ * @return {string}
+ */
+ Utils.getNotification = function (iCode, mMessage)
+ {
+ iCode = Utils.pInt(iCode);
+ if (Enums.Notification.ClientViewError === iCode && mMessage)
+ {
+ return mMessage;
+ }
+
+ return Utils.isUnd(Globals.oNotificationI18N[iCode]) ? '' : Globals.oNotificationI18N[iCode];
+ };
+
+ Utils.initNotificationLanguage = function ()
+ {
+ var oN = Globals.oNotificationI18N || {};
+ oN[Enums.Notification.InvalidToken] = Utils.i18n('NOTIFICATIONS/INVALID_TOKEN');
+ oN[Enums.Notification.AuthError] = Utils.i18n('NOTIFICATIONS/AUTH_ERROR');
+ oN[Enums.Notification.AccessError] = Utils.i18n('NOTIFICATIONS/ACCESS_ERROR');
+ oN[Enums.Notification.ConnectionError] = Utils.i18n('NOTIFICATIONS/CONNECTION_ERROR');
+ oN[Enums.Notification.CaptchaError] = Utils.i18n('NOTIFICATIONS/CAPTCHA_ERROR');
+ oN[Enums.Notification.SocialFacebookLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE');
+ oN[Enums.Notification.SocialTwitterLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE');
+ oN[Enums.Notification.SocialGoogleLoginAccessDisable] = Utils.i18n('NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE');
+ oN[Enums.Notification.DomainNotAllowed] = Utils.i18n('NOTIFICATIONS/DOMAIN_NOT_ALLOWED');
+ oN[Enums.Notification.AccountNotAllowed] = Utils.i18n('NOTIFICATIONS/ACCOUNT_NOT_ALLOWED');
+
+ oN[Enums.Notification.AccountTwoFactorAuthRequired] = Utils.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED');
+ oN[Enums.Notification.AccountTwoFactorAuthError] = Utils.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR');
+
+ oN[Enums.Notification.CouldNotSaveNewPassword] = Utils.i18n('NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD');
+ oN[Enums.Notification.CurrentPasswordIncorrect] = Utils.i18n('NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT');
+ oN[Enums.Notification.NewPasswordShort] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_SHORT');
+ oN[Enums.Notification.NewPasswordWeak] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_WEAK');
+ oN[Enums.Notification.NewPasswordForbidden] = Utils.i18n('NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT');
+
+ oN[Enums.Notification.ContactsSyncError] = Utils.i18n('NOTIFICATIONS/CONTACTS_SYNC_ERROR');
+
+ oN[Enums.Notification.CantGetMessageList] = Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST');
+ oN[Enums.Notification.CantGetMessage] = Utils.i18n('NOTIFICATIONS/CANT_GET_MESSAGE');
+ oN[Enums.Notification.CantDeleteMessage] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_MESSAGE');
+ oN[Enums.Notification.CantMoveMessage] = Utils.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
+ oN[Enums.Notification.CantCopyMessage] = Utils.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
+
+ oN[Enums.Notification.CantSaveMessage] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_MESSAGE');
+ oN[Enums.Notification.CantSendMessage] = Utils.i18n('NOTIFICATIONS/CANT_SEND_MESSAGE');
+ oN[Enums.Notification.InvalidRecipients] = Utils.i18n('NOTIFICATIONS/INVALID_RECIPIENTS');
+
+ oN[Enums.Notification.CantCreateFolder] = Utils.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER');
+ oN[Enums.Notification.CantRenameFolder] = Utils.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER');
+ oN[Enums.Notification.CantDeleteFolder] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER');
+ oN[Enums.Notification.CantDeleteNonEmptyFolder] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER');
+ oN[Enums.Notification.CantSubscribeFolder] = Utils.i18n('NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER');
+ oN[Enums.Notification.CantUnsubscribeFolder] = Utils.i18n('NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER');
+
+ oN[Enums.Notification.CantSaveSettings] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_SETTINGS');
+ oN[Enums.Notification.CantSavePluginSettings] = Utils.i18n('NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS');
+
+ oN[Enums.Notification.DomainAlreadyExists] = Utils.i18n('NOTIFICATIONS/DOMAIN_ALREADY_EXISTS');
+
+ oN[Enums.Notification.CantInstallPackage] = Utils.i18n('NOTIFICATIONS/CANT_INSTALL_PACKAGE');
+ oN[Enums.Notification.CantDeletePackage] = Utils.i18n('NOTIFICATIONS/CANT_DELETE_PACKAGE');
+ oN[Enums.Notification.InvalidPluginPackage] = Utils.i18n('NOTIFICATIONS/INVALID_PLUGIN_PACKAGE');
+ oN[Enums.Notification.UnsupportedPluginPackage] = Utils.i18n('NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE');
+
+ oN[Enums.Notification.LicensingServerIsUnavailable] = Utils.i18n('NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE');
+ oN[Enums.Notification.LicensingExpired] = Utils.i18n('NOTIFICATIONS/LICENSING_EXPIRED');
+ oN[Enums.Notification.LicensingBanned] = Utils.i18n('NOTIFICATIONS/LICENSING_BANNED');
+
+ oN[Enums.Notification.DemoSendMessageError] = Utils.i18n('NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR');
+
+ oN[Enums.Notification.AccountAlreadyExists] = Utils.i18n('NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS');
+
+ oN[Enums.Notification.MailServerError] = Utils.i18n('NOTIFICATIONS/MAIL_SERVER_ERROR');
+ oN[Enums.Notification.InvalidInputArgument] = Utils.i18n('NOTIFICATIONS/INVALID_INPUT_ARGUMENT');
+ oN[Enums.Notification.UnknownNotification] = Utils.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
+ oN[Enums.Notification.UnknownError] = Utils.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
+ };
+
+ /**
+ * @param {*} mCode
+ * @return {string}
+ */
+ Utils.getUploadErrorDescByCode = function (mCode)
+ {
+ var sResult = '';
+ switch (Utils.pInt(mCode)) {
+ case Enums.UploadErrorCode.FileIsTooBig:
+ sResult = Utils.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG');
+ break;
+ case Enums.UploadErrorCode.FilePartiallyUploaded:
+ sResult = Utils.i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED');
+ break;
+ case Enums.UploadErrorCode.FileNoUploaded:
+ sResult = Utils.i18n('UPLOAD/ERROR_NO_FILE_UPLOADED');
+ break;
+ case Enums.UploadErrorCode.MissingTempFolder:
+ sResult = Utils.i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER');
+ break;
+ case Enums.UploadErrorCode.FileOnSaveingError:
+ sResult = Utils.i18n('UPLOAD/ERROR_ON_SAVING_FILE');
+ break;
+ case Enums.UploadErrorCode.FileType:
+ sResult = Utils.i18n('UPLOAD/ERROR_FILE_TYPE');
+ break;
+ default:
+ sResult = Utils.i18n('UPLOAD/ERROR_UNKNOWN');
+ break;
+ }
+
+ return sResult;
+ };
+
+ /**
+ * @param {?} oObject
+ * @param {string} sMethodName
+ * @param {Array=} aParameters
+ * @param {number=} nDelay
+ */
+ Utils.delegateRun = function (oObject, sMethodName, aParameters, nDelay)
+ {
+ if (oObject && oObject[sMethodName])
+ {
+ nDelay = Utils.pInt(nDelay);
+ if (0 >= nDelay)
+ {
+ oObject[sMethodName].apply(oObject, Utils.isArray(aParameters) ? aParameters : []);
+ }
+ else
+ {
+ _.delay(function () {
+ oObject[sMethodName].apply(oObject, Utils.isArray(aParameters) ? aParameters : []);
+ }, nDelay);
+ }
+ }
+ };
+
+ /**
+ * @param {?} oEvent
+ */
+ Utils.killCtrlAandS = function (oEvent)
+ {
+ oEvent = oEvent || window.event;
+ if (oEvent && oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey)
+ {
+ var
+ oSender = oEvent.target || oEvent.srcElement,
+ iKey = oEvent.keyCode || oEvent.which
+ ;
+
+ if (iKey === Enums.EventKeyCode.S)
+ {
+ oEvent.preventDefault();
+ return;
+ }
+
+ if (oSender && oSender.tagName && oSender.tagName.match(/INPUT|TEXTAREA/i))
+ {
+ return;
+ }
+
+ if (iKey === Enums.EventKeyCode.A)
+ {
+ if (window.getSelection)
+ {
+ window.getSelection().removeAllRanges();
+ }
+ else if (window.document.selection && window.document.selection.clear)
+ {
+ window.document.selection.clear();
+ }
+
+ oEvent.preventDefault();
+ }
+ }
+ };
+
+ /**
+ * @param {(Object|null|undefined)} oContext
+ * @param {Function} fExecute
+ * @param {(Function|boolean|null)=} fCanExecute
+ * @return {Function}
+ */
+ Utils.createCommand = function (oContext, fExecute, fCanExecute)
+ {
+ var
+ fResult = fExecute ? function () {
+ if (fResult.canExecute && fResult.canExecute())
+ {
+ fExecute.apply(oContext, Array.prototype.slice.call(arguments));
+ }
+ return false;
+ } : function () {}
+ ;
+
+ fResult.enabled = ko.observable(true);
+
+ fCanExecute = Utils.isUnd(fCanExecute) ? true : fCanExecute;
+ if (Utils.isFunc(fCanExecute))
+ {
+ fResult.canExecute = ko.computed(function () {
+ return fResult.enabled() && fCanExecute.call(oContext);
+ });
+ }
+ else
+ {
+ fResult.canExecute = ko.computed(function () {
+ return fResult.enabled() && !!fCanExecute;
+ });
+ }
+
+ return fResult;
+ };
+
+ /**
+ * @param {Object} oData
+ */
+ Utils.initDataConstructorBySettings = function (oData)
+ {
+ oData.editorDefaultType = ko.observable(Enums.EditorDefaultType.Html);
+ oData.showImages = ko.observable(false);
+ oData.interfaceAnimation = ko.observable(Enums.InterfaceAnimation.Full);
+ oData.contactsAutosave = ko.observable(false);
+
+ Globals.sAnimationType = Enums.InterfaceAnimation.Full;
+
+ oData.capaThemes = ko.observable(false);
+ oData.allowLanguagesOnSettings = ko.observable(true);
+ oData.allowLanguagesOnLogin = ko.observable(true);
+
+ oData.useLocalProxyForExternalImages = ko.observable(false);
+
+ oData.desktopNotifications = ko.observable(false);
+ oData.useThreads = ko.observable(true);
+ oData.replySameFolder = ko.observable(true);
+ oData.useCheckboxesInList = ko.observable(true);
+
+ oData.layout = ko.observable(Enums.Layout.SidePreview);
+ oData.usePreviewPane = ko.computed(function () {
+ return Enums.Layout.NoPreview !== oData.layout();
+ });
+
+ oData.interfaceAnimation.subscribe(function (sValue) {
+ if (Globals.bMobileDevice || sValue === Enums.InterfaceAnimation.None)
+ {
+ $html.removeClass('rl-anim rl-anim-full').addClass('no-rl-anim');
+
+ Globals.sAnimationType = Enums.InterfaceAnimation.None;
+ }
+ else
+ {
+ switch (sValue)
+ {
+ case Enums.InterfaceAnimation.Full:
+ $html.removeClass('no-rl-anim').addClass('rl-anim rl-anim-full');
+ Globals.sAnimationType = sValue;
+ break;
+ case Enums.InterfaceAnimation.Normal:
+ $html.removeClass('no-rl-anim rl-anim-full').addClass('rl-anim');
+ Globals.sAnimationType = sValue;
+ break;
+ }
+ }
+ });
+
+ oData.interfaceAnimation.valueHasMutated();
+
+ oData.desktopNotificationsPermisions = ko.computed(function () {
+ oData.desktopNotifications();
+ var iResult = Enums.DesktopNotifications.NotSupported;
+ if (NotificationClass && NotificationClass.permission)
+ {
+ switch (NotificationClass.permission.toLowerCase())
+ {
+ case 'granted':
+ iResult = Enums.DesktopNotifications.Allowed;
+ break;
+ case 'denied':
+ iResult = Enums.DesktopNotifications.Denied;
+ break;
+ case 'default':
+ iResult = Enums.DesktopNotifications.NotAllowed;
+ break;
+ }
+ }
+ else if (window.webkitNotifications && window.webkitNotifications.checkPermission)
+ {
+ iResult = window.webkitNotifications.checkPermission();
+ }
+
+ return iResult;
+ });
+
+ oData.useDesktopNotifications = ko.computed({
+ 'read': function () {
+ return oData.desktopNotifications() &&
+ Enums.DesktopNotifications.Allowed === oData.desktopNotificationsPermisions();
+ },
+ 'write': function (bValue) {
+ if (bValue)
+ {
+ var iPermission = oData.desktopNotificationsPermisions();
+ if (Enums.DesktopNotifications.Allowed === iPermission)
+ {
+ oData.desktopNotifications(true);
+ }
+ else if (Enums.DesktopNotifications.NotAllowed === iPermission)
+ {
+ NotificationClass.requestPermission(function () {
+ oData.desktopNotifications.valueHasMutated();
+ if (Enums.DesktopNotifications.Allowed === oData.desktopNotificationsPermisions())
+ {
+ if (oData.desktopNotifications())
+ {
+ oData.desktopNotifications.valueHasMutated();
+ }
+ else
+ {
+ oData.desktopNotifications(true);
+ }
+ }
+ else
+ {
+ if (oData.desktopNotifications())
+ {
+ oData.desktopNotifications(false);
+ }
+ else
+ {
+ oData.desktopNotifications.valueHasMutated();
+ }
+ }
+ });
+ }
+ else
+ {
+ oData.desktopNotifications(false);
+ }
+ }
+ else
+ {
+ oData.desktopNotifications(false);
+ }
+ }
+ });
+
+ oData.language = ko.observable('');
+ oData.languages = ko.observableArray([]);
+
+ oData.mainLanguage = ko.computed({
+ 'read': oData.language,
+ 'write': function (sValue) {
+ if (sValue !== oData.language())
+ {
+ if (-1 < Utils.inArray(sValue, oData.languages()))
+ {
+ oData.language(sValue);
+ }
+ else if (0 < oData.languages().length)
+ {
+ oData.language(oData.languages()[0]);
+ }
+ }
+ else
+ {
+ oData.language.valueHasMutated();
+ }
+ }
+ });
+
+ oData.theme = ko.observable('');
+ oData.themes = ko.observableArray([]);
+
+ oData.mainTheme = ko.computed({
+ 'read': oData.theme,
+ 'write': function (sValue) {
+ if (sValue !== oData.theme())
+ {
+ var aThemes = oData.themes();
+ if (-1 < Utils.inArray(sValue, aThemes))
+ {
+ oData.theme(sValue);
+ }
+ else if (0 < aThemes.length)
+ {
+ oData.theme(aThemes[0]);
+ }
+ }
+ else
+ {
+ oData.theme.valueHasMutated();
+ }
+ }
+ });
+
+ oData.capaAdditionalAccounts = ko.observable(false);
+ oData.capaAdditionalIdentities = ko.observable(false);
+ oData.capaGravatar = ko.observable(false);
+ oData.determineUserLanguage = ko.observable(false);
+ oData.determineUserDomain = ko.observable(false);
+
+ oData.messagesPerPage = ko.observable(Consts.Defaults.MessagesPerPage);//.extend({'throttle': 200});
+
+ oData.mainMessagesPerPage = oData.messagesPerPage;
+ oData.mainMessagesPerPage = ko.computed({
+ 'read': oData.messagesPerPage,
+ 'write': function (iValue) {
+ if (-1 < Utils.inArray(Utils.pInt(iValue), Consts.Defaults.MessagesPerPageArray))
+ {
+ if (iValue !== oData.messagesPerPage())
+ {
+ oData.messagesPerPage(iValue);
+ }
+ }
+ else
+ {
+ oData.messagesPerPage.valueHasMutated();
+ }
+ }
+ });
+
+ oData.facebookSupported = ko.observable(false);
+ oData.facebookEnable = ko.observable(false);
+ oData.facebookAppID = ko.observable('');
+ oData.facebookAppSecret = ko.observable('');
+
+ oData.twitterEnable = ko.observable(false);
+ oData.twitterConsumerKey = ko.observable('');
+ oData.twitterConsumerSecret = ko.observable('');
+
+ oData.googleEnable = ko.observable(false);
+ oData.googleClientID = ko.observable('');
+ oData.googleClientSecret = ko.observable('');
+ oData.googleApiKey = ko.observable('');
+
+ oData.dropboxEnable = ko.observable(false);
+ oData.dropboxApiKey = ko.observable('');
+
+ oData.contactsIsAllowed = ko.observable(false);
+ };
+
+ /**
+ * @param {{moment:Function}} oObject
+ */
+ Utils.createMomentDate = function (oObject)
+ {
+ if (Utils.isUnd(oObject.moment))
+ {
+ oObject.moment = ko.observable(moment());
+ }
+
+ return ko.computed(function () {
+ Globals.momentTrigger();
+ var oMoment = this.moment();
+ return 1970 === oMoment.year() ? '' : oMoment.fromNow();
+ }, oObject);
+ };
+
+ /**
+ * @param {{moment:Function, momentDate:Function}} oObject
+ */
+ Utils.createMomentShortDate = function (oObject)
+ {
+ return ko.computed(function () {
+
+ var
+ sResult = '',
+ oMomentNow = moment(),
+ oMoment = this.moment(),
+ sMomentDate = this.momentDate()
+ ;
+
+ if (1970 === oMoment.year())
+ {
+ sResult = '';
+ }
+ else if (4 >= oMomentNow.diff(oMoment, 'hours'))
+ {
+ sResult = sMomentDate;
+ }
+ else if (oMomentNow.format('L') === oMoment.format('L'))
+ {
+ sResult = Utils.i18n('MESSAGE_LIST/TODAY_AT', {
+ 'TIME': oMoment.format('LT')
+ });
+ }
+ else if (oMomentNow.clone().subtract('days', 1).format('L') === oMoment.format('L'))
+ {
+ sResult = Utils.i18n('MESSAGE_LIST/YESTERDAY_AT', {
+ 'TIME': oMoment.format('LT')
+ });
+ }
+ else if (oMomentNow.year() === oMoment.year())
+ {
+ sResult = oMoment.format('D MMM.');
+ }
+ else
+ {
+ sResult = oMoment.format('LL');
+ }
+
+ return sResult;
+
+ }, oObject);
+ };
+
+ /**
+ * @param {string} sFullNameHash
+ * @return {boolean}
+ */
+ Utils.isFolderExpanded = function (sFullNameHash)
+ {
+ var aExpandedList = /** @type {Array|null} */ RL.local().get(Enums.ClientSideKeyName.ExpandedFolders);
+ return _.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash);
+ };
+
+ /**
+ * @param {string} sFullNameHash
+ * @param {boolean} bExpanded
+ */
+ Utils.setExpandedFolder = function (sFullNameHash, bExpanded)
+ {
+ var aExpandedList = /** @type {Array|null} */ RL.local().get(Enums.ClientSideKeyName.ExpandedFolders);
+ if (!_.isArray(aExpandedList))
+ {
+ aExpandedList = [];
+ }
+
+ if (bExpanded)
+ {
+ aExpandedList.push(sFullNameHash);
+ aExpandedList = _.uniq(aExpandedList);
+ }
+ else
+ {
+ aExpandedList = _.without(aExpandedList, sFullNameHash);
+ }
+
+ RL.local().set(Enums.ClientSideKeyName.ExpandedFolders, aExpandedList);
+ };
+
+ Utils.initLayoutResizer = function (sLeft, sRight, sClientSideKeyName)
+ {
+ var
+ iDisabledWidth = 60,
+ iMinWidth = 155,
+ oLeft = $(sLeft),
+ oRight = $(sRight),
+
+ mLeftWidth = RL.local().get(sClientSideKeyName) || null,
+
+ fSetWidth = function (iWidth) {
+ if (iWidth)
+ {
+ oLeft.css({
+ 'width': '' + iWidth + 'px'
+ });
+
+ oRight.css({
+ 'left': '' + iWidth + 'px'
+ });
+ }
+ },
+
+ fDisable = function (bDisable) {
+ if (bDisable)
+ {
+ oLeft.resizable('disable');
+ fSetWidth(iDisabledWidth);
+ }
+ else
+ {
+ oLeft.resizable('enable');
+ var iWidth = Utils.pInt(RL.local().get(sClientSideKeyName)) || iMinWidth;
+ fSetWidth(iWidth > iMinWidth ? iWidth : iMinWidth);
+ }
+ },
+
+ fResizeFunction = function (oEvent, oObject) {
+ if (oObject && oObject.size && oObject.size.width)
+ {
+ RL.local().set(sClientSideKeyName, oObject.size.width);
+
+ oRight.css({
+ 'left': '' + oObject.size.width + 'px'
+ });
+ }
+ }
+ ;
+
+ if (null !== mLeftWidth)
+ {
+ fSetWidth(mLeftWidth > iMinWidth ? mLeftWidth : iMinWidth);
+ }
+
+ oLeft.resizable({
+ 'helper': 'ui-resizable-helper',
+ 'minWidth': iMinWidth,
+ 'maxWidth': 350,
+ 'handles': 'e',
+ 'stop': fResizeFunction
+ });
+
+ RL.sub('left-panel.off', function () {
+ fDisable(true);
+ });
+
+ RL.sub('left-panel.on', function () {
+ fDisable(false);
+ });
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.initBlockquoteSwitcher = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ var $oList = $('blockquote:not(.rl-bq-switcher)', oMessageTextBody).filter(function () {
+ return 0 === $(this).parent().closest('blockquote', oMessageTextBody).length;
+ });
+
+ if ($oList && 0 < $oList.length)
+ {
+ $oList.each(function () {
+ var $self = $(this), iH = $self.height();
+ if (0 === iH || 100 < iH)
+ {
+ $self.addClass('rl-bq-switcher hidden-bq');
+ $('')
+ .insertBefore($self)
+ .click(function () {
+ $self.toggleClass('hidden-bq');
+ Utils.windowResize();
+ })
+ .after('
')
+ .before('
')
+ ;
+ }
+ });
+ }
+ }
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.removeBlockquoteSwitcher = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ $(oMessageTextBody).find('blockquote.rl-bq-switcher').each(function () {
+ $(this).removeClass('rl-bq-switcher hidden-bq');
+ });
+
+ $(oMessageTextBody).find('.rlBlockquoteSwitcher').each(function () {
+ $(this).remove();
+ });
+ }
+ };
+
+ /**
+ * @param {Object} oMessageTextBody
+ */
+ Utils.toggleMessageBlockquote = function (oMessageTextBody)
+ {
+ if (oMessageTextBody)
+ {
+ oMessageTextBody.find('.rlBlockquoteSwitcher').click();
+ }
+ };
+
+ /**
+ * @param {string} sName
+ * @param {Function} ViewModelClass
+ * @param {Function=} AbstractViewModel = KnoinAbstractViewModel
+ */
+ Utils.extendAsViewModel = function (sName, ViewModelClass, AbstractViewModel)
+ {
+ if (ViewModelClass)
+ {
+ if (!AbstractViewModel)
+ {
+ AbstractViewModel = KnoinAbstractViewModel;
+ }
+
+ ViewModelClass.__name = sName;
+ Plugins.regViewModelHook(sName, ViewModelClass);
+ _.extend(ViewModelClass.prototype, AbstractViewModel.prototype);
+ }
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ * @param {string} sLabelName
+ * @param {string} sTemplate
+ * @param {string} sRoute
+ * @param {boolean=} bDefault
+ */
+ Utils.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute, bDefault)
+ {
+ SettingsViewModelClass.__rlSettingsData = {
+ 'Label': sLabelName,
+ 'Template': sTemplate,
+ 'Route': sRoute,
+ 'IsDefault': !!bDefault
+ };
+
+ Globals.aViewModels['settings'].push(SettingsViewModelClass);
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ */
+ Utils.removeSettingsViewModel = function (SettingsViewModelClass)
+ {
+ Globals.aViewModels['settings-removed'].push(SettingsViewModelClass);
+ };
+
+ /**
+ * @param {Function} SettingsViewModelClass
+ */
+ Utils.disableSettingsViewModel = function (SettingsViewModelClass)
+ {
+ Globals.aViewModels['settings-disabled'].push(SettingsViewModelClass);
+ };
+
+ Utils.convertThemeName = function (sTheme)
+ {
+ if ('@custom' === sTheme.substr(-7))
+ {
+ sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7));
+ }
+
+ return Utils.trim(sTheme.replace(/[^a-zA-Z]+/g, ' ').replace(/([A-Z])/g, ' $1').replace(/[\s]+/g, ' '));
+ };
+
+ /**
+ * @param {string} sName
+ * @return {string}
+ */
+ Utils.quoteName = function (sName)
+ {
+ return sName.replace(/["]/g, '\\"');
+ };
+
+ /**
+ * @return {number}
+ */
+ Utils.microtime = function ()
+ {
+ return (new Date()).getTime();
+ };
+
+ /**
+ *
+ * @param {string} sLanguage
+ * @param {boolean=} bEng = false
+ * @return {string}
+ */
+ Utils.convertLangName = function (sLanguage, bEng)
+ {
+ return Utils.i18n('LANGS_NAMES' + (true === bEng ? '_EN' : '') + '/LANG_' +
+ sLanguage.toUpperCase().replace(/[^a-zA-Z0-9]+/, '_'), null, sLanguage);
+ };
+
+ /**
+ * @param {number=} iLen
+ * @return {string}
+ */
+ Utils.fakeMd5 = function(iLen)
+ {
+ var
+ sResult = '',
+ sLine = '0123456789abcdefghijklmnopqrstuvwxyz'
+ ;
+
+ iLen = Utils.isUnd(iLen) ? 32 : Utils.pInt(iLen);
+
+ while (sResult.length < iLen)
+ {
+ sResult += sLine.substr(Math.round(Math.random() * sLine.length), 1);
+ }
+
+ return sResult;
+ };
+
+ /* jshint ignore:start */
+
+ /**
+ * @param {string} s
+ * @return {string}
+ */
+ Utils.md5 = function(s){function L(k,d){return(k<>>(32-d))}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H>>29;return aa}function B(x){var k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");var d="";for(var F=0;F127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P /g, '>').replace(/');
+ };
+
+ Utils.draggeblePlace = function ()
+ {
+ return $(' ').appendTo('#rl-hidden');
+ };
+
+ Utils.defautOptionsAfterRender = function (oOption, oItem)
+ {
+ if (oItem && !Utils.isUnd(oItem.disabled) && oOption)
+ {
+ $(oOption)
+ .toggleClass('disabled', oItem.disabled)
+ .prop('disabled', oItem.disabled)
+ ;
+ }
+ };
+
+ /**
+ * @param {Object} oViewModel
+ * @param {string} sTemplateID
+ * @param {string} sTitle
+ * @param {Function=} fCallback
+ */
+ Utils.windowPopupKnockout = function (oViewModel, sTemplateID, sTitle, fCallback)
+ {
+ var
+ oScript = null,
+ oWin = window.open(''),
+ sFunc = '__OpenerApplyBindingsUid' + Utils.fakeMd5() + '__',
+ oTemplate = $('#' + sTemplateID)
+ ;
+
+ window[sFunc] = function () {
+
+ if (oWin && oWin.document.body && oTemplate && oTemplate[0])
+ {
+ var oBody = $(oWin.document.body);
+
+ $('#rl-content', oBody).html(oTemplate.html());
+ $('html', oWin.document).addClass('external ' + $('html').attr('class'));
+
+ Utils.i18nToNode(oBody);
+
+ Knoin.prototype.applyExternal(oViewModel, $('#rl-content', oBody)[0]);
+
+ window[sFunc] = null;
+
+ fCallback(oWin);
+ }
+ };
+
+ oWin.document.open();
+ oWin.document.write('' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' +
+ '' + Utils.encodeHtml(sTitle) + ' ' +
+ '');
+ oWin.document.close();
+
+ oScript = oWin.document.createElement('script');
+ oScript.type = 'text/javascript';
+ oScript.innerHTML = 'if(window&&window.opener&&window.opener[\'' + sFunc + '\']){window.opener[\'' + sFunc + '\']();window.opener[\'' + sFunc + '\']=null}';
+ oWin.document.getElementsByTagName('head')[0].appendChild(oScript);
+ };
+
+ Utils.settingsSaveHelperFunction = function (fCallback, koTrigger, oContext, iTimer)
+ {
+ oContext = oContext || null;
+ iTimer = Utils.isUnd(iTimer) ? 1000 : Utils.pInt(iTimer);
+ return function (sType, mData, bCached, sRequestAction, oRequestParameters) {
+ koTrigger.call(oContext, mData && mData['Result'] ? Enums.SaveSettingsStep.TrueResult : Enums.SaveSettingsStep.FalseResult);
+ if (fCallback)
+ {
+ fCallback.call(oContext, sType, mData, bCached, sRequestAction, oRequestParameters);
+ }
+ _.delay(function () {
+ koTrigger.call(oContext, Enums.SaveSettingsStep.Idle);
+ }, iTimer);
+ };
+ };
+
+ Utils.settingsSaveHelperSimpleFunction = function (koTrigger, oContext)
+ {
+ return Utils.settingsSaveHelperFunction(null, koTrigger, oContext, 1000);
+ };
+
+ Utils.$div = $('');
+
+ /**
+ * @param {string} sHtml
+ * @return {string}
+ */
+ Utils.htmlToPlain = function (sHtml)
+ {
+ var
+ iPos = 0,
+ iP1 = 0,
+ iP2 = 0,
+ iP3 = 0,
+ iLimit = 0,
+
+ sText = '',
+
+ splitPlainText = function (sText)
+ {
+ var
+ iLen = 100,
+ sPrefix = '',
+ sSubText = '',
+ sResult = sText,
+ iSpacePos = 0,
+ iNewLinePos = 0
+ ;
+
+ while (sResult.length > iLen)
+ {
+ sSubText = sResult.substring(0, iLen);
+ iSpacePos = sSubText.lastIndexOf(' ');
+ iNewLinePos = sSubText.lastIndexOf('\n');
+
+ if (-1 !== iNewLinePos)
+ {
+ iSpacePos = iNewLinePos;
+ }
+
+ if (-1 === iSpacePos)
+ {
+ iSpacePos = iLen;
+ }
+
+ sPrefix += sSubText.substring(0, iSpacePos) + '\n';
+ sResult = sResult.substring(iSpacePos + 1);
+ }
+
+ return sPrefix + sResult;
+ },
+
+ convertBlockquote = function (sText) {
+ sText = splitPlainText($.trim(sText));
+ sText = '> ' + sText.replace(/\n/gm, '\n> ');
+ return sText.replace(/(^|\n)([> ]+)/gm, function () {
+ return (arguments && 2 < arguments.length) ? arguments[1] + $.trim(arguments[2].replace(/[\s]/, '')) + ' ' : '';
+ });
+ },
+
+ convertDivs = function () {
+ if (arguments && 1 < arguments.length)
+ {
+ var sText = $.trim(arguments[1]);
+ if (0 < sText.length)
+ {
+ sText = sText.replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs);
+ sText = '\n' + $.trim(sText) + '\n';
+ }
+
+ return sText;
+ }
+
+ return '';
+ },
+
+ convertPre = function () {
+ return (arguments && 1 < arguments.length) ? arguments[1].toString().replace(/[\n]/gm, '
') : '';
+ },
+
+ fixAttibuteValue = function () {
+ return (arguments && 1 < arguments.length) ?
+ '' + arguments[1] + arguments[2].replace(//g, '>') : '';
+ },
+
+ convertLinks = function () {
+ return (arguments && 1 < arguments.length) ? $.trim(arguments[1]) : '';
+ }
+ ;
+
+ sText = sHtml
+ .replace(/]*>([\s\S\r\n]*)<\/pre>/gmi, convertPre)
+ .replace(/[\s]+/gm, ' ')
+ .replace(/((?:href|data)\s?=\s?)("[^"]+?"|'[^']+?')/gmi, fixAttibuteValue)
+ .replace(/
]*>/gmi, '\n')
+ .replace(/<\/h[\d]>/gi, '\n')
+ .replace(/<\/p>/gi, '\n\n')
+ .replace(/<\/li>/gi, '\n')
+ .replace(/<\/td>/gi, '\n')
+ .replace(/<\/tr>/gi, '\n')
+ .replace(/
]*>/gmi, '\n_______________________________\n\n')
+ .replace(/]*>([\s\S\r\n]*)<\/div>/gmi, convertDivs)
+ .replace(/]*>/gmi, '\n__bq__start__\n')
+ .replace(/<\/blockquote>/gmi, '\n__bq__end__\n')
+ .replace(/]*>([\s\S\r\n]*?)<\/a>/gmi, convertLinks)
+ .replace(/<\/div>/gi, '\n')
+ .replace(/ /gi, ' ')
+ .replace(/"/gi, '"')
+ .replace(/<[^>]*>/gm, '')
+ ;
+
+ sText = Utils.$div.html(sText).text();
+
+ sText = sText
+ .replace(/\n[ \t]+/gm, '\n')
+ .replace(/[\n]{3,}/gm, '\n\n')
+ .replace(/>/gi, '>')
+ .replace(/</gi, '<')
+ .replace(/&/gi, '&')
+ ;
+
+ iPos = 0;
+ iLimit = 100;
+
+ while (0 < iLimit)
+ {
+ iLimit--;
+ iP1 = sText.indexOf('__bq__start__', iPos);
+ if (-1 < iP1)
+ {
+ iP2 = sText.indexOf('__bq__start__', iP1 + 5);
+ iP3 = sText.indexOf('__bq__end__', iP1 + 5);
+
+ if ((-1 === iP2 || iP3 < iP2) && iP1 < iP3)
+ {
+ sText = sText.substring(0, iP1) +
+ convertBlockquote(sText.substring(iP1 + 13, iP3)) +
+ sText.substring(iP3 + 11);
+
+ iPos = 0;
+ }
+ else if (-1 < iP2 && iP2 < iP3)
+ {
+ iPos = iP2 - 1;
+ }
+ else
+ {
+ iPos = 0;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ sText = sText
+ .replace(/__bq__start__/gm, '')
+ .replace(/__bq__end__/gm, '')
+ ;
+
+ return sText;
+ };
+
+ /**
+ * @param {string} sPlain
+ * @param {boolean} bLinkify = false
+ * @return {string}
+ */
+ Utils.plainToHtml = function (sPlain, bLinkify)
+ {
+ sPlain = sPlain.toString().replace(/\r/g, '');
+
+ var
+ bIn = false,
+ bDo = true,
+ bStart = true,
+ aNextText = [],
+ sLine = '',
+ iIndex = 0,
+ aText = sPlain.split("\n")
+ ;
+
+ do
+ {
+ bDo = false;
+ aNextText = [];
+ for (iIndex = 0; iIndex < aText.length; iIndex++)
+ {
+ sLine = aText[iIndex];
+ bStart = '>' === sLine.substr(0, 1);
+ if (bStart && !bIn)
+ {
+ bDo = true;
+ bIn = true;
+ aNextText.push('~~~blockquote~~~');
+ aNextText.push(sLine.substr(1));
+ }
+ else if (!bStart && bIn)
+ {
+ bIn = false;
+ aNextText.push('~~~/blockquote~~~');
+ aNextText.push(sLine);
+ }
+ else if (bStart && bIn)
+ {
+ aNextText.push(sLine.substr(1));
+ }
+ else
+ {
+ aNextText.push(sLine);
+ }
+ }
+
+ if (bIn)
+ {
+ bIn = false;
+ aNextText.push('~~~/blockquote~~~');
+ }
+
+ aText = aNextText;
+ }
+ while (bDo);
+
+ sPlain = aText.join("\n");
+
+ sPlain = sPlain
+ .replace(/&/g, '&')
+ .replace(/>/g, '>').replace(/')
+ .replace(/[\s]*~~~\/blockquote~~~/g, '
')
+ .replace(/[\-_~]{10,}/g, '
')
+ .replace(/\n/g, '
');
+
+ return bLinkify ? Utils.linkify(sPlain) : sPlain;
+ };
+
+ window.rainloop_Utils_htmlToPlain = Utils.htmlToPlain;
+ window.rainloop_Utils_plainToHtml = Utils.plainToHtml;
+
+ /**
+ * @param {string} sHtml
+ * @return {string}
+ */
+ Utils.linkify = function (sHtml)
+ {
+ if ($.fn && $.fn.linkify)
+ {
+ sHtml = Utils.$div.html(sHtml.replace(/&/ig, 'amp_amp_12345_amp_amp'))
+ .linkify()
+ .find('.linkified').removeClass('linkified').end()
+ .html()
+ .replace(/amp_amp_12345_amp_amp/g, '&')
+ ;
+ }
+
+ return sHtml;
+ };
+
+ Utils.resizeAndCrop = function (sUrl, iValue, fCallback)
+ {
+ var oTempImg = new window.Image();
+ oTempImg.onload = function() {
+
+ var
+ aDiff = [0, 0],
+ oCanvas = document.createElement('canvas'),
+ oCtx = oCanvas.getContext('2d')
+ ;
+
+ oCanvas.width = iValue;
+ oCanvas.height = iValue;
+
+ if (this.width > this.height)
+ {
+ aDiff = [this.width - this.height, 0];
+ }
+ else
+ {
+ aDiff = [0, this.height - this.width];
+ }
+
+ oCtx.fillStyle = '#fff';
+ oCtx.fillRect(0, 0, iValue, iValue);
+ oCtx.drawImage(this, aDiff[0] / 2, aDiff[1] / 2, this.width - aDiff[0], this.height - aDiff[1], 0, 0, iValue, iValue);
+
+ fCallback(oCanvas.toDataURL('image/jpeg'));
+ };
+
+ oTempImg.src = sUrl;
+ };
+
+ Utils.computedPagenatorHelper = function (koCurrentPage, koPageCount)
+ {
+ return function() {
+ var
+ iPrev = 0,
+ iNext = 0,
+ iLimit = 2,
+ aResult = [],
+ iCurrentPage = koCurrentPage(),
+ iPageCount = koPageCount(),
+
+ /**
+ * @param {number} iIndex
+ * @param {boolean=} bPush
+ * @param {string=} sCustomName
+ */
+ fAdd = function (iIndex, bPush, sCustomName) {
+
+ var oData = {
+ 'current': iIndex === iCurrentPage,
+ 'name': Utils.isUnd(sCustomName) ? iIndex.toString() : sCustomName.toString(),
+ 'custom': Utils.isUnd(sCustomName) ? false : true,
+ 'title': Utils.isUnd(sCustomName) ? '' : iIndex.toString(),
+ 'value': iIndex.toString()
+ };
+
+ if (Utils.isUnd(bPush) ? true : !!bPush)
+ {
+ aResult.push(oData);
+ }
+ else
+ {
+ aResult.unshift(oData);
+ }
+ }
+ ;
+
+ if (1 < iPageCount || (0 < iPageCount && iPageCount < iCurrentPage))
+ // if (0 < iPageCount && 0 < iCurrentPage)
+ {
+ if (iPageCount < iCurrentPage)
+ {
+ fAdd(iPageCount);
+ iPrev = iPageCount;
+ iNext = iPageCount;
+ }
+ else
+ {
+ if (3 >= iCurrentPage || iPageCount - 2 <= iCurrentPage)
+ {
+ iLimit += 2;
+ }
+
+ fAdd(iCurrentPage);
+ iPrev = iCurrentPage;
+ iNext = iCurrentPage;
+ }
+
+ while (0 < iLimit) {
+
+ iPrev -= 1;
+ iNext += 1;
+
+ if (0 < iPrev)
+ {
+ fAdd(iPrev, false);
+ iLimit--;
+ }
+
+ if (iPageCount >= iNext)
+ {
+ fAdd(iNext, true);
+ iLimit--;
+ }
+ else if (0 >= iPrev)
+ {
+ break;
+ }
+ }
+
+ if (3 === iPrev)
+ {
+ fAdd(2, false);
+ }
+ else if (3 < iPrev)
+ {
+ fAdd(Math.round((iPrev - 1) / 2), false, '...');
+ }
+
+ if (iPageCount - 2 === iNext)
+ {
+ fAdd(iPageCount - 1, true);
+ }
+ else if (iPageCount - 2 > iNext)
+ {
+ fAdd(Math.round((iPageCount + iNext) / 2), true, '...');
+ }
+
+ // first and last
+ if (1 < iPrev)
+ {
+ fAdd(1, false);
+ }
+
+ if (iPageCount > iNext)
+ {
+ fAdd(iPageCount, true);
+ }
+ }
+
+ return aResult;
+ };
+ };
+
+ Utils.selectElement = function (element)
+ {
+ /* jshint onevar: false */
+ if (window.getSelection)
+ {
+ var sel = window.getSelection();
+ sel.removeAllRanges();
+ var range = document.createRange();
+ range.selectNodeContents(element);
+ sel.addRange(range);
+ }
+ else if (document.selection)
+ {
+ var textRange = document.body.createTextRange();
+ textRange.moveToElementText(element);
+ textRange.select();
+ }
+ /* jshint onevar: true */
+ };
+
+ Utils.disableKeyFilter = function ()
+ {
+ if (window.key)
+ {
+ key.filter = function () {
+ return RL.data().useKeyboardShortcuts();
+ };
+ }
+ };
+
+ Utils.restoreKeyFilter = function ()
+ {
+ if (window.key)
+ {
+ key.filter = function (event) {
+
+ if (RL.data().useKeyboardShortcuts())
+ {
+ var
+ element = event.target || event.srcElement,
+ tagName = element ? element.tagName : ''
+ ;
+
+ tagName = tagName.toUpperCase();
+ return !(tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA' ||
+ (element && tagName === 'DIV' && 'editorHtmlArea' === element.className && element.contentEditable)
+ );
+ }
+
+ return false;
+ };
+ }
+ };
+
+ Utils.detectDropdownVisibility = _.debounce(function () {
+ Globals.dropdownVisibility(!!_.find(Globals.aBootstrapDropdowns, function (oItem) {
+ return oItem.hasClass('open');
+ }));
+ }, 50);
+
+ Utils.triggerAutocompleteInputChange = function (bDelay) {
+
+ var fFunc = function () {
+ $('.checkAutocomplete').trigger('change');
+ };
+
+ if (bDelay)
+ {
+ _.delay(fFunc, 100);
+ }
+ else
+ {
+ fFunc();
+ }
+ };
+
+ module.exports = Utils;
+
+}(module));
+},{"../External/$doc.js":9,"../External/$window.js":11,"../External/NotificationClass.js":13,"../External/jquery.js":16,"../External/ko.js":17,"../External/underscore.js":19,"../External/window.js":20,"./Enums.js":5,"./Globals.js":6}],9:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')(window.document);
+
+},{"./jquery.js":16}],10:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')('html');
+
+},{"./jquery.js":16}],11:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./jquery.js')(window);
+
+},{"./jquery.js":16}],12:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = require('./window.js')['rainloopAppData'] || {};
+},{"./window.js":20}],13:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+var
+ window = require('./window.js')
+;
+
+module.exports = window.Notification && window.Notification.requestPermission ? window.Notification : null;
+},{"./window.js":20}],14:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = crossroads;
+},{}],15:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = hasher;
+},{}],16:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = $;
+},{}],17:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ $ = require('./jquery.js'),
+ _ = require('./underscore.js'),
+ window = require('./window.js'),
+ $window = require('./$window.js'),
+ $doc = require('./$doc.js'),
+ Globals = require('../Common/Globals.js'),
+ Utils = require('../Common/Utils.js')
+ ;
+
+ ko.bindingHandlers.tooltip = {
+ 'init': function (oElement, fValueAccessor) {
+ if (!Globals.bMobileDevice)
+ {
+ var
+ $oEl = $(oElement),
+ sClass = $oEl.data('tooltip-class') || '',
+ sPlacement = $oEl.data('tooltip-placement') || 'top'
+ ;
+
+ $oEl.tooltip({
+ 'delay': {
+ 'show': 500,
+ 'hide': 100
+ },
+ 'html': true,
+ 'container': 'body',
+ 'placement': sPlacement,
+ 'trigger': 'hover',
+ 'title': function () {
+ return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '' +
+ Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + '';
+ }
+ }).click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.tooltip2 = {
+ 'init': function (oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ sClass = $oEl.data('tooltip-class') || '',
+ sPlacement = $oEl.data('tooltip-placement') || 'top'
+ ;
+
+ $oEl.tooltip({
+ 'delay': {
+ 'show': 500,
+ 'hide': 100
+ },
+ 'html': true,
+ 'container': 'body',
+ 'placement': sPlacement,
+ 'title': function () {
+ return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' :
+ '' + fValueAccessor()() + '';
+ }
+ }).click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ }
+ };
+
+ ko.bindingHandlers.tooltip3 = {
+ 'init': function (oElement) {
+
+ var $oEl = $(oElement);
+
+ $oEl.tooltip({
+ 'container': 'body',
+ 'trigger': 'hover manual',
+ 'title': function () {
+ return $oEl.data('tooltip3-data') || '';
+ }
+ });
+
+ $doc.click(function () {
+ $oEl.tooltip('hide');
+ });
+
+ Globals.tooltipTrigger.subscribe(function () {
+ $oEl.tooltip('hide');
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var sValue = ko.utils.unwrapObservable(fValueAccessor());
+ if ('' === sValue)
+ {
+ $(oElement).data('tooltip3-data', '').tooltip('hide');
+ }
+ else
+ {
+ $(oElement).data('tooltip3-data', sValue).tooltip('show');
+ }
+ }
+ };
+
+ ko.bindingHandlers.registrateBootstrapDropdown = {
+ 'init': function (oElement) {
+ Globals.aBootstrapDropdowns.push($(oElement));
+ }
+ };
+
+ ko.bindingHandlers.openDropdownTrigger = {
+ 'update': function (oElement, fValueAccessor) {
+ if (ko.utils.unwrapObservable(fValueAccessor()))
+ {
+ var $el = $(oElement);
+ if (!$el.hasClass('open'))
+ {
+ $el.find('.dropdown-toggle').dropdown('toggle');
+ Utils.detectDropdownVisibility();
+ }
+
+ fValueAccessor()(false);
+ }
+ }
+ };
+
+ ko.bindingHandlers.dropdownCloser = {
+ 'init': function (oElement) {
+ $(oElement).closest('.dropdown').on('click', '.e-item', function () {
+ $(oElement).dropdown('toggle');
+ });
+ }
+ };
+
+ ko.bindingHandlers.popover = {
+ 'init': function (oElement, fValueAccessor) {
+ $(oElement).popover(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.csstext = {
+ 'init': function (oElement, fValueAccessor) {
+ if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
+ {
+ oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
+ }
+ else
+ {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ },
+ 'update': function (oElement, fValueAccessor) {
+ if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
+ {
+ oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
+ }
+ else
+ {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ }
+ };
+
+ ko.bindingHandlers.resizecrop = {
+ 'init': function (oElement) {
+ $(oElement).addClass('resizecrop').resizecrop({
+ 'width': '100',
+ 'height': '100',
+ 'wrapperCSS': {
+ 'border-radius': '10px'
+ }
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ fValueAccessor()();
+ $(oElement).resizecrop({
+ 'width': '100',
+ 'height': '100'
+ });
+ }
+ };
+
+ ko.bindingHandlers.onEnter = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ $(oElement).on('keypress', function (oEvent) {
+ if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10))
+ {
+ $(oElement).trigger('change');
+ fValueAccessor().call(oViewModel);
+ }
+ });
+ }
+ };
+
+ ko.bindingHandlers.onEsc = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ $(oElement).on('keypress', function (oEvent) {
+ if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10))
+ {
+ $(oElement).trigger('change');
+ fValueAccessor().call(oViewModel);
+ }
+ });
+ }
+ };
+
+ ko.bindingHandlers.clickOnTrue = {
+ 'update': function (oElement, fValueAccessor) {
+ if (ko.utils.unwrapObservable(fValueAccessor()))
+ {
+ $(oElement).click();
+ }
+ }
+ };
+
+ ko.bindingHandlers.modal = {
+ 'init': function (oElement, fValueAccessor) {
+
+ $(oElement).toggleClass('fade', !Globals.bMobileDevice).modal({
+ 'keyboard': false,
+ 'show': ko.utils.unwrapObservable(fValueAccessor())
+ })
+ .on('shown', function () {
+ Utils.windowResize();
+ })
+ .find('.close').click(function () {
+ fValueAccessor()(false);
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).modal(ko.utils.unwrapObservable(fValueAccessor()) ? 'show' : 'hide');
+ }
+ };
+
+ ko.bindingHandlers.i18nInit = {
+ 'init': function (oElement) {
+ Utils.i18nToNode(oElement);
+ }
+ };
+
+ ko.bindingHandlers.i18nUpdate = {
+ 'update': function (oElement, fValueAccessor) {
+ ko.utils.unwrapObservable(fValueAccessor());
+ Utils.i18nToNode(oElement);
+ }
+ };
+
+ ko.bindingHandlers.link = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.title = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.textF = {
+ 'init': function (oElement, fValueAccessor) {
+ $(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
+ }
+ };
+
+ ko.bindingHandlers.initDom = {
+ 'init': function (oElement, fValueAccessor) {
+ fValueAccessor()(oElement);
+ }
+ };
+
+ ko.bindingHandlers.initResizeTrigger = {
+ 'init': function (oElement, fValueAccessor) {
+ var aValues = ko.utils.unwrapObservable(fValueAccessor());
+ $(oElement).css({
+ 'height': aValues[1],
+ 'min-height': aValues[1]
+ });
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var
+ aValues = ko.utils.unwrapObservable(fValueAccessor()),
+ iValue = Utils.pInt(aValues[1]),
+ iSize = 0,
+ iOffset = $(oElement).offset().top
+ ;
+
+ if (0 < iOffset)
+ {
+ iOffset += Utils.pInt(aValues[2]);
+ iSize = $window.height() - iOffset;
+
+ if (iValue < iSize)
+ {
+ iValue = iSize;
+ }
+
+ $(oElement).css({
+ 'height': iValue,
+ 'min-height': iValue
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.appendDom = {
+ 'update': function (oElement, fValueAccessor) {
+ $(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show();
+ }
+ };
+
+ ko.bindingHandlers.draggable = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ if (!Globals.bMobileDevice)
+ {
+ var
+ iTriggerZone = 100,
+ iScrollSpeed = 3,
+ fAllValueFunc = fAllBindingsAccessor(),
+ sDroppableSelector = fAllValueFunc && fAllValueFunc['droppableSelector'] ? fAllValueFunc['droppableSelector'] : '',
+ oConf = {
+ 'distance': 20,
+ 'handle': '.dragHandle',
+ 'cursorAt': {'top': 22, 'left': 3},
+ 'refreshPositions': true,
+ 'scroll': true
+ }
+ ;
+
+ if (sDroppableSelector)
+ {
+ oConf['drag'] = function (oEvent) {
+
+ $(sDroppableSelector).each(function () {
+ var
+ moveUp = null,
+ moveDown = null,
+ $this = $(this),
+ oOffset = $this.offset(),
+ bottomPos = oOffset.top + $this.height()
+ ;
+
+ window.clearInterval($this.data('timerScroll'));
+ $this.data('timerScroll', false);
+
+ if (oEvent.pageX >= oOffset.left && oEvent.pageX <= oOffset.left + $this.width())
+ {
+ if (oEvent.pageY >= bottomPos - iTriggerZone && oEvent.pageY <= bottomPos)
+ {
+ moveUp = function() {
+ $this.scrollTop($this.scrollTop() + iScrollSpeed);
+ Utils.windowResize();
+ };
+
+ $this.data('timerScroll', window.setInterval(moveUp, 10));
+ moveUp();
+ }
+
+ if (oEvent.pageY >= oOffset.top && oEvent.pageY <= oOffset.top + iTriggerZone)
+ {
+ moveDown = function() {
+ $this.scrollTop($this.scrollTop() - iScrollSpeed);
+ Utils.windowResize();
+ };
+
+ $this.data('timerScroll', window.setInterval(moveDown, 10));
+ moveDown();
+ }
+ }
+ });
+ };
+
+ oConf['stop'] = function() {
+ $(sDroppableSelector).each(function () {
+ window.clearInterval($(this).data('timerScroll'));
+ $(this).data('timerScroll', false);
+ });
+ };
+ }
+
+ oConf['helper'] = function (oEvent) {
+ return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null);
+ };
+
+ $(oElement).draggable(oConf).on('mousedown', function () {
+ Utils.removeInFocus();
+ });
+ }
+ }
+ };
+
+ ko.bindingHandlers.droppable = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ if (!Globals.bMobileDevice)
+ {
+ var
+ fValueFunc = fValueAccessor(),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fOverCallback = fAllValueFunc && fAllValueFunc['droppableOver'] ? fAllValueFunc['droppableOver'] : null,
+ fOutCallback = fAllValueFunc && fAllValueFunc['droppableOut'] ? fAllValueFunc['droppableOut'] : null,
+ oConf = {
+ 'tolerance': 'pointer',
+ 'hoverClass': 'droppableHover'
+ }
+ ;
+
+ if (fValueFunc)
+ {
+ oConf['drop'] = function (oEvent, oUi) {
+ fValueFunc(oEvent, oUi);
+ };
+
+ if (fOverCallback)
+ {
+ oConf['over'] = function (oEvent, oUi) {
+ fOverCallback(oEvent, oUi);
+ };
+ }
+
+ if (fOutCallback)
+ {
+ oConf['out'] = function (oEvent, oUi) {
+ fOutCallback(oEvent, oUi);
+ };
+ }
+
+ $(oElement).droppable(oConf);
+ }
+ }
+ }
+ };
+
+ ko.bindingHandlers.nano = {
+ 'init': function (oElement) {
+ if (!Globals.bDisableNanoScroll)
+ {
+ $(oElement)
+ .addClass('nano')
+ .nanoScroller({
+ 'iOSNativeScrolling': false,
+ 'preventPageScrolling': true
+ })
+ ;
+ }
+ }
+ };
+
+ ko.bindingHandlers.saveTrigger = {
+ 'init': function (oElement) {
+
+ var $oEl = $(oElement);
+
+ $oEl.data('save-trigger-type', $oEl.is('input[type=text],input[type=email],input[type=password],select,textarea') ? 'input' : 'custom');
+
+ if ('custom' === $oEl.data('save-trigger-type'))
+ {
+ $oEl.append(
+ ' '
+ ).addClass('settings-saved-trigger');
+ }
+ else
+ {
+ $oEl.addClass('settings-saved-trigger-input');
+ }
+ },
+ 'update': function (oElement, fValueAccessor) {
+ var
+ mValue = ko.utils.unwrapObservable(fValueAccessor()),
+ $oEl = $(oElement)
+ ;
+
+ if ('custom' === $oEl.data('save-trigger-type'))
+ {
+ switch (mValue.toString())
+ {
+ case '1':
+ $oEl
+ .find('.animated,.error').hide().removeClass('visible')
+ .end()
+ .find('.success').show().addClass('visible')
+ ;
+ break;
+ case '0':
+ $oEl
+ .find('.animated,.success').hide().removeClass('visible')
+ .end()
+ .find('.error').show().addClass('visible')
+ ;
+ break;
+ case '-2':
+ $oEl
+ .find('.error,.success').hide().removeClass('visible')
+ .end()
+ .find('.animated').show().addClass('visible')
+ ;
+ break;
+ default:
+ $oEl
+ .find('.animated').hide()
+ .end()
+ .find('.error,.success').removeClass('visible')
+ ;
+ break;
+ }
+ }
+ else
+ {
+ switch (mValue.toString())
+ {
+ case '1':
+ $oEl.addClass('success').removeClass('error');
+ break;
+ case '0':
+ $oEl.addClass('error').removeClass('success');
+ break;
+ case '-2':
+ // $oEl;
+ break;
+ default:
+ $oEl.removeClass('error success');
+ break;
+ }
+ }
+ }
+ };
+
+ ko.bindingHandlers.emailsTags = {
+ 'init': function(oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ fValue = fValueAccessor(),
+ fFocusCallback = function (bValue) {
+ if (fValue && fValue.focusTrigger)
+ {
+ fValue.focusTrigger(bValue);
+ }
+ }
+ ;
+
+ $oEl.inputosaurus({
+ 'parseOnBlur': true,
+ 'allowDragAndDrop': true,
+ 'focusCallback': fFocusCallback,
+ 'inputDelimiters': [',', ';'],
+ 'autoCompleteSource': function (oData, fResponse) {
+ RL.getAutocomplete(oData.term, function (aData) {
+ fResponse(_.map(aData, function (oEmailItem) {
+ return oEmailItem.toLine(false);
+ }));
+ });
+ },
+ 'parseHook': function (aInput) {
+ return _.map(aInput, function (sInputValue) {
+
+ var
+ sValue = Utils.trim(sInputValue),
+ oEmail = null
+ ;
+
+ if ('' !== sValue)
+ {
+ oEmail = new EmailModel();
+ oEmail.mailsoParse(sValue);
+ oEmail.clearDuplicateName();
+ return [oEmail.toLine(false), oEmail];
+ }
+
+ return [sValue, null];
+
+ });
+ },
+ 'change': _.bind(function (oEvent) {
+ $oEl.data('EmailsTagsValue', oEvent.target.value);
+ fValue(oEvent.target.value);
+ }, this)
+ });
+ },
+ 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ var
+ $oEl = $(oElement),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null,
+ sValue = ko.utils.unwrapObservable(fValueAccessor())
+ ;
+
+ if ($oEl.data('EmailsTagsValue') !== sValue)
+ {
+ $oEl.val(sValue);
+ $oEl.data('EmailsTagsValue', sValue);
+ $oEl.inputosaurus('refresh');
+ }
+
+ if (fEmailsTagsFilter && ko.utils.unwrapObservable(fEmailsTagsFilter))
+ {
+ $oEl.inputosaurus('focus');
+ }
+ }
+ };
+
+ ko.bindingHandlers.contactTags = {
+ 'init': function(oElement, fValueAccessor) {
+ var
+ $oEl = $(oElement),
+ fValue = fValueAccessor(),
+ fFocusCallback = function (bValue) {
+ if (fValue && fValue.focusTrigger)
+ {
+ fValue.focusTrigger(bValue);
+ }
+ }
+ ;
+
+ $oEl.inputosaurus({
+ 'parseOnBlur': true,
+ 'allowDragAndDrop': false,
+ 'focusCallback': fFocusCallback,
+ 'inputDelimiters': [',', ';'],
+ 'outputDelimiter': ',',
+ 'autoCompleteSource': function (oData, fResponse) {
+ RL.getContactTagsAutocomplete(oData.term, function (aData) { // TODO cjs
+ fResponse(_.map(aData, function (oTagItem) {
+ return oTagItem.toLine(false);
+ }));
+ });
+ },
+ 'parseHook': function (aInput) {
+ return _.map(aInput, function (sInputValue) {
+
+ var
+ sValue = Utils.trim(sInputValue),
+ oTag = null
+ ;
+
+ if ('' !== sValue)
+ {
+ oTag = new ContactTagModel();
+ oTag.name(sValue);
+ return [oTag.toLine(false), oTag];
+ }
+
+ return [sValue, null];
+
+ });
+ },
+ 'change': _.bind(function (oEvent) {
+ $oEl.data('ContactTagsValue', oEvent.target.value);
+ fValue(oEvent.target.value);
+ }, this)
+ });
+ },
+ 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
+
+ var
+ $oEl = $(oElement),
+ fAllValueFunc = fAllBindingsAccessor(),
+ fContactTagsFilter = fAllValueFunc['contactTagsFilter'] || null,
+ sValue = ko.utils.unwrapObservable(fValueAccessor())
+ ;
+
+ if ($oEl.data('ContactTagsValue') !== sValue)
+ {
+ $oEl.val(sValue);
+ $oEl.data('ContactTagsValue', sValue);
+ $oEl.inputosaurus('refresh');
+ }
+
+ if (fContactTagsFilter && ko.utils.unwrapObservable(fContactTagsFilter))
+ {
+ $oEl.inputosaurus('focus');
+ }
+ }
+ };
+
+ ko.bindingHandlers.command = {
+ 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
+ var
+ jqElement = $(oElement),
+ oCommand = fValueAccessor()
+ ;
+
+ if (!oCommand || !oCommand.enabled || !oCommand.canExecute)
+ {
+ throw new Error('You are not using command function');
+ }
+
+ jqElement.addClass('command');
+ ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments);
+ },
+
+ 'update': function (oElement, fValueAccessor) {
+
+ var
+ bResult = true,
+ jqElement = $(oElement),
+ oCommand = fValueAccessor()
+ ;
+
+ bResult = oCommand.enabled();
+ jqElement.toggleClass('command-not-enabled', !bResult);
+
+ if (bResult)
+ {
+ bResult = oCommand.canExecute();
+ jqElement.toggleClass('command-can-not-be-execute', !bResult);
+ }
+
+ jqElement.toggleClass('command-disabled disable disabled', !bResult).toggleClass('no-disabled', !!bResult);
+
+ if (jqElement.is('input') || jqElement.is('button'))
+ {
+ jqElement.prop('disabled', !bResult);
+ }
+ }
+ };
+
+ ko.extenders.trimmer = function (oTarget)
+ {
+ var oResult = ko.computed({
+ 'read': oTarget,
+ 'write': function (sNewValue) {
+ oTarget(Utils.trim(sNewValue.toString()));
+ },
+ 'owner': this
+ });
+
+ oResult(oTarget());
+ return oResult;
+ };
+
+ ko.extenders.posInterer = function (oTarget, iDefault)
+ {
+ var oResult = ko.computed({
+ 'read': oTarget,
+ 'write': function (sNewValue) {
+ var iNew = Utils.pInt(sNewValue.toString(), iDefault);
+ if (0 >= iNew)
+ {
+ iNew = iDefault;
+ }
+
+ if (iNew === oTarget() && '' + iNew !== '' + sNewValue)
+ {
+ oTarget(iNew + 1);
+ }
+
+ oTarget(iNew);
+ }
+ });
+
+ oResult(oTarget());
+ return oResult;
+ };
+
+ ko.extenders.reversible = function (oTarget)
+ {
+ var mValue = oTarget();
+
+ oTarget.commit = function ()
+ {
+ mValue = oTarget();
+ };
+
+ oTarget.reverse = function ()
+ {
+ oTarget(mValue);
+ };
+
+ oTarget.commitedValue = function ()
+ {
+ return mValue;
+ };
+
+ return oTarget;
+ };
+
+ ko.extenders.toggleSubscribe = function (oTarget, oOptions)
+ {
+ oTarget.subscribe(oOptions[1], oOptions[0], 'beforeChange');
+ oTarget.subscribe(oOptions[2], oOptions[0]);
+
+ return oTarget;
+ };
+
+ ko.extenders.falseTimeout = function (oTarget, iOption)
+ {
+ oTarget.iTimeout = 0;
+ oTarget.subscribe(function (bValue) {
+ if (bValue)
+ {
+ window.clearTimeout(oTarget.iTimeout);
+ oTarget.iTimeout = window.setTimeout(function () {
+ oTarget(false);
+ oTarget.iTimeout = 0;
+ }, Utils.pInt(iOption));
+ }
+ });
+
+ return oTarget;
+ };
+
+ ko.observable.fn.validateNone = function ()
+ {
+ this.hasError = ko.observable(false);
+ return this;
+ };
+
+ ko.observable.fn.validateEmail = function ()
+ {
+ this.hasError = ko.observable(false);
+
+ this.subscribe(function (sValue) {
+ sValue = Utils.trim(sValue);
+ this.hasError('' !== sValue && !(/^[^@\s]+@[^@\s]+$/.test(sValue)));
+ }, this);
+
+ this.valueHasMutated();
+ return this;
+ };
+
+ ko.observable.fn.validateSimpleEmail = function ()
+ {
+ this.hasError = ko.observable(false);
+
+ this.subscribe(function (sValue) {
+ sValue = Utils.trim(sValue);
+ this.hasError('' !== sValue && !(/^.+@.+$/.test(sValue)));
+ }, this);
+
+ this.valueHasMutated();
+ return this;
+ };
+
+ ko.observable.fn.validateFunc = function (fFunc)
+ {
+ this.hasFuncError = ko.observable(false);
+
+ if (Utils.isFunc(fFunc))
+ {
+ this.subscribe(function (sValue) {
+ this.hasFuncError(!fFunc(sValue));
+ }, this);
+
+ this.valueHasMutated();
+ }
+
+ return this;
+ };
+
+ module.exports = ko;
+
+}(module));
+},{"../Common/Globals.js":6,"../Common/Utils.js":8,"./$doc.js":9,"./$window.js":11,"./jquery.js":16,"./underscore.js":19,"./window.js":20}],18:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = ssm;
+},{}],19:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = window;
+},{}],20:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+'use strict';
+
+module.exports = window;
+
+},{}],21:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ $ = require('../External/jquery.js'),
+ _ = require('../External/underscore.js'),
+ ko = require('../External/ko.js'),
+ hasher = require('../External/hasher.js'),
+ crossroads = require('../External/crossroads.js'),
+ $html = require('../External/$html.js'),
+ Utils = require('../Common/Utils.js'),
+ Globals = require('../Common/Globals.js'),
+ Enums = require('../Common/Enums.js')
+ ;
+
+ /**
+ * @constructor
+ */
+ function Knoin()
+ {
+ this.sDefaultScreenName = '';
+ this.oScreens = {};
+ this.oCurrentScreen = null;
+ }
+
+ /**
+ * @param {Object} thisObject
+ */
+ Knoin.constructorEnd = function (thisObject)
+ {
+ if (Utils.isFunc(thisObject['__constructor_end']))
+ {
+ thisObject['__constructor_end'].call(thisObject);
+ }
+ };
+
+ Knoin.prototype.sDefaultScreenName = '';
+ Knoin.prototype.oScreens = {};
+ Knoin.prototype.oCurrentScreen = null;
+
+ Knoin.prototype.hideLoading = function ()
+ {
+ $('#rl-loading').hide();
+ };
+
+ Knoin.prototype.routeOff = function ()
+ {
+ hasher.changed.active = false;
+ };
+
+ Knoin.prototype.routeOn = function ()
+ {
+ hasher.changed.active = true;
+ };
+
+ /**
+ * @param {string} sScreenName
+ * @return {?Object}
+ */
+ Knoin.prototype.screen = function (sScreenName)
+ {
+ return ('' !== sScreenName && !Utils.isUnd(this.oScreens[sScreenName])) ? this.oScreens[sScreenName] : null;
+ };
+
+ /**
+ * @param {Function} ViewModelClass
+ * @param {Object=} oScreen
+ */
+ Knoin.prototype.buildViewModel = function (ViewModelClass, oScreen)
+ {
+ if (ViewModelClass && !ViewModelClass.__builded)
+ {
+ var
+ oViewModel = new ViewModelClass(oScreen),
+ sPosition = oViewModel.viewModelPosition(),
+ oViewModelPlace = $('#rl-content #rl-' + sPosition.toLowerCase()),
+ oViewModelDom = null
+ ;
+
+ ViewModelClass.__builded = true;
+ ViewModelClass.__vm = oViewModel;
+ oViewModel.data = RL.data(); // TODO cjs
+
+ oViewModel.viewModelName = ViewModelClass.__name;
+
+ if (oViewModelPlace && 1 === oViewModelPlace.length)
+ {
+ oViewModelDom = $('').addClass('rl-view-model').addClass('RL-' + oViewModel.viewModelTemplate()).hide();
+ oViewModelDom.appendTo(oViewModelPlace);
+
+ oViewModel.viewModelDom = oViewModelDom;
+ ViewModelClass.__dom = oViewModelDom;
+
+ if ('Popups' === sPosition)
+ {
+ oViewModel.cancelCommand = oViewModel.closeCommand = Utils.createCommand(oViewModel, function () {
+ kn.hideScreenPopup(ViewModelClass); // TODO cjs
+ });
+
+ oViewModel.modalVisibility.subscribe(function (bValue) {
+
+ var self = this;
+ if (bValue)
+ {
+ this.viewModelDom.show();
+ this.storeAndSetKeyScope();
+
+ RL.popupVisibilityNames.push(this.viewModelName); // TODO cjs
+ oViewModel.viewModelDom.css('z-index', 3000 + RL.popupVisibilityNames().length + 10); // TODO cjs
+
+ Utils.delegateRun(this, 'onFocus', [], 500);
+ }
+ else
+ {
+ Utils.delegateRun(this, 'onHide');
+ this.restoreKeyScope();
+
+ RL.popupVisibilityNames.remove(this.viewModelName); // TODO cjs
+ oViewModel.viewModelDom.css('z-index', 2000);
+
+ Globals.tooltipTrigger(!Globals.tooltipTrigger());
+
+ _.delay(function () {
+ self.viewModelDom.hide();
+ }, 300);
+ }
+
+ }, oViewModel);
+ }
+
+ Plugins.runHook('view-model-pre-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs
+
+ ko.applyBindingAccessorsToNode(oViewModelDom[0], {
+ 'i18nInit': true,
+ 'template': function () { return {'name': oViewModel.viewModelTemplate()};}
+ }, oViewModel);
+
+ Utils.delegateRun(oViewModel, 'onBuild', [oViewModelDom]);
+ if (oViewModel && 'Popups' === sPosition)
+ {
+ oViewModel.registerPopupKeyDown();
+ }
+
+ Plugins.runHook('view-model-post-build', [ViewModelClass.__name, oViewModel, oViewModelDom]); // TODO cjs
+ }
+ else
+ {
+ Utils.log('Cannot find view model position: ' + sPosition);
+ }
+ }
+
+ return ViewModelClass ? ViewModelClass.__vm : null;
+ };
+
+ /**
+ * @param {Object} oViewModel
+ * @param {Object} oViewModelDom
+ */
+ Knoin.prototype.applyExternal = function (oViewModel, oViewModelDom)
+ {
+ if (oViewModel && oViewModelDom)
+ {
+ ko.applyBindings(oViewModel, oViewModelDom);
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToHide
+ */
+ Knoin.prototype.hideScreenPopup = function (ViewModelClassToHide)
+ {
+ if (ViewModelClassToHide && ViewModelClassToHide.__vm && ViewModelClassToHide.__dom)
+ {
+ ViewModelClassToHide.__vm.modalVisibility(false);
+ Plugins.runHook('view-model-on-hide', [ViewModelClassToHide.__name, ViewModelClassToHide.__vm]); // TODO cjs
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToShow
+ * @param {Array=} aParameters
+ */
+ Knoin.prototype.showScreenPopup = function (ViewModelClassToShow, aParameters)
+ {
+ if (ViewModelClassToShow)
+ {
+ this.buildViewModel(ViewModelClassToShow);
+
+ if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom)
+ {
+ ViewModelClassToShow.__vm.modalVisibility(true);
+ Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []);
+ Plugins.runHook('view-model-on-show', [ViewModelClassToShow.__name, ViewModelClassToShow.__vm, aParameters || []]); // TODO cjs
+ }
+ }
+ };
+
+ /**
+ * @param {Function} ViewModelClassToShow
+ * @return {boolean}
+ */
+ Knoin.prototype.isPopupVisible = function (ViewModelClassToShow)
+ {
+ return ViewModelClassToShow && ViewModelClassToShow.__vm ? ViewModelClassToShow.__vm.modalVisibility() : false;
+ };
+
+ /**
+ * @param {string} sScreenName
+ * @param {string} sSubPart
+ */
+ Knoin.prototype.screenOnRoute = function (sScreenName, sSubPart)
+ {
+ var
+ self = this,
+ oScreen = null,
+ oCross = null
+ ;
+
+ if ('' === Utils.pString(sScreenName))
+ {
+ sScreenName = this.sDefaultScreenName;
+ }
+
+ if ('' !== sScreenName)
+ {
+ oScreen = this.screen(sScreenName);
+ if (!oScreen)
+ {
+ oScreen = this.screen(this.sDefaultScreenName);
+ if (oScreen)
+ {
+ sSubPart = sScreenName + '/' + sSubPart;
+ sScreenName = this.sDefaultScreenName;
+ }
+ }
+
+ if (oScreen && oScreen.__started)
+ {
+ if (!oScreen.__builded)
+ {
+ oScreen.__builded = true;
+
+ if (Utils.isNonEmptyArray(oScreen.viewModels()))
+ {
+ _.each(oScreen.viewModels(), function (ViewModelClass) {
+ this.buildViewModel(ViewModelClass, oScreen);
+ }, this);
+ }
+
+ Utils.delegateRun(oScreen, 'onBuild');
+ }
+
+ _.defer(function () {
+
+ // hide screen
+ if (self.oCurrentScreen)
+ {
+ Utils.delegateRun(self.oCurrentScreen, 'onHide');
+
+ if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
+ {
+ _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
+
+ if (ViewModelClass.__vm && ViewModelClass.__dom &&
+ 'Popups' !== ViewModelClass.__vm.viewModelPosition())
+ {
+ ViewModelClass.__dom.hide();
+ ViewModelClass.__vm.viewModelVisibility(false);
+ Utils.delegateRun(ViewModelClass.__vm, 'onHide');
+ }
+
+ });
+ }
+ }
+ // --
+
+ self.oCurrentScreen = oScreen;
+
+ // show screen
+ if (self.oCurrentScreen)
+ {
+ Utils.delegateRun(self.oCurrentScreen, 'onShow');
+
+ Plugins.runHook('screen-on-show', [self.oCurrentScreen.screenName(), self.oCurrentScreen]); // TODO cjs
+
+ if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
+ {
+ _.each(self.oCurrentScreen.viewModels(), function (ViewModelClass) {
+
+ if (ViewModelClass.__vm && ViewModelClass.__dom &&
+ 'Popups' !== ViewModelClass.__vm.viewModelPosition())
+ {
+ ViewModelClass.__dom.show();
+ ViewModelClass.__vm.viewModelVisibility(true);
+ Utils.delegateRun(ViewModelClass.__vm, 'onShow');
+ Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200);
+
+ Plugins.runHook('view-model-on-show', [ViewModelClass.__name, ViewModelClass.__vm]); // TODO cjs
+ }
+
+ }, self);
+ }
+ }
+ // --
+
+ oCross = oScreen.__cross();
+ if (oCross)
+ {
+ oCross.parse(sSubPart);
+ }
+ });
+ }
+ }
+ };
+
+ /**
+ * @param {Array} aScreensClasses
+ */
+ Knoin.prototype.startScreens = function (aScreensClasses)
+ {
+ $('#rl-content').css({
+ 'visibility': 'hidden'
+ });
+
+ _.each(aScreensClasses, function (CScreen) {
+
+ var
+ oScreen = new CScreen(),
+ sScreenName = oScreen ? oScreen.screenName() : ''
+ ;
+
+ if (oScreen && '' !== sScreenName)
+ {
+ if ('' === this.sDefaultScreenName)
+ {
+ this.sDefaultScreenName = sScreenName;
+ }
+
+ this.oScreens[sScreenName] = oScreen;
+ }
+
+ }, this);
+
+
+ _.each(this.oScreens, function (oScreen) {
+ if (oScreen && !oScreen.__started && oScreen.__start)
+ {
+ oScreen.__started = true;
+ oScreen.__start();
+
+ Plugins.runHook('screen-pre-start', [oScreen.screenName(), oScreen]); // TODO cjs
+ Utils.delegateRun(oScreen, 'onStart');
+ Plugins.runHook('screen-post-start', [oScreen.screenName(), oScreen]); // TODO cjs
+ }
+ }, this);
+
+ var oCross = crossroads.create();
+ oCross.addRoute(/^([a-zA-Z0-9\-]*)\/?(.*)$/, _.bind(this.screenOnRoute, this));
+
+ hasher.initialized.add(oCross.parse, oCross);
+ hasher.changed.add(oCross.parse, oCross);
+ hasher.init();
+
+ $('#rl-content').css({
+ 'visibility': 'visible'
+ });
+
+ _.delay(function () {
+ $html.removeClass('rl-started-trigger').addClass('rl-started');
+ }, 50);
+ };
+
+ /**
+ * @param {string} sHash
+ * @param {boolean=} bSilence = false
+ * @param {boolean=} bReplace = false
+ */
+ Knoin.prototype.setHash = function (sHash, bSilence, bReplace)
+ {
+ sHash = '#' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
+ sHash = '/' === sHash.substr(0, 1) ? sHash.substr(1) : sHash;
+
+ bReplace = Utils.isUnd(bReplace) ? false : !!bReplace;
+
+ if (Utils.isUnd(bSilence) ? false : !!bSilence)
+ {
+ hasher.changed.active = false;
+ hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
+ hasher.changed.active = true;
+ }
+ else
+ {
+ hasher.changed.active = true;
+ hasher[bReplace ? 'replaceHash' : 'setHash'](sHash);
+ hasher.setHash(sHash);
+ }
+ };
+
+ /**
+ * @return {Knoin}
+ */
+ Knoin.prototype.bootstart = function (RL)
+ {
+ var
+ window = require('../External/window.js'),
+ $window = require('../External/$window.js'),
+ $html = require('../External/$html.js'),
+ Plugins = require('../Common/Plugins.js'),
+ EmailModel = require('../Models/EmailModel.js')
+ ;
+
+ $html.addClass(Globals.bMobileDevice ? 'mobile' : 'no-mobile');
+
+ $window.keydown(Utils.killCtrlAandS).keyup(Utils.killCtrlAandS);
+ $window.unload(function () {
+ Globals.bUnload = true;
+ });
+
+ $html.on('click.dropdown.data-api', function () {
+ Utils.detectDropdownVisibility();
+ });
+
+ // export
+ window['rl'] = window['rl'] || {};
+ window['rl']['addHook'] = Plugins.addHook;
+ window['rl']['settingsGet'] = Plugins.mainSettingsGet;
+ window['rl']['remoteRequest'] = Plugins.remoteRequest;
+ window['rl']['pluginSettingsGet'] = Plugins.settingsGet;
+ window['rl']['addSettingsViewModel'] = Utils.addSettingsViewModel;
+ window['rl']['createCommand'] = Utils.createCommand;
+
+ window['rl']['EmailModel'] = EmailModel;
+ window['rl']['Enums'] = Enums;
+
+ window['__RLBOOT'] = function (fCall) {
+
+ // boot
+ $(function () {
+
+ if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0])
+ {
+ $('#rl-templates').html(window['rainloopTEMPLATES'][0]);
+
+ _.delay(function () {
+
+ RL.bootstart();
+
+ $html.removeClass('no-js rl-booted-trigger').addClass('rl-booted');
+ }, 50);
+ }
+ else
+ {
+ fCall(false);
+ }
+
+ window['__RLBOOT'] = null;
+ });
+ };
+ };
+
+ module.exports = new Knoin();
+
+}(module));
+},{"../Common/Enums.js":5,"../Common/Globals.js":6,"../Common/Plugins.js":7,"../Common/Utils.js":8,"../External/$html.js":10,"../External/$window.js":11,"../External/crossroads.js":14,"../External/hasher.js":15,"../External/jquery.js":16,"../External/ko.js":17,"../External/underscore.js":19,"../External/window.js":20,"../Models/EmailModel.js":23}],22:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ /**
+ * @constructor
+ */
+ function KnoinAbstractBoot()
+ {
+
+ }
+
+ KnoinAbstractBoot.prototype.bootstart = function ()
+ {
+
+ };
+
+ module.exports = KnoinAbstractBoot;
+
+}(module));
+},{}],23:[function(require,module,exports){
+/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
+
+(function (module) {
+
+ 'use strict';
+
+ var
+ Enums = require('../Common/Enums.js'),
+ Utils = require('../Common/Utils.js')
+ ;
+
+ /**
+ * @param {string=} sEmail
+ * @param {string=} sName
+ *
+ * @constructor
+ */
+ function EmailModel(sEmail, sName)
+ {
+ this.email = sEmail || '';
+ this.name = sName || '';
+ this.privateType = null;
+
+ this.clearDuplicateName();
+ }
+
+ /**
+ * @static
+ * @param {AjaxJsonEmail} oJsonEmail
+ * @return {?EmailModel}
+ */
+ EmailModel.newInstanceFromJson = function (oJsonEmail)
+ {
+ var oEmailModel = new EmailModel();
+ return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
+ };
+
+ /**
+ * @type {string}
+ */
+ EmailModel.prototype.name = '';
+
+ /**
+ * @type {string}
+ */
+ EmailModel.prototype.email = '';
+
+ /**
+ * @type {(number|null)}
+ */
+ EmailModel.prototype.privateType = null;
+
+ EmailModel.prototype.clear = function ()
+ {
+ this.email = '';
+ this.name = '';
+ this.privateType = null;
+ };
+
+ /**
+ * @returns {boolean}
+ */
+ EmailModel.prototype.validate = function ()
+ {
+ return '' !== this.name || '' !== this.email;
+ };
+
+ /**
+ * @param {boolean} bWithoutName = false
+ * @return {string}
+ */
+ EmailModel.prototype.hash = function (bWithoutName)
+ {
+ return '#' + (bWithoutName ? '' : this.name) + '#' + this.email + '#';
+ };
+
+ EmailModel.prototype.clearDuplicateName = function ()
+ {
+ if (this.name === this.email)
+ {
+ this.name = '';
+ }
+ };
+
+ /**
+ * @return {number}
+ */
+ EmailModel.prototype.type = function ()
+ {
+ if (null === this.privateType)
+ {
+ if (this.email && '@facebook.com' === this.email.substr(-13))
+ {
+ this.privateType = Enums.EmailType.Facebook;
+ }
+
+ if (null === this.privateType)
+ {
+ this.privateType = Enums.EmailType.Default;
+ }
+ }
+
+ return this.privateType;
+ };
+
+ /**
+ * @param {string} sQuery
+ * @return {boolean}
+ */
+ EmailModel.prototype.search = function (sQuery)
+ {
+ return -1 < (this.name + ' ' + this.email).toLowerCase().indexOf(sQuery.toLowerCase());
+ };
+
+ /**
+ * @param {string} sString
+ */
+ EmailModel.prototype.parse = function (sString)
+ {
+ this.clear();
+
+ sString = Utils.trim(sString);
+
+ var
+ mRegex = /(?:"([^"]+)")? ?(.*?@[^>,]+)>?,? ?/g,
+ mMatch = mRegex.exec(sString)
+ ;
+
+ if (mMatch)
+ {
+ this.name = mMatch[1] || '';
+ this.email = mMatch[2] || '';
+
+ this.clearDuplicateName();
+ }
+ else if ((/^[^@]+@[^@]+$/).test(sString))
+ {
+ this.name = '';
+ this.email = sString;
+ }
+ };
+
+ /**
+ * @param {AjaxJsonEmail} oJsonEmail
+ * @return {boolean}
+ */
+ EmailModel.prototype.initByJson = function (oJsonEmail)
+ {
+ var bResult = false;
+ if (oJsonEmail && 'Object/Email' === oJsonEmail['@Object'])
+ {
+ this.name = Utils.trim(oJsonEmail.Name);
+ this.email = Utils.trim(oJsonEmail.Email);
+
+ bResult = '' !== this.email;
+ this.clearDuplicateName();
+ }
+
+ return bResult;
+ };
+
+ /**
+ * @param {boolean} bFriendlyView
+ * @param {boolean=} bWrapWithLink = false
+ * @param {boolean=} bEncodeHtml = false
+ * @return {string}
+ */
+ EmailModel.prototype.toLine = function (bFriendlyView, bWrapWithLink, bEncodeHtml)
+ {
+ var sResult = '';
+ if ('' !== this.email)
+ {
+ bWrapWithLink = Utils.isUnd(bWrapWithLink) ? false : !!bWrapWithLink;
+ bEncodeHtml = Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml;
+
+ if (bFriendlyView && '' !== this.name)
+ {
+ sResult = bWrapWithLink ? '') +
+ '" target="_blank" tabindex="-1">' + Utils.encodeHtml(this.name) + '' :
+ (bEncodeHtml ? Utils.encodeHtml(this.name) : this.name);
+ }
+ else
+ {
+ sResult = this.email;
+ if ('' !== this.name)
+ {
+ if (bWrapWithLink)
+ {
+ sResult = Utils.encodeHtml('"' + this.name + '" <') +
+ '') + '" target="_blank" tabindex="-1">' + Utils.encodeHtml(sResult) + '' + Utils.encodeHtml('>');
+ }
+ else
+ {
+ sResult = '"' + this.name + '" <' + sResult + '>';
+ if (bEncodeHtml)
+ {
+ sResult = Utils.encodeHtml(sResult);
+ }
+ }
+ }
+ else if (bWrapWithLink)
+ {
+ sResult = '' + Utils.encodeHtml(this.email) + '';
+ }
+ }
+ }
+
+ return sResult;
+ };
+
+ /**
+ * @param {string} $sEmailAddress
+ * @return {boolean}
+ */
+ EmailModel.prototype.mailsoParse = function ($sEmailAddress)
+ {
+ $sEmailAddress = Utils.trim($sEmailAddress);
+ if ('' === $sEmailAddress)
+ {
+ return false;
+ }
+
+ var
+ substr = function (str, start, len) {
+ str += '';
+ var end = str.length;
+
+ if (start < 0) {
+ start += end;
+ }
+
+ end = typeof len === 'undefined' ? end : (len < 0 ? len + end : len + start);
+
+ return start >= str.length || start < 0 || start > end ? false : str.slice(start, end);
+ },
+
+ substr_replace = function (str, replace, start, length) {
+ if (start < 0) {
+ start = start + str.length;
+ }
+ length = length !== undefined ? length : str.length;
+ if (length < 0) {
+ length = length + str.length - start;
+ }
+ return str.slice(0, start) + replace.substr(0, length) + replace.slice(length) + str.slice(start + length);
+ },
+
+ $sName = '',
+ $sEmail = '',
+ $sComment = '',
+
+ $bInName = false,
+ $bInAddress = false,
+ $bInComment = false,
+
+ $aRegs = null,
+
+ $iStartIndex = 0,
+ $iEndIndex = 0,
+ $iCurrentIndex = 0
+ ;
+
+ while ($iCurrentIndex < $sEmailAddress.length)
+ {
+ switch ($sEmailAddress.substr($iCurrentIndex, 1))
+ {
+ case '"':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
+ {
+ $bInName = true;
+ $iStartIndex = $iCurrentIndex;
+ }
+ else if ((!$bInAddress) && (!$bInComment))
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sName = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInName = false;
+ }
+ break;
+ case '<':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
+ {
+ if ($iCurrentIndex > 0 && $sName.length === 0)
+ {
+ $sName = substr($sEmailAddress, 0, $iCurrentIndex);
+ }
+
+ $bInAddress = true;
+ $iStartIndex = $iCurrentIndex;
+ }
+ break;
+ case '>':
+ if ($bInAddress)
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sEmail = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInAddress = false;
+ }
+ break;
+ case '(':
+ if ((!$bInName) && (!$bInAddress) && (!$bInComment))
+ {
+ $bInComment = true;
+ $iStartIndex = $iCurrentIndex;
+ }
+ break;
+ case ')':
+ if ($bInComment)
+ {
+ $iEndIndex = $iCurrentIndex;
+ $sComment = substr($sEmailAddress, $iStartIndex + 1, $iEndIndex - $iStartIndex - 1);
+ $sEmailAddress = substr_replace($sEmailAddress, '', $iStartIndex, $iEndIndex - $iStartIndex + 1);
+ $iEndIndex = 0;
+ $iCurrentIndex = 0;
+ $iStartIndex = 0;
+ $bInComment = false;
+ }
+ break;
+ case '\\':
+ $iCurrentIndex++;
+ break;
+ }
+
+ $iCurrentIndex++;
+ }
+
+ if ($sEmail.length === 0)
+ {
+ $aRegs = $sEmailAddress.match(/[^@\s]+@\S+/i);
+ if ($aRegs && $aRegs[0])
+ {
+ $sEmail = $aRegs[0];
+ }
+ else
+ {
+ $sName = $sEmailAddress;
+ }
+ }
+
+ if ($sEmail.length > 0 && $sName.length === 0 && $sComment.length === 0)
+ {
+ $sName = $sEmailAddress.replace($sEmail, '');
+ }
+
+ $sEmail = Utils.trim($sEmail).replace(/^[<]+/, '').replace(/[>]+$/, '');
+ $sName = Utils.trim($sName).replace(/^["']+/, '').replace(/["']+$/, '');
+ $sComment = Utils.trim($sComment).replace(/^[(]+/, '').replace(/[)]+$/, '');
+
+ // Remove backslash
+ $sName = $sName.replace(/\\\\(.)/, '$1');
+ $sComment = $sComment.replace(/\\\\(.)/, '$1');
+
+ this.name = $sName;
+ this.email = $sEmail;
+
+ this.clearDuplicateName();
+ return true;
+ };
+
+ /**
+ * @return {string}
+ */
+ EmailModel.prototype.inputoTagLine = function ()
+ {
+ return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email;
+ };
+
+ module.exports = EmailModel;
+
+}(module));
+},{"../Common/Enums.js":5,"../Common/Utils.js":8}]},{},[1]);