%PDF- %PDF-
Direktori : /www/varak.net/mail2.varak.net_old/static/js/ |
Current File : //www/varak.net/mail2.varak.net_old/static/js/app-filestorage-pub.js |
/*! * Copyright 2004-2014, AfterLogic Corp. * Licensed under AGPLv3 license or AfterLogic license * if commerical version of the product was purchased. * See the LICENSE file for a full license statement. */ (function ($, window, ko, crossroads, hasher) { 'use strict'; var /** * @type {Object} */ Consts = {}, /** * @type {Object} */ Enums = {}, /** * @type {Object.<Function>} */ Utils = {}, /** * @type {Object} */ I18n = window.pSevenI18N || {}, /** * @type {CApp|Object} */ App = {}, /** * @type {Object.<Function>} */ AfterLogicApi = {}, /** * @type {AjaxAppDataResponse|Object} */ AppData = window.pSevenAppData || {}, /** * @type {boolean} */ bExtApp = false, /** * @type {boolean} */ bMobileApp = false, $html = $('html'), /** * @type {boolean} */ bIsIosDevice = -1 < navigator.userAgent.indexOf('iPhone') || -1 < navigator.userAgent.indexOf('iPod') || -1 < navigator.userAgent.indexOf('iPad'), /** * @type {boolean} */ bIsAndroidDevice = -1 < navigator.userAgent.toLowerCase().indexOf('android'), /** * @type {boolean} */ bMobileDevice = bIsIosDevice || bIsAndroidDevice, aViewMimeTypes = [ 'image/jpeg', 'image/png', 'image/gif', 'text/html', 'text/plain', 'text/css', 'text/rfc822-headers', 'message/delivery-status', 'application/x-httpd-php', 'application/javascript', 'application/pdf' ] ; if (window.Modernizr && navigator) { // v = 15; window.Modernizr.addTest('pdf', function() { var aMimes = navigator.mimeTypes, iIndex = 0, iLen = aMimes.length; for (; iIndex < iLen; iIndex++) { if ('application/pdf' === aMimes[iIndex].type) { return true; } } return false; }); } if (!Date.now) { Date.now = function () { return (new Date()).getTime(); }; } bExtApp = true; /** * @constructor */ function CBrowser() { this.ie11 = !!navigator.userAgent.match(/Trident.*rv[ :]*11\./); this.ie = (/msie/.test(navigator.userAgent.toLowerCase()) && !window.opera) || this.ie11; this.ieVersion = this.getIeVersion(); this.ie8AndBelow = this.ie && this.ieVersion <= 8; this.ie9AndBelow = this.ie && this.ieVersion <= 9; this.ie10AndAbove = this.ie && this.ieVersion >= 10; this.opera = !!window.opera || /opr/.test(navigator.userAgent.toLowerCase()); this.firefox = /firefox/.test(navigator.userAgent.toLowerCase()); this.chrome = /chrome/.test(navigator.userAgent.toLowerCase()) && !/opr/.test(navigator.userAgent.toLowerCase()); this.chromeIos = /crios/.test(navigator.userAgent.toLowerCase()); this.safari = /safari/.test(navigator.userAgent.toLowerCase()) && !this.chromeIos; } CBrowser.prototype.getIeVersion = function () { var sUa = navigator.userAgent.toLowerCase(), iVersion = Utils.pInt(sUa.slice(sUa.indexOf('msie') + 4, sUa.indexOf(';', sUa.indexOf('msie') + 4))) ; if (this.ie11) { iVersion = 11; } return iVersion; }; /** * @constructor */ function CAjax() { this.sUrl = '?/Ajax/'; this.requests = ko.observableArray([]); // not "computed", because "reguests" is frequently updated this.openedRequestsCount = ko.observable(0); this.requests.subscribe(function () { this.openedRequestsCount(this.requests().length); }, this); } /** * @param {string=} sAction = '' * @returns {Boolean} */ CAjax.prototype.hasOpenedRequests = function (sAction) { sAction = Utils.isUnd(sAction) ? '' : sAction; this.requests(_.filter(this.requests(), function (oReq) { var bComplete = oReq && oReq.Xhr.readyState === 4, bAbort = !oReq || oReq.Xhr.readyState === 0 && oReq.Xhr.statusText === 'abort', bSameAction = (sAction === '') || oReq && (oReq.Parameters.Action === sAction) ; return oReq && !bComplete && !bAbort && bSameAction; })); return this.requests().length > 0; }; /** * @return {boolean} */ CAjax.prototype.isSearchMessages = function () { var bSearchMessages = false; _.each(this.requests(), function (oReq) { if (oReq && oReq.Parameters && oReq.Parameters.Action === 'MessageList' && oReq.Parameters.Search !== '') { bSearchMessages = true; } }, this); return bSearchMessages; }; /** * @param {string} sAction */ CAjax.prototype.isAllowedActionWithoutAuth = function (sAction) { var aActionsWithoutAuth = ['Login', 'LoginLanguageUpdate', 'Logout', 'AccountCreate', 'SetMobile', 'RegisterAccount', 'GetForgotAccountQuestion', 'ValidateForgotAccountQuestion', 'ChangeForgotAccountPassword']; return _.indexOf(aActionsWithoutAuth, sAction) !== -1; }; CAjax.prototype.isAllowedExtAction = function (sAction) { return sAction === 'SocialRegister' || sAction === 'HelpdeskRegister' || sAction === 'HelpdeskForgot' || sAction === 'HelpdeskLogin' || sAction === 'Logout'; }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext * @param {Function=} fDone */ CAjax.prototype.doSend = function (oParameters, fResponseHandler, oContext, fDone) { var doneFunc = _.bind((fDone || null), this, oParameters, fResponseHandler, oContext), failFunc = _.bind(this.fail, this, oParameters, fResponseHandler, oContext), alwaysFunc = _.bind(this.always, this, oParameters), oXhr = null ; if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('ajax-default-request', [oParameters.Action, oParameters]); } if (AppData.Token) { oParameters.Token = AppData.Token; } this.abortRequests(oParameters); Utils.log('Ajax request send', oParameters.Action, oParameters); oXhr = $.ajax({ url: this.sUrl, type: 'POST', async: true, dataType: 'json', data: oParameters, success: doneFunc, error: failFunc, complete: alwaysFunc }); this.requests().push({Parameters: oParameters, Xhr: oXhr}); }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext */ CAjax.prototype.send = function (oParameters, fResponseHandler, oContext) { var bCurrentAccountId = oParameters.AccountID === undefined, bAccountExists = bCurrentAccountId || AppData.Accounts.hasAccountWithId(oParameters.AccountID) ; if (oParameters && (AppData.Auth && bAccountExists || this.isAllowedActionWithoutAuth(oParameters.Action))) { if (bCurrentAccountId && oParameters.Action !== 'Login') { oParameters.AccountID = AppData.Accounts.currentId(); } this.doSend(oParameters, fResponseHandler, oContext, this.done); } }; /** * @param {Object} oParameters * @param {Function=} fResponseHandler * @param {Object=} oContext */ CAjax.prototype.sendExt = function (oParameters, fResponseHandler, oContext) { var aActionsWithoutAuth = [ 'SocialRegister', 'HelpdeskRegister', 'HelpdeskForgot', 'HelpdeskLogin', 'HelpdeskForgotChangePassword', 'Logout', 'CalendarList', 'EventList', 'FilesPub' ], bAllowWithoutAuth = _.indexOf(aActionsWithoutAuth, oParameters.Action) !== -1 ; if (oParameters && (AppData.Auth || bAllowWithoutAuth)) { if (AppData.TenantHash) { oParameters.TenantHash = AppData.TenantHash; } this.doSend(oParameters, fResponseHandler, oContext, this.doneExt); } }; /** * @param {Object} oParameters */ CAjax.prototype.abortRequests = function (oParameters) { switch (oParameters.Action) { case 'MessageMove': case 'MessageDelete': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); this.abortRequestByActionName('Message'); break; case 'MessageList': case 'MessageSetSeen': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); break; case 'MessageSetAllSeen': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); this.abortRequestByActionName('MessageListByUids', {'Folder': oParameters.Folder}); break; case 'FolderClear': this.abortRequestByActionName('MessageList', {'Folder': oParameters.Folder}); // FolderCounts-request aborted during folder cleaning, not to get the wrong information. this.abortRequestByActionName('FolderCounts'); break; case 'ContactList': case 'GlobalContactList': this.abortRequestByActionName('ContactList'); this.abortRequestByActionName('GlobalContactList'); break; case 'Contact': case 'GlobalContact': this.abortRequestByActionName('Contact'); this.abortRequestByActionName('GlobalContact'); break; case 'EventUpdate': this.abortRequestByActionName('EventUpdate', {'calendarId': oParameters.calendarId, 'uid': oParameters.uid}); break; } }; /** * @param {string} sAction * @param {Object=} oParameters */ CAjax.prototype.abortRequestByActionName = function (sAction, oParameters) { var bDoAbort; _.each(this.requests(), function (oReq, iIndex) { bDoAbort = false; if (oReq && oReq.Parameters.Action === sAction) { switch (sAction) { case 'MessageList': if (oParameters.Folder === oReq.Parameters.Folder) { bDoAbort = true; } break; case 'EventUpdate': if (oParameters.calendarId === oReq.Parameters.calendarId && oParameters.uid === oReq.Parameters.uid) { bDoAbort = true; } break; default: bDoAbort = true; break; } } if (bDoAbort) { oReq.Xhr.abort(); this.requests()[iIndex] = undefined; } }, this); this.requests(_.compact(this.requests())); }; CAjax.prototype.abortAllRequests = function () { _.each(this.requests(), function (oReq) { if (oReq) { oReq.Xhr.abort(); } }, this); this.requests([]); }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {{Result:boolean}} oData * @param {string} sType * @param {Object} oXhr */ CAjax.prototype.done = function (oParameters, fResponseHandler, oContext, oData, sType, oXhr) { var bAllowedActionWithoutAuth = this.isAllowedActionWithoutAuth(oParameters.Action), bAccountExists = AppData.Accounts.hasAccountWithId(oParameters.AccountID), bDefaultAccount = (oParameters.AccountID === AppData.Accounts.defaultId()) ; Utils.log('Ajax request done', oParameters.Action, sType, Utils.getAjaxDataForLog(oParameters.Action, oData), oParameters); if (bAllowedActionWithoutAuth || bAccountExists) { if (oData && !oData.Result) { switch (oData.ErrorCode) { case Enums.Errors.InvalidToken: if (!bAllowedActionWithoutAuth) { App.tokenProblem(); } break; case Enums.Errors.AuthError: if (bDefaultAccount && !bAllowedActionWithoutAuth) { this.abortAllRequests(); App.authProblem(); } break; } } this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); } }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {{Result:boolean}} oData * @param {string} sType * @param {Object} oXhr */ CAjax.prototype.doneExt = function (oParameters, fResponseHandler, oContext, oData, sType, oXhr) { this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); }; /** * @param {Object} oParameters * @param {Function} fResponseHandler * @param {Object} oContext * @param {Object} oXhr * @param {string} sType * @param {string} sErrorText */ CAjax.prototype.fail = function (oParameters, fResponseHandler, oContext, oXhr, sType, sErrorText) { var oData = {'Result': false, 'ErrorCode': 0}; Utils.log('Ajax request fail', oParameters.Action, sType, oParameters); switch (sType) { case 'abort': oData = {'Result': false, 'ErrorCode': Enums.Errors.NotDisplayedError}; break; default: case 'error': case 'parseerror': if (sErrorText === '') { oData = {'Result': false, 'ErrorCode': Enums.Errors.NotDisplayedError}; } else { oData = {'Result': false, 'ErrorCode': Enums.Errors.DataTransferFailed}; } break; } this.executeResponseHandler(fResponseHandler, oContext, oData, oParameters); }; /** * @param {Function} fResponseHandler * @param {Object} oContext * @param {Object} oData * @param {Object} oParameters */ CAjax.prototype.executeResponseHandler = function (fResponseHandler, oContext, oData, oParameters) { if (!oData) { oData = {'Result': false, 'ErrorCode': 0}; } if (AfterLogicApi.runPluginHook) { AfterLogicApi.runPluginHook('ajax-default-response', [oParameters.Action, oData]); } if (typeof fResponseHandler === 'function') { fResponseHandler.apply(oContext, [oData, oParameters]); } }; /** * @param {Object} oXhr * @param {string} sType * @param {{Action:string}} oParameters */ CAjax.prototype.always = function (oParameters, oXhr, sType) { _.each(this.requests(), function (oReq, iIndex) { if (oReq && _.isEqual(oReq.Parameters, oParameters)) { this.requests()[iIndex] = undefined; } }, this); this.requests(_.compact(this.requests())); Utils.checkConnection(oParameters.Action, sType); if (App.Prefetcher && sType !== 'abort' && !this.hasOpenedRequests()) { App.Prefetcher.start(); } }; /** * @enum {string} */ Enums.Screens = { 'Login': 'login', 'Information': 'information', 'Header': 'header', 'Mailbox': 'mailbox', 'SingleMessageView': 'single-message-view', 'Compose': 'compose', 'SingleCompose': 'single-compose', 'Settings': 'settings', 'Contacts': 'contacts', 'Calendar': 'calendar', 'FileStorage': 'files', 'Helpdesk': 'helpdesk', 'SingleHelpdesk': 'single-helpdesk' }; /** * @enum {number} */ Enums.CalendarDefaultTab = { 'Day': 1, 'Week': 2, 'Month': 3 }; /** * @enum {number} */ Enums.TimeFormat = { 'F24': '0', 'F12': '1' }; /** * @enum {number} */ Enums.Errors = { 'InvalidToken': 101, 'AuthError': 102, 'DataBaseError': 104, 'LicenseProblem': 105, 'DemoLimitations': 106, 'Captcha': 107, 'AccessDenied': 108, 'CanNotGetMessage': 202, 'ImapQuota': 205, 'NotSavedInSentItems': 304, 'NoRequestedMailbox': 305, 'CanNotChangePassword': 502, 'AccountOldPasswordNotCorrect': 503, 'FetcherIncServerNotAvailable': 702, 'FetcherLoginNotCorrect': 703, 'HelpdeskThrowInWebmail': 805, 'HelpdeskUserNotExists': 807, 'HelpdeskUserNotActivated': 808, 'MailServerError': 901, 'DataTransferFailed': 1100, 'NotDisplayedError': 1155 }; /** * @enum {number} */ Enums.FolderTypes = { 'Inbox': 1, 'Sent': 2, 'Drafts': 3, 'Spam': 4, 'Trash': 5, 'Virus': 6, 'Starred': 7, 'System': 9, 'User': 10 }; /** * @enum {string} */ Enums.FolderFilter = { 'Flagged': 'flagged', 'Unseen': 'unseen' }; /** * @enum {number} */ Enums.LoginFormType = { 'Email': 0, 'Login': 3, 'Both': 4 }; /** * @enum {number} */ Enums.LoginSignMeType = { 'DefaultOff': 0, 'DefaultOn': 1, 'Unuse': 2 }; /** * @enum {string} */ Enums.ReplyType = { 'Reply': 'reply', 'ReplyAll': 'reply-all', 'Resend': 'resend', 'Forward': 'forward' }; /** * @enum {number} */ Enums.Importance = { 'Low': 5, 'Normal': 3, 'High': 1 }; /** * @enum {number} */ Enums.Sensivity = { 'Nothing': 0, 'Confidential': 1, 'Private': 2, 'Personal': 3 }; /** * @enum {string} */ Enums.ContactEmailType = { 'Personal': 'Personal', 'Business': 'Business', 'Other': 'Other' }; /** * @enum {string} */ Enums.ContactPhoneType = { 'Mobile': 'Mobile', 'Personal': 'Personal', 'Business': 'Business' }; /** * @enum {string} */ Enums.ContactAddressType = { 'Personal': 'Personal', 'Business': 'Business' }; /** * @enum {string} */ Enums.ContactSortType = { 'Email': 'Email', 'Name': 'Name', 'Frequency': 'Frequency' }; /** * @enum {number} */ Enums.SaveMail = { 'Hidden': 0, 'Checked': 1, 'Unchecked': 2 }; /** * @enum {string} */ Enums.SettingsTab = { 'Common': 'common', 'EmailAccounts': 'accounts', 'Calendar': 'calendar', 'MobileSync': 'mobile_sync', 'OutLookSync': 'outlook_sync', 'Helpdesk': 'helpdesk', 'Pgp': 'pgp', 'Services': 'services' }; /** * @enum {string} */ Enums.AccountSettingsTab = { 'Properties': 'properties', 'Signature': 'signature', 'Filters': 'filters', 'Autoresponder': 'autoresponder', 'Forward': 'forward', 'Folders': 'folders', 'FetcherInc': 'fetcher-inc', 'FetcherOut': 'fetcher-out', 'FetcherSig': 'fetcher-sig', 'IdentityProperties': 'identity-properties', 'IdentitySignature': 'identity-signature' }; /** * @enum {number} */ Enums.ContactsGroupListType = { 'Personal': 0, 'SubGroup': 1, 'Global': 2, 'SharedToAll': 3, 'All': 4 }; /** * @enum {string} */ Enums.IcalType = { Request: 'REQUEST', Reply: 'REPLY', Cancel: 'CANCEL', Save: 'SAVE' }; /** * @enum {string} */ Enums.IcalConfig = { Accepted: 'ACCEPTED', Declined: 'DECLINED', Tentative: 'TENTATIVE', NeedsAction: 'NEEDS-ACTION' }; /** * @enum {number} */ Enums.IcalConfigInt = { Accepted: 1, Declined: 2, Tentative: 3, NeedsAction: 0 }; /** * @enum {number} */ Enums.Key = { 'Tab': 9, 'Enter': 13, 'Shift': 16, 'Ctrl': 17, 'Esc': 27, 'Space': 32, 'PageUp': 33, 'PageDown': 34, 'End': 35, 'Home': 36, 'Up': 38, 'Down': 40, 'Left': 37, 'Right': 39, 'Del': 46, 'Six': 54, 'a': 65, 'b': 66, 'c': 67, 'f': 70, 'i': 73, 'k': 75, 'n': 78, 'p': 80, 'q': 81, 'r': 82, 's': 83, 'u': 85, 'v': 86, 'y': 89, 'z': 90, 'F5': 116, 'Comma': 188, 'Dot': 190, 'Dash': 192, 'Apostrophe': 222 }; Enums.MouseKey = { 'Left': 0, 'Middle': 1, 'Right': 2 }; /** * @enum {number} */ Enums.FileStorageType = { 'Personal': 0, 'Corporate': 1, 'Shared': 2, 'GoogleDrive': 3, 'Dropbox': 4 }; /** * @enum {number} */ Enums.FileStorageLinkType = { 'Unknown': 0, 'GoogleDrive': 1, 'Dropbox': 2 }; /** * @enum {number} */ Enums.HelpdeskThreadStates = { 'None': 0, 'Pending': 1, 'Waiting': 2, 'Answered': 3, 'Resolved': 4, 'Deferred': 5 }; /** * @enum {number} */ Enums.HelpdeskPostType = { 'Normal': 0, 'Internal': 1, 'System': 2 }; /** * @enum {number} */ Enums.HelpdeskFilters = { 'All': 0, 'Pending': 1, 'Resolved': 2, 'InWork': 3, 'Open': 4, 'Archived': 9 }; /** * @enum {number} */ Enums.CalendarAccess = { 'Full': 0, 'Write': 1, 'Read': 2 }; /** * @enum {number} */ Enums.CalendarEditRecurrenceEvent = { 'None': 0, 'OnlyThisInstance': 1, 'AllEvents': 2 }; /** * @enum {number} */ Enums.CalendarRepeatPeriod = { 'None': 0, 'Daily': 1, 'Weekly': 2, 'Monthly': 3, 'Yearly': 4 }; Enums.PhoneAction = { 'Offline': 'offline', 'OfflineError': 'offline_error', 'OfflineInit': 'offline_init', 'OfflineActive': 'offline_active', 'Online': 'online', 'OnlineActive': 'online_active', 'Incoming': 'incoming', 'IncomingConnect': 'incoming_connect', 'Outgoing': 'outgoing', 'OutgoingConnect': 'outgoing_connect', 'Settings': 'settings' }; Enums.HtmlEditorImageSizes = { 'Small': 'small', 'Medium': 'medium', 'Large': 'large', 'Original': 'original' }; Enums.MobilePanel = { 'Groups': 1, 'Items': 2, 'View': 3 }; Enums.PgpAction = { 'Import': 'import', 'Generate': 'generate', 'Encrypt': 'encrypt', 'Sign': 'sign', 'EncryptSign': 'encrypt-sign', 'Verify': 'ferify', 'DecryptVerify': 'decrypt-ferify' }; Enums.SocialType = { 'Unknown': 0, 'Google': 1, 'Dropbox': 2, 'Facebook': 3, 'Twitter': 4, 'Vkontakte': 5 }; Enums.notificationPermission = { 'Granted': 'granted', 'Denied': 'denied', 'Default': 'default' }; 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('unavailable', !bResult); } jqElement.toggleClass('command-disabled disable disabled', !bResult); jqElement.toggleClass('command-disabled', !bResult); // if (jqElement.is('input') || jqElement.is('button')) // { // jqElement.prop('disabled', !bResult); // } } }; ko.bindingHandlers.simpleTemplate = { 'init': function (oElement, fValueAccessor) { var sTemplateID = ko.utils.unwrapObservable(fValueAccessor()), oEl = $('#' + sTemplateID) ; if (oEl && oEl[0]) { $(oElement).html(oEl.html().replace(/<script(.*?)>/i, '<script$1>').replace(/<\/script(.*?)>/i, '</script>')); } } }; ko.bindingHandlers.findFocused = { 'init': function (oElement) { var $oEl = $(oElement), $oInp = null ; $oInp = $oEl.find('.catch-focus'); if ($oInp && 1 === $oInp.length && $oInp[0]) { $oInp.on('blur', function () { $oEl.removeClass('focused'); }).on('focus', function () { $oEl.addClass('focused'); }); } } }; ko.bindingHandlers.findFilled = { 'init': function (oElement) { var $oEl = $(oElement), $oInp = null, fFunc = null ; $oInp = $oEl.find('.catch-filled'); if ($oInp && 1 === $oInp.length && $oInp[0]) { fFunc = function () { $oEl.toggleClass('filled', '' !== $oInp.val()); }; fFunc(); _.delay(fFunc, 200); $oInp.on('change', fFunc); } } }; ko.bindingHandlers.alert = { 'init': function (oElement, fValueAccessor) { window.alert(ko.utils.unwrapObservable(fValueAccessor())); }, 'update': function (oElement, fValueAccessor) { window.alert(ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.onEnter = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onCtrlEnter = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10) && oEvent.ctrlKey) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); return false; } return true; } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onEsc = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); fValueAccessor().call(this, oData); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onFocusSelect = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'focus': function () { oElement.select(); } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.onEnterChange = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { ko.bindingHandlers.event.init(oElement, function () { return { 'keyup': function (oData, oEvent) { if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10)) { $(oElement).trigger('change'); } } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.fadeIn = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { $(oElement).hide().fadeIn('fast'); } } }; ko.bindingHandlers.fadeOut = { 'update': function (oElement, fValueAccessor) { if (ko.utils.unwrapObservable(fValueAccessor())) { $(oElement).fadeOut(); } } }; 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.i18n = { 'init': function (oElement, fValueAccessor) { var sKey = $(oElement).data('i18n'), sValue = sKey ? Utils.i18n(sKey) : sKey ; if ('' !== sValue) { switch (fValueAccessor()) { case 'value': $(oElement).val(sValue); break; case 'text': $(oElement).text(sValue); break; case 'html': $(oElement).html(sValue); break; case 'title': $(oElement).attr('title', sValue); break; case 'placeholder': $(oElement).attr({'placeholder': sValue}); break; } } } }; ko.bindingHandlers.link = { 'init': function (oElement, fValueAccessor) { $(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.title = { 'init': function (oElement, fValueAccessor) { $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); }, 'update': function (oElement, fValueAccessor) { $(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.initDom = { 'init': function (oElement, fValueAccessor) { if (fValueAccessor()) { if (_.isArray(fValueAccessor())) { var aList = fValueAccessor(), iIndex = aList.length - 1 ; for (; 0 <= iIndex; iIndex--) { aList[iIndex]($(oElement)); } } else { fValueAccessor()($(oElement)); } } } }; ko.bindingHandlers.customScrollbar = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { if (bMobileDevice) { return; } var jqElement = $(oElement), oCommand = fValueAccessor() ; /*_.delay(_.bind(function () { var jqCustomScrollbar = jqElement.find('.customscroll-scrollbar-vertical'); jqCustomScrollbar.on('click', function (oEv) { oEv.stopPropagation(); }); }, this), 1000);*/ oCommand = /** @type {{scrollToTopTrigger:{subscribe:Function},scrollToBottomTrigger:{subscribe:Function},scrollTo:{subscribe:Function},reset:Function}}*/ oCommand; jqElement.addClass('scroll-wrap').customscroll(oCommand); if (!Utils.isUnd(oCommand.reset)) { oElement._customscroll_reset = _.throttle(function () { jqElement.data('customscroll').reset(); }, 100); } if (!Utils.isUnd(oCommand.scrollToTopTrigger) && Utils.isFunc(oCommand.scrollToTopTrigger.subscribe)) { oCommand.scrollToTopTrigger.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollToTop'](); } }); } if (!Utils.isUnd(oCommand.scrollToBottomTrigger) && Utils.isFunc(oCommand.scrollToBottomTrigger.subscribe)) { oCommand.scrollToBottomTrigger.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollToBottom'](); } }); } if (!Utils.isUnd(oCommand.scrollTo) && Utils.isFunc(oCommand.scrollTo.subscribe)) { oCommand.scrollTo.subscribe(function () { if (jqElement.data('customscroll')) { jqElement.data('customscroll')['scrollTo'](oCommand.scrollTo()); } }); } }, 'update': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { if (bMobileDevice) { return; } if (oElement._customscroll_reset) { oElement._customscroll_reset(); } if (!Utils.isUnd(fValueAccessor().top)) { $(oElement).data('customscroll')['vertical'].set(fValueAccessor().top); } } }; /*jslint vars: true*/ ko.bindingHandlers.customOptions = { 'init': function () { return { 'controlsDescendantBindings': true }; }, 'update': function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { var i = 0, j = 0; var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) { return node.tagName && node.tagName === 'OPTION' && node.selected; }), function (node) { return ko.selectExtensions.readValue(node) || node.innerText || node.textContent; }); var previousScrollTop = element.scrollTop; var value = ko.utils.unwrapObservable(valueAccessor()); // Remove all existing <option>s. while (element.length > 0) { ko.cleanNode(element.options[0]); element.remove(0); } if (value) { if (typeof value.length !== 'number') { value = [value]; } var optionsBind = allBindingsAccessor()['optionsBind']; for (i = 0, j = value.length; i < j; i++) { var option = document.createElement('OPTION'); var optionValue = ko.utils.unwrapObservable(value[i]); ko.selectExtensions.writeValue(option, optionValue); option.appendChild(document.createTextNode(optionValue)); element.appendChild(option); if (optionsBind) { option.setAttribute('data-bind', optionsBind); ko.applyBindings(bindingContext['createChildContext'](optionValue), option); } } var newOptions = element.getElementsByTagName('OPTION'); var countSelectionsRetained = 0; var isIe = navigator.userAgent.indexOf("MSIE 6") >= 0; for (i = 0, j = newOptions.length; i < j; i++) { if (ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[i])) >= 0) { if (isIe) { newOptions[i].setAttribute("selected", true); } else { newOptions[i].selected = true; } countSelectionsRetained++; } } element.scrollTop = previousScrollTop; if (countSelectionsRetained < previousSelectedValues.length) { ko.utils.triggerEvent(element, 'change'); } } } }; /*jslint vars: false*/ ko.bindingHandlers.splitter = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { var jqElement = $(oElement), oCommand = fValueAccessor() //fResizeTo = oCommand.resizeTo ; setTimeout(function(){ jqElement.splitter(_.defaults( oCommand, { //'name': '' //'sizeLeft': 200, //'minLeft': 20, //'minRight': 40 } )); /*if (fResizeTo) { fResizeTo.subscribe(function (nSize) { if (nSize) { jqElement.trigger('resize', [nSize]); } }, this); }*/ }, 1); } }; ko.bindingHandlers.dropdown = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'expand': 'expand', 'control': true, 'container': '.dropdown_content', 'scrollToTopContainer': '.scroll-inner', 'passClick': true, 'trueValue': true } ), element = oCommand['control'] ? jqElement.find('.control') : jqElement, jqDropHelper = jqElement.find('.dropdown_helper'), jqDropArrow = jqElement.find('.dropdown_arrow'), oDocument = $(document), bScrollBar = false, oOffset, iLeft, iFitToScreenOffset, fCallback = function () { if (!Utils.isUnd(oCommand['callback'])) { oCommand['callback'].call( oViewModel, jqElement.hasClass(oCommand['expand']) ? oCommand['trueValue'] : false, jqElement ); } }, fStop = function (event) { event.stopPropagation(); }, fScrollToTop = function () { if (oCommand['scrollToTopContainer']) { jqElement.find(oCommand['scrollToTopContainer']).scrollTop(0); } }, fToggleExpand = function (bValue) { if (Utils.isUnd(bValue)) { bValue = !jqElement.hasClass(oCommand['expand']); } if (!bValue && jqElement.hasClass(oCommand['expand'])) { fScrollToTop(); } jqElement.toggleClass(oCommand['expand'], bValue); }, fFitToScreen = function (iOffsetLeft) { oOffset = jqDropHelper.offset(); if (!Utils.isUnd(oOffset)) { iLeft = oOffset.left + 10; iFitToScreenOffset = $(window).width() - (iLeft + jqDropHelper.outerWidth()); if (iFitToScreenOffset > 0) { iFitToScreenOffset = 0; } jqDropHelper.css('left', iOffsetLeft || iFitToScreenOffset + 'px'); jqDropArrow.css('left', iOffsetLeft || Math.abs(iFitToScreenOffset ? iFitToScreenOffset + parseInt(jqDropArrow.css('margin-left')) : 0) + 'px'); } } ; if (!oCommand['passClick']) { jqElement.find(oCommand['container']).click(fStop); element.click(fStop); } fToggleExpand(false); if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'].subscribe(function (bValue) { if (!bValue) { oDocument.unbind('click.dropdown'); fToggleExpand(false); } fCallback(); }); } jqElement.on('mousedown', function(oEv, oEl) { bScrollBar = ($(oEv.target).hasClass('customscroll-scrollbar') || $(oEv.target.parentElement).hasClass('customscroll-scrollbar')); }); //TODO fix data-bind click element.click(function(oEv){ if (!jqElement.hasClass(oCommand['disabled']) && !bScrollBar) { fToggleExpand(); _.defer(function(){ fCallback(); }); if (jqElement.hasClass(oCommand['expand'])) { if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'](true); } _.defer(function(){ oDocument.on('click.dropdown', function (ev) { if((oCommand['passClick'] || ev.button !== Enums.MouseKey.Right) && !bScrollBar) { oDocument.unbind('click.dropdown'); if (oCommand['close'] && oCommand['close']['subscribe']) { oCommand['close'](false); } fToggleExpand(false); fCallback(); fFitToScreen(0); } bScrollBar = false; }); }); fFitToScreen(); } } }); } }; ko.bindingHandlers.customSelect = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'selected': 'selected', 'expand': 'expand', 'control': true, 'input': false, 'expandState': function () {} } ), aOptions = [], oControl = oCommand['control'] ? jqElement.find('.control') : jqElement, oContainer = jqElement.find('.dropdown_content'), oText = jqElement.find('.link'), updateField = function (value) { _.each(aOptions, function (item) { item.removeClass(oCommand['selected']); }); var item = _.find(oCommand['options'], function (item) { return item[oCommand['optionsValue']] === value; }); if (Utils.isUnd(item)) { item = oCommand['options'][0]; } else { aOptions[_.indexOf(oCommand['options'], item)].addClass(oCommand['selected']); oText.text($.trim(item[oCommand['optionsText']])); } // aOptions[_.indexOf(oCommand['options'], item)].addClass(oCommand['selected']); // oText.text($.trim(item[oCommand['optionsText']])); return item[oCommand['optionsValue']]; }, updateList = function (aList) { oContainer.empty(); aOptions = []; _.each(aList ? aList : oCommand['options'], function (item) { var oOption = $('<span class="item"></span>') .text(item[oCommand['optionsText']]) .data('value', item[oCommand['optionsValue']]), isDisabled = item['isDisabled'] ; if (isDisabled) { oOption.data('isDisabled', isDisabled).addClass('disabled'); } else { oOption.data('isDisabled', isDisabled).removeClass('disabled'); } aOptions.push(oOption); oContainer.append(oOption); }, this); } ; updateList(); oContainer.on('click', '.item', function () { var jqItem = $(this); if(!jqItem.data('isDisabled')) { oCommand.value(jqItem.data('value')); } }); if (!oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { var mValue = updateField(oCommand['value']()); if (oCommand['value']() !== mValue) { oCommand['value'](mValue); } }, oViewModel); oCommand['value'].valueHasMutated(); } if (oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { updateField(oCommand['value']()); }, oViewModel); oCommand['value'].valueHasMutated(); } if (oCommand.input && oCommand['value'] && oCommand['value'].subscribe) { oCommand['value'].subscribe(function () { updateField(oCommand['value']()); }, oViewModel); oCommand['value'].valueHasMutated(); } if(oCommand.alarmOptions) { oCommand.alarmOptions.subscribe(function () { updateList(); }, oViewModel); } if(oCommand.timeOptions) { oCommand.timeOptions.subscribe(function (aList) { updateList(aList); }, oViewModel); } //TODO fix data-bind click jqElement.removeClass(oCommand['expand']); oControl.click(function(ev){ if (!jqElement.hasClass(oCommand['disabled'])) { jqElement.toggleClass(oCommand['expand']); oCommand['expandState'](jqElement.hasClass(oCommand['expand'])); if (jqElement.hasClass(oCommand['expand'])) { var jqContent = jqElement.find('.dropdown_content'), jqSelected = jqContent.find('.selected'); if (jqSelected.position()) { jqContent.scrollTop(0);// need for proper calculation position().top jqContent.scrollTop(jqSelected.position().top - 100);// 100 - hardcoded indent to the element in pixels } _.defer(function(){ $(document).one('click', function () { jqElement.removeClass(oCommand['expand']); oCommand['expandState'](false); }); }); } // else // { // jqElement.addClass(oCommand['expand']); // } } }); } }; ko.bindingHandlers.moveToFolderFilter = { 'init': function (oElement, fValueAccessor, allBindingsAccessor, viewModel, bindingContext) { var jqElement = $(oElement), oCommand = fValueAccessor(), jqContainer = $(oElement).find(oCommand['container']), aOptions = _.isArray(oCommand['options']) ? oCommand['options'] : oCommand['options'](), sFolderName = oCommand['value'] ? oCommand['value']() : '', oFolderOption = _.find(aOptions, function (oOption) { return oOption[oCommand['optionsValue']] === sFolderName; }) ; if (!oFolderOption) { sFolderName = ''; oCommand['value'](''); } jqElement.removeClass('expand'); jqContainer.empty(); _.each(aOptions, function (oOption) { var jqOption = $('<span class="item"></span>') .text(oOption[oCommand['optionsText']]) .data('value', oOption[oCommand['optionsValue']]); if (sFolderName === oOption[oCommand['optionsValue']]) { jqOption.addClass('selected'); } oOption['jq'] = jqOption; jqContainer.append(jqOption); }); jqContainer.on('click', '.item', function () { var sFolderName = $(this).data('value'); oCommand['value'](sFolderName); }); jqElement.click(function () { jqElement.toggleClass('expand'); if (jqElement.hasClass('expand')) { _.defer(function () { $(document).one('click', function () { jqElement.removeClass('expand'); }); }); } }); }, 'update': function (oElement, fValueAccessor) { var jqElement = $(oElement), oCommand = fValueAccessor(), aOptions = _.isArray(oCommand['options']) ? oCommand['options'] : oCommand['options'](), sFolderName = oCommand['value'] ? oCommand['value']() : '', oFolderOption = _.find(aOptions, function (oOption) { return oOption[oCommand['optionsValue']] === sFolderName; }), jqText = jqElement.find('.link') ; _.each(aOptions, function (oOption) { if (oOption['jq']) { oOption['jq'].toggleClass('selected', sFolderName === oOption[oCommand['optionsValue']]); } }); if (oFolderOption) { jqText.text($.trim(oFolderOption[oCommand['optionsText']])); } } }; ko.bindingHandlers.contactcard = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) { var jqElement = $(oElement), bShown = false, oCommand = _.defaults( fValueAccessor(), { 'disabled': 'disabled', 'expand': 'expand', 'control': true } ), element = oCommand['control'] ? jqElement.find('.control') : jqElement ; if (oCommand['trigger'] !== undefined && oCommand['trigger'].subscribe !== undefined) { jqElement.removeClass(oCommand['expand']); element.bind({ 'mouseover': function() { if (!jqElement.hasClass(oCommand['disabled']) && oCommand['trigger']()) { bShown = true; _.delay(function () { if (bShown) { if (oCommand['controlWidth'] !== undefined && oCommand['controlWidth'].subscribe !== undefined) { oCommand['controlWidth'](element.width()); } jqElement.addClass(oCommand['expand']); } }, 200); } }, 'mouseout': function() { if (oCommand['trigger']()) { bShown = false; _.delay(function () { if (!bShown) { jqElement.removeClass(oCommand['expand']); } }, 200); } } }); } } }; ko.bindingHandlers.checkmail = { 'update': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var oOptions = oElement.oOptions || null, jqElement = oElement.jqElement || null, oIconIE = oElement.oIconIE || null, values = fValueAccessor(), state = values.state ; if (values.state !== undefined) { if (!jqElement) { oElement.jqElement = jqElement = $(oElement); } if (!oOptions) { oElement.oOptions = oOptions = _.defaults( values, { 'activeClass': 'process', 'duration': 800 } ); } Utils.deferredUpdate(jqElement, state, oOptions['duration'], function(element, state){ if (App.browser.ie9AndBelow) { if (!oIconIE) { oElement.oIconIE = oIconIE = jqElement.find('.icon'); } if (!oIconIE.__intervalIE && !!state) { var i = 0, style = '' ; oIconIE.__intervalIE = setInterval(function() { style = '0px -' + (20 * i) + 'px'; i = i < 7 ? i + 1 : 0; oIconIE.css({'background-position': style}); } , 1000/12); } else { oIconIE.css({'background-position': '0px 0px'}); clearInterval(oIconIE.__intervalIE); oIconIE.__intervalIE = null; } } else { element.toggleClass(oOptions['activeClass'], state); } }); } } }; ko.bindingHandlers.heightAdjust = { 'update': function (oElement, fValueAccessor, fAllBindingsAccessor) { var jqElement = oElement.jqElement || null, height = 0, sLocation = fValueAccessor().location, sDelay = fValueAccessor().delay || 400 ; if (!jqElement) { oElement.jqElement = jqElement = $(oElement); } _.delay(function () { _.each(fValueAccessor().elements, function (mItem) { var element = mItem(); if (element) { height += element.is(':visible') ? element.outerHeight() : 0; } }); if (sLocation === 'top' || sLocation === undefined) { jqElement.css({ 'padding-top': height, 'margin-top': -height }); } else if (sLocation === 'bottom') { jqElement.css({ 'padding-bottom': height, 'margin-bottom': -height }); } }, sDelay); } }; ko.bindingHandlers.triggerInview = { 'update': function (oElement, fValueAccessor) { if (fValueAccessor().trigger().length <= 0 ) { return; } _.defer(function () { var $element = $(oElement), frameHeight = $element.height(), oCommand = fValueAccessor(), elements = null, delayedScroll = null ; oCommand = /** @type {{selector:string}}*/ oCommand; elements = $element.find(oCommand.selector); elements.each(function () { this.$el = $(this); this.inviewHeight = this.$el.height(); this.inview = false; }); delayedScroll = _.debounce(function () { elements.each(function () { var inview = this.inview || false, elOffset = this.$el.position().top + parseInt(this.$el.css('margin-top'), 10) ; if (elOffset > 0 && elOffset < frameHeight) { if (!inview) { this.inview = true; this.$el.trigger('inview'); } } else { this.inview = false; } }); }, 2000); $element.scroll(delayedScroll); delayedScroll(); }); } }; ko.bindingHandlers.watchWidth = { 'init': function (oElement, fValueAccessor) { var isTriggered = false; if (!isTriggered) { fValueAccessor().subscribe(function () { fValueAccessor()($(oElement).outerWidth()); isTriggered = true; }, this); } } }; ko.bindingHandlers.columnCalc = { 'init': function (oElement, fValueAccessor) { var $oElement = $(oElement), oProp = fValueAccessor()['prop'], $oItem = null, iWidth = 0 ; $oItem = $oElement.find(fValueAccessor()['itemSelector']); if ($oItem[0] === undefined) { return; } iWidth = $oItem.outerWidth(true); iWidth = 1 >= iWidth ? 1 : iWidth; if (oProp) { $(window).bind('resize', function () { var iW = $oElement.width(); oProp(0 < iW ? Math.floor(iW / iWidth) : 1); }); } } }; ko.bindingHandlers.quickReplyAnim = { 'update': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqTextarea = oElement.jqTextarea || null, jqStatus = oElement.jqStatus || null, jqButtons = oElement.jqButtons || null, jqElement = oElement.jqElement || null, oPrevActions = oElement.oPrevActions || null, values = fValueAccessor(), oActions = null ; oActions = _.defaults( values, { 'saveAction': false, 'sendAction': false, 'activeAction': false } ); if (!jqElement) { oElement.jqElement = jqElement = $(oElement); oElement.jqTextarea = jqTextarea = jqElement.find('textarea'); oElement.jqStatus = jqStatus = jqElement.find('.status'); oElement.jqButtons = jqButtons = jqElement.find('.buttons'); oElement.oPrevActions = oPrevActions = { 'saveAction': null, 'sendAction': null, 'activeAction': null }; } if (jqElement.is(':visible')) { if (App.browser.ie9AndBelow) { if (jqTextarea && !jqElement.defualtHeight && !jqTextarea.defualtHeight) { jqElement.defualtHeight = jqElement.outerHeight(); jqTextarea.defualtHeight = jqTextarea.outerHeight(); jqStatus.defualtHeight = jqButtons.outerHeight(); jqButtons.defualtHeight = jqButtons.outerHeight(); } _.defer(function () { var activeChanged = oPrevActions.activeAction !== oActions['activeAction'], sendChanged = oPrevActions.sendAction !== oActions['sendAction'], saveChanged = oPrevActions.saveAction !== oActions['saveAction'] ; if (activeChanged) { if (oActions['activeAction']) { jqTextarea.animate({ 'height': jqTextarea.defualtHeight + 50 }, 300); jqElement.animate({ 'max-height': jqElement.defualtHeight + jqButtons.defualtHeight + 50 }, 300); } else { jqTextarea.animate({ 'height': jqTextarea.defualtHeight }, 300); jqElement.animate({ 'max-height': jqElement.defualtHeight }, 300); } } if (sendChanged || saveChanged) { if (oActions['sendAction']) { jqElement.animate({ 'max-height': '30px' }, 300); jqStatus.animate({ 'max-height': '30px', 'opacity': 1 }, 300); } else if (oActions['saveAction']) { jqElement.animate({ 'max-height': 0 }, 300); } else { jqElement.animate({ 'max-height': jqElement.defualtHeight + jqButtons.defualtHeight + 50 }, 300); jqStatus.animate({ 'max-height': 0, 'opacity': 0 }, 300); } } }); } else { jqElement.toggleClass('saving', oActions['saveAction']); jqElement.toggleClass('sending', oActions['sendAction']); jqElement.toggleClass('active', oActions['activeAction']); } } _.defer(function () { oPrevActions = oActions; }); } }; ko.extenders.reversible = function (oTarget) { var mValue = oTarget(); oTarget.commit = function () { mValue = oTarget(); }; oTarget.revert = function () { oTarget(mValue); }; oTarget.commitedValue = function () { return mValue; }; oTarget.changed = function () { return mValue !== oTarget(); }; return oTarget; }; ko.extenders.autoResetToFalse = function (oTarget, iOption) { oTarget.iTimeout = 0; oTarget.subscribe(function (bValue) { if (bValue) { window.clearTimeout(oTarget.iTimeout); oTarget.iTimeout = window.setTimeout(function () { oTarget.iTimeout = 0; oTarget(false); }, Utils.pInt(iOption)); } }); return oTarget; }; /** * @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()) { return 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; }; ko.bindingHandlers.autocomplete = { 'init': function (oElement, fValueAccessor) { function split(val) { return val.split(/,\s*/); } function extractLast(term) { return split(term).pop(); } var fCallback = fValueAccessor(), oJqElement = $(oElement) ; if (fCallback && oJqElement && oJqElement[0]) { oJqElement.autocomplete({ 'minLength': 1, 'autoFocus': true, 'source': function (request, response) { fCallback(extractLast(request['term']), response); }, 'search': function () { var term = extractLast(this.value); if (term.length < 1) { return false; } return true; }, 'focus': function () { return false; }, 'select': function (event, ui) { var terms = split(this.value), moveCursorToEnd = null; terms.pop(); terms.push(ui['item']['value']); terms.push(''); this.value = terms.join(', ').slice(0, -2); oJqElement.trigger('change'); // Move to the end of the input string moveCursorToEnd = function(el) { var endIndex = el.value.length; //Chrome el.blur(); el.focus(); //IE, firefox and Opera if (el.setSelectionRange) { el.setSelectionRange(endIndex, endIndex); } }; moveCursorToEnd(oJqElement[0]); return false; } }); } } }; ko.bindingHandlers.autocompleteSimple = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), fCallback = oOptions['callback'], fDataAccessor = oOptions.dataAccessor // fAutocompleteTrigger = oOptions.autocompleteTrigger ; if (fCallback && jqEl && jqEl[0]) { jqEl.autocomplete({ 'minLength': 1, 'autoFocus': true, 'position': { collision: "flip" }, 'source': function (request, response) { fCallback(request['term'], response); }, 'focus': function () { return false; }, 'select': function (oEvent, oItem) { _.delay(function () { jqEl.trigger('change'); }, 5); if (fDataAccessor) { fDataAccessor(oItem.item); } return true; } }); /*if (fAutocompleteTrigger) { fAutocompleteTrigger.subscribe(function() { jqEl.autocomplete( "option", "minLength", 0 );// dirty hack for trigger search jqEl.autocomplete("search"); jqEl.autocomplete( "option", "minLength", 1 ); }, this); }*/ } } }; ko.bindingHandlers.draggablePlace = { 'init': bMobileApp ? null : function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { if (fValueAccessor() === null) { return null; } var oAllBindingsAccessor = fAllBindingsAccessor ? fAllBindingsAccessor() : null; $(oElement).draggable({ 'distance': 20, 'handle': '.dragHandle', 'cursorAt': {'top': 0, 'left': 0}, 'helper': function (oEvent) { return fValueAccessor().call(oViewModel, oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null); }, 'start': (oAllBindingsAccessor && oAllBindingsAccessor['draggableDragStartCallback']) ? oAllBindingsAccessor['draggableDragStartCallback'] : Utils.emptyFunction, 'stop': (oAllBindingsAccessor && oAllBindingsAccessor['draggableDragStopCallback']) ? oAllBindingsAccessor['draggableDragStopCallback'] : Utils.emptyFunction }).on('mousedown', function () { Utils.removeActiveFocus(); }); } }; ko.bindingHandlers.droppable = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { var oOptions = fValueAccessor(), fValueFunc = oOptions.valueFunc, fSwitchObserv = oOptions.switchObserv ; if (false !== fValueFunc) { $(oElement).droppable({ 'hoverClass': 'droppableHover', 'drop': function (oEvent, oUi) { fValueFunc(oEvent, oUi); } }); } if(fSwitchObserv && fValueFunc !== false) { fSwitchObserv.subscribe(function (bIsSelected) { if($(oElement).data().droppable) { if(bIsSelected) { $(oElement).droppable('disable'); } else { $(oElement).droppable('enable'); } } }, this); fSwitchObserv.valueHasMutated(); } } }; ko.bindingHandlers.draggable = { 'init': bMobileApp ? null : function (oElement, fValueAccessor) { $(oElement).attr('draggable', ko.utils.unwrapObservable(fValueAccessor())); } }; ko.bindingHandlers.autosize = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), iHeight = jqEl.height(), iOuterHeight = jqEl.outerHeight(), iInnerHeight = jqEl.innerHeight(), iBorder = iOuterHeight - iInnerHeight, iPaddingTB = iInnerHeight - iHeight, iMinHeight = oOptions.minHeight ? oOptions.minHeight : 0, iMaxHeight = oOptions.maxHeight ? oOptions.maxHeight : 0, iScrollableHeight = oOptions.scrollableHeight ? oOptions.scrollableHeight : 1000,// max-height of .scrollable_field oAutosizeTrigger = oOptions.autosizeTrigger ? oOptions.autosizeTrigger : null, /** * @param {boolean=} bIgnoreScrollableHeight */ fResize = function (bIgnoreScrollableHeight) { var iPadding = 0; if (App.browser.firefox) { iPadding = parseInt(jqEl.css('padding-top'), 10) * 2; } if (iMaxHeight) { /* 0-timeout to get the already changed text */ setTimeout(function () { if (jqEl.prop('scrollHeight') < iMaxHeight) { jqEl.height(iMinHeight - iPaddingTB - iBorder); jqEl.height(jqEl.prop('scrollHeight') + iPadding - iPaddingTB); } else { jqEl.height(iMaxHeight - iPaddingTB - iBorder); } }, 100); } else if (bIgnoreScrollableHeight || jqEl.prop('scrollHeight') < iScrollableHeight) { setTimeout(function () { jqEl.height(iMinHeight - iPaddingTB - iBorder); jqEl.height(jqEl.prop('scrollHeight') + iPadding - iPaddingTB); //$('.calendar_event .scrollable_field').scrollTop(jqEl.height('scrollHeight')) }, 100); } } ; jqEl.on('keydown', function(oEvent, oData) { fResize(); }); jqEl.on('paste', function(oEvent, oData) { fResize(); }); /*jqEl.on('input', function(oEvent, oData) { fResize(); }); ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { fResize(); return true; } }; }, fAllBindingsAccessor, oViewModel);*/ if (oAutosizeTrigger) { oAutosizeTrigger.subscribe(function (arg) { fResize(arg); }, this); } fResize(); } }; ko.bindingHandlers.customBind = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var oOptions = fValueAccessor(), oKeydown = oOptions.onKeydown ? oOptions.onKeydown : null, oKeyup = oOptions.onKeyup ? oOptions.onKeyup : null, oPaste = oOptions.onPaste ? oOptions.onPaste : null, oInput = oOptions.onInput ? oOptions.onInput : null, oValueObserver = oOptions.valueObserver ? oOptions.valueObserver : null ; ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { if(oKeydown) { oKeydown.call(this, oElement, oEvent, oValueObserver); } return true; }, 'keyup': function (oData, oEvent) { if(oKeyup) { oKeyup.call(this, oElement, oEvent, oValueObserver); } return true; }, 'paste': function (oData, oEvent) { if(oPaste) { oPaste.call(this, oElement, oEvent, oValueObserver); } return true; }, 'input': function (oData, oEvent) { if(oInput) { oInput.call(this, oElement, oEvent, oValueObserver); } return true; } }; }, fAllBindingsAccessor, oViewModel); } }; ko.bindingHandlers.fade = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqElFaded = $('<span class="faded"></span>'), oOptions = _.defaults( fValueAccessor(), { 'color': null, 'css': 'fadeout' } ), oColor = oOptions.color, sCss = oOptions.css, updateColor = function (sColor) { if (sColor === '') { return; } var oHex2Rgb = hex2Rgb(sColor), sRGBColor = "rgba("+oHex2Rgb.r+","+oHex2Rgb.g+","+oHex2Rgb.b ; colorIt(sColor, sRGBColor); }, hex2Rgb = function (sHex) { // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF") var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i, result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(sHex) ; sHex = sHex.replace(shorthandRegex, function(m, r, g, b) { return r + r + g + g + b + b; }); return result ? { r: parseInt(result[1], 16), g: parseInt(result[2], 16), b: parseInt(result[3], 16) } : null; }, colorIt = function (hex, rgb) { if (Utils.isRTL()) { jqElFaded .css("filter", "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + hex + "', endColorstr='" + hex + "',GradientType=1 )") .css("background-image", "-webkit-gradient(linear, left top, right top, color-stop(0%," + rgb + ",1)" + "), color-stop(100%," + rgb + ",0)" + "))") .css("background-image", "-moz-linear-gradient(left, " + rgb + ",1)" + "0%, " + rgb + ",0)" + "100%)") .css("background-image", "-webkit-linear-gradient(left, " + rgb + "1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "-o-linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "-ms-linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)") .css("background-image", "linear-gradient(left, " + rgb + ",1)" + "0%," + rgb + ",0)" + "100%)"); } else { jqElFaded .css("filter", "progid:DXImageTransform.Microsoft.gradient(startColorstr='" + hex + "', endColorstr='" + hex + "',GradientType=1 )") .css("background-image", "-webkit-gradient(linear, left top, right top, color-stop(0%," + rgb + ",0)" + "), color-stop(100%," + rgb + ",1)" + "))") .css("background-image", "-moz-linear-gradient(left, " + rgb + ",0)" + "0%, " + rgb + ",1)" + "100%)") .css("background-image", "-webkit-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "-o-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "-ms-linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)") .css("background-image", "linear-gradient(left, " + rgb + ",0)" + "0%," + rgb + ",1)" + "100%)"); } } ; jqEl.parent().addClass(sCss); jqEl.after(jqElFaded); if (oOptions.color.subscribe !== undefined) { updateColor(oColor()); oColor.subscribe(function (sColor) { updateColor(sColor); }, this); } } }; ko.bindingHandlers.highlighter = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), oOptions = fValueAccessor(), oValueObserver = oOptions.valueObserver ? oOptions.valueObserver : null, oHighlighterValueObserver = oOptions.highlighterValueObserver ? oOptions.highlighterValueObserver : null, oHighlightTrigger = oOptions.highlightTrigger ? oOptions.highlightTrigger : null, aHighlightWords = ['from:', 'to:', 'subject:', 'text:', 'email:', 'has:', 'date:', 'text:', 'body:'], rPattern = (function () { var sPatt = ''; $.each(aHighlightWords, function(i, oEl) { sPatt = (!i) ? (sPatt + '\\b' + oEl) : (sPatt + '|\\b' + oEl); }); return new RegExp('(' + sPatt + ')', 'g'); }()), fClear = function (sStr) { return sStr.replace(/\xC2\xA0/g, ' ').replace(/\xA0/g, ' ').replace(/[\s]+/g, ' '); }, iPrevKeyCode = -1, sUserLanguage = window.navigator.language || window.navigator.userLanguage, aTabooLang = ['zh', 'zh-TW', 'zh-CN', 'zh-HK', 'zh-SG', 'zh-MO', 'ja', 'ja-JP', 'ko', 'ko-KR', 'vi', 'vi-VN', 'th', 'th-TH'],// , 'ru', 'ru-RU' bHighlight = !_.include(aTabooLang, sUserLanguage) ; ko.bindingHandlers.event.init(oElement, function () { return { 'keydown': function (oData, oEvent) { return oEvent.keyCode !== Enums.Key.Enter; }, 'keyup': function (oData, oEvent) { var aMoveKeys = [Enums.Key.Left, Enums.Key.Right, Enums.Key.Home, Enums.Key.End], bMoveKeys = -1 !== Utils.inArray(oEvent.keyCode, aMoveKeys) ; if (!( // oEvent.keyCode === Enums.Key.Enter || oEvent.keyCode === Enums.Key.Shift || oEvent.keyCode === Enums.Key.Ctrl || // for international english ------------------------- oEvent.keyCode === Enums.Key.Dash || oEvent.keyCode === Enums.Key.Apostrophe || oEvent.keyCode === Enums.Key.Six && oEvent.shiftKey || // --------------------------------------------------- bMoveKeys || // ((oEvent.shiftKey || iPrevKeyCode === Enums.Key.Shift) && bMoveKeys) || ((oEvent.ctrlKey || iPrevKeyCode === Enums.Key.Ctrl) && oEvent.keyCode === Enums.Key.a) )) { oValueObserver(fClear(jqEl.text())); highlight(false); } iPrevKeyCode = oEvent.keyCode; return true; }, // firefox fix for html paste 'paste': function (oData, oEvent) { setTimeout(function () { oValueObserver(fClear(jqEl.text())); highlight(false); }, 0); return true; } }; }, fAllBindingsAccessor, oViewModel); // highlight on init setTimeout(function () { highlight(true); }, 0); function highlight(bNotRestoreSel) { if(bHighlight) { var iCaretPos = 0, sContent = jqEl.text(), aContent = sContent.split(rPattern), aDividedContent = [], sReplaceWith = '<span class="search_highlight"' + '>$&</span>' ; $.each(aContent, function (i, sEl) { if (_.any(aHighlightWords, function (oAnyEl) {return oAnyEl === sEl;})) { $.each(sEl, function (i, sElem) { aDividedContent.push($(sElem.replace(/(.)/, sReplaceWith))); }); } else { $.each(sEl, function(i, sElem) { if(sElem === ' ') { // space fix for firefox aDividedContent.push(document.createTextNode('\u00A0')); } else { aDividedContent.push(document.createTextNode(sElem)); } }); } }); if (bNotRestoreSel) { jqEl.empty().append(aDividedContent); } else { iCaretPos = getCaretOffset(); jqEl.empty().append(aDividedContent); setCursor(iCaretPos); } } } function getCaretOffset() { var caretOffset = 0, range, preCaretRange, textRange, preCaretTextRange ; if (typeof window.getSelection !== "undefined") { range = window.getSelection().getRangeAt(0); preCaretRange = range.cloneRange(); preCaretRange.selectNodeContents(oElement); preCaretRange.setEnd(range.endContainer, range.endOffset); caretOffset = preCaretRange.toString().length; } else if (typeof document.selection !== "undefined" && document.selection.type !== "Control") { textRange = document.selection.createRange(); preCaretTextRange = document.body.createTextRange(); preCaretTextRange.moveToElementText(oElement); preCaretTextRange.setEndPoint("EndToEnd", textRange); caretOffset = preCaretTextRange.text.length; } return caretOffset; } function setCursor(iCaretPos) { var range, selection, textRange ; if (!oElement) { return false; } else if(document.createRange) { range = document.createRange(); range.selectNodeContents(oElement); range.setStart(oElement, iCaretPos); range.setEnd(oElement, iCaretPos); selection = window.getSelection(); selection.removeAllRanges(); selection.addRange(range); } else if(oElement.createTextRange) { textRange = oElement.createTextRange(); textRange.collapse(true); textRange.moveEnd(iCaretPos); textRange.moveStart(iCaretPos); textRange.select(); return true; } else if(oElement.setSelectionRange) { oElement.setSelectionRange(iCaretPos, iCaretPos); return true; } return false; } oHighlightTrigger.notifySubscribers(); oHighlightTrigger.subscribe(function (bNotRestoreSel) { setTimeout(function () { highlight(!!bNotRestoreSel); }, 0); }, this); oHighlighterValueObserver.subscribe(function () { jqEl.text(oValueObserver()); }, this); } }; ko.bindingHandlers.quoteText = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqButton = $('<span class="button_quote">' + Utils.i18n('HELPDESK/BUTTON_QUOTE') + '</span>'), oOptions = fValueAccessor(), fActionHandler = oOptions.actionHandler, bIsQuoteArea = false, oSelection = null, sText = '' ; $('#pSevenContent').append(jqButton); $(document.body).on('click', function(oEvent) { bIsQuoteArea = !!(($(oEvent.target)).parents('.posts')[0]); if (document.getSelection) { oSelection = document.getSelection(); if (oSelection) { sText = oSelection.toString(); } } else { sText = document.selection.createRange().text; } if(bIsQuoteArea) { if(sText.replace(/[\n\r\s]/, '') !== '') //replace - for dbl click on empty area { jqButton.css({ 'top': oEvent.clientY + 20, //20 - custom indent 'left': oEvent.clientX + 20 }).show(); } else { jqButton.hide(); } } else { jqButton.hide(); } }); jqButton.on('click', function(oEvent) { fActionHandler.call(oViewModel, sText); }); } }; ko.bindingHandlers.adjustHeightToContent = { 'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel, bindingContext) { var jqEl = $(oElement), jqTargetEl = null, jqParentEl = null, jqNearEl = null ; _.delay(_.bind(function(){ jqTargetEl = $(_.max(jqEl.find('.title .text'), function(domEl){ return domEl.offsetWidth; })); jqParentEl = jqTargetEl.parent(); jqNearEl = jqParentEl.find('.icon'); jqEl.css('min-width', parseInt(jqParentEl.css("margin-left")) + parseInt(jqParentEl.css("padding-left")) + parseInt(jqNearEl.width()) + parseInt(jqNearEl.css("margin-left")) + parseInt(jqNearEl.css("margin-right")) + parseInt(jqNearEl.css("padding-left")) + parseInt(jqNearEl.css("padding-right")) + parseInt(jqTargetEl.width()) + parseInt(jqTargetEl.css("margin-left")) + parseInt(jqTargetEl.css("padding-left")) + 10 ); },this), 1); } }; ko.bindingHandlers.customTooltip = { 'update': bMobileApp ? null : function (oElement, fValueAccessor) { var sTooltipText = Utils.i18n(fValueAccessor()); $(oElement).attr('title', sTooltipText); // var // sTooltipText = Utils.i18n(fValueAccessor()), // oDropdown = $(oElement).find('span.dropdown'), // bShown = false // ; // // if (sTooltipText === '') // { // $(oElement).hover(function () { // }, function () { // }); // } // else // { // $(oElement).hover(function () { // var $ItemToAlign = $(this); // bShown = true; // _.delay(function () { // if (bShown) // { // Utils.CustomTooltip.show(sTooltipText, $ItemToAlign); // } // }, 200); // }, function () { // bShown = false; // Utils.CustomTooltip.hide(); // }); // // if (oDropdown.length > 0) // { // oDropdown.hover(function () { // bShown = false; // Utils.CustomTooltip.hide(); // }, function () {}); // } // } } }; /** * @type {Function} */ Utils.inArray = $.inArray; /** * @type {Function} */ Utils.isFunc = $.isFunction; /** * @type {Function} */ Utils.trim = $.trim; /** * @type {Function} */ Utils.emptyFunction = function () {}; /** * @param {*} mValue * * @return {boolean} */ Utils.isUnd = function (mValue) { return undefined === mValue; }; /** * @param {*} oValue * * @return {boolean} */ Utils.isNull = function (oValue) { return null === oValue; }; /** * @param {*} oValue * * @return {boolean} */ Utils.isNormal = function (oValue) { return !Utils.isUnd(oValue) && !Utils.isNull(oValue); }; /** * @param {(string|number)} mValue * * @return {boolean} */ Utils.isNumeric = function (mValue) { return Utils.isNormal(mValue) ? (/^[1-9]+[0-9]*$/).test(mValue.toString()) : false; }; /** * @param {*} mValue * * @return {number} */ Utils.pInt = function (mValue) { var iValue = window.parseInt(mValue, 10); if (isNaN(iValue)) { iValue = 0; } return iValue; }; /** * @param {*} mValue * * @return {string} */ Utils.pString = function (mValue) { return Utils.isNormal(mValue) ? mValue.toString() : ''; }; /** * @param {*} aValue * @param {number=} iArrayLen * * @return {boolean} */ Utils.isNonEmptyArray = function (aValue, iArrayLen) { iArrayLen = iArrayLen || 1; return _.isArray(aValue) && iArrayLen <= aValue.length; }; /** * @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 (sText) ? sText.toString() .replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>') .replace(/"/g, '"').replace(/'/g, ''') : ''; }; /** * @param {string} sKey * @param {?Object=} oValueList * @param {?string=} sDefaultValue * @param {number=} nPluralCount * * @return {string} */ Utils.i18n = function (sKey, oValueList, sDefaultValue, nPluralCount) { var sValueName = '', sResult = Utils.isUnd(I18n[sKey]) ? (Utils.isNormal(sDefaultValue) ? sDefaultValue : sKey) : I18n[sKey] ; if (!Utils.isUnd(nPluralCount)) { sResult = (function (nPluralCount, sResult) { var nPlural = Utils.getPlural(AppData.User.DefaultLanguage, nPluralCount), aPluralParts = sResult.split('|') ; return (aPluralParts && aPluralParts[nPlural]) ? aPluralParts[nPlural] : ( aPluralParts && aPluralParts[0] ? aPluralParts[0] : sResult); }(nPluralCount, sResult)); } if (Utils.isNormal(oValueList)) { for (sValueName in oValueList) { if (oValueList.hasOwnProperty(sValueName)) { sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]); } } } return sResult; }; /** * @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) { var iBytesInKb = 1024, iBytesInMb = iBytesInKb * iBytesInKb, iBytesInGb = iBytesInKb * iBytesInKb * iBytesInKb ; iSizeInBytes = Utils.pInt(iSizeInBytes); if (iSizeInBytes >= iBytesInGb) { return Utils.roundNumber(iSizeInBytes / iBytesInGb, 1) + Utils.i18n('MAIN/GIGABYTES'); } else if (iSizeInBytes >= iBytesInMb) { return Utils.roundNumber(iSizeInBytes / iBytesInMb, 1) + Utils.i18n('MAIN/MEGABYTES'); } else if (iSizeInBytes >= iBytesInKb) { return Utils.roundNumber(iSizeInBytes / iBytesInKb, 0) + Utils.i18n('MAIN/KILOBYTES'); } return iSizeInBytes + Utils.i18n('MAIN/BYTES'); }; 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.$log = null; Utils.aLog = []; Utils.log = function () { if (!AppData || !AppData.ClientDebug || !App.browser || App.browser.ie9AndBelow) { return; } function fCensor(mKey, mValue) { if (typeof(mValue) === 'string' && mValue.length > 50) { return mValue.substring(0, 50); } return mValue; } var $log = Utils.$log || $('<div style="display: none;"></div>').appendTo('body'), aNewRow = [] ; _.each(arguments, function (mArg) { var sRowPart = typeof(mArg) === 'string' ? mArg : JSON.stringify(mArg, fCensor); if (aNewRow.length === 0) { sRowPart = ' *** ' + sRowPart + ' *** '; } aNewRow.push(sRowPart); }); aNewRow.push(moment().format(' *** D MMMM, YYYY, HH:mm:ss *** ')); Utils.$log = $log; if (Utils.aLog.length > 200) { Utils.aLog.shift(); } Utils.aLog.push(Utils.encodeHtml(aNewRow.join(', '))); $log.html(Utils.aLog.join('<br /><br />')); }; /** * @param {string} sAction * @param {Object} oData * * @returns {Object} */ Utils.getAjaxDataForLog = function (sAction, oData) { var oDataForLog = oData; if (oData && oData.Result) { switch (sAction) { case 'MessageList': case 'MessageListByUids': oDataForLog = { 'Result': { 'Uids': oData.Result.Uids, 'UidNext': oData.Result.UidNext, 'FolderHash': oData.Result.FolderHash, 'MessageCount': oData.Result.MessageCount, 'MessageUnseenCount': oData.Result.MessageUnseenCount, 'MessageResultCount': oData.Result.MessageResultCount } }; break; case 'Message': oDataForLog = { 'Result': { 'Folder': oData.Result.Folder, 'Uid': oData.Result.Uid, 'Subject': oData.Result.Subject, 'Size': oData.Result.Size, 'TextSize': oData.Result.TextSize, 'From': oData.Result.From, 'To': oData.Result.To } }; break; case 'Messages': oDataForLog = { 'Result': _.map(oData.Result, function (oMessage) { return { 'Uid': oMessage.Uid, 'Subject': oMessage.Subject }; }) }; break; } } else if (oData) { oDataForLog = { 'Result': oData.Result, 'ErrorCode': oData.ErrorCode }; } return oDataForLog; }; /** * @param {string} sFullEmail * * @return {Object} */ Utils.getEmailParts = function (sFullEmail) { var iQuote1Pos = sFullEmail.indexOf('"'), iQuote2Pos = sFullEmail.indexOf('"', iQuote1Pos + 1), iLeftBrocketPos = sFullEmail.indexOf('<', iQuote2Pos), iPrevLeftBroketPos = -1, iRightBrocketPos = -1, sName = '', sEmail = '' ; while (iLeftBrocketPos !== -1) { iPrevLeftBroketPos = iLeftBrocketPos; iLeftBrocketPos = sFullEmail.indexOf('<', iLeftBrocketPos + 1); } iLeftBrocketPos = iPrevLeftBroketPos; iRightBrocketPos = sFullEmail.indexOf('>', iLeftBrocketPos + 1); if (iLeftBrocketPos === -1) { sEmail = Utils.trim(sFullEmail); } else { sName = (iQuote1Pos === -1) ? Utils.trim(sFullEmail.substring(0, iLeftBrocketPos)) : Utils.trim(sFullEmail.substring(iQuote1Pos + 1, iQuote2Pos)); sEmail = Utils.trim(sFullEmail.substring(iLeftBrocketPos + 1, iRightBrocketPos)); } return { 'name': sName, 'email': sEmail, 'FullEmail': sFullEmail }; }; /** * @param {string} sValue * * @return {boolean} */ Utils.isCorrectEmail = function (sValue) { return !!(sValue.match(/^[A-Z0-9\"!#\$%\^\{\}`~&'\+\-=_\.]+@[A-Z0-9\.\-]+$/i)); }; /** * @param {string} sAddresses * * @return {Array} */ Utils.getIncorrectEmailsFromAddressString = function (sAddresses) { var aEmails = sAddresses.replace(/"[^"]*"/g, '').replace(/;/g, ',').split(','), aIncorrectEmails = [], iIndex = 0, iLen = aEmails.length, sFullEmail = '', oEmailParts = null ; for (; iIndex < iLen; iIndex++) { sFullEmail = Utils.trim(aEmails[iIndex]); if (sFullEmail.length > 0) { oEmailParts = Utils.getEmailParts(Utils.trim(aEmails[iIndex])); if (!Utils.isCorrectEmail(oEmailParts.email)) { aIncorrectEmails.push(oEmailParts.email); } } } return aIncorrectEmails; }; /** * @param {string} sRecipients * * return {Array} */ Utils.getArrayRecipients = function (sRecipients) { if (!sRecipients) { return []; } var aRecipients = [], sWorkingRecipients = Utils.trim(sRecipients) + ' ', emailStartPos = 0, emailEndPos = 0, isInQuotes = false, chQuote = '"', isInAngleBrackets = false, isInBrackets = false, currentPos = 0, sWorkingRecipientsLen = sWorkingRecipients.length, currentChar = '', str = '', oRecipient = null, inList = false, jCount = 0, j = 0 ; while (currentPos < sWorkingRecipientsLen) { currentChar = sWorkingRecipients.substring(currentPos, currentPos+1); switch (currentChar) { case '\'': case '"': if (isInQuotes) { if (chQuote === currentChar) { isInQuotes = false; } } else { if (!isInAngleBrackets && !isInBrackets) { chQuote = currentChar; isInQuotes = true; } } break; case '<': if (!isInQuotes && !isInAngleBrackets && !isInBrackets) { isInAngleBrackets = true; } break; case '>': if (isInAngleBrackets) { isInAngleBrackets = false; } break; case '(': if (!isInQuotes && !isInAngleBrackets && !isInBrackets) { isInBrackets = true; } break; case ')': if (isInBrackets) { isInBrackets = false; } break; default: if (currentChar !== ',' && currentChar !== ';' && currentPos !== (sWorkingRecipientsLen - 1)) { break; } if (!isInAngleBrackets && !isInBrackets && !isInQuotes) { emailEndPos = (currentPos !== (sWorkingRecipientsLen-1)) ? currentPos : sWorkingRecipientsLen; str = sWorkingRecipients.substring(emailStartPos, emailEndPos); if (Utils.trim(str).length > 0) { oRecipient = Utils.getEmailParts(str); inList = false; jCount = aRecipients.length; for (j = 0; j < jCount; j++) { if (aRecipients[j].email === oRecipient.email) { inList = true; } } if (!inList && Utils.isCorrectEmail(oRecipient.email)) { aRecipients.push(oRecipient); } } emailStartPos = currentPos + 1; } break; } currentPos++; } return aRecipients; }; /** * Gets link for contacts inport. * * @return {string} */ Utils.getImportContactsLink = function () { return '?/ImportContacts/'; }; /** * Gets link for contacts export. * * @param {number} iAccountId * @param {string} $sSyncType * @return {string} */ Utils.getExportContactsLink = function ($sSyncType) { return '?/Raw/Contacts' + $sSyncType + '/'; }; /** * Gets link for calendar export by hash. * * @param {number} iAccountId * @param {string} sHash * * @return {string} */ Utils.getExportCalendarLinkByHash = function (iAccountId, sHash) { return '?/Raw/Calendar/' + iAccountId + '/' + sHash; }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getDownloadLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Download/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getViewLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/View/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash in iframe. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getIframeLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Iframe/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for view by hash in iframe. * * @param {number} iAccountId * @param {string} sUrl * * @return {string} */ Utils.getIframeWrappwer = function (iAccountId, sUrl) { return '?/Raw/Iframe/' + iAccountId + '/' + window.encodeURIComponent(sUrl) + '/'; }; /** * Gets link for thumbnail by hash. * * @param {number} iAccountId * @param {string} sHash * @param {boolean=} bIsExt = false * @param {string=} sTenatHash = '' * * @return {string} */ Utils.getViewThumbnailLinkByHash = function (iAccountId, sHash, bIsExt, sTenatHash) { bIsExt = Utils.isUnd(bIsExt) ? false : !!bIsExt; sTenatHash = Utils.isUnd(sTenatHash) ? '' : sTenatHash; return '?/Raw/Thumbnail/' + iAccountId + '/' + sHash + '/' + (bIsExt ? '1' : '0') + ('' === sTenatHash ? '' : '/' + sTenatHash); }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string=} sPublicHash * * @return {string} */ Utils.getFilestorageDownloadLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesDownload/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for download by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string=} sPublicHash * * @return {string} */ Utils.getFilestorageViewLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesView/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for thumbnail by hash. * * @param {number} iAccountId * @param {string} sHash * @param {string} sPublicHash * * @return {string} */ Utils.getFilestorageViewThumbnailLinkByHash = function (iAccountId, sHash, sPublicHash) { var sUrl = '?/Raw/FilesThumbnail/' + iAccountId + '/' + sHash; if (!Utils.isUnd(sPublicHash)) { sUrl = sUrl + '/0/' + sPublicHash; } return sUrl; }; /** * Gets link for public by hash. * * @param {string} sHash * * @return {string} */ Utils.getFilestoragePublicViewLinkByHash = function (sHash) { return '?/Window/Files/0/' + sHash; }; /** * Gets link for public by hash. * * @param {string} sHash * * @return {string} */ Utils.getFilestoragePublicDownloadLinkByHash = function (sHash) { return '?/Raw/FilesPub/0/' + sHash; }; /** * @param {number} iMonth * @param {number} iYear * * @return {number} */ Utils.daysInMonth = function (iMonth, iYear) { if (0 < iMonth && 13 > iMonth && 0 < iYear) { return new Date(iYear, iMonth, 0).getDate(); } return 31; }; /** * @return {string} */ Utils.getAppPath = function () { return window.location.protocol + '//' + window.location.host + window.location.pathname; }; Utils.WindowOpener = { _iDefaultRatio: 0.8, _aOpenedWins: [], /** * @param {{folder:Function, uid:Function}} oMessage * @param {boolean=} bDrafts */ openMessage: function (oMessage, bDrafts) { if (oMessage) { var sFolder = oMessage.folder(), sUid = oMessage.uid(), sHash = '', oWin = null ; if (bDrafts) { sHash = App.Routing.buildHashFromArray([Enums.Screens.SingleCompose, 'drafts', sFolder, sUid]); } else { sHash = App.Routing.buildHashFromArray([Enums.Screens.SingleMessageView, sFolder, 'msg' + sUid]); } oWin = this.openTab(sHash); } }, /** * @param {string} sUrl * * @return Object */ openTab: function (sUrl) { var oWin = null; oWin = window.open(sUrl, '_blank'); oWin.focus(); oWin.name = AppData.Accounts.currentId(); this._aOpenedWins.push(oWin); return oWin; }, /** * @param {string} sUrl * @param {string} sPopupName * @param {boolean=} bMenubar = false * * @return Object */ open: function (sUrl, sPopupName, bMenubar) { var sMenubar = (bMenubar) ? ',menubar=yes' : ',menubar=no', sParams = 'location=no,toolbar=no,status=no,scrollbars=yes,resizable=yes' + sMenubar, oWin = null ; sPopupName = sPopupName.replace(/\W/g, ''); // forbidden characters in the name of the window for ie sParams += this._getSizeParameters(); oWin = window.open(sUrl, sPopupName, sParams); oWin.focus(); oWin.name = AppData.Accounts.currentId(); this._aOpenedWins.push(oWin); return oWin; }, closeAll: function () { var iLen = this._aOpenedWins.length, iIndex = 0, oWin = null ; for (; iIndex < iLen; iIndex++) { oWin = this._aOpenedWins[iIndex]; if (!oWin.closed) { oWin.close(); } } this._aOpenedWins = []; }, /** * @return string */ _getSizeParameters: function () { var iScreenWidth = window.screen.width, iWidth = Math.ceil(iScreenWidth * this._iDefaultRatio), iLeft = Math.ceil((iScreenWidth - iWidth) / 2), iScreenHeight = window.screen.height, iHeight = Math.ceil(iScreenHeight * this._iDefaultRatio), iTop = Math.ceil((iScreenHeight - iHeight) / 2) ; return ',width=' + iWidth + ',height=' + iHeight + ',top=' + iTop + ',left=' + iLeft; } }; /** * @param {?} oObject * @param {string} sDelegateName * @param {Array=} aParameters */ Utils.delegateRun = function (oObject, sDelegateName, aParameters) { if (oObject && oObject[sDelegateName]) { oObject[sDelegateName].apply(oObject, _.isArray(aParameters) ? aParameters : []); } }; /** * @param {string} input * @param {number} multiplier * @return {string} */ Utils.strRepeat = function (input, multiplier) { return (new Array(multiplier + 1)).join(input); }; Utils.deferredUpdate = function (element, state, duration, callback) { if (!element.__interval && !!state) { element.__state = true; callback(element, true); element.__interval = window.setInterval(function () { if (!element.__state) { callback(element, false); window.clearInterval(element.__interval); element.__interval = null; } }, duration); } else if (!state) { element.__state = false; } }; Utils.draggableMessages = function () { return $('<div class="draggable draggableMessages"><div class="content"><span class="count-text"></span></div></div>').appendTo('#pSevenHidden'); }; Utils.draggableContacts = function () { return $('<div class="draggable draggableContacts"><div class="content"><span class="count-text"></span></div></div>').appendTo('#pSevenHidden'); }; Utils.removeActiveFocus = function () { if (document && document.activeElement && document.activeElement.blur) { var oA = $(document.activeElement); if (oA.is('input') || oA.is('textarea')) { document.activeElement.blur(); } } }; Utils.uiDropHelperAnim = function (oEvent, oUi) { var iLeft = 0, iTop = 0, iNewLeft = 0, iNewTop = 0, iWidth = 0, iHeight = 0, helper = oUi.helper.clone().appendTo('#pSevenHidden'), target = $(oEvent.target).find('.animGoal'), position = null ; target = target[0] ? $(target[0]) : $(oEvent.target); position = target && target[0] ? target.offset() : null; if (position) { iLeft = window.Math.round(position.left); iTop = window.Math.round(position.top); iWidth = target.width(); iHeight = target.height(); iNewLeft = iLeft; if (0 < iWidth) { iNewLeft += window.Math.round(iWidth / 2); } iNewTop = iTop; if (0 < iHeight) { iNewTop += window.Math.round(iHeight / 2); } helper.animate({ 'left': iNewLeft + 'px', 'top': iNewTop + 'px', 'font-size': '0px', 'opacity': 0 }, 800, 'easeOutQuint', function() { $(this).remove(); }); } }; Utils.isTextFieldFocused = function () { var mTag = document && document.activeElement ? document.activeElement : null, mTagName = mTag ? mTag.tagName : null, mTagType = mTag && mTag.type ? mTag.type.toLowerCase() : null, mContentEditable = mTag ? mTag.contentEditable : null ; return ('INPUT' === mTagName && (mTagType === 'text' || mTagType === 'password' || mTagType === 'email')) || 'TEXTAREA' === mTagName || 'IFRAME' === mTagName || mContentEditable === 'true'; }; Utils.removeSelection = function () { if (window.getSelection) { window.getSelection().removeAllRanges(); } else if (document.selection) { document.selection.empty(); } }; Utils.getMonthNamesArray = function () { var aMonthes = Utils.i18n('DATETIME/MONTH_NAMES').split(' '), iLen = 12, iIndex = aMonthes.length ; for (; iIndex < iLen; iIndex++) { aMonthes[iIndex] = ''; } return aMonthes; }; /** * http://docs.translatehouse.org/projects/localization-guide/en/latest/l10n/pluralforms.html?id=l10n/pluralforms * * @param {string} sLang * @param {number} iNumber * * @return {number} */ Utils.getPlural = function (sLang, iNumber) { var iResult = 0; iNumber = Utils.pInt(iNumber); switch (sLang) { case 'Arabic': iResult = (iNumber === 0 ? 0 : iNumber === 1 ? 1 : iNumber === 2 ? 2 : iNumber % 100 >= 3 && iNumber % 100 <= 10 ? 3 : iNumber % 100 >= 11 ? 4 : 5); break; case 'Bulgarian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Chinese-Simplified': iResult = 0; break; case 'Chinese-Traditional': iResult = (iNumber === 1 ? 0 : 1); break; case 'Czech': iResult = (iNumber === 1) ? 0 : (iNumber >= 2 && iNumber <= 4) ? 1 : 2; break; case 'Danish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Dutch': iResult = (iNumber === 1 ? 0 : 1); break; case 'English': iResult = (iNumber === 1 ? 0 : 1); break; case 'Estonian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Finish': iResult = (iNumber === 1 ? 0 : 1); break; case 'French': iResult = (iNumber === 1 ? 0 : 1); break; case 'German': iResult = (iNumber === 1 ? 0 : 1); break; case 'Greek': iResult = (iNumber === 1 ? 0 : 1); break; case 'Hebrew': iResult = (iNumber === 1 ? 0 : 1); break; case 'Hungarian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Italian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Japanese': iResult = 0; break; case 'Korean': iResult = 0; break; case 'Latvian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber !== 0 ? 1 : 2); break; case 'Lithuanian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Norwegian': iResult = (iNumber === 1 ? 0 : 1); break; case 'Persian': iResult = 0; break; case 'Polish': iResult = (iNumber === 1 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Portuguese-Portuguese': iResult = (iNumber === 1 ? 0 : 1); break; case 'Portuguese-Brazil': iResult = (iNumber === 1 ? 0 : 1); break; case 'Romanian': iResult = (iNumber === 1 ? 0 : (iNumber === 0 || (iNumber % 100 > 0 && iNumber % 100 < 20)) ? 1 : 2); break; case 'Russian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Serbian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; case 'Spanish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Swedish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Thai': iResult = 0; break; case 'Turkish': iResult = (iNumber === 1 ? 0 : 1); break; case 'Ukrainian': iResult = (iNumber % 10 === 1 && iNumber % 100 !== 11 ? 0 : iNumber % 10 >= 2 && iNumber % 10 <= 4 && (iNumber % 100 < 10 || iNumber % 100 >= 20) ? 1 : 2); break; default: iResult = 0; break; } return iResult; }; /** * @param {string} sFile * * @return {string} */ Utils.getFileExtension = function (sFile) { var sResult = '', iIndex = sFile.lastIndexOf('.') ; if (iIndex > -1) { sResult = sFile.substr(iIndex + 1); } return sResult; }; /** * @param {string} sFile * * @return {string} */ Utils.getFileNameWithoutExtension = function (sFile) { var sResult = sFile, iIndex = sFile.lastIndexOf('.') ; if (iIndex > -1) { sResult = sFile.substr(0, iIndex); } return sResult; }; /** * @param {Object} oElement * @param {Object} oItem */ Utils.defaultOptionsAfterRender = function (oElement, oItem) { if (oItem) { if (!Utils.isUnd(oItem.disable)) { ko.applyBindingsToNode(oElement, { 'disable': oItem.disable }, oItem); } } }; /** * @param {string} sDateFormat * * @return string */ Utils.getDateFormatForMoment = function (sDateFormat) { var sMomentDateFormat = 'MM/DD/YYYY'; switch (sDateFormat) { case 'MM/DD/YYYY': sMomentDateFormat = 'MM/DD/YYYY'; break; case 'DD/MM/YYYY': sMomentDateFormat = 'DD/MM/YYYY'; break; case 'DD Month YYYY': sMomentDateFormat = 'DD MMMM YYYY'; break; } return sMomentDateFormat; }; /** * @param {string} sDateFormat * * @return string */ Utils.getDateFormatForDatePicker = function (sDateFormat) { var sDatePickerDateFormat = 'mm/dd/yy'; switch (sDateFormat) { case 'MM/DD/YYYY': sDatePickerDateFormat = 'mm/dd/yy'; break; case 'DD/MM/YYYY': sDatePickerDateFormat = 'dd/mm/yy'; break; case 'DD Month YYYY': sDatePickerDateFormat = 'dd MM yy'; break; } return sDatePickerDateFormat; }; /** * @return Array */ Utils.getDateFormatsForSelector = function () { return _.map(AppData.App.DateFormats, function (sDateFormat) { switch (sDateFormat) { case 'MM/DD/YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_MMDDYYYY'), value: sDateFormat}; case 'DD/MM/YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_DDMMYYYY'), value: sDateFormat}; case 'DD Month YYYY': return {name: Utils.i18n('DATETIME/DATEFORMAT_DDMONTHYYYY'), value: sDateFormat}; default: return {name: sDateFormat, value: sDateFormat}; } }); }; /** * @param {string} sSubject * * @return {string} */ Utils.getTitleForEvent = function (sSubject) { var sTitle = sSubject ? Utils.trim(sSubject.replace(/[\n\r]/, ' ')) : '', iFirstSpacePos = sTitle.indexOf(' ', 180) ; if (iFirstSpacePos >= 0) { sTitle = sTitle.substring(0, iFirstSpacePos) + '...'; } if (sTitle.length > 200) { sTitle = sTitle.substring(0, 200) + '...'; } return sTitle; }; Utils.desktopNotify = (function () { var aNotifications = [], iTimeoutID = 0 ; return function (oData) { if (AppData.User.DesktopNotifications && window.Notification && !App.focused()) { if (oData && oData.action === 'show' && window.Notification.permission !== Enums.notificationPermission.Denied) { // oData - action, body, dir, lang, tag, icon, callback, timeout var oOptions = { //https://developer.mozilla.org/en-US/docs/Web/API/Notification body: oData.body || '', //A string representing an extra content to display within the notification dir: oData.dir || "auto", //The direction of the notification; it can be auto, ltr, or rtl lang: oData.lang || '', //Specify the lang used within the notification. This string must be a valid BCP 47 language tag tag: oData.tag || Math.floor(Math.random() * (1000 - 100) + 100), //An ID for a given notification that allows to retrieve, replace or remove it if necessary icon: oData.icon || false //The URL of an image to be used as an icon by the notification }, oNotification, fShowNotification = function() { oNotification = new window.Notification(oData.title, oOptions); //Firefox and Safari close the notifications automatically after a few moments, e.g. 4 seconds. oNotification.onclick = function (oEv) { if(oData.callback) { oData.callback(); } oNotification.close(); }; oNotification.onshow = function (oEv) {}; oNotification.onclose = function (oEv) {}; oNotification.onerror = function (oEv) {}; if(oData.timeout) { iTimeoutID = setTimeout(function() {oNotification.close();}, oData.timeout); } aNotifications.push(oNotification); } ; if (window.Notification.permission === 'granted') { fShowNotification(); } else if (window.Notification.permission === 'default') { window.Notification.requestPermission(function (sPermission) { if(sPermission === "granted") { fShowNotification(); } }); } } else if (oData && oData.action === 'hide') { _.each(aNotifications, function (oNotifi, ikey) { if (oData.tag === oNotifi.tag) { oNotifi.close(); aNotifications.splice(ikey, 1); } }); } else if (oData && oData.action === 'hideAll') { _.each(aNotifications,function (oNotifi) { oNotifi.close(); }); aNotifications.length = 0; } } }; }()); /** * @return {boolean} */ Utils.isRTL = function () { return $html.hasClass('rtl'); }; /** * @param {string} sName * @return {boolean} */ Utils.validateFileOrFolderName = function (sName) { sName = Utils.trim(sName); return '' !== sName && !/["\/\\*?<>|:]/.test(sName); }; /** * @param {string} sColor * @param {number} iPercent * * @return {string} */ Utils.shadeColor = function (sColor, iPercent) { var usePound = false, num = 0, r = 0, b = 0, g = 0 ; if (sColor[0] === "#") { sColor = sColor.slice(1); usePound = true; } num = window.parseInt(sColor, 16); r = (num >> 16) + iPercent; if (r > 255) { r = 255; } else if (r < 0) { r = 0; } b = ((num >> 8) & 0x00FF) + iPercent; if (b > 255) { b = 255; } else if (b < 0) { b = 0; } g = (num & 0x0000FF) + iPercent; if (g > 255) { g = 255; } else if (g < 0) { g = 0; } return (usePound ? "#" : "") + (g | (b << 8) | (r << 16)).toString(16); }; /** * @param {Object} ChildClass * @param {Object} ParentClass */ Utils.extend = function (ChildClass, ParentClass) { /** * @constructor */ var TmpClass = function(){}; TmpClass.prototype = ParentClass.prototype; ChildClass.prototype = new TmpClass(); ChildClass.prototype.constructor = ChildClass; }; Utils.thumbQueue = (function () { var oImages = {}, oImagesIncrements = {}, iNumberOfImages = 2 ; return function (sSessionUid, sImageSrc, fImageSrcObserver) { if(sImageSrc && fImageSrcObserver) { if(!(sSessionUid in oImagesIncrements) || oImagesIncrements[sSessionUid] > 0) //load first images { if(!(sSessionUid in oImagesIncrements)) //on first image { oImagesIncrements[sSessionUid] = iNumberOfImages; oImages[sSessionUid] = []; } oImagesIncrements[sSessionUid]--; fImageSrcObserver(sImageSrc); //load image } else //create queue { oImages[sSessionUid].push({ imageSrc: sImageSrc, imageSrcObserver: fImageSrcObserver, messageUid: sSessionUid }); } } else //load images from queue (fires load event) { if(oImages[sSessionUid] && oImages[sSessionUid].length) { oImages[sSessionUid][0].imageSrcObserver(oImages[sSessionUid][0].imageSrc); oImages[sSessionUid].shift(); } } }; }()); Utils.checkConnection = (function () { var iTimer = -1, iLastWakeTime = new Date().getTime(), iCurrentTime = 0, bAwoke = false ; setInterval(function() { //fix for sleep mode iCurrentTime = new Date().getTime(); bAwoke = iCurrentTime > (iLastWakeTime + 5000 + 1000); iLastWakeTime = iCurrentTime; if(bAwoke) { App.Api.hideError(true); } }, 5000); return function (sAction, sStatus) { clearTimeout(iTimer); if(sStatus !== 'error') { App.Api.hideError(true); } else { if (sAction === 'Ping') { //if (!bAwoke) { App.Api.showError(Utils.i18n('WARNING/NO_INTERNET_CONNECTION'), false, true, true); iTimer = setTimeout(function () { App.Ajax.send({'Action': 'Ping'}); }, 60000); //} } else { App.Ajax.send({'Action': 'Ping'}); } } }; }()); Utils.loadScript = function (sUrl, fCallback, aParams, sFuncName) { var script = document.createElement('script'); if (!Utils.isUnd(sFuncName) && fCallback) { window[sFuncName] = fCallback; } if (Utils.isUnd(aParams)) { aParams = {}; } _.each(aParams, function(value, key){ script.setAttribute(key, value); }); script.type = 'text/javascript'; script.src = sUrl; document.body.appendChild(script); }; Utils.registerMailto = function (bRegisterOnce) { if (window.navigator && Utils.isFunc(window.navigator.registerProtocolHandler) && (!bRegisterOnce || App.Storage.getData('MailtoAsked') !== 1)) { window.navigator.registerProtocolHandler( 'mailto', Utils.getAppPath() + '#' + Enums.Screens.Compose + '/to/%s', AppData.App.SiteName !== '' ? AppData.App.SiteName : 'WebMail' ); App.Storage.setData('MailtoAsked', 1); } }; Utils.CustomTooltip = { _$Region: null, _$ArrowTop: null, _$Text: null, _$ArrowBottom: null, _iArrowBorderLeft: 0, _iArrowMarginLeft: 0, _iLeftShift: 0, _bInitialized: false, init: function () { if (!this._bInitialized) { this._$Region = $('<span class="custom_tooltip"></span>').appendTo('body').hide(); this._$ArrowTop = $('<span class="custom_tooltip_arrow top"></span>').appendTo(this._$Region); this._$Text = $('<span class="custom_tooltip_text"></span>').appendTo(this._$Region); this._$ArrowBottom = $('<span class="custom_tooltip_arrow bottom"></span>').appendTo(this._$Region); this._iArrowMarginLeft = Utils.pInt(this._$ArrowTop.css('margin-left')); this._iArrowBorderLeft = Utils.pInt(this._$ArrowTop.css('border-left-width')); this._iLeftShift = this._iArrowBorderLeft + this._iArrowMarginLeft + Utils.pInt(this._$Region.css('margin-left')); this._bInitialized = true; } this._$ArrowTop.show(); this._$ArrowBottom.hide(); this._$ArrowTop.css({ 'margin-left': this._iArrowMarginLeft + 'px' }); this._$ArrowBottom.css({ 'margin-left': this._iArrowMarginLeft + 'px' }); }, show: function (sText, $ItemToAlign) { this.init(); var oItemOffset = $ItemToAlign.offset(), iItemHalfWidth = Math.round($ItemToAlign.innerWidth()/2), iLeftShift = this._iLeftShift - iItemHalfWidth ; this._$Text.html(sText); this._$Region.fadeIn().css({ 'top': oItemOffset.top + $ItemToAlign.height(), 'left': oItemOffset.left - iLeftShift, 'right': 'auto' }); if ($('body').height() < this._$Region.height() + this._$Region.offset().top) { this._$ArrowTop.hide(); this._$ArrowBottom.show(); this._$Region.css({ 'top': oItemOffset.top - this._$Region.height() }); } if ($('body').width() < (this._$Region.outerWidth(true) + this._$Region.offset().left)) { this._$Region.css({ 'left': 'auto', 'right': 0 }); this._$ArrowTop.css({ 'margin-left': (iItemHalfWidth + oItemOffset.left - this._$Region.offset().left - this._iArrowBorderLeft) + 'px' }); } }, hide: function () { if (this._bInitialized) { this._$Region.hide(); } } }; /** * @param {Function} list (knockout) * @param {Function=} fSelectCallback * @param {Function=} fDeleteCallback * @param {Function=} fDblClickCallback * @param {Function=} fEnterCallback * @param {Function=} multiplyLineFactor (knockout) * @param {boolean=} bResetCheckedOnClick = false * @param {boolean=} bCheckOnSelect = false * @param {boolean=} bUnselectOnCtrl = false * @param {boolean=} bDisableMultiplySelection = false * @constructor */ function CSelector(list, fSelectCallback, fDeleteCallback, fDblClickCallback, fEnterCallback, multiplyLineFactor, bResetCheckedOnClick, bCheckOnSelect, bUnselectOnCtrl, bDisableMultiplySelection) { this.fBeforeSelectCallback = null; this.fSelectCallback = fSelectCallback || function() {}; this.fDeleteCallback = fDeleteCallback || function() {}; this.fDblClickCallback = (!bMobileApp && fDblClickCallback) ? fDblClickCallback : function() {}; this.fEnterCallback = fEnterCallback || function() {}; this.bResetCheckedOnClick = Utils.isUnd(bResetCheckedOnClick) ? false : !!bResetCheckedOnClick; this.bCheckOnSelect = Utils.isUnd(bCheckOnSelect) ? false : !!bCheckOnSelect; this.bUnselectOnCtrl = Utils.isUnd(bUnselectOnCtrl) ? false : !!bUnselectOnCtrl; this.bDisableMultiplySelection = Utils.isUnd(bDisableMultiplySelection) ? false : !!bDisableMultiplySelection; this.useKeyboardKeys = ko.observable(false); this.list = ko.observableArray([]); if (list && list['subscribe']) { list['subscribe'](function (mValue) { this.list(mValue); }, this); } this.multiplyLineFactor = multiplyLineFactor; this.oLast = null; this.oListScope = null; this.oScrollScope = null; this.iTimer = 0; this.iFactor = 1; this.KeyUp = Enums.Key.Up; this.KeyDown = Enums.Key.Down; this.KeyLeft = Enums.Key.Up; this.KeyRight = Enums.Key.Down; if (this.multiplyLineFactor) { if (this.multiplyLineFactor.subscribe) { this.multiplyLineFactor.subscribe(function (iValue) { this.iFactor = 0 < iValue ? iValue : 1; }, this); } else { this.iFactor = Utils.pInt(this.multiplyLineFactor); } this.KeyUp = Enums.Key.Up; this.KeyDown = Enums.Key.Down; this.KeyLeft = Enums.Key.Left; this.KeyRight = Enums.Key.Right; if ($('html').hasClass('rtl')) { this.KeyLeft = Enums.Key.Right; this.KeyRight = Enums.Key.Left; } } this.sActionSelector = ''; this.sSelectabelSelector = ''; this.sCheckboxSelector = ''; var self = this; // reading returns a list of checked items. // recording (bool) puts all checked, or unchecked. this.listChecked = ko.computed({ 'read': function () { var aList = _.filter(this.list(), function (oItem) { var bC = oItem.checked(), bS = oItem.selected() ; return bC || (self.bCheckOnSelect && bS); }); return aList; }, 'write': function (bValue) { bValue = !!bValue; _.each(this.list(), function (oItem) { oItem.checked(bValue); }); this.list.valueHasMutated(); }, 'owner': this }); this.checkAll = ko.computed({ 'read': function () { return 0 < this.listChecked().length; }, 'write': function (bValue) { this.listChecked(!!bValue); }, 'owner': this }); this.selectorHook = ko.observable(null); this.selectorHook.subscribe(function () { var oPrev = this.selectorHook(); if (oPrev) { oPrev.selected(false); } }, this, 'beforeChange'); this.selectorHook.subscribe(function (oGroup) { if (oGroup) { oGroup.selected(true); } }, this); this.itemSelected = ko.computed({ 'read': this.selectorHook, 'write': function (oItemToSelect) { this.selectorHook(oItemToSelect); if (oItemToSelect) { // self.scrollToSelected(); this.oLast = oItemToSelect; } }, 'owner': this }); this.list.subscribe(function (aList) { if (_.isArray(aList)) { var oSelected = this.itemSelected(); if (oSelected) { if (!_.find(aList, function (oItem) { return oSelected === oItem; })) { this.itemSelected(null); } } } else { this.itemSelected(null); } }, this); this.listCheckedOrSelected = ko.computed({ 'read': function () { var oSelected = this.itemSelected(), aChecked = this.listChecked() ; return 0 < aChecked.length ? aChecked : (oSelected ? [oSelected] : []); }, 'write': function (bValue) { if (!bValue) { this.itemSelected(null); this.listChecked(false); } else { this.listChecked(true); } }, 'owner': this }); this.listCheckedAndSelected = ko.computed({ 'read': function () { var aResult = [], oSelected = this.itemSelected(), aChecked = this.listChecked() ; if (aChecked) { aResult = aChecked.slice(0); } if (oSelected && _.indexOf(aChecked, oSelected) === -1) { aResult.push(oSelected); } return aResult; }, 'write': function (bValue) { if (!bValue) { this.itemSelected(null); this.listChecked(false); } else { this.listChecked(true); } }, 'owner': this }); this.isIncompleteChecked = ko.computed(function () { var iM = this.list().length, iC = this.listChecked().length ; return 0 < iM && 0 < iC && iM > iC; }, this); this.onKeydownBinded = _.bind(this.onKeydown, this); } CSelector.prototype.iTimer = 0; CSelector.prototype.bResetCheckedOnClick = false; CSelector.prototype.bCheckOnSelect = false; CSelector.prototype.bUnselectOnCtrl = false; CSelector.prototype.bDisableMultiplySelection = false; /** * @param {Function} fBeforeSelectCallback */ CSelector.prototype.setBeforeSelectCallback = function (fBeforeSelectCallback) { this.fBeforeSelectCallback = fBeforeSelectCallback || null; }; CSelector.prototype.getLastOrSelected = function () { var iCheckedCount = 0, oLastSelected = null ; _.each(this.list(), function (oItem) { if (oItem.checked()) { iCheckedCount++; } if (oItem.selected()) { oLastSelected = oItem; } }); return 0 === iCheckedCount && oLastSelected ? oLastSelected : this.oLast; }; /** * @return {boolean} */ /*CSelector.prototype.inFocus = function () { var mTagName = document && document.activeElement ? document.activeElement.tagName : null; return 'INPUT' === mTagName || 'TEXTAREA' === mTagName || 'IFRAME' === mTagName; };*/ /** * @param {string} sActionSelector css-selector for the active for pressing regions of the list * @param {string} sSelectabelSelector css-selector to the item that was selected * @param {string} sCheckboxSelector css-selector to the element that checkbox in the list * @param {*} oListScope * @param {*} oScrollScope */ CSelector.prototype.initOnApplyBindings = function (sActionSelector, sSelectabelSelector, sCheckboxSelector, oListScope, oScrollScope) { $(document).on('keydown', this.onKeydownBinded); this.oListScope = oListScope; this.oScrollScope = oScrollScope; this.sActionSelector = sActionSelector; this.sSelectabelSelector = sSelectabelSelector; this.sCheckboxSelector = sCheckboxSelector; var self = this, fEventClickFunction = function (oLast, oItem, oEvent) { var iIndex = 0, iLength = 0, oListItem = null, bChangeRange = false, bIsInRange = false, aList = [], bChecked = false ; oItem = oItem ? oItem : null; if (oEvent && oEvent.shiftKey) { if (null !== oItem && null !== oLast && oItem !== oLast) { aList = self.list(); bChecked = oItem.checked(); for (iIndex = 0, iLength = aList.length; iIndex < iLength; iIndex++) { oListItem = aList[iIndex]; bChangeRange = false; if (oListItem === oLast || oListItem === oItem) { bChangeRange = true; } if (bChangeRange) { bIsInRange = !bIsInRange; } if (bIsInRange || bChangeRange) { oListItem.checked(bChecked); } } } } if (oItem) { self.oLast = oItem; } } ; $(this.oListScope).on('dblclick', sActionSelector, function (oEvent) { var oItem = ko.dataFor(this); if (oItem && oEvent && !oEvent.ctrlKey && !oEvent.altKey && !oEvent.shiftKey) { self.onDblClick(oItem); } }); if (bMobileDevice) { $(this.oListScope).on('touchstart', sActionSelector, function (e) { if (!e) { return; } var t2 = e.timeStamp, t1 = $(this).data('lastTouch') || t2, dt = t2 - t1, fingers = e.originalEvent && e.originalEvent.touches ? e.originalEvent.touches.length : 0 ; $(this).data('lastTouch', t2); if (!dt || dt > 250 || fingers > 1) { return; } e.preventDefault(); $(this).trigger('dblclick'); }); } $(this.oListScope).on('click', sActionSelector, function (oEvent) { var bClick = true, oSelected = null, oLast = self.getLastOrSelected(), oItem = ko.dataFor(this) ; if (oItem && oEvent) { if (oEvent.shiftKey) { bClick = false; if (!self.bDisableMultiplySelection) { if (null === self.oLast) { self.oLast = oItem; } oItem.checked(!oItem.checked()); fEventClickFunction(oLast, oItem, oEvent); } } else if (oEvent.ctrlKey) { bClick = false; if (!self.bDisableMultiplySelection) { self.oLast = oItem; oSelected = self.itemSelected(); if (oSelected && !oSelected.checked() && !oItem.checked()) { oSelected.checked(true); } if (self.bUnselectOnCtrl && oItem === self.itemSelected()) { oItem.checked(!oItem.selected()); self.itemSelected(null); } else { oItem.checked(!oItem.checked()); } } } if (bClick) { self.onSelect(oItem); self.scrollToSelected(); } } }); $(this.oListScope).on('click', sCheckboxSelector, function (oEvent) { var oItem = ko.dataFor(this); if (oItem && oEvent && !self.bDisableMultiplySelection) { if (oEvent.shiftKey) { if (null === self.oLast) { self.oLast = oItem; } fEventClickFunction(self.getLastOrSelected(), oItem, oEvent); } else { self.oLast = oItem; } } if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }); $(this.oListScope).on('dblclick', sCheckboxSelector, function (oEvent) { if (oEvent && oEvent.stopPropagation) { oEvent.stopPropagation(); } }); }; /** * @param {Object} oSelected * @param {number} iEventKeyCode * * @return {Object} */ CSelector.prototype.getResultSelection = function (oSelected, iEventKeyCode) { var self = this, bStop = false, bNext = false, oResult = null, iPageStep = this.iFactor, bMultiply = !!this.multiplyLineFactor, iIndex = 0, iLen = 0, aList = [] ; if (!oSelected && -1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyDown, this.KeyLeft, this.KeyRight, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End])) { aList = this.list(); if (aList && 0 < aList.length) { if (-1 < Utils.inArray(iEventKeyCode, [this.KeyDown, this.KeyRight, Enums.Key.PageUp, Enums.Key.Home])) { oResult = aList[0]; } else if (-1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyLeft, Enums.Key.PageDown, Enums.Key.End])) { oResult = aList[aList.length - 1]; } } } else if (oSelected) { aList = this.list(); iLen = aList ? aList.length : 0; if (0 < iLen) { if ( Enums.Key.Home === iEventKeyCode || Enums.Key.PageUp === iEventKeyCode || Enums.Key.End === iEventKeyCode || Enums.Key.PageDown === iEventKeyCode || (bMultiply && (Enums.Key.Left === iEventKeyCode || Enums.Key.Right === iEventKeyCode)) || (!bMultiply && (Enums.Key.Up === iEventKeyCode || Enums.Key.Down === iEventKeyCode)) ) { _.each(aList, function (oItem) { if (!bStop) { switch (iEventKeyCode) { case self.KeyUp: case self.KeyLeft: if (oSelected === oItem) { bStop = true; } else { oResult = oItem; } break; case Enums.Key.Home: case Enums.Key.PageUp: oResult = oItem; bStop = true; break; case self.KeyDown: case self.KeyRight: if (bNext) { oResult = oItem; bStop = true; } else if (oSelected === oItem) { bNext = true; } break; case Enums.Key.End: case Enums.Key.PageDown: oResult = oItem; break; } } }); } else if (bMultiply && this.KeyDown === iEventKeyCode) { for (; iIndex < iLen; iIndex++) { if (oSelected === aList[iIndex]) { iIndex += iPageStep; if (iLen - 1 < iIndex) { iIndex -= iPageStep; } oResult = aList[iIndex]; break; } } } else if (bMultiply && this.KeyUp === iEventKeyCode) { for (iIndex = iLen; iIndex >= 0; iIndex--) { if (oSelected === aList[iIndex]) { iIndex -= iPageStep; if (0 > iIndex) { iIndex += iPageStep; } oResult = aList[iIndex]; break; } } } } } return oResult; }; /** * @param {Object} oResult * @param {Object} oSelected * @param {number} iEventKeyCode */ CSelector.prototype.shiftClickResult = function (oResult, oSelected, iEventKeyCode) { if (oSelected) { var bMultiply = !!this.multiplyLineFactor, bInRange = false, bSelected = false ; if (-1 < Utils.inArray(iEventKeyCode, bMultiply ? [Enums.Key.Left, Enums.Key.Right] : [Enums.Key.Up, Enums.Key.Down])) { oSelected.checked(!oSelected.checked()); } else if (-1 < Utils.inArray(iEventKeyCode, bMultiply ? [Enums.Key.Up, Enums.Key.Down, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End] : [Enums.Key.Left, Enums.Key.Right, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End] )) { bSelected = !oSelected.checked(); _.each(this.list(), function (oItem) { var Add = false; if (oItem === oResult || oSelected === oItem) { bInRange = !bInRange; Add = true; } if (bInRange || Add) { oItem.checked(bSelected); Add = false; } }); if (bMultiply && oResult && (iEventKeyCode === Enums.Key.Up || iEventKeyCode === Enums.Key.Down)) { oResult.checked(!oResult.checked()); } } } }; /** * @param {number} iEventKeyCode * @param {boolean} bShiftKey */ CSelector.prototype.clickNewSelectPosition = function (iEventKeyCode, bShiftKey) { var self = this, iTimeout = 0, oResult = null, oSelected = this.itemSelected() ; oResult = this.getResultSelection(oSelected, iEventKeyCode); if (oResult) { if (bShiftKey) { this.shiftClickResult(oResult, oSelected, iEventKeyCode); } if (oResult && this.fBeforeSelectCallback) { this.fBeforeSelectCallback(oResult, function (bResult) { if (bResult) { self.itemSelected(oResult); iTimeout = 0 === self.iTimer ? 50 : 150; if (0 !== self.iTimer) { window.clearTimeout(self.iTimer); } self.iTimer = window.setTimeout(function () { self.iTimer = 0; self.onSelect(oResult, false); }, iTimeout); this.scrollToSelected(); } }); this.scrollToSelected(); } else { this.itemSelected(oResult); iTimeout = 0 === this.iTimer ? 50 : 150; if (0 !== this.iTimer) { window.clearTimeout(this.iTimer); } this.iTimer = window.setTimeout(function () { self.iTimer = 0; self.onSelect(oResult); }, iTimeout); this.scrollToSelected(); } } else if (oSelected) { if (bShiftKey && (-1 < Utils.inArray(iEventKeyCode, [this.KeyUp, this.KeyDown, this.KeyLeft, this.KeyRight, Enums.Key.PageUp, Enums.Key.PageDown, Enums.Key.Home, Enums.Key.End]))) { oSelected.checked(!oSelected.checked()); } } }; /** * @param {Object} oEvent * * @return {boolean} */ CSelector.prototype.onKeydown = function (oEvent) { var bResult = true, iCode = 0 ; if (this.useKeyboardKeys() && oEvent && !Utils.isTextFieldFocused()) { iCode = oEvent.keyCode; if (!oEvent.ctrlKey && ( this.KeyUp === iCode || this.KeyDown === iCode || this.KeyLeft === iCode || this.KeyRight === iCode || Enums.Key.PageUp === iCode || Enums.Key.PageDown === iCode || Enums.Key.Home === iCode || Enums.Key.End === iCode ) ) { this.clickNewSelectPosition(iCode, oEvent.shiftKey); bResult = false; } else if (Enums.Key.Del === iCode && !oEvent.ctrlKey && !oEvent.shiftKey) { if (0 < this.list().length) { this.onDelete(); bResult = false; } } else if (Enums.Key.Enter === iCode) { if (0 < this.list().length && !oEvent.ctrlKey) { this.onEnter(this.itemSelected()); bResult = false; } } else if (oEvent.ctrlKey && !oEvent.altKey && !oEvent.shiftKey && Enums.Key.a === iCode) { this.checkAll(!(this.checkAll() && !this.isIncompleteChecked())); bResult = false; } } return bResult; }; CSelector.prototype.onDelete = function () { this.fDeleteCallback.call(this, this.listCheckedOrSelected()); }; /** * @param {Object} oItem */ CSelector.prototype.onEnter = function (oItem) { var self = this; if (oItem && this.fBeforeSelectCallback) { this.fBeforeSelectCallback(oItem, function (bResult) { if (bResult) { self.itemSelected(oItem); self.fEnterCallback.call(this, oItem); } }); } else { this.itemSelected(oItem); this.fEnterCallback.call(this, oItem); } }; /** * @param {Object} oItem */ CSelector.prototype.selectionFunc = function (oItem) { this.itemSelected(null); if (this.bResetCheckedOnClick) { this.listChecked(false); } this.itemSelected(oItem); this.fSelectCallback.call(this, oItem); }; /** * @param {Object} oItem * @param {boolean=} bCheckBefore = true */ CSelector.prototype.onSelect = function (oItem, bCheckBefore) { bCheckBefore = Utils.isUnd(bCheckBefore) ? true : !!bCheckBefore; if (this.fBeforeSelectCallback && bCheckBefore) { var self = this; this.fBeforeSelectCallback(oItem, function (bResult) { if (bResult) { self.selectionFunc(oItem); } }); } else { this.selectionFunc(oItem); } }; /** * @param {Object} oItem */ CSelector.prototype.onDblClick = function (oItem) { this.fDblClickCallback.call(this, oItem); }; CSelector.prototype.koCheckAll = function () { return ko.computed({ 'read': this.checkAll, 'write': this.checkAll, 'owner': this }); }; CSelector.prototype.koCheckAllIncomplete = function () { return ko.computed({ 'read': this.isIncompleteChecked, 'write': this.isIncompleteChecked, 'owner': this }); }; /** * @return {boolean} */ CSelector.prototype.scrollToSelected = function () { if (!this.oListScope || !this.oScrollScope) { return false; } var iOffset = 20, oSelected = $(this.sSelectabelSelector, this.oScrollScope), oPos = oSelected.position(), iVisibleHeight = this.oScrollScope.height(), iSelectedHeight = oSelected.outerHeight() ; if (oPos && (oPos.top < 0 || oPos.top + iSelectedHeight > iVisibleHeight)) { if (oPos.top < 0) { this.oScrollScope.scrollTop(this.oScrollScope.scrollTop() + oPos.top - iOffset); } else { this.oScrollScope.scrollTop(this.oScrollScope.scrollTop() + oPos.top - iVisibleHeight + iSelectedHeight + iOffset); } return true; } return false; }; (function ($) { /** * @param {{name:string,resizeFunc:Function}} args */ $.fn.splitter = function(args) { args = args || {}; return this.each(function () { var bIsMouseSplit = false, storageKey = args.name, initPosition = 0, nSize = 0, oLastState = {}, oLastStateReserve = {}, startSplitMouse = function (e) { bIsMouseSplit = true; bar.addClass(opts['activeClass']); opts['_posSplit'] = -((rtl ? splitter._overallWidth - e[opts['eventPos']] : e[opts['eventPos']]) - panes.get(0)[opts['pxSplit']] ); $('body') .attr({'unselectable': "on"}) .addClass('unselectable'); $(document) .bind('mousemove', doSplitMouse) .bind('mouseup', endSplitMouse); }, doSplitMouse = function (e) { var newPos = (rtl ? splitter._overallWidth - e[opts['eventPos']] : e[opts['eventPos']]) + opts['_posSplit']; resplit(newPos); if (Utils.isFunc(args.resizeFunc)) { args.resizeFunc(); } }, endSplitMouse = function endSplitMouse(e) { bar.removeClass(opts['activeClass']); $('body') .attr({'unselectable': 'off'}) .removeClass('unselectable'); // Store 'width' data if (storageKey) { App.Storage.setData(storageKey + 'ResizerWidth', panes.get(0)[opts['pxSplit']]); } $(document) .unbind('mousemove', doSplitMouse) .unbind('mouseup', endSplitMouse); if (Utils.isFunc(args.resizeFunc)) { args.resizeFunc(); } }, resplit = function (newPosition, bIgnoreSizeLimits) { if (!bIgnoreSizeLimits) { // Constrain new splitbar position to fit pane size limits newPosition = window.Math.max( panes.get(0)._min, splitter._overallWidth - panes.get(1)._max, window.Math.min(newPosition, panes.get(0)._max, splitter._overallWidth - panes.get(1)._min) ); } panes.get(0).$.css(opts['split'], newPosition); panes.get(1).$.css(opts['split'], splitter._overallWidth - newPosition); if (!App.browser.ie8AndBelow) { panes.trigger('resize'); } }, dimSum = function (elem, dims) { // Opera returns -1 for missing min/max width, turn into 0 var sum = 0, i = 1; for (; i < arguments.length; i++) { sum += window.Math.max(window.parseInt(elem.css(arguments[i]), 10) || 0, 0); } return sum; }, vh = (args.splitHorizontal ? 'h' : args.splitVertical ? 'v' : args.type) || 'v', opts = $.extend({ 'activeClass': 'active', // class name for active splitter 'pxPerKey': 8, // splitter px moved per keypress 'tabIndex': 0, // tab order indicator 'accessKey': '' // accessKey for splitbar },{ v: { // Vertical splitters: 'keyLeft': 39, 'keyRight': 37, 'type': 'v', 'eventPos': "pageX", 'origin': "left", 'split': "width", 'pxSplit': "offsetWidth", 'side1': "Left", 'side2': "Right", 'fixed': "height", 'pxFixed': "offsetHeight", 'side3': "Top", 'side4': "Bottom" }, h: { // Horizontal splitters: 'keyTop': 40, 'keyBottom': 38, 'type': 'h', 'eventPos': "pageY", 'origin': "top", 'split': "height", 'pxSplit': "offsetHeight", 'side1': "Top", 'side2': "Bottom", 'fixed': "width", 'pxFixed': "offsetWidth", 'side3': "Left", 'side4': "Right" } }[vh], args), splitter = $(this), panes = $(">*:not(css3pie)", splitter).each(function(){this.$ = $(this);}), bar = $('.resize_handler', panes.get(0)) .attr({'unselectable': 'on'}) .bind('mousedown', startSplitMouse), rtl = splitter.css('direction') === 'rtl' ; panes.get(0)._paneName = opts['side1']; panes.get(1)._paneName = opts['side2']; panes.each(function(){ this._min = opts['min' + this._paneName] || dimSum(this.$, 'min-' + opts['split']); this._max = opts['max' + this._paneName] || dimSum(this.$, 'max-' + opts['split']) || 9999; this._init = opts['size' + this._paneName] === undefined ? window.parseInt($.css(this, opts['split']), 10) : opts['size' + this._paneName]; }); // Determine initial position, get from cookie if specified if (storageKey) { initPosition = App.Storage.getData(storageKey + 'ResizerWidth') || panes.get(0)._init; } else { initPosition = panes.get(0)._init; } /*// no need because we store only primary (left or top) panel if (!isNaN(panes.get(1)._init)) // recalc initial B size as an offset from the top or left side { initPosition = splitter[0][opts['pxSplit']] - panes.get(1)._init; }*/ if (isNaN(initPosition)) { initPosition = splitter[0][opts['pxSplit']]; initPosition = window.Math.round(initPosition / panes.length); } // Resize event propagation and splitter sizing if (opts['resizeToWidth'] && !(App.browser.ie8AndBelow)) { $(window).bind('resize', function(e) { if (e.target !== this) { return; } splitter.trigger('resize'); }); } splitter.bind('resize', function (ev, size, sCommand, bIgnoreSizeLimits) { var tKey = ev.target.className + '_' + sCommand; if (bIsMouseSplit) { oLastState = {}; } // Custom events bubble in jQuery 1.3; don't get into a Yo Dawg if (ev.target !== this) { return; } // Determine new width/height of splitter container splitter._overallWidth = splitter[0][opts['pxSplit']]; // Return if splitter isn't visible or content isn't there yet if (splitter._overallWidth <= 0) { return; } if (!(opts['sizeRight'] || opts['sizeBottom'])) { nSize = panes.get(0)[opts['pxSplit']]; } else { nSize = splitter._overallWidth - panes.get(1)[opts['pxSplit']]; } if (isNaN(size)) { size = nSize; } else if (sCommand) { bIsMouseSplit = false; if (oLastState[tKey]) { size = oLastState[tKey]; oLastState[tKey] = null; } else { if (size === nSize) { oLastState[tKey] = null; size = oLastStateReserve[tKey]; } else { oLastState[tKey] = oLastStateReserve[tKey] = nSize; } _.each(oLastState, function(num, key) { if (key !== tKey) { oLastState[key] = null; } }); } } resplit(size, bIgnoreSizeLimits); }).trigger('resize', [initPosition]); }); }; })(jQuery); (function ($) { /** * extend jQuery autocomplete */ // styling results $.ui.autocomplete.prototype._renderItem = function (ul, item) { item.label = Utils.trim(item.label); item.label = item.label.replace(/\([^\)]+\)$/i, function (sMatch) { return '~~1~~' + sMatch + '~~2~~'; }); item.label = item.label.replace(/<[^>]+>$/i, function (sMatch) { return '~~1~~' + sMatch + '~~2~~'; }); item.label = Utils.encodeHtml(item.label); item.label = item.label .replace(/~~1~~/, '<span style="opacity: 0.5">') .replace(/~~2~~/, '</span>') ; return $('<li>') .append('<a>' + item.label + '</a>') .appendTo(ul); }; // add categories $.ui.autocomplete.prototype._renderMenu = function(ul, items) { var self = this, currentCategory = '' ; $.each(items, function(index, item) { if (item && item.category && item.category !== currentCategory) { currentCategory = item.category; ul.append('<li class="ui-autocomplete-category">' + item.category + '</li>'); } self._renderItemData(ul, item); }); }; })(jQuery); /** * @constructor */ function CApi() { this.openPgp = null; this.openPgpCallbacks = []; } /** * @param {string} sToAddresses */ CApi.prototype.openComposeMessage = function (sToAddresses) { App.Routing.setHash(App.Links.composeWithToField(sToAddresses)); }; /** * Downloads by url through iframe or new window. * * @param {string} sUrl */ CApi.prototype.downloadByUrl = function (sUrl) { var oIframe = null; if (bMobileDevice) { window.open(sUrl); } else { oIframe = $('<iframe style="display: none;"></iframe>').appendTo(document.body); oIframe.attr('src', sUrl); setTimeout(function () { oIframe.remove(); }, 60000); } }; /** * @return {boolean} */ CApi.prototype.isPgpSupported = function () { return !!(window.crypto && window.crypto.getRandomValues); }; /** * @param {Function} fCallback * @param {mixed=} sUserUid */ CApi.prototype.pgp = function (fCallback, sUserUid) { if (Utils.isFunc(fCallback)) { if (this.openPgp) { fCallback(this.openPgp); } else if (this.isPgpSupported()) { if (null !== this.openPgpCallbacks) { this.openPgpCallbacks.push(fCallback); } else { fCallback(false); } var self = this; if (!this.openPgpRequest) { this.openPgpRequest = true; $.ajax({ 'url': 'static/js/openpgp.js', 'dataType': 'script', 'cache': true, 'complete': function () { self.openPgp = window.openpgp ? new OpenPgp(window.openpgp, 'user_' + (sUserUid || '0') + '_') : false; if (null !== self.openPgpCallbacks) { _.each(self.openPgpCallbacks, function (fItemCallback) { fItemCallback(self.openPgp); }); } self.openPgpCallbacks = null; } }); } } else { fCallback(false); } } }; /** * @param {string} sLoading */ CApi.prototype.showLoading = function (sLoading) { App.Screens.showLoading(sLoading); }; CApi.prototype.hideLoading = function () { App.Screens.hideLoading(); }; /** * @param {string} sReport * @param {number=} iDelay */ CApi.prototype.showReport = function (sReport, iDelay) { App.Screens.showReport(sReport, iDelay); }; /** * @param {string} sError * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CApi.prototype.showError = function (sError, bHtml, bNotHide, bGray) { App.Screens.showError(sError, bHtml, bNotHide, bGray); }; /** * @param {boolean=} bGray = false */ CApi.prototype.hideError = function (bGray) { App.Screens.hideError(bGray); }; /** * @param {Object} oRes * @param {string} sPgpAction * @param {string=} sDefaultError */ CApi.prototype.showPgpErrorByCode = function (oRes, sPgpAction, sDefaultError) { var aErrors = Utils.isNonEmptyArray(oRes.errors) ? oRes.errors : [], aNotices = Utils.isNonEmptyArray(oRes.notices) ? oRes.notices : [], aEmailsWithoutPublicKey = [], aEmailsWithoutPrivateKey = [], sError = '', bNoSignDataNotice = false, bNotice = true ; _.each(_.union(aErrors, aNotices), function (aError) { if (aError.length === 2) { switch(aError[0]) { case OpenPgpResult.Enum.GenerateKeyError: sError = Utils.i18n('OPENPGP/ERROR_GENERATE_KEY'); break; case OpenPgpResult.Enum.ImportKeyError: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_KEY'); break; case OpenPgpResult.Enum.ImportNoKeysFoundError: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_FOUNDED'); break; case OpenPgpResult.Enum.PrivateKeyNotFoundError: case OpenPgpResult.Enum.PrivateKeyNotFoundNotice: aEmailsWithoutPrivateKey.push(aError[1]); break; case OpenPgpResult.Enum.PublicKeyNotFoundError: bNotice = false; aEmailsWithoutPublicKey.push(aError[1]); break; case OpenPgpResult.Enum.PublicKeyNotFoundNotice: aEmailsWithoutPublicKey.push(aError[1]); break; case OpenPgpResult.Enum.KeyIsNotDecodedError: if (sPgpAction === Enums.PgpAction.DecryptVerify) { sError = Utils.i18n('OPENPGP/ERROR_DECRYPT') + ' ' + Utils.i18n('OPENPGP/ERROR_KEY_NOT_DECODED', {'USER': aError[1]}); } else if (sPgpAction === Enums.PgpAction.Sign || sPgpAction === Enums.PgpAction.EncryptSign) { sError = Utils.i18n('OPENPGP/ERROR_SIGN') + ' ' + Utils.i18n('OPENPGP/ERROR_KEY_NOT_DECODED', {'USER': aError[1]}); } break; case OpenPgpResult.Enum.SignError: sError = Utils.i18n('OPENPGP/ERROR_SIGN'); break; case OpenPgpResult.Enum.VerifyError: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case OpenPgpResult.Enum.EncryptError: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT'); break; case OpenPgpResult.Enum.DecryptError: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT'); break; case OpenPgpResult.Enum.SignAndEncryptError: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT_OR_SIGN'); break; case OpenPgpResult.Enum.VerifyAndDecryptError: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT_OR_VERIFY'); break; case OpenPgpResult.Enum.DeleteError: sError = Utils.i18n('OPENPGP/ERROR_DELETE_KEY'); break; case OpenPgpResult.Enum.VerifyErrorNotice: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case OpenPgpResult.Enum.NoSignDataNotice: bNoSignDataNotice = true; break; } } }); if (aEmailsWithoutPublicKey.length > 0) { aEmailsWithoutPublicKey = _.without(aEmailsWithoutPublicKey, ''); if (aEmailsWithoutPublicKey.length > 0) { sError = Utils.i18n('OPENPGP/ERROR_NO_PUBLIC_KEYS_FOR_USERS_PLURAL', {'USERS': aEmailsWithoutPublicKey.join(', ')}, null, aEmailsWithoutPublicKey.length); } else if (sPgpAction === Enums.PgpAction.Verify) { sError = Utils.i18n('OPENPGP/ERROR_NO_PUBLIC_KEY_FOUND_FOR_VERIFY'); } if (bNotice && sError !== '') { sError += ' ' + Utils.i18n('OPENPGP/ERROR_MESSAGE_WAS_NOT_VERIFIED'); } } else if (aEmailsWithoutPrivateKey.length > 0) { aEmailsWithoutPrivateKey = _.without(aEmailsWithoutPrivateKey, ''); if (aEmailsWithoutPrivateKey.length > 0) { sError = Utils.i18n('OPENPGP/ERROR_NO_PRIVATE_KEYS_FOR_USERS_PLURAL', {'USERS': aEmailsWithoutPrivateKey.join(', ')}, null, aEmailsWithoutPrivateKey.length); } else if (sPgpAction === Enums.PgpAction.DecryptVerify) { sError = Utils.i18n('OPENPGP/ERROR_NO_PRIVATE_KEY_FOUND_FOR_DECRYPT'); } } if (sError === '' && !bNoSignDataNotice) { switch (sPgpAction) { case Enums.PgpAction.Generate: sError = Utils.i18n('OPENPGP/ERROR_GENERATE_KEY'); break; case Enums.PgpAction.Import: sError = Utils.i18n('OPENPGP/ERROR_IMPORT_KEY'); break; case Enums.PgpAction.DecryptVerify: sError = Utils.i18n('OPENPGP/ERROR_DECRYPT'); break; case Enums.PgpAction.Verify: sError = Utils.i18n('OPENPGP/ERROR_VERIFY'); break; case Enums.PgpAction.Encrypt: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT'); break; case Enums.PgpAction.EncryptSign: sError = Utils.i18n('OPENPGP/ERROR_ENCRYPT_OR_SIGN'); break; case Enums.PgpAction.Sign: sError = Utils.i18n('OPENPGP/ERROR_SIGN'); break; } sError = sDefaultError; } if (sError !== '') { App.Api.showError(sError); } return bNoSignDataNotice; }; /** * @param {Object} oResponse * @param {string=} sDefaultError */ CApi.prototype.showErrorByCode = function (oResponse, sDefaultError) { var iErrorCode = oResponse.ErrorCode, sErrorMessage = oResponse.ErrorMessage || '' ; if (sErrorMessage !== '') { sErrorMessage = ' (' + sErrorMessage + ')'; } switch (iErrorCode) { default: if (sDefaultError && sDefaultError.length > 0) { this.showError(sDefaultError + sErrorMessage); } else if (sErrorMessage !== '') { this.showError(sErrorMessage); } break; case Enums.Errors.AuthError: this.showError(Utils.i18n('WARNING/LOGIN_PASS_INCORRECT') + sErrorMessage); break; case Enums.Errors.DemoLimitations: this.showError(Utils.i18n('DEMO/WARNING_THIS_FEATURE_IS_DISABLED') + sErrorMessage); break; case Enums.Errors.Captcha: this.showError(Utils.i18n('WARNING/CAPTCHA_IS_INCORRECT') + sErrorMessage); break; case Enums.Errors.CanNotGetMessage: this.showError(Utils.i18n('MESSAGE/ERROR_MESSAGE_DELETED') + sErrorMessage); break; case Enums.Errors.NoRequestedMailbox: this.showError(sDefaultError + ' ' + Utils.i18n('COMPOSE/ERROR_INVALID_ADDRESS', {'ADDRESS': oResponse.Mailbox}) + sErrorMessage); break; case Enums.Errors.CanNotChangePassword: this.showError(Utils.i18n('WARNING/UNABLE_CHANGE_PASSWORD') + sErrorMessage); break; case Enums.Errors.AccountOldPasswordNotCorrect: this.showError(Utils.i18n('WARNING/CURRENT_PASSWORD_NOT_CORRECT') + sErrorMessage); break; case Enums.Errors.FetcherIncServerNotAvailable: this.showError(Utils.i18n('WARNING/FETCHER_SAVE_ERROR') + sErrorMessage); break; case Enums.Errors.FetcherLoginNotCorrect: this.showError(Utils.i18n('WARNING/FETCHER_SAVE_ERROR') + sErrorMessage); break; case Enums.Errors.HelpdeskUserNotExists: this.showError(Utils.i18n('HELPDESK/ERROR_FORGOT_NO_ACCOUNT') + sErrorMessage); break; case Enums.Errors.MailServerError: this.showError(Utils.i18n('WARNING/CANT_CONNECT_TO_SERVER') + sErrorMessage); break; case Enums.Errors.DataTransferFailed: this.showError(Utils.i18n('WARNING/DATA_TRANSFER_FAILED') + sErrorMessage); break; case Enums.Errors.NotDisplayedError: if (sErrorMessage !== '') { this.showError(sErrorMessage); } break; } }; /** * @constructor */ function CStorage() { Data.init(); } CStorage.prototype.setData = function (key, value) { Data.setVar(key, value); }; CStorage.prototype.removeData = function (key) { Data.setVar(key, ''); }; CStorage.prototype.getData = function (key) { return Data.getVar(key); }; CStorage.prototype.hasData = function (key) { return Data.hasVar(key); }; /** * @todo * @param {Object} oOpenPgp * @param {string=} sPrefix * @constructor */ function OpenPgp(oOpenPgp, sPrefix) { this.pgp = oOpenPgp; this.pgpKeyring = new this.pgp.Keyring(new this.pgp.Keyring.localstore(sPrefix)); this.keys = ko.observableArray([]); this.reloadKeysFromStorage(); } OpenPgp.prototype.pgp = null; OpenPgp.prototype.pgpKeyring = null; OpenPgp.prototype.keys = []; /** * @return {Array} */ OpenPgp.prototype.getKeys = function () { return this.keys(); }; /** * @return {mixed} */ OpenPgp.prototype.getKeysObservable = function () { return this.keys; }; /** * @private */ OpenPgp.prototype.reloadKeysFromStorage = function () { var aKeys = [], oOpenpgpKeys = this.pgpKeyring.getAllKeys() ; _.each(oOpenpgpKeys, function (oItem) { if (oItem && oItem.primaryKey) { aKeys.push(new OpenPgpKey(oItem)); } }); this.keys(aKeys); }; /** * @private * @param {Array} aKeys * @return {Array} */ OpenPgp.prototype.convertToNativeKeys = function (aKeys) { return _.map(aKeys, function (oItem) { return (oItem && oItem.pgpKey) ? oItem.pgpKey : oItem; }); }; /** * @private */ OpenPgp.prototype.cloneKey = function (oKey) { var oPrivateKey = null; if (oKey) { oPrivateKey = this.pgp.key.readArmored(oKey.armor()); if (oPrivateKey && !oPrivateKey.err && oPrivateKey.keys && oPrivateKey.keys[0]) { oPrivateKey = oPrivateKey.keys[0]; if (!oPrivateKey || !oPrivateKey.primaryKey) { oPrivateKey = null; } } else { oPrivateKey = null; } } return oPrivateKey; }; /** * @private */ OpenPgp.prototype.decryptKeyHelper = function (oResult, oKey, sPassword, sKeyEmail) { if (oKey) { try { oKey.decrypt(Utils.pString(sPassword)); if (!oKey || !oKey.primaryKey || !oKey.primaryKey.isDecrypted) { oResult.addError(OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } } else { oResult.addError(OpenPgpResult.Enum.KeyIsNotDecodedError, sKeyEmail || ''); } }; /** * @private */ OpenPgp.prototype.verifyMessageHelper = function (oResult, sFromEmail, oDecryptedMessage) { var bResult = false, oValidKey = null, aVerifyResult = [], aVerifyKeysId = [], aPublicKeys = [] ; if (oDecryptedMessage && oDecryptedMessage.getSigningKeyIds) { aVerifyKeysId = oDecryptedMessage.getSigningKeyIds(); if (aVerifyKeysId && 0 < aVerifyKeysId.length) { aPublicKeys = this.findKeysByEmails([sFromEmail], true); if (!aPublicKeys || 0 === aPublicKeys.length) { oResult.addNotice(OpenPgpResult.Enum.PublicKeyNotFoundNotice, sFromEmail); } else { aVerifyResult = []; try { aVerifyResult = oDecryptedMessage.verify(this.convertToNativeKeys(aPublicKeys)); } catch (e) { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice, sFromEmail); } if (aVerifyResult && 0 < aVerifyResult.length) { oValidKey = _.find(aVerifyResult, function (oItem) { return oItem && oItem.keyid && oItem.valid; }); if (oValidKey && oValidKey.keyid && aPublicKeys && aPublicKeys[0] && oValidKey.keyid.toHex().toLowerCase() === aPublicKeys[0].getId()) { bResult = true; } else { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice, sFromEmail); } } } } else { oResult.addNotice(OpenPgpResult.Enum.NoSignDataNotice); } } else { oResult.addError(OpenPgpResult.Enum.UnknownError); } if (!bResult && !oResult.hasNotices()) { oResult.addNotice(OpenPgpResult.Enum.VerifyErrorNotice); } // window.console.log(oResult); return bResult; }; /** * @param {string} sUserID * @param {string} sPassword * @param {number} nKeyLength * * @return {OpenPgpResult} */ OpenPgp.prototype.generateKey = function (sUserID, sPassword, nKeyLength) { var oResult = new OpenPgpResult(), mKeyPair = null ; try { // mKeyPair = this.pgp.generateKeyPair(1, Utils.pInt(nKeyLength), sUserID, Utils.trim(sPassword)); mKeyPair = this.pgp.generateKeyPair({ 'userId': sUserID, 'numBits': Utils.pInt(nKeyLength), 'passphrase': Utils.trim(sPassword) }); } catch (e) { oResult.addExceptionMessage(e); } if (mKeyPair && mKeyPair.privateKeyArmored) { try { this.pgpKeyring.privateKeys.importKey(mKeyPair.privateKeyArmored); this.pgpKeyring.publicKeys.importKey(mKeyPair.publicKeyArmored); this.pgpKeyring.store(); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.GenerateKeyError); } } else { oResult.addError(OpenPgpResult.Enum.GenerateKeyError); } this.reloadKeysFromStorage(); return oResult; }; /** * @private * @param {string} sArmor * @return {Array} */ OpenPgp.prototype.splitKeys = function (sArmor) { var aResult = [], iCount = 0, iLimit = 30, aMatch = null, sKey = Utils.trim(sArmor), oReg = /[\-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[\-]{3,6}[\s\S]+?[\-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[\-]{3,6}/gi ; sKey = sKey.replace(/[\r\n]([a-zA-Z0-9]{2,}:[^\r\n]+)[\r\n]+([a-zA-Z0-9\/\\+=]{10,})/g, '\n$1---xyx---$2') .replace(/[\n\r]+/g, '\n').replace(/---xyx---/g, '\n\n'); do { aMatch = oReg.exec(sKey); if (!aMatch || 0 > iLimit) { break; } if (aMatch[0] && aMatch[1] && aMatch[2] && aMatch[1] === aMatch[2]) { if ('PRIVATE' === aMatch[1] || 'PUBLIC' === aMatch[1]) { aResult.push([aMatch[1], aMatch[0]]); iCount++; } } iLimit--; } while (true); return aResult; }; /** * @param {string} sArmor * @return {OpenPgpResult} */ OpenPgp.prototype.importKeys = function (sArmor) { sArmor = Utils.trim(sArmor); var iIndex = 0, iCount = 0, oResult = new OpenPgpResult(), aData = null, aKeys = [] ; if (!sArmor) { return oResult.addError(OpenPgpResult.Enum.InvalidArgumentErrors); } aKeys = this.splitKeys(sArmor); for (iIndex = 0; iIndex < aKeys.length; iIndex++) { aData = aKeys[iIndex]; if ('PRIVATE' === aData[0]) { try { this.pgpKeyring.privateKeys.importKey(aData[1]); iCount++; } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.ImportKeyError, 'private'); } } else if ('PUBLIC' === aData[0]) { try { this.pgpKeyring.publicKeys.importKey(aData[1]); iCount++; } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.ImportKeyError, 'public'); } } } if (0 < iCount) { this.pgpKeyring.store(); } else { oResult.addError(OpenPgpResult.Enum.ImportNoKeysFoundError); } this.reloadKeysFromStorage(); return oResult; }; /** * @param {string} sArmor * @return {Array|boolean} */ OpenPgp.prototype.getArmorInfo = function (sArmor) { sArmor = Utils.trim(sArmor); var iIndex = 0, iCount = 0, oKey = null, aResult = [], aData = null, aKeys = [] ; if (!sArmor) { return false; } aKeys = this.splitKeys(sArmor); for (iIndex = 0; iIndex < aKeys.length; iIndex++) { aData = aKeys[iIndex]; if ('PRIVATE' === aData[0]) { try { oKey = this.pgp.key.readArmored(aData[1]); if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) { aResult.push(new OpenPgpKey(oKey.keys[0])); } iCount++; } catch (e) { aResult.push(null); } } else if ('PUBLIC' === aData[0]) { try { oKey = this.pgp.key.readArmored(aData[1]); if (oKey && !oKey.err && oKey.keys && oKey.keys[0]) { aResult.push(new OpenPgpKey(oKey.keys[0])); } iCount++; } catch (e) { aResult.push(null); } } } return aResult; }; /** * @param {string} sID * @param {boolean} bPublic * @return {OpenPgpKey|null} */ OpenPgp.prototype.findKeyByID = function (sID, bPublic) { bPublic = !!bPublic; sID = sID.toLowerCase(); var oKey = _.find(this.keys(), function (oKey) { var oResult = false, aKeys = null ; if (oKey && bPublic === oKey.isPublic()) { aKeys = oKey.pgpKey.getKeyIds(); if (aKeys) { oResult = _.find(aKeys, function (oKey) { return oKey && oKey.toHex && sID === oKey.toHex().toLowerCase(); }); } } return !!oResult; }); return oKey ? oKey : null; }; /** * @param {Array} aEmail * @param {boolean} bIsPublic * @param {OpenPgpResult=} oResult * @return {Array} */ OpenPgp.prototype.findKeysByEmails = function (aEmail, bIsPublic, oResult) { bIsPublic = !!bIsPublic; var aResult = [], aKeys = this.keys() ; _.each(aEmail, function (sEmail) { var oKey = _.find(aKeys, function (oKey) { return oKey && bIsPublic === oKey.isPublic() && sEmail === oKey.getEmail(); }); if (oKey) { aResult.push(oKey); } else { if (oResult) { oResult.addError(bIsPublic ? OpenPgpResult.Enum.PublicKeyNotFoundError : OpenPgpResult.Enum.PrivateKeyNotFoundError, sEmail); } } }); return aResult; }; /** * @param {string} sData * @param {string} sAccountEmail * @param {string} sFromEmail * @param {string=} sPrivateKeyPassword = '' * @return {string} */ OpenPgp.prototype.decryptAndVerify = function (sData, sAccountEmail, sFromEmail, sPrivateKeyPassword) { var self = this, oMessage = null, oPrivateEmailKey = null, oPrivateKey = null, oPrivateKeyClone = null, oMessageDecrypted = null, oResult = new OpenPgpResult(), aEncryptionKeyIds = [] ; oMessage = this.pgp.message.readArmored(sData); if (oMessage && oMessage.decrypt) { aEncryptionKeyIds = oMessage.getEncryptionKeyIds(); if (aEncryptionKeyIds) { oPrivateKey = null; oPrivateEmailKey = null; _.each(aEncryptionKeyIds, function (oKey) { if (!oPrivateEmailKey) { oPrivateEmailKey = self.findKeyByID(oKey.toHex(), false); if (oPrivateEmailKey && sAccountEmail !== oPrivateEmailKey.getEmail()) { oPrivateEmailKey = null; } } }); if (oPrivateEmailKey) { oPrivateKey = oPrivateEmailKey; } if (!oPrivateKey) { _.each(aEncryptionKeyIds, function (oKey) { if (!oPrivateKey) { oPrivateKey = self.findKeyByID(oKey.toHex(), false); } }); } } if (!oPrivateKey) { oResult.addError(OpenPgpResult.Enum.PrivateKeyNotFoundError); } else { oPrivateKeyClone = this.cloneKey(this.convertToNativeKeys([oPrivateKey])[0]); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, oPrivateKey.getEmail()); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oMessageDecrypted = oMessage.decrypt(oPrivateKeyClone); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.DecryptError); oMessageDecrypted = null; } } if (oMessageDecrypted && !oResult.hasErrors()) { this.verifyMessageHelper(oResult, sFromEmail, oMessageDecrypted); oResult.result = oMessageDecrypted.getText(); } } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @return {string} */ OpenPgp.prototype.verify = function (sData, sFromEmail) { var oMessageDecrypted = null, oResult = new OpenPgpResult() ; oMessageDecrypted = this.pgp.cleartext.readArmored(sData); if (oMessageDecrypted && oMessageDecrypted.getText && oMessageDecrypted.verify) { this.verifyMessageHelper(oResult, sFromEmail, oMessageDecrypted); oResult.result = oMessageDecrypted.getText(); } else { oResult.addError(OpenPgpResult.Enum.CanNotReadMessage); } return oResult; }; /** * @param {string} sData * @param {Array} aPrincipalsEmail * @return {string} */ OpenPgp.prototype.encrypt = function (sData, aPrincipalsEmail) { var oResult = new OpenPgpResult(), aPublicKeys = this.findKeysByEmails(aPrincipalsEmail, true, oResult) ; if (!oResult.hasErrors()) { try { oResult.result = this.pgp.encryptMessage( this.convertToNativeKeys(aPublicKeys), sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.EncryptError); } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @param {string=} sPrivateKeyPassword * @return {string} */ OpenPgp.prototype.sign = function (sData, sFromEmail, sPrivateKeyPassword) { var oResult = new OpenPgpResult(), oPrivateKey = null, oPrivateKeyClone = null, aPrivateKeys = this.findKeysByEmails([sFromEmail], false, oResult) ; if (!oResult.hasErrors()) { oPrivateKey = this.convertToNativeKeys(aPrivateKeys)[0]; oPrivateKeyClone = this.cloneKey(oPrivateKey); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, sFromEmail); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oResult.result = this.pgp.signClearMessage([oPrivateKeyClone], sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.SignError, sFromEmail); } } } return oResult; }; /** * @param {string} sData * @param {string} sFromEmail * @param {Array} aPrincipalsEmail * @param {string=} sPrivateKeyPassword * @return {string} */ OpenPgp.prototype.signAndEncrypt = function (sData, sFromEmail, aPrincipalsEmail, sPrivateKeyPassword) { var oPrivateKey = null, oPrivateKeyClone = null, oResult = new OpenPgpResult(), aPrivateKeys = this.findKeysByEmails([sFromEmail], false, oResult), aPublicKeys = this.findKeysByEmails(aPrincipalsEmail, true, oResult) ; if (!oResult.hasErrors()) { oPrivateKey = this.convertToNativeKeys(aPrivateKeys)[0]; oPrivateKeyClone = this.cloneKey(oPrivateKey); this.decryptKeyHelper(oResult, oPrivateKeyClone, sPrivateKeyPassword, sFromEmail); if (oPrivateKeyClone && !oResult.hasErrors()) { try { oResult.result = this.pgp.signAndEncryptMessage( this.convertToNativeKeys(aPublicKeys), oPrivateKeyClone, sData); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.SignAndEncryptError); } } } return oResult; }; /** * @param {OpenPgpKey} oKey */ OpenPgp.prototype.deleteKey = function (oKey) { var oResult = new OpenPgpResult(); if (oKey) { try { this.pgpKeyring[oKey.isPrivate() ? 'privateKeys' : 'publicKeys'].removeForId(oKey.getFingerprint()); this.pgpKeyring.store(); } catch (e) { oResult.addExceptionMessage(e, OpenPgpResult.Enum.DeleteError); } } else { oResult.addError(oKey ? OpenPgpResult.Enum.UnknownError : OpenPgpResult.Enum.InvalidArgumentError); } this.reloadKeysFromStorage(); return oResult; }; /** * @todo * @param {Object} oOpenPgpKey * @constructor */ function OpenPgpKey(oOpenPgpKey) { this.pgpKey = oOpenPgpKey; var oPrimaryUser = this.pgpKey.getPrimaryUser(); this.user = (oPrimaryUser && oPrimaryUser.user) ? oPrimaryUser.user.userId.userid : (this.pgpKey.users && this.pgpKey.users[0] ? this.pgpKey.users[0].userId.userid : ''); this.emailParts = Utils.getEmailParts(this.user); } /** * @type {Object} */ OpenPgpKey.prototype.pgpKey = null; /** * @type {Object} */ OpenPgpKey.prototype.emailParts = null; /** * @type {string} */ OpenPgpKey.prototype.user = ''; /** * @return {string} */ OpenPgpKey.prototype.getId = function () { return this.pgpKey.primaryKey.getKeyId().toHex().toLowerCase(); }; /** * @return {string} */ OpenPgpKey.prototype.getEmail = function () { return this.emailParts['email'] || this.user; }; /** * @return {string} */ OpenPgpKey.prototype.getUser = function () { return this.user; }; /** * @return {string} */ OpenPgpKey.prototype.getFingerprint = function () { return this.pgpKey.primaryKey.getFingerprint(); }; /** * @return {number} */ OpenPgpKey.prototype.getBitSize = function () { return this.pgpKey.primaryKey.getBitSize(); }; /** * @return {string} */ OpenPgpKey.prototype.getArmor = function () { return this.pgpKey.armor(); }; /** * @return {boolean} */ OpenPgpKey.prototype.isPrivate = function () { return !!this.pgpKey.isPrivate(); }; /** * @return {boolean} */ OpenPgpKey.prototype.isPublic = function () { return !this.isPrivate(); }; /** * @todo * @constructor */ function OpenPgpResult() { this.result = true; this.errors = null; this.notices = null; this.exceptions = null; } OpenPgpResult.Enum = { 'UnknownError': 0, 'UnknownNotice': 1, 'InvalidArgumentError': 2, 'GenerateKeyError': 10, 'ImportKeyError': 20, 'ImportNoKeysFoundError': 21, 'PrivateKeyNotFoundError': 30, 'PublicKeyNotFoundError': 31, 'KeyIsNotDecodedError': 32, 'SignError': 40, 'VerifyError': 41, 'EncryptError': 42, 'DecryptError': 43, 'SignAndEncryptError': 44, 'VerifyAndDecryptError': 45, 'CanNotReadMessage': 50, 'CanNotReadKey': 51, 'DeleteError': 60, 'PublicKeyNotFoundNotice': 70, 'PrivateKeyNotFoundNotice': 71, 'VerifyErrorNotice': 72, 'NoSignDataNotice': 73 }; /** * @type {mixed} */ OpenPgpResult.prototype.result = false; /** * @type {Array|null} */ OpenPgpResult.prototype.errors = null; /** * @type {Array|null} */ OpenPgpResult.prototype.notices = null; /** * @param {number} iCode * @param {string} sValue * @return {OpenPgpResult} */ OpenPgpResult.prototype.addError = function (iCode, sValue) { this.result = false; this.errors = this.errors || []; this.errors.push([iCode || OpenPgpResult.Enum.UnknownError, sValue || '']); return this; }; /** * @param {number} iCode * @param {string} sValue * @return {OpenPgpResult} */ OpenPgpResult.prototype.addNotice = function (iCode, sValue) { this.notices = this.notices || []; this.notices.push([iCode || OpenPgpResult.Enum.UnknownNotice, sValue || '']); return this; }; /** * @param {Error} e * @param {number=} iErrorCode * @param {string=} sErrorMessage * @return {OpenPgpResult} */ OpenPgpResult.prototype.addExceptionMessage = function (e, iErrorCode, sErrorMessage) { if (e) { this.result = false; this.exceptions = this.exceptions || []; this.exceptions.push('' + (e.name || 'unknown') + ': ' + (e.message || '')); } if (!Utils.isUnd(iErrorCode)) { this.addError(iErrorCode, sErrorMessage); } return this; }; /** * @return {boolean} */ OpenPgpResult.prototype.hasErrors = function () { return this.errors && 0 < this.errors.length; }; /** * @return {boolean} */ OpenPgpResult.prototype.hasNotices = function () { return this.notices && 0 < this.notices.length; }; /** * @constructor */ function AlertPopup() { this.alertDesc = ko.observable(''); this.closeCallback = null; this.title = ko.observable(''); this.okButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_OK')); } /** * @param {string} sDesc * @param {Function=} fCloseCallback = null * @param {string=} sTitle = '' * @param {string=} sOkButtonText = 'Ok' */ AlertPopup.prototype.onShow = function (sDesc, fCloseCallback, sTitle, sOkButtonText) { this.alertDesc(sDesc); this.closeCallback = fCloseCallback || null; this.title(sTitle || ''); this.okButtonText(sOkButtonText || Utils.i18n('MAIN/BUTTON_OK')); }; /** * @return {string} */ AlertPopup.prototype.popupTemplate = function () { return 'Popups_AlertPopupViewModel'; }; AlertPopup.prototype.onEnterHandler = function () { this.close(); }; AlertPopup.prototype.close = function () { if (Utils.isFunc(this.closeCallback)) { this.closeCallback(); } this.closeCommand(); }; /** * @constructor */ function ConfirmPopup() { this.fConfirmCallback = null; this.confirmDesc = ko.observable(''); this.title = ko.observable(''); this.okButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_OK')); this.cancelButtonText = ko.observable(Utils.i18n('MAIN/BUTTON_CANCEL')); this.shown = false; } /** * @param {string} sDesc * @param {Function} fConfirmCallback * @param {string=} sTitle = '' * @param {string=} sOkButtonText = '' * @param {string=} sCancelButtonText = '' */ ConfirmPopup.prototype.onShow = function (sDesc, fConfirmCallback, sTitle, sOkButtonText, sCancelButtonText) { this.title(sTitle || ''); this.okButtonText(sOkButtonText || Utils.i18n('MAIN/BUTTON_OK')); this.cancelButtonText(sCancelButtonText || Utils.i18n('MAIN/BUTTON_CANCEL')); if (Utils.isFunc(fConfirmCallback)) { this.fConfirmCallback = fConfirmCallback; this.confirmDesc(sDesc); } this.shown = true; }; ConfirmPopup.prototype.onHide = function () { this.shown = false; }; /** * @return {string} */ ConfirmPopup.prototype.popupTemplate = function () { return 'Popups_ConfirmPopupViewModel'; }; ConfirmPopup.prototype.onEnterHandler = function () { this.yesClick(); }; ConfirmPopup.prototype.yesClick = function () { if (this.shown && this.fConfirmCallback) { this.fConfirmCallback(true); } this.closeCommand(); }; ConfirmPopup.prototype.noClick = function () { if (this.fConfirmCallback) { this.fConfirmCallback(false); } this.closeCommand(); }; ConfirmPopup.prototype.onEscHandler = function () { this.noClick(); }; /** * @constructor */ function CImportOpenPgpKeyPopup() { this.pgp = null; this.keyArmor = ko.observable(''); this.keyArmorFocused = ko.observable(false); this.keys = ko.observableArray([]); this.hasExistingKeys = ko.observable(false); this.headlineText = ko.computed(function () { return Utils.i18n('OPENPGP/INFO_TEXT_INCLUDES_KEYS_PLURAL', {}, null, this.keys().length); }, this); } /** * @param {Object} oPgp */ CImportOpenPgpKeyPopup.prototype.onShow = function (oPgp, sArmor) { this.pgp = oPgp; this.keyArmor(sArmor || ''); this.keyArmorFocused(true); this.keys([]); this.hasExistingKeys(false); if (this.keyArmor() !== '') { this.checkArmor(); } }; /** * @return {string} */ CImportOpenPgpKeyPopup.prototype.popupTemplate = function () { return 'Popups_ImportOpenPgpKeyPopupViewModel'; }; CImportOpenPgpKeyPopup.prototype.checkArmor = function () { var aRes = null, aKeys = [], oPgp = this.pgp, bHasExistingKeys = false ; if (this.keyArmor() === '') { this.keyArmorFocused(true); } else if (oPgp) { aRes = oPgp.getArmorInfo(this.keyArmor()); if (Utils.isNonEmptyArray(aRes)) { _.each(aRes, function (oKey) { if (oKey) { var oSameKey = oPgp.findKeyByID(oKey.getId(), oKey.isPublic()), bHasSameKey = (oSameKey !== null), sAddInfoLangKey = oKey.isPublic() ? 'OPENPGP/PUBLIC_KEY_ADD_INFO' : 'OPENPGP/PRIVATE_KEY_ADD_INFO' ; bHasExistingKeys = bHasExistingKeys || bHasSameKey; aKeys.push({ 'armor': oKey.getArmor(), 'email': oKey.user, 'id': oKey.getId(), 'addInfo': Utils.i18n(sAddInfoLangKey, {'LENGTH': oKey.getBitSize()}), 'needToImport': ko.observable(!bHasSameKey), 'disabled': bHasSameKey }); } }); } if (aKeys.length === 0) { App.Api.showError(Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_FOUNDED')); } this.keys(aKeys); this.hasExistingKeys(bHasExistingKeys); } }; CImportOpenPgpKeyPopup.prototype.importKey = function () { var oRes = null, aArmors = [] ; if (this.pgp) { _.each(this.keys(), function (oSimpleKey) { if (oSimpleKey.needToImport()) { aArmors.push(oSimpleKey.armor); } }); if (aArmors.length > 0) { oRes = this.pgp.importKeys(aArmors.join('')); if (oRes && oRes.result) { App.Api.showReport(Utils.i18n('OPENPGP/REPORT_KEY_SUCCESSFULLY_IMPORTED_PLURAL', {}, null, aArmors.length)); } if (oRes && !oRes.result) { App.Api.showPgpErrorByCode(oRes, Enums.PgpAction.Import, Utils.i18n('OPENPGP/ERROR_IMPORT_KEY')); } this.closeCommand(); } else { App.Api.showError(Utils.i18n('OPENPGP/ERROR_IMPORT_NO_KEY_SELECTED')); } } }; /** * @constructor */ function FileStorageFolderCreatePopup() { this.fCallback = null; this.folderName = ko.observable(''); this.folderName.focus = ko.observable(false); this.folderName.error = ko.observable(''); this.folderName.subscribe(function () { this.folderName.error(''); }, this); } /** * @param {Function} fCallback */ FileStorageFolderCreatePopup.prototype.onShow = function (fCallback) { this.folderName(''); this.folderName.focus(true); this.folderName.error(''); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } }; /** * @return {string} */ FileStorageFolderCreatePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_FolderCreatePopupViewModel'; }; FileStorageFolderCreatePopup.prototype.onOKClick = function () { this.folderName.error(''); if (this.fCallback) { var sError = this.fCallback(this.folderName()); if (sError) { this.folderName.error('' + sError); } else { this.closeCommand(); } } else { this.closeCommand(); } }; FileStorageFolderCreatePopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function FileStorageLinkCreatePopup() { this.fCallback = null; this.link = ko.observable(''); this.linkPrev = ko.observable(''); this.linkFocus = ko.observable(false); this.checkTimeout = null; this.urlChecked = ko.observable(false); this.saveCommand = Utils.createCommand(this, this.executeSave, function () { return (this.urlChecked()); }); this.fileItem = ko.observable(new CCommonFileModel()); } /** * @param {Function} fCallback */ FileStorageLinkCreatePopup.prototype.onShow = function (fCallback) { this.link(''); this.linkFocus(true); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } this.checkTimer = setTimeout(_.bind(this.checkUrl, this), 2000); }; /** * @return {string} */ FileStorageLinkCreatePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_LinkCreatePopupViewModel'; }; FileStorageLinkCreatePopup.prototype.checkUrl = function () { clearTimeout(this.checkTimer); if (this.link() !== this.linkPrev()) { this.linkPrev(this.link()); App.Ajax.send({ 'Action': 'CheckUrl', 'Url': this.link() }, this.onCheckUrlResponse, this ); } this.checkTimer = setTimeout(_.bind(this.checkUrl, this), 1000); }; FileStorageLinkCreatePopup.prototype.onCheckUrlResponse = function (oData) { var fileItem = new CCommonFileModel(); if (oData.Result) { fileItem.isPopupItem(true); fileItem.linkUrl(this.link()); fileItem.fileName(oData.Result.Name); fileItem.size(oData.Result.Size); fileItem.allowDownload(false); if (oData.Result.Thumb) { fileItem.thumb(true); fileItem.thumbnailSrc(oData.Result.Thumb); } this.fileItem(fileItem); this.urlChecked(true); } else { this.urlChecked(false); } }; FileStorageLinkCreatePopup.prototype.executeSave = function () { if (this.fCallback) { this.fCallback(this.fileItem()); this.link(''); this.linkPrev(''); this.urlChecked(false); } clearTimeout(this.checkTimer); this.closeCommand(); }; FileStorageLinkCreatePopup.prototype.onCancelClick = function () { this.link(''); this.linkPrev(''); this.urlChecked(false); clearTimeout(this.checkTimer); this.closeCommand(); }; FileStorageLinkCreatePopup.prototype.onEscHandler = function () { this.onCancelClick(); }; /** * @constructor */ function FileStorageRenamePopup() { this.fCallback = null; this.item = null; this.name = ko.observable(''); this.name.focus = ko.observable(false); this.name.error = ko.observable(''); this.name.subscribe(function () { this.name.error(''); }, this); } /** * @param {Object} oItem * @param {Function} fCallback */ FileStorageRenamePopup.prototype.onShow = function (oItem, fCallback) { this.item = oItem; this.item.nameForEdit(this.item.fileName()); this.name(this.item.nameForEdit()); this.name.focus(true); this.name.error(''); if (Utils.isFunc(fCallback)) { this.fCallback = fCallback; } }; /** * @return {string} */ FileStorageRenamePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_RenamePopupViewModel'; }; FileStorageRenamePopup.prototype.onOKClick = function () { this.name.error(''); if (this.fCallback) { this.item.nameForEdit(this.name()); var sError = this.fCallback(this.item); if (sError) { this.name.error('' + sError); } else { this.closeCommand(); } } else { this.closeCommand(); } }; /** * */ FileStorageRenamePopup.prototype.onCancelClick = function () { this.closeCommand(); }; /** * @constructor */ function FileStorageSharePopup() { this.item = null; this.pub = ko.observable(''); this.pubFocus = ko.observable(false); } /** * @param {Object} oItem */ FileStorageSharePopup.prototype.onShow = function (oItem) { this.item = oItem; this.pub(''); App.Ajax.send({ 'Action': 'FilesCreatePublicLink', 'Account': AppData.Accounts.defaultId(), 'Type': oItem.storageType(), 'Path': oItem.path(), 'Name': oItem.fileName(), 'Size': oItem.size(), 'IsFolder': oItem.isFolder() ? '1' : '0' }, this.onFilesCreatePublicLinkResponse, this ); }; /** * @param {Object} oData * @param {Object} oParameters */ FileStorageSharePopup.prototype.onFilesCreatePublicLinkResponse = function (oData, oParameters) { if (oData.Result) { this.pub(oData.Result); this.pubFocus(true); this.item.shared(true); } }; /** * @return {string} */ FileStorageSharePopup.prototype.popupTemplate = function () { return 'Popups_FileStorage_SharePopupViewModel'; }; FileStorageSharePopup.prototype.onOKClick = function () { this.closeCommand(); }; /** * @param {Object} oData * @param {Object} oParameters */ FileStorageSharePopup.prototype.onFilesDeletePublicLinkResponse = function (oData, oParameters) { this.closeCommand(); }; FileStorageSharePopup.prototype.onCancelSharingClick = function () { if (this.item) { App.Ajax.send({ 'Action': 'FilesDeletePublicLink', 'Account': AppData.Accounts.defaultId(), 'Type': this.item.storageType(), 'Path': this.item.path(), 'Name': this.item.fileName() }, this.onFilesDeletePublicLinkResponse, this); this.item.shared(false); } }; /** * @constructor */ function CUserSettingsModel() { this.IdUser = 1; // general settings that can be changed in the settings screen this.MailsPerPage = 20; this.ContactsPerPage = 20; this.iInterval = -1; this.AutoCheckMailInterval = 0; this.DefaultTheme = 'Default'; this.DefaultLanguage = 'English'; this.DefaultLanguageShort = 'en'; this.DefaultDateFormat = 'MM/DD/YYYY'; this.defaultTimeFormat = ko.observable(Enums.TimeFormat.F24); this.ThreadsEnabled = true; this.useThreads = ko.observable(true); this.SaveRepliedToCurrFolder = true; this.AllowChangeInputDirection = false; this.DesktopNotifications = false; // allows the creation of messages this.AllowCompose = true; this.AllowReply = true; this.AllowForward = true; this.SaveMail = Enums.SaveMail.Checked; this.AllowFetcher = false; this.OutlookSyncEnable = true; this.MobileSyncEnable = true; this.ShowPersonalContacts = true; this.ShowGlobalContacts = false; this.IsFilesSupported = false; this.IsHelpdeskSupported = false; this.IsHelpdeskAgent = false; this.HelpdeskIframeUrl = ''; // allows to go to contacts screen and edit their settings this.ShowContacts = this.ShowPersonalContacts || this.ShowGlobalContacts; this.LastLogin = 0; this.IsDemo = false; this.AllowVoice = false; this.SipRealm = ''; this.SipWebsocketProxyUrl = ''; this.SipOutboundProxyUrl = ''; this.SipCallerID = ''; this.SipImpi = ''; this.SipImpu = ''; this.SipPassword = ''; this.VoiceProvider = ''; // this.VoiceAccountSID = ''; // this.VoiceAuthToken = ''; // this.VoiceAppSID = ''; // allows to go to calendar screen and edit its settings this.AllowCalendar = true; this.CalendarSharing = false; this.CalendarAppointments = false; // calendar settings that can be changed in the settings screen this.CalendarShowWeekEnds = false; this.CalendarShowWorkDay = false; this.CalendarWorkDayStarts = 0; this.CalendarWorkDayEnds = 0; this.CalendarWeekStartsOn = 0; this.CalendarDefaultTab = Enums.CalendarDefaultTab.Month; this.mobileSync = ko.observable(null); this.MobileSyncDemoPass = 'demo'; this.outlookSync = ko.observable(null); this.OutlookSyncDemoPass = 'demo'; this.AllowHelpdeskNotifications = false; this.IsCollaborationSupported = false; this.AllowFilesSharing = false; this.DefaultFontName = 'Tahoma'; this.fillDefaultFontName(); this.DefaultFontSize = 3; this.fillDefaultFontSize(); this.enableOpenPgp = ko.observable(false); this.AllowAutosaveInDrafts = true; this.AutosignOutgoingEmails = false; this.filesEnable = ko.observable(true); this.SocialAccounts = ko.observableArray([]); } CUserSettingsModel.prototype.fillDefaultFontName = function () { var sDefaultFontName = Utils.pString(AppData.HtmlEditorDefaultFontName); if (sDefaultFontName !== '') { this.DefaultFontName = sDefaultFontName; } }; CUserSettingsModel.prototype.fillDefaultFontSize = function () { var iDefaultFontSize = Utils.pInt(AppData.HtmlEditorDefaultFontSize); if (Utils.inArray(iDefaultFontSize, [2, 3, 5, 7]) !== -1) { this.DefaultFontSize = iDefaultFontSize; } }; /** * @return {boolean} */ CUserSettingsModel.prototype.getSaveMailInSentItems = function () { var bSaveMailInSentItems = true; switch (this.SaveMail) { case Enums.SaveMail.Unchecked: bSaveMailInSentItems = false; break; case Enums.SaveMail.Checked: case Enums.SaveMail.Hidden: bSaveMailInSentItems = true; break; } return bSaveMailInSentItems; }; /** * @return {boolean} */ CUserSettingsModel.prototype.getUseSaveMailInSentItems = function () { var bUseSaveMailInSentItems = false; switch (this.SaveMail) { case Enums.SaveMail.Unchecked: case Enums.SaveMail.Checked: bUseSaveMailInSentItems = true; break; case Enums.SaveMail.Hidden: bUseSaveMailInSentItems = false; break; } return bUseSaveMailInSentItems; }; /** * @param {AjaxUserSettingsResponse} oData */ CUserSettingsModel.prototype.parse = function (oData) { var oCalendar = null; if (oData !== null) { this.IdUser = Utils.pInt(oData.IdUser); this.MailsPerPage = Utils.pInt(oData.MailsPerPage); this.ContactsPerPage = Utils.pInt(oData.ContactsPerPage); this.AutoCheckMailInterval = Utils.pInt(oData.AutoCheckMailInterval); this.DefaultTheme = Utils.pString(oData.DefaultTheme); this.DefaultLanguage = Utils.pString(oData.DefaultLanguage); this.DefaultLanguageShort = Utils.pString(oData.DefaultLanguageShort); this.DefaultDateFormat = Utils.pString(oData.DefaultDateFormat); this.defaultTimeFormat(Utils.pString(oData.DefaultTimeFormat)); this.ThreadsEnabled = !!oData.ThreadsEnabled; this.useThreads(!!oData.UseThreads); this.SaveRepliedToCurrFolder = !!oData.SaveRepliedMessagesToCurrentFolder; this.DesktopNotifications = !!oData.DesktopNotifications; this.AllowChangeInputDirection = !!oData.AllowChangeInputDirection; this.AllowCompose = !!oData.AllowCompose; this.AllowReply = !!oData.AllowReply; this.AllowForward = !!oData.AllowForward; this.SaveMail = Utils.pInt(oData.SaveMail); this.AllowFetcher = !!oData.AllowFetcher; this.OutlookSyncEnable = !!oData.OutlookSyncEnable; this.MobileSyncEnable = !!oData.MobileSyncEnable; this.ShowPersonalContacts = !!oData.ShowPersonalContacts; this.ShowGlobalContacts = !!oData.ShowGlobalContacts; this.ShowContacts = this.ShowPersonalContacts || this.ShowGlobalContacts; this.IsFilesSupported = !!oData.IsFilesSupported && !bMobileApp; this.IsFilesSupported = !!oData.IsFilesSupported && !bMobileApp; this.filesEnable(!!oData.FilesEnable && !bMobileApp); this.IsHelpdeskSupported = !!oData.IsHelpdeskSupported && !bMobileApp; this.IsHelpdeskAgent = !!oData.IsHelpdeskAgent; this.LastLogin = Utils.pInt(oData.LastLogin); this.AllowCalendar = !!oData.AllowCalendar && !bMobileApp; this.CalendarSharing = !!oData.CalendarSharing; this.CalendarAppointments = !!oData.CalendarAppointments; this.IsDemo = !!oData.IsDemo; this.AllowVoice = !!oData.AllowVoice; this.SipRealm = oData.SipRealm; this.SipWebsocketProxyUrl = oData.SipWebsocketProxyUrl; this.SipOutboundProxyUrl = oData.SipOutboundProxyUrl; this.SipCallerID = oData.SipCallerID; this.SipImpi = oData.SipImpi; this.SipImpu = oData.SipImpu; this.SipPassword = oData.SipPassword; this.VoiceProvider = oData.VoiceProvider; // this.VoiceAccountSID = oData.VoiceRealm; // this.VoiceAuthToken = oData.VoiceAuthToken; // this.VoiceAppSID = oData.VoiceAppSID; this.AllowHelpdeskNotifications = oData.AllowHelpdeskNotifications; this.IsCollaborationSupported = !!oData.IsCollaborationSupported; this.AllowFilesSharing = !!oData.AllowFilesSharing; this.enableOpenPgp(!!oData.EnableOpenPgp); this.AllowAutosaveInDrafts = !!oData.AllowAutosaveInDrafts && (AppData.App ? AppData.App.AutoSave : false); // this.AutosignOutgoingEmails = !!oData.AutosignOutgoingEmails; oCalendar = oData.Calendar; if (oCalendar) { this.CalendarShowWeekEnds = !!oCalendar.ShowWeekEnds; this.CalendarShowWorkDay = !!oCalendar.ShowWorkDay; this.CalendarWorkDayStarts = Utils.pInt(oCalendar.WorkDayStarts); this.CalendarWorkDayEnds = Utils.pInt(oCalendar.WorkDayEnds); this.CalendarWeekStartsOn = Utils.pInt(oCalendar.WeekStartsOn); this.CalendarDefaultTab = Utils.pInt(oCalendar.DefaultTab); } this.SocialAccounts(oData.SocialAccounts); } }; /** * @param {number} iMailsPerPage * @param {number} iContactsPerPage * @param {number} iAutoCheckMailInterval * @param {string} sDefaultTheme * @param {string} sDefaultLanguage * @param {string} sDefaultDateFormat * @param {string} sDefaultTimeFormat * @param {string} sUseThreads * @param {string} sSaveRepliedToCurrFolder * @param {string} sDesktopNotifications * @param {string} sAllowChangeInputDirection */ CUserSettingsModel.prototype.updateCommonSettings = function (iMailsPerPage, iContactsPerPage, iAutoCheckMailInterval, sDefaultTheme, sDefaultLanguage, sDefaultDateFormat, sDefaultTimeFormat, sUseThreads, sSaveRepliedToCurrFolder, sDesktopNotifications, sAllowChangeInputDirection) { var bNeedToUpdateMessageDates = this.defaultTimeFormat() !== sDefaultTimeFormat; this.MailsPerPage = iMailsPerPage; this.ContactsPerPage = iContactsPerPage; this.AutoCheckMailInterval = iAutoCheckMailInterval; App.MailCache.setAutocheckmailTimer(); this.DefaultTheme = sDefaultTheme; this.DefaultLanguage = sDefaultLanguage; this.DefaultDateFormat = sDefaultDateFormat; this.defaultTimeFormat(sDefaultTimeFormat); this.useThreads('1' === sUseThreads); this.SaveRepliedToCurrFolder = '1' === sSaveRepliedToCurrFolder; this.AllowChangeInputDirection = '1' === sAllowChangeInputDirection; this.DesktopNotifications = '1' === sDesktopNotifications; if (bNeedToUpdateMessageDates) { App.nowMoment.valueHasMutated(); } }; /** * @param {string} sEnableOpenPgp * @param {string} sAllowAutosaveInDrafts * @param {string} sAutosignOutgoingEmails */ CUserSettingsModel.prototype.updateOpenPgpSettings = function (sEnableOpenPgp, sAllowAutosaveInDrafts, sAutosignOutgoingEmails) { this.enableOpenPgp('1' === sEnableOpenPgp); this.AllowAutosaveInDrafts = '1' === sAllowAutosaveInDrafts; // this.AutosignOutgoingEmails = '1' === sAutosignOutgoingEmails; }; /** * @param {boolean} bShowWeekEnds * @param {boolean} bShowWorkDay * @param {number} iWorkDayStarts * @param {number} iWorkDayEnds * @param {number} iWeekStartsOn * @param {number} iDefaultTab */ CUserSettingsModel.prototype.updateCalendarSettings = function (bShowWeekEnds, bShowWorkDay, iWorkDayStarts, iWorkDayEnds, iWeekStartsOn, iDefaultTab) { this.CalendarShowWeekEnds = bShowWeekEnds; this.CalendarShowWorkDay = bShowWorkDay; this.CalendarWorkDayStarts = iWorkDayStarts; this.CalendarWorkDayEnds = iWorkDayEnds; this.CalendarWeekStartsOn = iWeekStartsOn; this.CalendarDefaultTab = iDefaultTab; }; /** * @param {boolean} bAllowHelpdeskNotifications */ CUserSettingsModel.prototype.updateHelpdeskSettings = function (bAllowHelpdeskNotifications) { this.AllowHelpdeskNotifications = bAllowHelpdeskNotifications; }; /** * @param {Object} oResponse * @param {Object} oRequest */ CUserSettingsModel.prototype.onSyncSettingsResponse = function (oResponse, oRequest) { if (oResponse.Result) { this.mobileSync(oResponse.Result.Mobile); this.outlookSync(oResponse.Result.Outlook); } else { App.Api.showErrorByCode(oResponse); } }; CUserSettingsModel.prototype.requestSyncSettings = function () { if (this.mobileSync() === null || this.outlookSync() === null) { App.Ajax.send({'Action': 'SyncSettings'}, this.onSyncSettingsResponse, this); } }; /** * @constructor */ function CDateModel() { this.iTimeStampInUTC = 0; this.oMoment = null; } /** * @param {number} iTimeStampInUTC */ CDateModel.prototype.parse = function (iTimeStampInUTC) { this.iTimeStampInUTC = iTimeStampInUTC; this.oMoment = moment.unix(this.iTimeStampInUTC); }; /** * @param {number} iYear * @param {number} iMonth * @param {number} iDay */ CDateModel.prototype.setDate = function (iYear, iMonth, iDay) { this.oMoment = moment([iYear, iMonth, iDay]); }; /** * @return {string} */ CDateModel.prototype.getTimeFormat = function () { return (AppData.User.defaultTimeFormat() === Enums.TimeFormat.F24) ? 'HH:mm' : 'hh:mm A'; }; /** * @return {string} */ CDateModel.prototype.getFullDate = function () { return (this.oMoment) ? this.oMoment.format('ddd, MMM D, YYYY, ' + this.getTimeFormat()) : ''; }; /** * @return {string} */ CDateModel.prototype.getMidDate = function () { return this.getShortDate(true); }; /** * @param {boolean=} bTime = false * * @return {string} */ CDateModel.prototype.getShortDate = function (bTime) { var sResult = '', oMomentNow = null ; if (this.oMoment) { oMomentNow = moment(); if (oMomentNow.format('L') === this.oMoment.format('L')) { sResult = this.oMoment.format(this.getTimeFormat()); } else { if (oMomentNow.clone().subtract('days', 1).format('L') === this.oMoment.format('L')) { sResult = Utils.i18n('DATETIME/YESTERDAY'); } else if (oMomentNow.year() === this.oMoment.year()) { sResult = this.oMoment.format('MMM D'); } else { sResult = this.oMoment.format('MMM D, YYYY'); } if (Utils.isUnd(bTime) ? false : !!bTime) { sResult += ', ' + this.oMoment.format(this.getTimeFormat()); } } } return sResult; }; /** * @return {string} */ CDateModel.prototype.getDate = function () { return (this.oMoment) ? this.oMoment.format('ddd, MMM D, YYYY') : ''; }; /** * @return {string} */ CDateModel.prototype.getTime = function () { return (this.oMoment) ? this.oMoment.format(this.getTimeFormat()): ''; }; /** * @param {string} iDate * * @return {string} */ CDateModel.prototype.convertDate = function (iDate) { var sFormat = Utils.getDateFormatForMoment(AppData.User.DefaultDateFormat) + ' ' + this.getTimeFormat(); return moment(iDate * 1000).format(sFormat); }; /** * @return {number} */ CDateModel.prototype.getTimeStampInUTC = function () { return this.iTimeStampInUTC; }; /** * @constructor */ function CCommonFileModel() { this.isIosDevice = bIsIosDevice; this.isFolder = ko.observable(false); this.isLink = ko.observable(false); this.linkType = ko.observable(Enums.FileStorageLinkType.Unknown); this.linkUrl = ko.observable(''); this.isPopupItem = ko.observable(false); this.id = ko.observable(''); this.fileName = ko.observable(''); this.tempName = ko.observable(''); this.displayName = ko.observable(''); this.extension = ko.observable(''); this.fileName.subscribe(function () { var sName = this.fileName(), iDotPos = sName.lastIndexOf('.') ; this.id(sName); if (!this.isFolder()) { this.displayName(sName.substr(0, iDotPos)); this.extension(sName.substr(iDotPos + 1)); } else { this.displayName(sName); this.extension(''); } }, this); this.size = ko.observable(0); this.friendlySize = ko.computed(function () { return Utils.friendlySize(this.size()); }, this); this.content = ko.observable(''); this.accountId = ko.observable((AppData.Accounts) ? AppData.Accounts.defaultId() : null); this.hash = ko.observable(''); this.thumb = ko.observable(false); this.iframedView = ko.observable(false); this.downloadLink = ko.computed(function () { return Utils.getDownloadLinkByHash(this.accountId(), this.hash()); }, this); this.viewLink = ko.computed(function () { var sUrl = Utils.getViewLinkByHash(this.accountId(), this.hash()); return this.iframedView() ? Utils.getIframeWrappwer(this.accountId(), sUrl) : sUrl; }, this); this.thumbnailSrc = ko.observable(''); this.thumbnailLoaded = ko.observable(false); this.thumbnailSessionUid = ko.observable(''); this.thumbnailLink = ko.computed(function () { return this.thumb() ? Utils.getViewThumbnailLinkByHash(this.accountId(), this.hash()) : ''; }, this); this.type = ko.observable(''); this.uploadUid = ko.observable(''); this.uploaded = ko.observable(false); this.uploadError = ko.observable(false); this.visibleImportLink = ko.computed(function () { return AppData.User.enableOpenPgp() && this.extension().toLowerCase() === 'asc' && this.content() !== '' && !this.isPopupItem(); }, this); this.isViewMimeType = ko.computed(function () { return (-1 !== $.inArray(this.type(), aViewMimeTypes)) || this.iframedView(); }, this); this.isMessageType = ko.observable(false); this.visibleViewLink = ko.computed(function () { return this.isVisibleViewLink() && !this.isPopupItem(); }, this); this.visibleDownloadLink = ko.computed(function () { return !this.isPopupItem(); }, this); this.subFiles = ko.observableArray([]); this.allowExpandSubFiles = ko.observable(false); this.subFilesLoaded = ko.observable(false); this.subFilesCollapsed = ko.observable(false); this.subFilesStartedLoading = ko.observable(false); this.visibleExpandLink = ko.computed(function () { return this.allowExpandSubFiles() && !this.subFilesCollapsed() && !this.subFilesStartedLoading(); }, this); this.visibleExpandingText = ko.computed(function () { return this.allowExpandSubFiles() && !this.subFilesCollapsed() && this.subFilesStartedLoading(); }, this); this.visibleSpinner = ko.observable(false); this.statusText = ko.observable(''); this.progressPercent = ko.observable(0); this.visibleProgress = ko.observable(false); this.uploadStarted = ko.observable(false); this.uploadStarted.subscribe(function () { if (this.uploadStarted()) { this.uploaded(false); this.visibleProgress(true); this.progressPercent(20); } else { this.progressPercent(100); this.visibleProgress(false); this.uploaded(true); } }, this); this.allowDrag = ko.observable(false); this.allowSelect = ko.observable(false); this.allowCheck = ko.observable(false); this.allowDelete = ko.observable(false); this.allowUpload = ko.observable(false); this.allowSharing = ko.observable(false); this.allowHeader = ko.observable(false); this.allowDownload = ko.observable(true); this.downloadTitle = ko.computed(function () { if (this.allowDownload()) { return Utils.i18n('MESSAGE/ATTACHMENT_CLICK_TO_DOWNLOAD', { 'FILENAME': this.fileName(), 'SIZE': this.friendlySize() }); } return ''; }, this); } /** * Can be overridden. */ CCommonFileModel.prototype.dataObjectName = ''; /** * Can be overridden. * * @returns {boolean} */ CCommonFileModel.prototype.isVisibleViewLink = function () { return this.uploaded() && !this.uploadError() && this.isViewMimeType(); }; /** * Parses attachment data from server. * * @param {AjaxAttachmenResponse} oData * @param {number} iAccountId */ CCommonFileModel.prototype.parse = function (oData, iAccountId) { if (oData['@Object'] === this.dataObjectName) { this.fileName(Utils.pString(oData.FileName)); this.tempName(Utils.pString(oData.TempName)); if (this.tempName() === '') { this.tempName(this.fileName()); } this.type(Utils.pString(oData.MimeType)); this.size(oData.EstimatedSize ? parseInt(oData.EstimatedSize, 10) : parseInt(oData.SizeInBytes, 10)); this.content(Utils.pString(oData.Content)); this.thumb(!!oData.Thumb); this.hash(Utils.pString(oData.Hash)); this.accountId(iAccountId); this.allowExpandSubFiles(!!oData.Expand); this.iframedView(!!oData.Iframed); this.uploadUid(this.hash()); this.uploaded(true); if (Utils.isFunc(this.additionalParse)) { this.additionalParse(oData); } } }; CCommonFileModel.prototype.getInThumbQueue = function (sThumbSessionUid) { this.thumbnailSessionUid(sThumbSessionUid); if(this.thumb() && (!this.linked || this.linked && !this.linked())) { Utils.thumbQueue(this.thumbnailSessionUid(), this.thumbnailLink(), this.thumbnailSrc); } }; /** * @param {Object=} oApp * * Starts downloading attachment on click. */ CCommonFileModel.prototype.downloadFile = function (oApp) { if (this.allowDownload()) { if (!oApp || !oApp.Api || !oApp.Api.downloadByUrl) { oApp = App; } if (oApp && this.downloadLink().length > 0 && this.downloadLink() !== '#') { oApp.Api.downloadByUrl(this.downloadLink()); } } }; /** * @param {Object} oResponse * @param {Object} oRequest */ CCommonFileModel.prototype.onExpandAttachmentResponse = function (oResponse, oRequest) { this.subFiles([]); if (Utils.isNonEmptyArray(oResponse.Result)) { _.each(oResponse.Result, _.bind(function (oRawFile) { var oFile = this.getInstance(); oRawFile['@Object'] = this.dataObjectName; oFile.parse(oRawFile, this.accountId()); this.subFiles.push(oFile); }, this)); this.subFilesLoaded(true); this.subFilesCollapsed(true); } this.subFilesStartedLoading(false); }; /** * Starts expanding attachment on click. */ CCommonFileModel.prototype.expandFile = function () { if (!this.subFilesLoaded()) { this.subFilesStartedLoading(true); App.Ajax.send({ 'Action': 'ExpandAttachment', 'RawKey': this.hash() }, this.onExpandAttachmentResponse, this); } else { this.subFilesCollapsed(true); } }; /** * Collapse attachment on click. */ CCommonFileModel.prototype.collapseFile = function () { this.subFilesCollapsed(false); }; /** * @returns {CCommonFileModel} */ CCommonFileModel.prototype.getInstance = function () { return new CCommonFileModel(); }; /** * Starts importing attachment on click. */ CCommonFileModel.prototype.importFile = function () { var sContent = this.content(), fPgpCallback = _.bind(function (oPgp) { if (oPgp) { App.Screens.showPopup(CImportOpenPgpKeyPopup, [oPgp, sContent]); } }, this) ; App.Api.pgp(fPgpCallback, AppData.User.IdUser); }; /** * Can be overridden. * * Starts viewing attachment on click. */ CCommonFileModel.prototype.viewFile = function () { this.viewCommonFile(); }; /** * Starts viewing attachment on click. */ CCommonFileModel.prototype.viewCommonFile = function () { var oWin = null, sUrl = Utils.getAppPath() + this.viewLink() ; if (this.visibleViewLink() && this.viewLink().length > 0 && this.viewLink() !== '#') { if (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/) { sUrl = this.linkUrl(); } if (this.iframedView()) { oWin = Utils.WindowOpener.openTab(sUrl); } else { oWin = Utils.WindowOpener.open(sUrl, sUrl, false); } if (oWin) { oWin.focus(); } } }; /** * @param {Object} oAttachment * @param {*} oEvent * @return {boolean} */ CCommonFileModel.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; }; /** * @return {string} */ CCommonFileModel.prototype.generateTransferDownloadUrl = function () { var sLink = this.downloadLink(); if ('http' !== sLink.substr(0, 4)) { sLink = window.location.protocol + '//' + window.location.host + window.location.pathname + sLink; } return this.type() + ':' + this.fileName() + ':' + sLink; }; /** * Fills attachment data for upload. * * @param {string} sFileUid * @param {Object} oFileData */ CCommonFileModel.prototype.onUploadSelect = function (sFileUid, oFileData) { this.fileName(oFileData['FileName']); this.type(oFileData['Type']); this.size(Utils.pInt(oFileData['Size'])); this.uploadUid(sFileUid); this.uploaded(false); this.visibleSpinner(false); this.statusText(''); this.progressPercent(0); this.visibleProgress(false); }; /** * Starts spinner and progress. */ CCommonFileModel.prototype.onUploadStart = function () { this.visibleSpinner(true); this.visibleProgress(true); }; /** * Fills progress upload data. * * @param {number} iUploadedSize * @param {number} iTotalSize */ CCommonFileModel.prototype.onUploadProgress = function (iUploadedSize, iTotalSize) { if (iTotalSize > 0) { this.progressPercent(Math.ceil(iUploadedSize / iTotalSize * 100)); this.visibleProgress(true); } }; /** * Fills data when upload has completed. * * @param {string} sFileUid * @param {boolean} bResponseReceived * @param {Object} oResult */ CCommonFileModel.prototype.onUploadComplete = function (sFileUid, bResponseReceived, oResult) { var bError = !bResponseReceived || !oResult || oResult.Error || false, sError = (oResult && oResult.Error === 'size') ? Utils.i18n('COMPOSE/UPLOAD_ERROR_SIZE') : Utils.i18n('COMPOSE/UPLOAD_ERROR_UNKNOWN') ; this.visibleSpinner(false); this.progressPercent(0); this.visibleProgress(false); this.uploaded(true); this.uploadError(bError); this.statusText(bError ? sError : Utils.i18n('COMPOSE/UPLOAD_COMPLETE')); if (!bError) { this.fillDataAfterUploadComplete(oResult, sFileUid); setTimeout((function (self) { return function () { self.statusText(''); }; })(this), 3000); } }; /** * Should be overriden. * * @param {Object} oResult * @param {string} sFileUid */ CCommonFileModel.prototype.fillDataAfterUploadComplete = function (oResult, sFileUid) { }; /** * @param {Object} oAttachmentModel * @param {Object} oEvent */ CCommonFileModel.prototype.onImageLoad = function (oAttachmentModel, oEvent) { if(this.thumb() && !this.thumbnailLoaded()) { this.thumbnailLoaded(true); Utils.thumbQueue(this.thumbnailSessionUid()); } }; /** * @constructor * @extends CCommonFileModel */ function CFileModel() { this.id = ko.observable(''); this.fileName = ko.observable(''); this.displayName = ko.observable(''); this.nameForEdit = ko.observable(''); this.storageType = ko.observable(Enums.FileStorageType.Personal); this.lastModified = ko.observable(''); this.path = ko.observable(''); this.fullPath = ko.observable(''); this.publicHash = ko.observable(''); this.selected = ko.observable(false); this.checked = ko.observable(false); this.isFolder = ko.observable(false); this.edited = ko.observable(false); this.isExternal = ko.observable(false); this.isLink = ko.observable(false); this.linkType = ko.observable(0); this.linkUrl = ko.observable(''); this.thumbnailExternalLink = ko.observable(''); this.deleted = ko.observable(false); // temporary removal until it was confirmation from the server to delete this.recivedAnim = ko.observable(false).extend({'autoResetToFalse': 500}); this.shared = ko.observable(false); this.owner = ko.observable(''); this.ownerHeaderText = ko.computed(function () { return Utils.i18n('FILESTORAGE/OWNER_HEADER_EMAIL', { 'OWNER': this.owner() }); }, this); this.lastModifiedHeaderText = ko.computed(function () { return Utils.i18n('FILESTORAGE/OWNER_HEADER_LAST_MODIFIED_DATE_TEXT', { 'LASTMODIFIED': this.lastModified() }); }, this); CCommonFileModel.call(this); this.fileName.subscribe(function (value) { this.nameForEdit(value); this.displayName(value); }, this); this.displayName.subscribe(function (value) { if (!this.isFolder()) { this.displayName(Utils.getFileNameWithoutExtension(value)); } }, this); this.type = this.storageType; this.uploaded = ko.observable(true); this.downloadLink = ko.computed(function () { return Utils.getFilestorageDownloadLinkByHash( (AppData.Accounts) ? AppData.Accounts.currentId() : null, this.hash(), this.publicHash() ); }, this); this.viewLink = ko.computed(function () { if (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/) { return this.linkUrl(); } else { var sUrl = Utils.getFilestorageViewLinkByHash( (AppData.Accounts) ? AppData.Accounts.currentId() : null, this.hash(), this.publicHash() ); return this.iframedView() ? Utils.getIframeWrappwer( (AppData.Accounts) ? AppData.Accounts.currentId() : null, sUrl) : sUrl; } }, this); this.isViewable = ko.computed(function () { var bResult = false, aViewableArray = [ 'JPEG', 'JPG', 'PNG', 'GIF', 'HTM', 'HTML', 'TXT', 'CSS', 'ASC', 'JS', 'PDF' ] ; if (_.indexOf(aViewableArray, this.extension().toUpperCase()) >= 0) { bResult = true; } return (this.iframedView() || bResult || (this.isLink()/* && this.linkType() === Enums.FileStorageLinkType.GoogleDrive*/)) && !this.isPopupItem(); }, this); this.visibleViewLink = this.isViewable; this.thumbnailLink = ko.computed(function () { if (this.isExternal() || (this.isLink() && this.linkType() === Enums.FileStorageLinkType.GoogleDrive)) { return this.thumbnailExternalLink(); } else { return this.thumb() ? Utils.getFilestorageViewThumbnailLinkByHash(this.accountId(), this.hash(), this.publicHash()) : ''; } }, this); this.edited.subscribe(function (value) { if (value === false) { this.nameForEdit(this.fileName()); } }, this); } Utils.extend(CFileModel, CCommonFileModel); /** * @returns {CFileModel} */ CFileModel.prototype.getInstance = function () { return new CFileModel(); }; CFileModel.prototype.parse = function (oData, sPublicHash) { var oDateModel = new CDateModel(); this.isFolder(!!oData.IsFolder); this.isLink(!!oData.IsLink); this.fileName(Utils.pString(oData.Name)); this.id(Utils.pString(oData.Id)); this.path(Utils.pString(oData.Path)); this.fullPath(Utils.pString(oData.FullPath)); this.storageType(Utils.pInt(oData.Type)); this.shared(!!oData.Shared); this.isExternal(!!oData.IsExternal); this.iframedView(!!oData.Iframed); if (this.isLink()) { this.linkUrl(Utils.pString(oData.LinkUrl)); this.linkType(Utils.pInt(oData.LinkType)); } if (!this.isFolder()) { this.size(Utils.pInt(oData.Size)); oDateModel.parse(oData['LastModified']); this.lastModified(oDateModel.getShortDate()); this.owner(Utils.pString(oData.Owner)); this.thumb(!!oData.Thumb); this.thumbnailExternalLink(Utils.pString(oData.ThumbnailLink)); this.hash(Utils.pString(oData.Hash)); this.publicHash(sPublicHash); } if(this.thumb() && this.thumbnailExternalLink() === '') { Utils.thumbQueue(this.thumbnailSessionUid(), this.thumbnailLink(), this.thumbnailSrc); } this.content(Utils.pString(oData.Content)); }; /** * Fills attachment data for upload. * * @param {string} sFileUid * @param {Object} oFileData * @param {string} sFileName * @param {string} sOwner * @param {string} sPath * @param {string} sStorageType */ CFileModel.prototype.onUploadSelectOwn = function (sFileUid, oFileData, sFileName, sOwner, sPath, sStorageType) { var oDateModel = new CDateModel(), oDate = new Date() ; this.onUploadSelect(sFileUid, oFileData); oDateModel.parse(oDate.getTime() /1000); this.fileName(sFileName); this.lastModified(oDateModel.getShortDate()); this.owner(sOwner); this.path(sPath); this.storageType(sStorageType); }; /** * @constructor */ function CFileStorageViewModel() { this.allowWebMail = !!(AppData.App && AppData.App.AllowWebMail); this.loaded = ko.observable(false); this.isPublic = bExtApp; this.publicHash = bExtApp ? AppData.FileStoragePubHash : ''; this.IsCollaborationSupported = AppData.User.IsCollaborationSupported; this.AllowFilesSharing = AppData.User.AllowFilesSharing; this.storages = ko.observableArray(); this.folders = ko.observableArray(); this.files = ko.observableArray(); this.uploadingFiles = ko.observableArray(); this.selected = ko.observable(false); this.rootPath = ko.observable(Utils.i18n('FILESTORAGE/TAB_PERSONAL_FILES')); this.storageType = ko.observable(Enums.FileStorageType.Personal); this.storageType.subscribe(function () { var oStorage = null ; if (this.isPublic) { this.rootPath(AppData.FileStoragePubParams.Name); } else { oStorage = this.getStorageByType(this.storageType()); if (oStorage) { this.rootPath(oStorage.displayName()); } } this.selector.listCheckedAndSelected(false); }, this); this.iPathIndex = ko.observable(-1); this.pathItems = ko.observableArray(); this.dropPath = ko.observable(''); this.path = ko.computed(function () { var aPath = _.map(this.pathItems(), function (oItem) { return oItem.id(); }); return aPath.join('/'); }, this); this.path.subscribe(function (value) { this.dropPath(value); }, this); this.collection = ko.computed(function () { var files = _.union(this.files(), this.getUploadingFiles()); files.sort(function(left, right) { return left.fileName() === right.fileName() ? 0 : (left.fileName() < right.fileName() ? -1 : 1); }); return _.union(this.folders(), files); }, this); this.columnCount = ko.observable(1); this.selector = new CSelector(this.collection, null, _.bind(this.onItemDelete, this), _.bind(this.onItemDblClick, this), _.bind(this.onEnter, this), this.columnCount, true, true, true); this.searchPattern = ko.observable(''); this.isSearchFocused = ko.observable(false); this.renameCommand = Utils.createCommand(this, this.executeRename, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isLink()); }); this.deleteCommand = Utils.createCommand(this, this.executeDelete, function () { var items = this.selector.listCheckedAndSelected(); return (0 < items.length); }); this.downloadCommand = Utils.createCommand(this, this.executeDownload, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isFolder()); }); this.shareCommand = Utils.createCommand(this, this.executeShare, function () { var items = this.selector.listCheckedAndSelected(); return (1 === items.length && !items[0].isLink()); }); this.sendCommand = Utils.createCommand(this, this.executeSend, function () { var aItems = this.selector.listCheckedAndSelected(), aFileItems = _.filter(aItems, function (oItem) { return !oItem.isFolder(); }, this) ; return (aFileItems.length > 0); }); this.uploaderButton = ko.observable(null); this.uploaderArea = ko.observable(null); this.bDragActive = ko.observable(false);//.extend({'throttle': 1}); // this.bDragActive.subscribe(function () { // if (this.searchPattern() !== '') // { // this.bDragActive(false); // } // }, this); this.bDragActiveComp = ko.computed(function () { var bDrag = this.bDragActive(); return bDrag && this.searchPattern() === ''; }, this); this.uploadError = ko.observable(false); this.quota = ko.observable(0); this.used = ko.observable(0); this.quotaDesc = ko.observable(''); this.quotaProc = ko.observable(-1); ko.computed(function () { if (!AppData.App || AppData.App && !AppData.App.ShowQuotaBar) { return true; } var iQuota = this.quota(), iUsed = this.used(), iProc = 0 < iQuota ? Math.ceil((iUsed / iQuota) * 100) : -1; iProc = 100 < iProc ? 100 : iProc; this.quotaProc(iProc); this.quotaDesc(-1 < iProc ? Utils.i18n('MAILBOX/QUOTA_TOOLTIP', { 'PROC': iProc, 'QUOTA': Utils.friendlySize(iQuota) }) : ''); return true; }, this); this.dragover = ko.observable(false); this.loading = ko.observable(false); this.loadedFiles = ko.observable(false); this.fileListInfoText = ko.computed(function () { var infoText = ''; if (this.loading()) { infoText = Utils.i18n('FILESTORAGE/INFO_LOADING'); } else if (this.loadedFiles()) { if (this.collection().length === 0) { if (this.isPublic) { infoText = Utils.i18n('FILESTORAGE/INFO_PUBLIC_FOLDER_NOT_EXIST'); } else { if (this.searchPattern() !== '' || this.isPublic) { infoText = Utils.i18n('FILESTORAGE/INFO_NO_ITEMS_FOUND'); } else { if (this.path() !== '' || this.isPopup) { infoText = Utils.i18n('FILESTORAGE/INFO_FOLDER_IS_EMPY'); } else { infoText = Utils.i18n('FILESTORAGE/INFO_FILESTORAGE_IS_EMTY'); } } } } } return infoText; }, this); this.dragAndDropHelperBinded = _.bind(this.dragAndDropHelper, this); this.isPopup = false; this.isCurrentStorageExternal = ko.computed(function () { var oStorage = this.getStorageByType(this.storageType()); return (oStorage && oStorage.isExternal()); }, this); this.timerId = null; } CFileStorageViewModel.prototype.__name = 'CFileStorageViewModel'; /** * @param {Object} $viewModel */ CFileStorageViewModel.prototype.onApplyBindings = function ($viewModel) { this.selector.initOnApplyBindings( '.items_sub_list .item', '.items_sub_list .selected.item', '.items_sub_list .item .custom_checkbox', $('.panel.files .items_list', $viewModel), $('.panel.files .items_list .files_scroll.scroll-inner', $viewModel) ); this.initUploader(); this.hotKeysBind(); }; CFileStorageViewModel.prototype.hotKeysBind = function () { var bIsFileStorageScreen = App.Screens.currentScreen() === Enums.Screens.FileStorage; $(document).on('keydown', _.bind(function(ev) { if (bIsFileStorageScreen && ev && ev.keyCode === Enums.Key.s && this.selector.useKeyboardKeys() && !Utils.isTextFieldFocused()) { ev.preventDefault(); this.isSearchFocused(true); } }, this)); }; /** * Initializes file uploader. */ CFileStorageViewModel.prototype.initUploader = function () { var self = this; if (this.uploaderButton() && this.uploaderArea()) { this.oJua = new Jua({ 'action': '?/Upload/File/', 'name': 'jua-uploader', 'queueSize': 2, 'clickElement': this.uploaderButton(), 'dragAndDropElement': this.uploaderArea(), 'disableAjaxUpload': this.isPublic ? true : false, 'disableFolderDragAndDrop': this.isPublic ? true : false, 'disableDragAndDrop': this.isPublic ? true : false, 'hidden': { 'Token': function () { return AppData.Token; }, 'AccountID': function () { return AppData.Accounts.currentId(); }, 'AdditionalData': function (oFile) { return JSON.stringify({ 'Type': self.storageType(), 'SubPath': oFile && !Utils.isUnd(oFile['Folder']) ? oFile['Folder'] : '', 'Path': self.dropPath() }); } } }); this.oJua .on('onProgress', _.bind(this.onFileUploadProgress, this)) .on('onSelect', _.bind(this.onFileUploadSelect, this)) .on('onStart', _.bind(this.onFileUploadStart, this)) .on('onDrop', _.bind(this.onDrop, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) ; } }; /** * Creates new attachment for upload. * * @param {string} sFileUid * @param {Object} oFileData */ CFileStorageViewModel.prototype.onFileUploadSelect = function (sFileUid, oFileData) { if (AppData.App.FileSizeLimit > 0 && oFileData.Size/(1024*1024) > AppData.App.FileSizeLimit) { App.Screens.showPopup(AlertPopup, [ Utils.i18n('FILESTORAGE/ERROR_SIZE_LIMIT', {'SIZE': AppData.App.FileSizeLimit}) ]); return false; } if (this.searchPattern() === '') { var oFile = new CFileModel(), sFileName = oFileData.FileName, sFileNameExt = Utils.getFileExtension(sFileName), sFileNameWoExt = Utils.getFileNameWithoutExtension(sFileName), iIndex = 0, oAccount = AppData.Accounts.getDefault() ; if (sFileNameExt !== '') { sFileNameExt = '.' + sFileNameExt; } while (!Utils.isUnd(this.getFileByName(sFileName))) { sFileName = sFileNameWoExt + '_' + iIndex + sFileNameExt; iIndex++; } oFile.onUploadSelectOwn(sFileUid, oFileData, sFileName, oAccount.email(), this.path(), this.storageType()); this.uploadingFiles.push(oFile); } }; /** * Finds attachment by uid. Calls it's function to start upload. * * @param {string} sFileUid */ CFileStorageViewModel.prototype.onFileUploadStart = function (sFileUid) { var oFile = this.getUploadFileByUid(sFileUid); if (oFile) { oFile.onUploadStart(); } }; /** * Finds attachment by uid. Calls it's function to progress upload. * * @param {string} sFileUid * @param {number} iUploadedSize * @param {number} iTotalSize */ CFileStorageViewModel.prototype.onFileUploadProgress = function (sFileUid, iUploadedSize, iTotalSize) { if (this.searchPattern() === '') { var oFile = this.getUploadFileByUid(sFileUid); if (oFile) { oFile.onUploadProgress(iUploadedSize, iTotalSize); } } }; /** * Finds attachment by uid. Calls it's function to complete upload. * * @param {string} sFileUid * @param {boolean} bResponseReceived * @param {Object} oResult */ CFileStorageViewModel.prototype.onFileUploadComplete = function (sFileUid, bResponseReceived, oResult) { if (this.searchPattern() === '') { var oFile = this.getUploadFileByUid(sFileUid) ; if (oFile) { oFile.onUploadComplete(sFileUid, bResponseReceived, oResult); this.deleteUploadFileByUid(sFileUid); if (oFile.uploadError()) { this.uploadError(true); App.Api.showError(oFile.statusText()); } else { this.files.push(oFile); if (this.uploadingFiles().length === 0) { App.Api.showReport(Utils.i18n('COMPOSE/UPLOAD_COMPLETE')); } } } this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern(), false); } }; /** * @param {Object} oFile * @param {Object} oEvent */ CFileStorageViewModel.prototype.onDrop = function (oFile, oEvent) { if (this.isPublic) { return; } if (oEvent && oEvent.target && this.searchPattern() === '') { var oFolder = ko.dataFor(oEvent.target); if (oFolder && oFolder instanceof CFileModel && oFolder.isFolder()) { this.dropPath(oFolder.fullPath()); } } else { App.Api.showReport(Utils.i18n('FILESTORAGE/INFO_CANNOT_UPLOAD_SEARCH_RESULT')); } }; /** * @param {Object} oFolder * @param {Object} oEvent * @param {Object} oUi */ CFileStorageViewModel.prototype.filesDrop = function (oFolder, oEvent, oUi) { if (this.isPublic) { return; } if (oFolder && oEvent) { var self = this, sFromPath = '', sToPath = oFolder.fullPath(), sAction = oEvent.ctrlKey ? 'FilesCopy' : 'FilesMove', aChecked = [], aItems = [] ; if (this.path() !== sToPath && this.storageType() === oFolder.storageType() || this.storageType() !== oFolder.storageType()) { oFolder.recivedAnim(true); Utils.uiDropHelperAnim(oEvent, oUi); aChecked = this.selector.listCheckedAndSelected(); aItems = _.map(aChecked, function (oItem) { if (!oEvent.ctrlKey) { if (!oItem.isFolder()) { self.deleteFileByName(oItem.id()); } else { self.deleteFolderByName(oItem.fileName()); } } sFromPath = oItem.path(); return { 'Name': oItem.id(), 'IsFolder': oItem.isFolder() }; }); App.Ajax.send({ 'Action': sAction, 'FromType': this.storageType(), 'ToType': oFolder.storageType(), 'FromPath': sFromPath, 'ToPath': sToPath, 'Files': JSON.stringify(aItems) }, this.onFilesMoveResponse, this ); } /* else { // TODO } */ } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesMoveResponse = function (oData, oParameters) { this.getQuota(this.storageType()); }; /** * @param {Object} oFile */ CFileStorageViewModel.prototype.dragAndDropHelper = function (oFile) { if (oFile) { oFile.checked(true); } var oHelper = Utils.draggableMessages(), aItems = this.selector.listCheckedAndSelected(), nCount = aItems.length, nFilesCount = 0, nFoldersCount = 0, sText = ''; _.each(aItems, function (oItem) { if (oItem.isFolder()) { nFoldersCount++; } else { nFilesCount++; } }, this); if (nFilesCount !== 0 && nFoldersCount !== 0) { sText = Utils.i18n('FILESTORAGE/DRAG_ITEMS_TEXT_PLURAL', {'COUNT': nCount}, null, nCount); } else if (nFilesCount === 0) { sText = Utils.i18n('FILESTORAGE/DRAG_FOLDERS_TEXT_PLURAL', {'COUNT': nFoldersCount}, null, nFoldersCount); } else if (nFoldersCount === 0) { sText = Utils.i18n('FILESTORAGE/DRAG_TEXT_PLURAL', {'COUNT': nFilesCount}, null, nFilesCount); } $('.count-text', oHelper).text(sText); return oHelper; }; CFileStorageViewModel.prototype.onItemDelete = function () { this.executeDelete(); }; /** * @param {{isFolder:Function,path:Function,name:Function,isViewable:Function,viewFile:Function,downloadFile:Function}} oItem */ CFileStorageViewModel.prototype.onEnter = function (oItem) { this.onItemDblClick(oItem); }; /** * @param {{isFolder:Function,path:Function,name:Function,isViewable:Function,viewFile:Function,downloadFile:Function}} oItem */ CFileStorageViewModel.prototype.onItemDblClick = function (oItem) { if (oItem) { if (oItem.isFolder()) { this.getFiles(this.storageType(), oItem); } else { if (oItem.isViewable()) { oItem.viewFile(); } else { oItem.downloadFile(); } } } }; /** * @param {AjaxDefaultResponse} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesResponse = function (oData, oParameters) { if (oData.Result) { var aFolderList = [], aFileList = [], sThumbSessionUid = Date.now().toString() ; if (oData.Result.Quota) { this.quota(oData.Result.Quota[0] + oData.Result.Quota[1]); this.used(oData.Result.Quota[0]); } _.each(oData.Result.Items, function (oValue) { var oItem = new CFileModel() .allowDrag(true) .allowSelect(true) .allowCheck(true) .allowDelete(true) .allowUpload(true) .allowSharing(true) .allowHeader(true) .allowDownload(false) .isPopupItem(this.isPopup); oItem.parse(oValue, this.publicHash); oItem.getInThumbQueue(sThumbSessionUid); if (oItem.isFolder()) { aFolderList.push(oItem); } else { aFileList.push(oItem); } }, this); if (this.isPublic || oParameters.Type === this.storageType()) { this.folders(aFolderList); this.files(aFileList); } this.loading(false); this.loadedFiles(true); clearTimeout(this.timerId); } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onQuotaResponse = function (oData, oParameters) { if (oData.Result && oData.Result.Quota) { this.quota(oData.Result.Quota[0] + oData.Result.Quota[1]); this.used(oData.Result.Quota[0]); } }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesDeleteResponse = function (oData, oParameters) { if (oData.Result) { this.expungeFileItems(); } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); } }; CFileStorageViewModel.prototype.executeRename = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked[0]) { App.Screens.showPopup(FileStorageRenamePopup, [aChecked[0], _.bind(this.renameItem, this)]); } }; CFileStorageViewModel.prototype.executeDownload = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (aChecked[0] && !aChecked[0].isFolder()) { aChecked[0].downloadFile(); } }; CFileStorageViewModel.prototype.executeShare = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked[0]) { App.Screens.showPopup(FileStorageSharePopup, [aChecked[0]]); } }; CFileStorageViewModel.prototype.executeSend = function () { var aItems = this.selector.listCheckedAndSelected(), aFileItems = _.filter(aItems, function (oItem) { return !oItem.isFolder(); }, this) ; if (aFileItems.length > 0) { App.Routing.goDirectly(App.Links.compose(), ['file', aFileItems]); } }; /** * @param {Object} oItem */ CFileStorageViewModel.prototype.onShareIconClick = function (oItem) { if (oItem) { App.Screens.showPopup(FileStorageSharePopup, [oItem]); } }; /** * @param {Object} oItem * @return {string} */ CFileStorageViewModel.prototype.renameItem = function (oItem) { var sName = Utils.trim(oItem.nameForEdit()); if (!Utils.validateFileOrFolderName(sName)) { return oItem.isFolder() ? Utils.i18n('FILESTORAGE/INVALID_FOLDER_NAME') : Utils.i18n('FILESTORAGE/INVALID_FILE_NAME'); } else { App.Ajax.send({ 'Action': 'FilesRename', 'Type': this.storageType(), 'Path': oItem.path(), 'Name': oItem.id(), 'NewName': sName }, this.onFilesRenameResponse, this ); } return ''; }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onFilesRenameResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); }; CFileStorageViewModel.prototype.executeDelete = function () { var aChecked = this.selector.listCheckedAndSelected() ; if (!this.isPublic && aChecked && aChecked.length > 0) { App.Screens.showPopup(ConfirmPopup, [Utils.i18n('FILESTORAGE/CONFIRMATION_DELETE'), _.bind(this.deleteItems, this, aChecked)]); } }; CFileStorageViewModel.prototype.onShow = function () { // if (!this.loaded() || this.isPopup) // { this.loaded(true); this.getStorages(); // } this.selector.useKeyboardKeys(true); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(true); } }; CFileStorageViewModel.prototype.onHide = function () { this.selector.useKeyboardKeys(false); if (this.oJua) { this.oJua.setDragAndDropEnabledStatus(false); } }; /** * @param {number} iType */ CFileStorageViewModel.prototype.getQuota = function (iType) { App.Ajax.send({ 'Action': 'FilesQuota', 'Type': iType }, this.onQuotaResponse, this ); }; CFileStorageViewModel.prototype.getStorageByType = function (storageType) { return _.find(this.storages(), function(oStorageItem){ return oStorageItem.storageType() === storageType; }); }; CFileStorageViewModel.prototype.getStorages = function () { // this.storages.removeAll(); if (!this.isPublic) { if (!this.getStorageByType(Enums.FileStorageType.Personal)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Personal) .displayName(Utils.i18n('FILESTORAGE/TAB_PERSONAL_FILES')) ); } if (this.IsCollaborationSupported) { if (!this.getStorageByType(Enums.FileStorageType.Corporate)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Corporate) .displayName(Utils.i18n('FILESTORAGE/TAB_CORPORATE_FILES')) ); } if (this.AllowFilesSharing) { if (!this.getStorageByType(Enums.FileStorageType.Shared)) { this.storages.push( new CFileModel() .isFolder(true) .storageType(Enums.FileStorageType.Shared) .displayName(Utils.i18n('FILESTORAGE/TAB_SHARED_FILES')) ); } } } if (!this.isPopup) { this.getExternalFileStorages(); } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); } } else { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); } }; CFileStorageViewModel.prototype.getExternalFileStorages = function () { App.Ajax.send({ 'Action': 'ExternalFileStorages' }, this.onExternalStoragesResponse, this ); }; CFileStorageViewModel.prototype.onExternalStoragesResponse = function (oData, oParameters) { if (oData.Result) { _.each(oData.Result, function(oStorage){ if (!this.getStorageByType(oStorage.Type)) { this.storages.push( new CFileModel() .isExternal(true) .isFolder(true) .storageType(oStorage.Type) .displayName(oStorage.DisplayName) ); } }, this); this.expungeExternalStorages(_.map(oData.Result, function(oStorage){ return oStorage.Type; }, this)); } if (!this.getStorageByType(this.storageType())) { this.storageType(Enums.FileStorageType.Personal); } this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {number} iType * @param {object=} oPath = '' * @param {string=} sPattern = '' * @param {boolean=} bLoading = true */ CFileStorageViewModel.prototype.getFiles = function (iType, oPath, sPattern, bLoading) { var self = this, iTypePrev = this.storageType(), iPathIndex = this.iPathIndex(), oFolder = new CFileModel() .isFolder(true) .storageType(iType) ; if (this.isPublic) { return this.getFilesPub(oPath); } this.storageType(iType); self.loadedFiles(false); if (Utils.isUnd(bLoading) || !Utils.isUnd(bLoading) && bLoading) { this.timerId = setTimeout(function() { if (!self.loadedFiles()) { self.folders([]); self.files([]); self.loading(true); } }, 1500); } this.searchPattern(Utils.isUnd(sPattern) ? '' : Utils.pString(sPattern)); if (Utils.isUnd(oPath) || oPath.id() === '') { this.pathItems.removeAll(); oFolder.displayName(this.rootPath()); } else { oFolder = oPath; } this.pathItems.push(oFolder); this.iPathIndex(this.pathItems().length - 1); if (iPathIndex !== this.iPathIndex() || iTypePrev !== this.storageType()) { this.folders([]); this.files([]); } App.Ajax.sendExt({ 'Action': 'Files', 'Type': iType, 'Path': this.path(), 'Pattern': this.searchPattern() }, this.onFilesResponse, this ); }; /** * @param {string} sHash */ CFileStorageViewModel.prototype.getFilesPub = function (oPath) { var iPathIndex = this.iPathIndex(), oFolder = new CFileModel() .isFolder(true) ; if (Utils.isUnd(oPath) || oPath.id() === '') { this.pathItems.removeAll(); oFolder.displayName(this.rootPath()); } else { oFolder = oPath; } this.pathItems.push(oFolder); this.iPathIndex(this.pathItems().length - 1); if (iPathIndex !== this.iPathIndex()) { this.folders([]); this.files([]); } App.Ajax.sendExt({ 'Action': 'FilesPub', 'Hash': AppData.FileStoragePubHash, 'Path': this.path() }, this.onFilesResponse, this ); }; /** * @param {Array} aChecked * @param {boolean} bOkAnswer */ CFileStorageViewModel.prototype.deleteItems = function (aChecked, bOkAnswer) { if (bOkAnswer && 0 < aChecked.length) { var aItems = _.map(aChecked, function (oItem) { oItem.deleted(true); return { 'Path': oItem.path(), 'Name': oItem.id() }; }); App.Ajax.send({ 'Action': 'FilesDelete', 'Type': this.storageType(), 'Path': this.path(), 'Items': JSON.stringify(aItems) }, this.onFilesDeleteResponse, this ); } }; /** * @param {number} iIndex * * @return {string} */ CFileStorageViewModel.prototype.getPathItemByIndex = function (iIndex) { var oItem = this.pathItems()[iIndex], oResult = new CFileModel().fileName(this.rootPath()).id('') ; this.pathItems(this.pathItems().slice(0, iIndex)); if (oItem && !this.isPublic) { oResult = oItem; } return oResult; }; /** * @param {number} iIndex * * @return {string} */ CFileStorageViewModel.prototype.getFullPathByIndex = function (iIndex) { var aPath = _.map(this.pathItems().slice(0, iIndex), function (oItem){ return oItem.fileName(); }); return aPath.join('/'); }; /** * @param {string} sName * * @return {?} */ CFileStorageViewModel.prototype.getFileByName = function (sName) { return _.find(this.files(), function(oItem){ return oItem.id() === sName; }); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.deleteFileByName = function (sName) { this.files(_.filter(this.files(), function (oItem) { return oItem.id() !== sName; })); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.deleteFolderByName = function (sName) { this.folders(_.filter(this.folders(), function (oItem) { return oItem.fileName() !== sName; })); }; /** * @param {string} sName */ CFileStorageViewModel.prototype.expungeFileItems = function () { this.folders(_.filter(this.folders(), function(oFolder){ return !oFolder.deleted(); }, this)); this.files(_.filter(this.files(), function(oFile){ return !oFile.deleted(); }, this)); }; /** * @param {array} aStorageTypes */ CFileStorageViewModel.prototype.expungeExternalStorages = function (aStorageTypes) { this.storages(_.filter(this.storages(), function(oStorage){ return !oStorage.isExternal() || _.include(aStorageTypes, oStorage.storageType()); },this)); }; /** * @param {int} iType */ CFileStorageViewModel.prototype.deleteStorageByType = function (iType) { this.storages(_.filter(this.storages(), function (oItem) { return oItem.storageType() !== iType; })); }; /** * @param {string} sFileUid * * @return {?} */ CFileStorageViewModel.prototype.getUploadFileByUid = function (sFileUid) { return _.find(this.uploadingFiles(), function(oItem){ return oItem.uploadUid() === sFileUid; }); }; /** * @param {string} sFileUid */ CFileStorageViewModel.prototype.deleteUploadFileByUid = function (sFileUid) { this.uploadingFiles(_.filter(this.uploadingFiles(), function (oItem) { return oItem.uploadUid() !== sFileUid; })); }; /** * @return {Array} */ CFileStorageViewModel.prototype.getUploadingFiles = function () { var aResult = [], uploadingFiles = this.uploadingFiles(), self = this; if (!Utils.isUnd(uploadingFiles)) { aResult = _.filter(uploadingFiles, function(oItem){ return oItem.path() === self.path() && oItem.storageType() === self.storageType(); }); } return aResult; }; /** * @param {string} sFileUid */ CFileStorageViewModel.prototype.onCancelUpload = function (sFileUid) { if (this.oJua) { this.oJua.cancel(sFileUid); } this.deleteUploadFileByUid(sFileUid); }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onCreateFolderResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {string} sFolderName */ CFileStorageViewModel.prototype.createFolder = function (sFolderName) { sFolderName = Utils.trim(sFolderName); if (!Utils.validateFileOrFolderName(sFolderName)) { return Utils.i18n('FILESTORAGE/INVALID_FOLDER_NAME'); } else { App.Ajax.send({ 'Action': 'FilesFolderCreate', 'Type': this.storageType(), 'Path': this.path(), 'FolderName': sFolderName }, this.onCreateFolderResponse, this ); } return ''; }; CFileStorageViewModel.prototype.onCreateFolderClick = function () { App.Screens.showPopup(FileStorageFolderCreatePopup, [_.bind(this.createFolder, this)]); }; /** * @param {Object} oData * @param {Object} oParameters */ CFileStorageViewModel.prototype.onCreateLinkResponse = function (oData, oParameters) { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @param {string} sFolderName */ CFileStorageViewModel.prototype.createLink = function (oFileItem) { App.Ajax.send({ 'Action': 'FilesLinkCreate', 'Type': this.storageType(), 'Path': this.path(), 'Link': oFileItem.linkUrl(), 'Name': oFileItem.fileName() }, this.onCreateLinkResponse, this ); }; CFileStorageViewModel.prototype.onCreateLinkClick = function () { var fCallBack = _.bind(this.createLink, this); App.Screens.showPopup(FileStorageLinkCreatePopup, [fCallBack]); }; CFileStorageViewModel.prototype.onSearch = function () { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex()), this.searchPattern()); }; CFileStorageViewModel.prototype.clearSearch = function () { this.getFiles(this.storageType(), this.getPathItemByIndex(this.iPathIndex())); }; /** * @constructor */ function CInformationViewModel() { this.iAnimationDuration = 500; this.iReportDuration = 5000; this.iErrorDuration = 10000; this.loadingMessage = ko.observable(''); this.loadingHidden = ko.observable(true); this.loadingVisible = ko.observable(false); this.reportMessage = ko.observable(''); this.reportHidden = ko.observable(true); this.reportVisible = ko.observable(false); this.iReportTimeout = -1; this.errorMessage = ko.observable(''); this.errorHidden = ko.observable(true); this.errorVisible = ko.observable(false); this.iErrorTimeout = -1; this.isHtmlError = ko.observable(false); this.gray = ko.observable(false); } /** * @param {string} sMessage */ CInformationViewModel.prototype.showLoading = function (sMessage) { if (sMessage && sMessage !== '') { this.loadingMessage(sMessage); } else { this.loadingMessage(Utils.i18n('MAIN/LOADING')); } this.loadingVisible(true); _.defer(_.bind(function () { this.loadingHidden(false); }, this)); } ; CInformationViewModel.prototype.hideLoading = function () { this.loadingHidden(true); setTimeout(_.bind(function () { if (this.loadingHidden()) { this.loadingVisible(false); } }, this), this.iAnimationDuration); }; /** * Displays a message. Starts a timer for hiding. * * @param {string} sMessage * @param {number} iDelay */ CInformationViewModel.prototype.showReport = function (sMessage, iDelay) { var self = this; iDelay = iDelay || this.iReportDuration; if (sMessage && sMessage !== '') { this.reportMessage(sMessage); this.reportVisible(true); _.defer(function () { self.reportHidden(false); }); clearTimeout(this.iReportTimeout); this.iReportTimeout = setTimeout(function () { self.reportHidden(true); setTimeout(function () { if (self.reportHidden()) { self.reportVisible(false); } }, this.iAnimationDuration); }, iDelay); } else { this.reportHidden(true); this.reportVisible(false); } }; /** * Displays an error message. Starts a timer for hiding. * * @param {string} sMessage * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CInformationViewModel.prototype.showError = function (sMessage, bHtml, bNotHide, bGray) { if (sMessage && sMessage !== '') { this.gray(!!bGray); this.errorMessage(sMessage); this.isHtmlError(bHtml); this.errorVisible(true); _.defer(_.bind(function () { this.errorHidden(false); }, this)); clearTimeout(this.iErrorTimeout); if (!bNotHide) { this.iErrorTimeout = setTimeout(_.bind(function () { this.selfHideError(); }, this), this.iErrorDuration); } } else { this.selfHideError(); } }; CInformationViewModel.prototype.selfHideError = function () { this.errorHidden(true); setTimeout(_.bind(function () { if (this.errorHidden()) { this.errorVisible(false); } }, this), this.iAnimationDuration); }; /** * @param {boolean=} bGray = false */ CInformationViewModel.prototype.hideError = function (bGray) { bGray = Utils.isUnd(bGray) ? false : !!bGray; if (bGray === this.gray()) { this.selfHideError(); } }; /** * @constructor */ function CScreens() { var $win = $(window); this.resizeAll = _.debounce(function () { $win.resize(); }, 100); this.oScreens = {}; this.currentScreen = ko.observable(''); this.popupVisibility = ko.observable(false); this.informationScreen = ko.observable(null); this.popups = []; } CScreens.prototype.initScreens = function () {}; CScreens.prototype.initLayout = function () {}; CScreens.prototype.init = function () { this.initScreens(); this.initLayout(); $('#pSevenContent').addClass('single_mode'); _.defer(function () { if (!AppData.SingleMode) { $('#pSevenContent').removeClass('single_mode'); } }); this.informationScreen(this.showNormalScreen(Enums.Screens.Information)); }; CScreens.prototype.getCurrentScreenModel = function () { var oCurrentScreen = this.oScreens[this.currentScreen()], oCurrentModel = (typeof oCurrentScreen !== 'undefined') ? oCurrentScreen.Model : null ; return oCurrentModel; }; /** * @param {string} sScreen * @param {?=} mParams */ CScreens.prototype.showCurrentScreen = function (sScreen, mParams) { var oCurrentScreen = this.oScreens[this.currentScreen()], oCurrentModel = (typeof oCurrentScreen !== 'undefined') ? oCurrentScreen.Model : null ; if (this.currentScreen() !== sScreen) { if (oCurrentModel && oCurrentScreen.bInitialized) { oCurrentModel.hideViewModel(); } this.currentScreen(sScreen); } this.showNormalScreen(sScreen, mParams); this.resizeAll(); }; /** * @param {string} sScreen * @param {?=} mParams * * @return Object */ CScreens.prototype.showNormalScreen = function (sScreen, mParams) { var sScreenId = sScreen, oScreen = this.oScreens[sScreenId] ; if (oScreen) { oScreen.bInitialized = (typeof oScreen.bInitialized !== 'boolean') ? false : oScreen.bInitialized; if (!oScreen.bInitialized) { oScreen.Model = this.initViewModel(oScreen.Model, oScreen.TemplateName); oScreen.bInitialized = true; } oScreen.Model.showViewModel(mParams); } return oScreen ? oScreen.Model : null; }; /** * @param {?} CViewModel * @param {string} sTemplateId * * @return {Object} */ CScreens.prototype.initViewModel = function (CViewModel, sTemplateId) { var oViewModel = null, $viewModel = null ; oViewModel = new CViewModel(); $viewModel = $('div[data-view-model="' + sTemplateId + '"]') .attr('data-bind', 'template: {name: \'' + sTemplateId + '\'}') .hide(); oViewModel.$viewModel = $viewModel; oViewModel.bShown = false; oViewModel.showViewModel = function (mParams) { this.$viewModel.show(); if (typeof this.onRoute === 'function') { this.onRoute(mParams); } if (!this.bShown) { if (typeof this.onShow === 'function') { this.onShow(mParams); } if (AfterLogicApi.runPluginHook) { if (this.__name) { AfterLogicApi.runPluginHook('view-model-on-show', [this.__name, this]); } } this.bShown = true; } }; oViewModel.hideViewModel = function () { this.$viewModel.hide(); if (typeof this.onHide === 'function') { this.onHide(); } this.bShown = false; }; ko.applyBindings(oViewModel, $viewModel[0]); if (typeof oViewModel.onApplyBindings === 'function') { oViewModel.onApplyBindings($viewModel); } return oViewModel; }; /** * @param {?} CPopupViewModel * @param {Array=} aParameters */ CScreens.prototype.showPopup = function (CPopupViewModel, aParameters) { if (CPopupViewModel) { if (!CPopupViewModel.__builded) { var oViewModelDom = null, oViewModel = new CPopupViewModel(), sTemplate = oViewModel.popupTemplate ? oViewModel.popupTemplate() : '' ; if ('' !== sTemplate) { oViewModelDom = $('div[data-view-model="' + sTemplate + '"]') .attr('data-bind', 'template: {name: \'' + sTemplate + '\'}') .removeClass('visible').hide(); if (oViewModelDom && 1 === oViewModelDom.length) { oViewModel.visibility = ko.observable(false); CPopupViewModel.__builded = true; CPopupViewModel.__vm = oViewModel; oViewModel.$viewModel = oViewModelDom; CPopupViewModel.__dom = oViewModelDom; oViewModel.showViewModel = Utils.createCommand(oViewModel, function () { if (App && App.Screens) { App.Screens.showPopup(CPopupViewModel); } }); oViewModel.closeCommand = Utils.createCommand(oViewModel, function () { if (App && App.Screens) { App.Screens.hidePopup(CPopupViewModel); } }); ko.applyBindings(oViewModel, oViewModelDom[0]); Utils.delegateRun(oViewModel, 'onApplyBindings', [oViewModelDom]); } } } if (CPopupViewModel.__vm && CPopupViewModel.__dom) { CPopupViewModel.__dom.show(); _.delay(function() { CPopupViewModel.__dom.addClass('visible'); }, 50); CPopupViewModel.__vm.visibility(true); Utils.delegateRun(CPopupViewModel.__vm, 'onShow', aParameters); this.popupVisibility(true); this.popups.push(CPopupViewModel); this.keyupPopupBinded = _.bind(this.keyupPopup, this, CPopupViewModel.__vm); $(document).on('keyup', this.keyupPopupBinded); } } }; /** * @param {Object} oViewModel * @param {Object} oEvent */ CScreens.prototype.keyupPopup = function (oViewModel, oEvent) { if (oEvent) { var iKeyCode = window.parseInt(oEvent.keyCode, 10); if (Enums.Key.Esc === iKeyCode) { if (oViewModel.onEscHandler) { oViewModel.onEscHandler(); } else { oViewModel.closeCommand(); } } if ((Enums.Key.Enter === iKeyCode || Enums.Key.Space === iKeyCode) && oViewModel.onEnterHandler) { oViewModel.onEnterHandler(); } } }; /** * @param {?} CPopupViewModel */ CScreens.prototype.hidePopup = function (CPopupViewModel) { if (CPopupViewModel && CPopupViewModel.__vm && CPopupViewModel.__dom) { if (this.keyupPopupBinded) { $(document).off('keyup', this.keyupPopupBinded); this.keyupPopupBinded = undefined; } CPopupViewModel.__dom.removeClass('visible').hide(); CPopupViewModel.__vm.visibility(false); Utils.delegateRun(CPopupViewModel.__vm, 'onHide'); this.popupVisibility(false); this.popups = _.without(this.popups, CPopupViewModel); } }; CScreens.prototype.hideAllPopup = function () { _.each(this.popups, function (oPopup) { this.hidePopup(oPopup); }, this); }; /** * @param {string} sMessage */ CScreens.prototype.showLoading = function (sMessage) { if (this.informationScreen()) { this.informationScreen().showLoading(sMessage); } }; CScreens.prototype.hideLoading = function () { if (this.informationScreen()) { this.informationScreen().hideLoading(); } }; /** * @param {string} sMessage * @param {number} iDelay */ CScreens.prototype.showReport = function (sMessage, iDelay) { if (this.informationScreen()) { this.informationScreen().showReport(sMessage, iDelay); } }; /** * @param {string} sMessage * @param {boolean=} bHtml = false * @param {boolean=} bNotHide = false * @param {boolean=} bGray = false */ CScreens.prototype.showError = function (sMessage, bHtml, bNotHide, bGray) { if (this.informationScreen()) { this.informationScreen().showError(sMessage, bHtml, bNotHide, bGray); } }; /** * @param {boolean=} bGray = false */ CScreens.prototype.hideError = function (bGray) { if (this.informationScreen()) { this.informationScreen().hideError(bGray); } }; CScreens.prototype.initHelpdesk = function () { var oScreen = this.oScreens[Enums.Screens.Helpdesk]; if (AppData.User.IsHelpdeskSupported && oScreen && !oScreen.bInitialized) { oScreen.Model = this.initViewModel(oScreen.Model, oScreen.TemplateName); oScreen.bInitialized = true; } }; CScreens.prototype.initScreens = function () { this.oScreens[Enums.Screens.Information] = { 'Model': CInformationViewModel, 'TemplateName': 'Common_InformationViewModel' }; this.oScreens[Enums.Screens.FileStorage] = { 'Model': CFileStorageViewModel, 'TemplateName': 'FileStorage_FileStorageViewModel' }; }; CScreens.prototype.initLayout = function () { $('#pSevenContent').append($('#FileStoragePubLayout').html()); }; /** * @constructor */ function AbstractApp() { this.browser = new CBrowser(); this.favico = window.Favico ? new window.Favico({ 'animation': 'none' }) : null; this.Ajax = new CAjax(); this.Screens = new CScreens(); this.Api = new CApi(); this.Storage = new CStorage(); this.helpdeskUnseenCount = ko.observable(0); this.mailUnseenCount = ko.observable(0); } AbstractApp.prototype.init = function () { }; AbstractApp.prototype.collectScreensData = function () { }; AbstractApp.prototype.run = function () { }; AbstractApp.prototype.momentDateTriggerCallback = function () { var oItem = ko.dataFor(this); if (oItem && oItem.updateMomentDate) { oItem.updateMomentDate(); } }; AbstractApp.prototype.fastMomentDateTrigger = function () { $('.moment-date-trigger-fast').each(this.momentDateTriggerCallback); }; /** * @param {string=} sTitle */ AbstractApp.prototype.setTitle = function (sTitle) { document.title = '.'; document.title = sTitle || ''; }; /** * @constructor */ function AppFileStoragePub() { AbstractApp.call(this); this.init(); } _.extend(AppFileStoragePub.prototype, AbstractApp.prototype); AppFileStoragePub.prototype.init = function () { AppData.User = new CUserSettingsModel(); }; // proto AppFileStoragePub.prototype.tokenProblem = function () { var sReloadFunc= 'window.location.reload(); return false;', sHtmlError = Utils.i18n('WARNING/TOKEN_PROBLEM_HTML', {'RELOAD_FUNC': sReloadFunc}) ; AppData.Auth = false; App.Api.showError(sHtmlError, true, true); }; AppFileStoragePub.prototype.authProblem = function () { }; AppFileStoragePub.prototype.run = function () { this.Screens.init(); this.Screens.showCurrentScreen(Enums.Screens.FileStorage); }; App = new AppFileStoragePub(); window.App = App; /** * AppData.IsMobile: * -1 - first time, mobile is not determined * 0 - mobile is switched off * 1 - mobile is switched on */ if (AppData.IsMobile === -1) { /*jshint onevar: false*/ var bMobile = !window.matchMedia('all and (min-width: 768px)').matches ? 1 : 0; /*jshint onevar: true*/ window.App.Ajax.send({ 'Action': 'SetMobile', 'Mobile': bMobile }, function () { if (bMobile) { window.location.reload(); } else { $(function () { _.defer(function () { App.run(); }); }); } }, this); } else { $(function () { _.defer(function () { App.run(); }); }); } if (window.Modernizr && navigator) { window.Modernizr.addTest('mobile', function() { return bMobileApp; }); } window.AfterLogicApi = AfterLogicApi; // export window.Enums = Enums; $html.removeClass('no-js').addClass('js'); if ($html.hasClass('pdf')) { aViewMimeTypes.push('application/pdf'); aViewMimeTypes.push('application/x-pdf'); } }(jQuery, window, ko, crossroads, hasher));