Uploading and preparing the repository to the dev version.

Original unminified source code (dev folder - js, css, less) (fixes #6)
Grunt build system
Multiple identities correction (fixes #9)
Compose html editor (fixes #12)
New general settings - Loading Description
New warning about default admin password
Split general and login screen settings
This commit is contained in:
RainLoop Team 2013-11-16 02:21:12 +04:00
parent afad45137e
commit 4cc2207513
846 changed files with 99453 additions and 2123 deletions

164
dev/Common/Base64.js Normal file
View file

@ -0,0 +1,164 @@
/*jslint bitwise: true*/
// Base64 encode / decode
// http://www.webtoolkit.info/
Base64 = {
// private property
_keyStr : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
// public method for urlsafe encoding
urlsafe_encode : function (input) {
return Base64.encode(input).replace(/[+]/g, '-').replace(/[\/]/g, '_').replace(/[=]/g, '.');
},
// public method for encoding
encode : function (input) {
var
output = '',
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0
;
input = Base64._utf8_encode(input);
while (i < input.length)
{
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2))
{
enc3 = enc4 = 64;
}
else if (isNaN(chr3))
{
enc4 = 64;
}
output = output +
this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
}
return output;
},
// public method for decoding
decode : function (input) {
var
output = '',
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
i = 0
;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, '');
while (i < input.length)
{
enc1 = this._keyStr.indexOf(input.charAt(i++));
enc2 = this._keyStr.indexOf(input.charAt(i++));
enc3 = this._keyStr.indexOf(input.charAt(i++));
enc4 = this._keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 !== 64)
{
output = output + String.fromCharCode(chr2);
}
if (enc4 !== 64)
{
output = output + String.fromCharCode(chr3);
}
}
return Base64._utf8_decode(output);
},
// private method for UTF-8 encoding
_utf8_encode : function (string) {
string = string.replace(/\r\n/g, "\n");
var
utftext = '',
n = 0,
l = string.length,
c = 0
;
for (; n < l; n++) {
c = string.charCodeAt(n);
if (c < 128)
{
utftext += String.fromCharCode(c);
}
else if ((c > 127) && (c < 2048))
{
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128);
}
else
{
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
},
// private method for UTF-8 decoding
_utf8_decode : function (utftext) {
var
string = '',
i = 0,
c = 0,
c2 = 0,
c3 = 0
;
while ( i < utftext.length )
{
c = utftext.charCodeAt(i);
if (c < 128)
{
string += String.fromCharCode(c);
i++;
}
else if((c > 191) && (c < 224))
{
c2 = utftext.charCodeAt(i+1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2;
}
else
{
c2 = utftext.charCodeAt(i+1);
c3 = utftext.charCodeAt(i+2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3;
}
}
return string;
}
};
/*jslint bitwise: false*/

101
dev/Common/Constants.js Normal file
View file

@ -0,0 +1,101 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
Consts.Defaults = {};
Consts.Values = {};
Consts.DataImages = {};
/**
* @const
* @type {number}
*/
Consts.Defaults.MessagesPerPage = 20;
/**
* @const
* @type {Array}
*/
Consts.Defaults.MessagesPerPageArray = [10, 20, 30, 50, 100/*, 150, 200, 300*/];
/**
* @const
* @type {number}
*/
Consts.Defaults.DefaultAjaxTimeout = 20000;
/**
* @const
* @type {number}
*/
Consts.Defaults.SearchAjaxTimeout = 120000;
/**
* @const
* @type {number}
*/
Consts.Defaults.SendMessageAjaxTimeout = 200000;
/**
* @const
* @type {number}
*/
Consts.Defaults.SaveMessageAjaxTimeout = 200000;
/**
* @const
* @type {string}
*/
Consts.Values.UnuseOptionValue = '__UNUSE__';
/**
* @const
* @type {string}
*/
Consts.Values.GmailFolderName = '[Gmail]';
/**
* @const
* @type {string}
*/
Consts.Values.ClientSideCookieIndexName = 'rlcsc';
/**
* @const
* @type {number}
*/
Consts.Values.ImapDefaulPort = 143;
/**
* @const
* @type {number}
*/
Consts.Values.ImapDefaulSecurePort = 993;
/**
* @const
* @type {number}
*/
Consts.Values.SmtpDefaulPort = 25;
/**
* @const
* @type {number}
*/
Consts.Values.SmtpDefaulSecurePort = 465;
/**
* @const
* @type {number}
*/
Consts.Values.iMessageBodyCacheLimit = 15;
/**
* @const
* @type {string}
*/
Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=';
/**
* @const
* @type {string}
*/
Consts.DataImages.TranspPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=';

286
dev/Common/Enums.js Normal file
View file

@ -0,0 +1,286 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @enum {string}
*/
Enums.StorageResultType = {
'Success': 'success',
'Abort': 'abort',
'Error': 'error',
'Unload': 'unload'
};
/**
* @enum {number}
*/
Enums.State = {
'Empty': 10,
'Login': 20,
'Auth': 30
};
/**
* @enum {number}
*/
Enums.StateType = {
'Webmail': 0,
'Admin': 1
};
/**
* @enum {number}
*/
Enums.FolderType = {
'Inbox': 10,
'SentItems': 11,
'Draft': 12,
'Trash': 13,
'Spam': 14,
'User': 99
};
/**
* @enum {string}
*/
Enums.LoginSignMeTypeAsString = {
'DefaultOff': 'defaultoff',
'DefaultOn': 'defaulton',
'Unused': 'unused'
};
/**
* @enum {number}
*/
Enums.LoginSignMeType = {
'DefaultOff': 0,
'DefaultOn': 1,
'Unused': 2
};
/**
* @enum {string}
*/
Enums.ComposeType = {
'Empty': 'empty',
'Reply': 'reply',
'ReplyAll': 'replyall',
'Forward': 'forward',
'ForwardAsAttachment': 'forward-as-attachment',
'Draft': 'draft'
};
/**
* @enum {number}
*/
Enums.UploadErrorCode = {
'Normal': 0,
'FileIsTooBig': 1,
'FilePartiallyUploaded': 2,
'FileNoUploaded': 3,
'MissingTempFolder': 4,
'FileOnSaveingError': 5,
'FileType': 98,
'Unknown': 99
};
/**
* @enum {number}
*/
Enums.SetSystemFoldersNotification = {
'None': 0,
'Sent': 1,
'Draft': 2,
'Spam': 3,
'Trash': 4
};
/**
* @enum {number}
*/
Enums.ClientSideKeyName = {
'FoldersLashHash': 0,
'MessagesInboxLastHash': 1,
'MailBoxListSize': 2,
'ExpandedFolders': 3,
'FolderListSize': 4
};
/**
* @enum {number}
*/
Enums.EventKeyCode = {
'Backspace': 8,
'Enter': 13,
'Esc': 27,
'PageUp': 33,
'PageDown': 34,
'Left': 37,
'Right': 39,
'Up': 38,
'Down': 40,
'End': 35,
'Home': 36,
'Insert': 45,
'Delete': 46,
'A': 65,
'S': 83
};
/**
* @enum {number}
*/
Enums.MessageSetAction = {
'SetSeen': 0,
'UnsetSeen': 1,
'SetFlag': 2,
'UnsetFlag': 3
};
/**
* @enum {number}
*/
Enums.MessageSelectAction = {
'All': 0,
'None': 1,
'Invert': 2,
'Unseen': 3,
'Seen': 4,
'Flagged': 5,
'Unflagged': 6
};
/**
* @enum {number}
*/
Enums.DesktopNotifications = {
'Allowed': 0,
'NotAllowed': 1,
'Denied': 2,
'NotSupported': 9
};
/**
* @enum {number}
*/
Enums.MessagePriority = {
'Low': 5,
'Normal': 3,
'High': 1
};
/**
* @enum {string}
*/
Enums.EditorDefaultType = {
'Html': 'Html',
'Plain': 'Plain'
};
/**
* @enum {string}
*/
Enums.CustomThemeType = {
'Light': 'Light',
'Dark': 'Dark'
};
/**
* @enum {number}
*/
Enums.ServerSecure = {
'None': 0,
'SSL': 1,
'TLS': 2
};
/**
* @enum {number}
*/
Enums.SearchDateType = {
'All': -1,
'Days3': 3,
'Days7': 7,
'Month': 30
};
/**
* @enum {number}
*/
Enums.EmailType = {
'Defailt': 0,
'Facebook': 1,
'Google': 2
};
/**
* @enum {number}
*/
Enums.SaveSettingsStep = {
'Animate': -2,
'Idle': -1,
'TrueResult': 1,
'FalseResult': 0
};
/**
* @enum {string}
*/
Enums.InterfaceAnimation = {
'None': 'None',
'Normal': 'Normal',
'Full': 'Full'
};
/**
* @enum {number}
*/
Enums.Notification = {
'InvalidToken': 101,
'AuthError': 102,
'AccessError': 103,
'ConnectionError': 104,
'CaptchaError': 105,
'SocialFacebookLoginAccessDisable': 106,
'SocialTwitterLoginAccessDisable': 107,
'SocialGoogleLoginAccessDisable': 108,
'DomainNotAllowed': 109,
'AccountNotAllowed': 110,
'CantGetMessageList': 201,
'CantGetMessage': 202,
'CantDeleteMessage': 203,
'CantMoveMessage': 204,
'CantSaveMessage': 301,
'CantSendMessage': 302,
'InvalidRecipients': 303,
'CantCreateFolder': 400,
'CantRenameFolder': 401,
'CantDeleteFolder': 402,
'CantSubscribeFolder': 403,
'CantUnsubscribeFolder': 404,
'CantDeleteNonEmptyFolder': 405,
'CantSaveSettings': 501,
'CantSavePluginSettings': 502,
'DomainAlreadyExists': 601,
'CantInstallPackage': 701,
'CantDeletePackage': 702,
'InvalidPluginPackage': 703,
'UnsupportedPluginPackage': 704,
'LicensingServerIsUnavailable': 710,
'LicensingExpired': 711,
'LicensingBanned': 712,
'DemoSendMessageError': 750,
'AccountAlreadyExists': 801,
'MailServerError': 901,
'UnknownNotification': 999,
'UnknownError': 999
};

67
dev/Common/Globals.js Normal file
View file

@ -0,0 +1,67 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @type {?}
*/
Globals.now = (new Date()).getTime();
/**
* @type {?}
*/
Globals.minuteTick = ko.observable(true);
/**
* @type {?}
*/
Globals.fiveMinuteTick = ko.observable(true);
/**
* @type {?}
*/
Globals.langChangeTick = ko.observable(true);
/**
* @type {number}
*/
Globals.iAjaxErrorCount = 0;
/**
* @type {number}
*/
Globals.iTokenErrorCount = 0;
/**
* @type {number}
*/
Globals.iMessageBodyCacheCount = 0;
/**
* @type {boolean}
*/
Globals.bUnload = false;
/**
* @type {string}
*/
Globals.sUserAgent = (navigator.userAgent || '').toLowerCase();
/**
* @type {boolean}
*/
Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad');
/**
* @type {boolean}
*/
Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android');
/**
* @type {boolean}
*/
Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice;
Globals.bDisableNanoScroll = Globals.bMobileDevice;
Globals.bAnimationSupported = !Globals.bMobileDevice && $html.hasClass('csstransitions');
Globals.sAnimationType = '';

897
dev/Common/HtmlEditor.js Normal file
View file

@ -0,0 +1,897 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @constructor
*/
function HtmlEditor(oTextAreaElem, oHtmlAreaElem, oToolBarElement, oOptions)
{
var
oDefOptions = {
'DisableHtml': false,
'onSwitch': false,
'LangSwitcherConferm': 'EDITOR_TEXT_SWITCHER_CONFIRM',
'LangSwitcherTextLabel': 'EDITOR_SWITCHER_TEXT_LABEL',
'LangSwitcherHtmlLabel': 'EDITOR_SWITCHER_HTML_LABEL'
}
;
this.bIe = !!/msie/.test(navigator.userAgent.toLowerCase());
oOptions = $.extend(oDefOptions, Utils.isUnd(oOptions) ? {} : oOptions);
this.oOptions = oOptions;
this.bOnlyPlain = !!this.oOptions.DisableHtml;
this.fOnSwitch = this.oOptions.onSwitch;
this.textarea = $(oTextAreaElem).empty().addClass('editorTextArea');
this.htmlarea = $(oHtmlAreaElem).empty().addClass('editorHtmlArea').prop('contentEditable', 'true');
this.toolbar = $(oToolBarElement).empty().addClass('editorToolbar');
HtmlEditor.htmlInitEditor.apply(this);
HtmlEditor.htmlInitToolbar.apply(this);
HtmlEditor.htmlAttachEditorEvents.apply(this);
if (this.bOnlyPlain)
{
this.toolbar.hide();
// this.switchToPlain(false);
}
}
/**
* @param {string} mA
* @param {string} mB
* @param {string} mC
*/
HtmlEditor.prototype.initLanguage = function (mA, mB, mC)
{
this.oOptions.LangSwitcherConferm = mA;
this.oOptions.LangSwitcherTextLabel = mB;
this.oOptions.LangSwitcherHtmlLabel = mC;
};
/**
* @param {string} mA
* @param {boolean=} mB
* @param {string=} mC
*/
HtmlEditor.prototype.execCom = function (mA, mB, mC)
{
if (window.document)
{
window.document.execCommand(mA, mB || false, mC || null);
this.updateTextArea();
}
};
HtmlEditor.prototype.getEditorSelection = function () {
var mSelection = null;
if (window.getSelection)
{
mSelection = window.getSelection();
}
else if (window.document.getSelection)
{
mSelection = window.document.getSelection();
}
else if (window.document.selection)
{
mSelection = window.document.selection;
}
return mSelection;
};
HtmlEditor.prototype.getEditorRange = function () {
var oSelection = this.getEditorSelection();
if (!oSelection || 0 === oSelection.rangeCount)
{
return null;
}
return (oSelection.getRangeAt) ? oSelection.getRangeAt(0) : oSelection.createRange();
};
/**
* @param {string} mA
* @param {boolean=} mB
* @param {string=} mC
*/
HtmlEditor.prototype.ec = function (mA, mB, mC)
{
this.execCom(mA, mB, mC);
};
/**
* @param {number} iHeading
*/
HtmlEditor.prototype.heading = function (iHeading)
{
this.ec('formatblock', false, (this.bIe) ? 'Heading ' + iHeading : 'h' + iHeading);
};
/**
* @param {string} sSrc
*/
HtmlEditor.prototype.insertImage = function (sSrc)
{
if (this.isHtml() && !this.bOnlyPlain)
{
this.htmlarea.focus();
this.ec('insertImage', false, sSrc);
}
};
HtmlEditor.prototype.focus = function ()
{
if (this.isHtml() && !this.bOnlyPlain)
{
this.htmlarea.focus();
}
else
{
this.textarea.focus();
}
};
/**
* @param {string} sType
* @param {string} sColor
*/
HtmlEditor.prototype.setcolor = function (sType, sColor)
{
var
oRange = null,
sCmd = ''
;
if (this.bIe && !document['addEventListener'])
{
oRange = this.getEditorRange();
if (oRange)
{
oRange.execCommand(('forecolor' === sType) ? 'ForeColor' : 'BackColor', false, sColor);
}
}
else
{
if (this.bIe)
{
sCmd = ('forecolor' === sType) ? 'ForeColor' : 'BackColor';
}
else
{
sCmd = ('forecolor' === sType) ? 'foreColor' : 'backColor';
}
this.ec(sCmd, false, sColor);
}
};
/**
* @return {boolean}
*/
HtmlEditor.prototype.isHtml = function ()
{
return (true === this.bOnlyPlain) ? false : this.textarea.is(':hidden');
};
/**
* @return {string}
*/
HtmlEditor.prototype.toHtmlString = function ()
{
return this.editor.innerHTML;
};
/**
* @return {string}
*/
HtmlEditor.prototype.toString = function ()
{
return this.editor.innerText;
};
HtmlEditor.prototype.updateTextArea = function ()
{
this.textarea.val(this.toHtmlString());
};
HtmlEditor.prototype.updateHtmlArea = function ()
{
this.editor.innerHTML = this.textarea.val();
};
/**
* @param {string} sInnerText
* @param {boolean} bIsHtml
*/
HtmlEditor.prototype.setRawText = function (sInnerText, bIsHtml)
{
if (bIsHtml && !this.bOnlyPlain)
{
if (!this.isHtml())
{
this.textarea.val('');
this.switchToHtml();
}
this.textarea.val(sInnerText.toString());
this.updateHtmlArea();
}
else
{
this.textarea.val(sInnerText.toString());
this.updateHtmlArea();
this.switchToPlain(false);
}
};
HtmlEditor.prototype.clear = function ()
{
this.textarea.val('');
this.editor.innerHTML = '';
if (this.bOnlyPlain)
{
this.toolbar.hide();
this.switchToPlain(false);
}
else
{
this.switchToHtml();
}
};
/**
* @return {string}
*/
HtmlEditor.prototype.getTextForRequest = function ()
{
if (this.isHtml())
{
this.updateTextArea();
return this.textarea.val();
}
return this.textarea.val();
};
/**
* @param {boolean=} bWrap
* @return {string}
*/
HtmlEditor.prototype.getTextFromHtml = function (bWrap)
{
var
sText = '',
sQuoteChar = '> ',
convertBlockquote = function () {
if (arguments && 1 < arguments.length)
{
var sText = Utils.trim(arguments[1])
.replace(/__bq__start__([\s\S\n\r]*)__bq__end__/gm, convertBlockquote)
;
sText = '\n' + sQuoteChar + Utils.trim(sText).replace(/\n/gm, '\n' + sQuoteChar) + '\n>\n';
return sText.replace(/\n([> ]+)/gm, function () {
return (arguments && 1 < arguments.length) ? '\n' + Utils.trim(arguments[1].replace(/[\s]/, '')) + ' ' : '';
});
}
return '';
},
convertDivs = function () {
if (arguments && 1 < arguments.length)
{
var sText = Utils.trim(arguments[1]);
if (0 < sText.length)
{
sText = sText.replace(/<div[^>]*>([\s\S]*)<\/div>/gmi, convertDivs);
sText = '\n' + Utils.trim(sText) + '\n';
}
return sText;
}
return '';
},
convertLinks = function () {
if (arguments && 1 < arguments.length)
{
var
sName = Utils.trim(arguments[1])
// sHref = Utils.trim(arguments[0].replace(/<a [\s\S]*href[ ]?=[ ]?["']?([^"']+).+<\/a>/gmi, '$1'))
;
return sName;
// sName = (0 === Utils.trim(sName).length) ? '' : sName;
// sHref = ('mailto:' === sHref.substr(0, 7)) ? '' : sHref;
// sHref = ('http' === sHref.substr(0, 4)) ? sHref : '';
// sHref = (sName === sHref) ? '' : sHref;
// sHref = (0 < sHref.length) ? ' (' + sHref + ') ' : '';
// return (0 < sName.length) ? sName + sHref : sName;
}
return '';
}
;
bWrap = Utils.isUnd(bWrap) ? true : !!bWrap;
sText = this.toHtmlString()
.replace(/[\s]+/gm, ' ')
.replace(/<br\s?\/?>/gmi, '\n')
.replace(/<\/h\d>/gi, '\n')
.replace(/<\/p>/gi, '\n\n')
.replace(/<\/li>/gi, '\n')
.replace(/<\/td>/gi, '\n')
.replace(/<\/tr>/gi, '\n')
.replace(/<hr[^>]*>/gmi, '\n_______________________________\n\n')
.replace(/<img [^>]*>/gmi, '')
.replace(/<div[^>]*>([\s\S]*)<\/div>/gmi, convertDivs)
.replace(/<blockquote[^>]*>/gmi, '\n__bq__start__\n')
.replace(/<\/blockquote>/gmi, '\n__bq__end__\n')
.replace(/<a [^>]*>([\s\S]*?)<\/a>/gmi, convertLinks)
.replace(/&nbsp;/gi, ' ')
.replace(/<[^>]*>/gm, '')
.replace(/&gt;/gi, '>')
.replace(/&lt;/gi, '<')
.replace(/&amp;/gi, '&')
.replace(/&\w{2,6};/gi, '')
;
return (bWrap ? Utils.splitPlainText(sText) : sText)
.replace(/\n[ \t]+/gm, '\n')
.replace(/[\n]{3,}/gm, '\n\n')
.replace(/__bq__start__([\s\S]*)__bq__end__/gm, convertBlockquote)
.replace(/__bq__start__/gm, '')
.replace(/__bq__end__/gm, '')
;
};
/**
* @return {string}
*/
HtmlEditor.prototype.getHtmlFromText = function ()
{
return Utils.convertPlainTextToHtml(this.textarea.val());
};
HtmlEditor.prototype.switchToggle = function ()
{
if (this.isHtml())
{
this.switchToPlain();
}
else
{
this.switchToHtml();
}
};
/**
* @param {boolean=} bWithConfirm
*/
HtmlEditor.prototype.switchToPlain = function (bWithConfirm)
{
bWithConfirm = Utils.isUnd(bWithConfirm) ? true : bWithConfirm;
var
sText = this.getTextFromHtml(),
fSwitch = _.bind(function (bValue) {
if (bValue)
{
this.toolbar.addClass('editorHideToolbar');
$('.editorSwitcher', this.toolbar).text(this.switcherLinkText(false));
this.textarea.val(sText);
this.textarea.show();
// this.textarea.css({'display': ''});
this.htmlarea.hide();
if (this.fOnSwitch)
{
this.fOnSwitch(false);
}
}
}, this)
;
if (!bWithConfirm || 0 === Utils.trim(sText).length)
{
fSwitch(true);
}
else
{
fSwitch(window.confirm(this.oOptions.LangSwitcherConferm));
// Utils.dialogConfirm(this.oOptions.LangSwitcherConferm, fSwitch);
}
};
/**
* @param {boolean} bIsPlain
* @return {string}
*/
HtmlEditor.prototype.switcherLinkText = function (bIsPlain)
{
return (bIsPlain) ? this.oOptions.LangSwitcherTextLabel : this.oOptions.LangSwitcherHtmlLabel;
// return (bIsPlain) ? '« ' + 'EDITOR_TEXT_SWITCHER_PLAINT_TEXT' : 'EDITOR_TEXT_SWITCHER_RICH_FORMATTING' + ' »';
};
HtmlEditor.prototype.switchToHtml = function ()
{
this.toolbar.removeClass('editorHideToolbar');
$('.editorSwitcher', this.toolbar).text(this.switcherLinkText(true));
this.textarea.val(this.getHtmlFromText());
this.updateHtmlArea();
this.textarea.hide();
this.htmlarea.show();
// this.htmlarea.css({'display': ''});
if (this.fOnSwitch)
{
this.fOnSwitch(true);
}
};
/**
* @param {string} sName
* @param {string} sTitle
*/
HtmlEditor.prototype.addButton = function (sName, sTitle)
{
var self = this;
$('<div />').addClass('editorToolbarButtom').append($('<a tabindex="-1" href="javascript:void(0);"></a>').addClass(sName)).attr('title', sTitle).click(function (oEvent) {
if (!Utils.isUnd(HtmlEditor.htmlFunctions[sName]))
{
HtmlEditor.htmlFunctions[sName].apply(self, [$(this), oEvent]);
}
else
{
window.alert(sName);
}
}).appendTo(this.toolbar);
};
HtmlEditor.htmlInitToolbar = function ()
{
if (!this.bOnlyPlain)
{
// this.addButton('fontname', 'Select font');
this.addButton('bold', 'Bold');
this.addButton('italic', 'Italic');
this.addButton('underline', 'Underline');
this.addButton('strikethrough', 'Strikethrough');
this.addButton('removeformat', 'removeformat');
this.addButton('justifyleft', 'justifyleft');
this.addButton('justifycenter', 'justifycenter');
this.addButton('justifyright', 'justifyright');
this.addButton('horizontalrule', 'horizontalrule');
this.addButton('orderedlist', 'orderedlist');
this.addButton('unorderedlist', 'unorderedlist');
this.addButton('indent', 'indent');
this.addButton('outdent', 'outdent');
this.addButton('forecolor', 'forecolor');
// this.addButton('backcolor', 'backcolor');
(function ($, that) {
$('<span />').addClass('editorSwitcher').text(that.switcherLinkText(true)).click(function () {
that.switchToggle();
}).appendTo(that.toolbar);
}($, this));
}
};
HtmlEditor.htmlInitEditor = function ()
{
this.editor = this.htmlarea[0];
this.editor.innerHTML = this.textarea.val();
};
HtmlEditor.htmlAttachEditorEvents = function ()
{
var
self = this,
fIsImage = function (oItem) {
return oItem && oItem.type && 0 === oItem.type.indexOf('image/');
},
// fUpdateHtmlArea = function () {
// self.updateHtmlArea();
// },
//
// fUpdateTextArea = function () {
// self.updateTextArea();
// },
fHandleFileSelect = function (oEvent) {
oEvent = (oEvent && oEvent.originalEvent ?
oEvent.originalEvent : oEvent) || window.event;
if (oEvent)
{
oEvent.stopPropagation();
oEvent.preventDefault();
var
oReader = null,
oFile = null,
aFiles = (oEvent.files || (oEvent.dataTransfer ? oEvent.dataTransfer.files : null))
;
if (aFiles && 1 === aFiles.length && fIsImage(aFiles[0]))
{
oFile = aFiles[0];
oReader = new window.FileReader();
oReader.onload = (function (oLocalFile) {
return function (oEvent) {
self.insertImage(oEvent.target.result, oLocalFile.name);
};
}(oFile));
oReader.readAsDataURL(oFile);
}
}
self.htmlarea.removeClass('editorDragOver');
},
fHandleDragLeave = function () {
self.htmlarea.removeClass('editorDragOver');
},
fHandleDragOver = function (oEvent) {
oEvent.stopPropagation();
oEvent.preventDefault();
self.htmlarea.addClass('editorDragOver');
},
fHandlePaste = function (oEvent) {
var oClipboardData = oEvent && oEvent.clipboardData ? oEvent.clipboardData :
(oEvent && oEvent.originalEvent && oEvent.originalEvent.clipboardData ? oEvent.originalEvent.clipboardData : null);
if (oClipboardData && oClipboardData.items)
{
_.each(oClipboardData.items, function (oItem) {
if (fIsImage(oItem) && oItem['getAsFile']) {
var oReader = null, oFile = oItem['getAsFile']();
if (oFile)
{
oReader = new window.FileReader();
oReader.onload = (function (oLocalFile) {
return function (oEvent) {
self.insertImage(oEvent.target.result, oLocalFile.name);
};
}(oFile));
oReader.readAsDataURL(oFile);
}
}
});
}
}
;
if (!this.bOnlyPlain)
{
// this.textarea.on('click keyup keydown mousedown blur', fUpdateHtmlArea);
// this.htmlarea.on('click keyup keydown mousedown blur', fUpdateTextArea);
//
if (window.File && window.FileReader && window.FileList)
{
this.htmlarea.bind('dragover', fHandleDragOver);
this.htmlarea.bind('dragleave', fHandleDragLeave);
this.htmlarea.bind('drop', fHandleFileSelect);
this.htmlarea.bind('paste', fHandlePaste);
}
}
};
HtmlEditor.htmlColorPickerColors = (function () {
var
aMaps = [],
aColors = [],
iIndex = 0,
iIndexSub = 0,
iIndexSubSub = 0,
iLen = 0,
sMap = ''
;
for (iIndex = 0; iIndex < 256; iIndex += 85)
{
sMap = iIndex.toString(16);
aMaps.push(1 === sMap.length ? '0' + sMap : sMap);
}
iLen = aMaps.length;
for (iIndex = 0; iIndex < iLen; iIndex++)
{
for (iIndexSub = 0; iIndexSub < iLen; iIndexSub++)
{
for (iIndexSubSub = 0; iIndexSubSub < iLen; iIndexSubSub++)
{
aColors.push('#' + aMaps[iIndex] + '' + aMaps[iIndexSub] + '' + aMaps[iIndexSubSub]);
}
}
}
return aColors;
}());
HtmlEditor.htmlFontPicker = (function () {
var
jqDoc = $(window.document),
bIsAppented = false,
oFontPickerHolder = $('<div style="position: absolute;" class="editorFontStylePicker"><div class="editorFpFonts"></div></div>'),
oFonts = oFontPickerHolder.find('.editorFpFonts'),
fCurrentFunc = function () {}
;
$.each(['Arial', 'Arial Black', 'Courier New', 'Tahoma', 'Times New Roman', 'Verdana'], function (iIndex, sFont) {
oFonts.append(
$('<a href="javascript:void(0);" tabindex="-1" class="editorFpFont" style="font-family: ' + sFont + ';">' + sFont + '</a>').click(function () {
fCurrentFunc(sFont);
})
);
oFonts.append('<br />');
});
oFontPickerHolder.hide();
return function (oClickObject, fSelectFunc, oTollbar) {
if (!bIsAppented)
{
oFontPickerHolder.appendTo(oTollbar);
bIsAppented = true;
}
fCurrentFunc = fSelectFunc;
jqDoc.unbind('click.fpNamespace');
window.setTimeout(function () {
jqDoc.one('click.fpNamespace', function () {
oFontPickerHolder.hide();
});
}, 500);
var oPos = $(oClickObject).position();
oFontPickerHolder
.css('top', (5 + oPos.top + $(oClickObject).height()) + 'px')
.css('left', oPos.left + 'px')
.show();
};
}());
HtmlEditor.htmlColorPicker = (function () {
var
jqDoc = $(window.document),
bIsAppented = false,
oColorPickerHolder = $('<div style="position: absolute;" class="editorColorPicker"><div class="editorCpColors"></div></div>'),
oColors = oColorPickerHolder.find('.editorCpColors'),
fCurrentFunc = function () {}
;
$.each(HtmlEditor.htmlColorPickerColors, function (iIndex, sColor) {
oColors.append('<a href="javascript:void(0);" tabindex="-1" class="editorCpColor" style="background-color: ' + sColor + ';"></a>');
});
oColorPickerHolder.hide();
$('.editorCpColor', oColors).click(function (oEvent) {
var
iIndex = 1,
sSelectedColor = '#000000',
sRgbString = $(oEvent.target).css('background-color'),
aParts = sRgbString.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/)
;
if (aParts !== null)
{
delete (aParts[0]);
for (; iIndex <= 3; ++iIndex)
{
aParts[iIndex] = Utils.pInt(aParts[iIndex]).toString(16);
if (1 === aParts[iIndex].length)
{
aParts[iIndex] = '0' + aParts[iIndex];
}
}
sSelectedColor = '#' + aParts.join('');
}
else
{
sSelectedColor = sRgbString;
}
fCurrentFunc(sSelectedColor);
});
return function (oClickObject, fSelectFunc, oTollbar) {
if (!bIsAppented)
{
oColorPickerHolder.appendTo(oTollbar);
bIsAppented = true;
}
var oPos = $(oClickObject).position();
fCurrentFunc = fSelectFunc;
jqDoc.unbind('click.cpNamespace');
window.setTimeout(function () {
jqDoc.one('click.cpNamespace', function () {
oColorPickerHolder.hide();
});
}, 100);
oColorPickerHolder
.css('top', (5 + oPos.top + $(oClickObject).height()) + 'px')
.css('left', oPos.left + 'px')
.show();
};
}());
/* ----------- */
HtmlEditor.htmlFunctions = {
/**
* @this {HtmlEditor}
*/
'bold': function ()
{
this.ec('bold');
},
/**
* @this {HtmlEditor}
*/
'italic': function ()
{
this.ec('italic');
},
/**
* @this {HtmlEditor}
*/
'underline': function ()
{
this.ec('underline');
},
/**
* @this {HtmlEditor}
*/
'strikethrough': function ()
{
this.ec('strikethrough');
},
/**
* @this {HtmlEditor}
*/
'indent': function ()
{
this.ec('indent');
},
/**
* @this {HtmlEditor}
*/
'outdent': function ()
{
this.ec('outdent');
},
/**
* @this {HtmlEditor}
*/
'justifyleft': function ()
{
this.ec('justifyLeft');
},
/**
* @this {HtmlEditor}
*/
'justifycenter': function ()
{
this.ec('justifyCenter');
},
/**
* @this {HtmlEditor}
*/
'justifyright': function ()
{
this.ec('justifyRight');
},
/**
* @this {HtmlEditor}
*/
'horizontalrule': function ()
{
this.ec('insertHorizontalRule', false, 'ht');
},
/**
* @this {HtmlEditor}
*/
'removeformat': function ()
{
this.ec('removeFormat');
},
/**
* @this {HtmlEditor}
*/
'orderedlist': function ()
{
this.ec('insertorderedlist');
},
/**
* @this {HtmlEditor}
*/
'unorderedlist': function ()
{
this.ec('insertunorderedlist');
},
/**
* @this {HtmlEditor}
*/
'forecolor': function (oClickObject)
{
HtmlEditor.htmlColorPicker(oClickObject, _.bind(function (sValue) {
this.setcolor('forecolor', sValue);
}, this), this.toolbar);
},
/**
* @this {HtmlEditor}
*/
'backcolor': function (oClickObject)
{
HtmlEditor.htmlColorPicker(oClickObject, _.bind(function (sValue) {
this.setcolor('backcolor', sValue);
}, this), this.toolbar);
},
/**
* @this {HtmlEditor}
*/
'fontname': function (oClickObject)
{
HtmlEditor.htmlFontPicker(oClickObject, _.bind(function (sValue) {
this.ec('fontname', false, sValue);
}, this), this.toolbar);
}
};

787
dev/Common/Knockout.js Normal file
View file

@ -0,0 +1,787 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
ko.bindingHandlers.tooltip = {
'init': function (oElement, fValueAccessor) {
if (!Globals.bMobileDevice)
{
var
sClass = $(oElement).data('tooltip-class') || '',
sPlacement = $(oElement).data('tooltip-placement') || 'top'
;
$(oElement).tooltip({
'delay': {
'show': 500,
'hide': 100
},
'html': true,
'placement': sPlacement,
'trigger': 'hover',
'title': function () {
return '<span class="tooltip-class ' + sClass + '">' +
Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + '</span>';
}
});
}
}
};
ko.bindingHandlers.tooltip2 = {
'init': function (oElement, fValueAccessor) {
var
sClass = $(oElement).data('tooltip-class') || '',
sPlacement = $(oElement).data('tooltip-placement') || 'top'
;
$(oElement).tooltip({
'delay': {
'show': 500,
'hide': 100
},
'html': true,
'placement': sPlacement,
'title': function () {
return '<span class="tooltip-class ' + sClass + '">' + fValueAccessor()() + '</span>';
}
});
}
};
ko.bindingHandlers.dropdown = {
'init': function (oElement) {
$(oElement).closest('.dropdown').on('click', '.e-item', function () {
$(oElement).dropdown('toggle');
});
}
};
ko.bindingHandlers.popover = {
'init': function (oElement, fValueAccessor) {
$(oElement).popover(ko.utils.unwrapObservable(fValueAccessor()));
}
};
ko.bindingHandlers.resizecrop = {
'init': function (oElement) {
$(oElement).addClass('resizecrop').resizecrop({
'width': '100',
'height': '100',
'wrapperCSS': {
'border-radius': '10px'
}
});
},
'update': function (oElement, fValueAccessor) {
fValueAccessor()();
$(oElement).resizecrop({
'width': '100',
'height': '100'
});
}
};
ko.bindingHandlers.onEnter = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress', function (oEvent) {
if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10))
{
$(oElement).trigger('change');
fValueAccessor().call(oViewModel);
}
});
}
};
ko.bindingHandlers.onEsc = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress', function (oEvent) {
if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10))
{
$(oElement).trigger('change');
fValueAccessor().call(oViewModel);
}
});
}
};
ko.bindingHandlers.modal = {
'init': function (oElement, fValueAccessor) {
$(oElement).modal({
'keyboard': false,
'show': ko.utils.unwrapObservable(fValueAccessor())
}).on('hidden', function () {
fValueAccessor()(false);
});
},
'update': function (oElement, fValueAccessor) {
var bValue = ko.utils.unwrapObservable(fValueAccessor());
$(oElement).modal(bValue ? 'show' : 'hide');
_.delay(function () {
$(oElement).toggleClass('popup-active', bValue);
}, 1);
}
};
ko.bindingHandlers.i18nInit = {
'init': function (oElement) {
Utils.i18nToNode(oElement);
}
};
ko.bindingHandlers.i18nUpdate = {
'update': function (oElement, fValueAccessor) {
ko.utils.unwrapObservable(fValueAccessor());
Utils.i18nToNode(oElement);
}
};
ko.bindingHandlers.link = {
'update': function (oElement, fValueAccessor) {
$(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor()));
}
};
ko.bindingHandlers.title = {
'update': function (oElement, fValueAccessor) {
$(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor()));
}
};
ko.bindingHandlers.textF = {
'init': function (oElement, fValueAccessor) {
$(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
}
};
ko.bindingHandlers.initDom = {
'init': function (oElement, fValueAccessor) {
fValueAccessor()(oElement);
}
};
ko.bindingHandlers.initResizeTrigger = {
'init': function (oElement, fValueAccessor) {
var aValues = ko.utils.unwrapObservable(fValueAccessor());
$(oElement).css({
'height': aValues[1],
'min-height': aValues[1]
});
},
'update': function (oElement, fValueAccessor) {
var
aValues = ko.utils.unwrapObservable(fValueAccessor()),
iValue = Utils.pInt(aValues[1]),
iSize = 0,
iOffset = $(oElement).offset().top
;
if (0 < iOffset)
{
iOffset += Utils.pInt(aValues[2]);
iSize = $window.height() - iOffset;
if (iValue < iSize)
{
iValue = iSize;
}
$(oElement).css({
'height': iValue,
'min-height': iValue
});
}
}
};
ko.bindingHandlers.appendDom = {
'update': function (oElement, fValueAccessor) {
$(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show();
}
};
ko.bindingHandlers.draggable = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
if (!Globals.bMobileDevice)
{
var
iTriggerZone = 100,
iScrollSpeed = 3,
fAllValueFunc = fAllBindingsAccessor(),
sDroppableSelector = fAllValueFunc && fAllValueFunc['droppableSelector'] ? fAllValueFunc['droppableSelector'] : '',
oConf = {
'distance': 20,
'handle': '.dragHandle',
'cursorAt': {'top': 22, 'left': 3},
'refreshPositions': true,
'scroll': true
}
;
if (sDroppableSelector)
{
oConf['drag'] = function (oEvent) {
$(sDroppableSelector).each(function () {
var
moveUp = null,
moveDown = null,
$this = $(this),
oOffset = $this.offset(),
bottomPos = oOffset.top + $this.height()
;
window.clearInterval($this.data('timerScroll'));
$this.data('timerScroll', false);
if (oEvent.pageX >= oOffset.left && oEvent.pageX <= oOffset.left + $this.width())
{
if (oEvent.pageY >= bottomPos - iTriggerZone && oEvent.pageY <= bottomPos)
{
moveUp = function() {
$this.scrollTop($this.scrollTop() + iScrollSpeed);
Utils.windowResize();
};
$this.data('timerScroll', window.setInterval(moveUp, 10));
moveUp();
}
if(oEvent.pageY >= oOffset.top && oEvent.pageY <= oOffset.top + iTriggerZone)
{
moveDown = function() {
$this.scrollTop($this.scrollTop() - iScrollSpeed);
Utils.windowResize();
};
$this.data('timerScroll', window.setInterval(moveDown, 10));
moveDown();
}
}
});
};
oConf['stop'] = function() {
$(sDroppableSelector).each(function () {
window.clearInterval($(this).data('timerScroll'));
$(this).data('timerScroll', false);
});
};
}
oConf['helper'] = function (oEvent) {
return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null);
};
$(oElement).draggable(oConf).on('mousedown', function () {
Utils.removeInFocus();
});
}
}
};
ko.bindingHandlers.droppable = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
if (!Globals.bMobileDevice)
{
var
fValueFunc = fValueAccessor(),
fAllValueFunc = fAllBindingsAccessor(),
fOverCallback = fAllValueFunc && fAllValueFunc['droppableOver'] ? fAllValueFunc['droppableOver'] : null,
fOutCallback = fAllValueFunc && fAllValueFunc['droppableOut'] ? fAllValueFunc['droppableOut'] : null,
oConf = {
'tolerance': 'pointer',
'hoverClass': 'droppableHover'
}
;
if (fValueFunc)
{
oConf['drop'] = function (oEvent, oUi) {
fValueFunc(oEvent, oUi);
};
if (fOverCallback)
{
oConf['over'] = function (oEvent, oUi) {
fOverCallback(oEvent, oUi);
};
}
if (fOutCallback)
{
oConf['out'] = function (oEvent, oUi) {
fOutCallback(oEvent, oUi);
};
}
$(oElement).droppable(oConf);
}
}
}
};
ko.bindingHandlers.nano = {
'init': function (oElement) {
if (!Globals.bDisableNanoScroll)
{
$(oElement)
.addClass('nano')
.nanoScroller({
'iOSNativeScrolling': false,
'preventPageScrolling': true
})
;
}
}
};
ko.bindingHandlers.saveTrigger1 = {
'init': function (oElement) {
var $oEl = $(oElement);
$oEl.data('save-trigger-type', $oEl.is('input[type=text]') ? 'input' : 'custom');
if ('custom' === $oEl.data('save-trigger-type'))
{
$oEl.append(
'&nbsp;&nbsp;<i class="icon-spinner-2 animated"></i><i class="icon-remove error"></i><i class="icon-ok success"></i>'
).addClass('settings-saved-trigger');
}
else
{
$oEl.addClass('settings-saved-trigger-input');
}
},
'update': function (oElement, fValueAccessor) {
var
mValue = ko.utils.unwrapObservable(fValueAccessor()),
$oEl = $(oElement),
bCustom = 'custom' === $oEl.data('save-trigger-type'),
sSuffix = bCustom ? '' : '-input'
;
switch (mValue.toString())
{
case '1':
$oEl
.find('.sst-animated' + sSuffix + ',.sst-error' + sSuffix).hide().removeClass('sst-visible' + sSuffix)
.end()
.find('.sst-success' + sSuffix).show().addClass('sst-visible' + sSuffix)
;
break;
case '0':
$oEl
.find('.sst-animated' + sSuffix + ',.sst-success' + sSuffix).hide().removeClass('sst-visible' + sSuffix)
.end()
.find('.sst-error' + sSuffix).show().addClass('sst-visible' + sSuffix)
;
break;
case '-2':
$oEl
.find('.sst-error' + sSuffix + ',.sst-success' + sSuffix).hide().removeClass('sst-visible' + sSuffix)
.end()
.find('.sst-animated' + sSuffix).show().addClass('sst-visible' + sSuffix)
;
break;
default:
$oEl
.find('.sst-animated' + sSuffix).hide()
.end()
.find('.sst-error' + sSuffix + ',.sst-success' + sSuffix).removeClass('sst-visible' + sSuffix)
;
break;
}
}
};
ko.bindingHandlers.saveTrigger = {
'init': function (oElement) {
var $oEl = $(oElement);
$oEl.data('save-trigger-type', $oEl.is('input[type=text],select,textarea') ? 'input' : 'custom');
if ('custom' === $oEl.data('save-trigger-type'))
{
$oEl.append(
'&nbsp;&nbsp;<i class="icon-spinner-2 animated"></i><i class="icon-remove error"></i><i class="icon-ok success"></i>'
).addClass('settings-saved-trigger');
}
else
{
$oEl.addClass('settings-saved-trigger-input');
}
},
'update': function (oElement, fValueAccessor) {
var
mValue = ko.utils.unwrapObservable(fValueAccessor()),
$oEl = $(oElement)
;
if ('custom' === $oEl.data('save-trigger-type'))
{
switch (mValue.toString())
{
case '1':
$oEl
.find('.animated,.error').hide().removeClass('visible')
.end()
.find('.success').show().addClass('visible')
;
break;
case '0':
$oEl
.find('.animated,.success').hide().removeClass('visible')
.end()
.find('.error').show().addClass('visible')
;
break;
case '-2':
$oEl
.find('.error,.success').hide().removeClass('visible')
.end()
.find('.animated').show().addClass('visible')
;
break;
default:
$oEl
.find('.animated').hide()
.end()
.find('.error,.success').removeClass('visible')
;
break;
}
}
else
{
switch (mValue.toString())
{
case '1':
$oEl.addClass('success').removeClass('error');
break;
case '0':
$oEl.addClass('error').removeClass('success');
break;
case '-2':
// $oEl;
break;
default:
$oEl.removeClass('error success');
break;
}
}
}
};
ko.bindingHandlers.select2 = {
'init': function(oElement, fValueAccessor) {
var
iTimer = 0,
iTimeout = 100,
oMatch = null,
oReg = new window.RegExp(/[a-zA-Z0-9\.\-_]+@[a-zA-Z0-9\.\-_]+/),
oReg2 = new window.RegExp(/(.+) [<]?([^\s<@]+@[a-zA-Z0-9\.\-_]+)[>]?/),
sEmptyTranslateFunction = function () {
return '';
},
/**
* @param {{term:string, callback:Function, matcher:Function}} oCall
*/
fLazyAutocomplete = function (oCall) {
RL.getAutocomplete(oCall['term'], oCall['page'], function (aData, bMore) {
oCall.callback({
'more': !!bMore,
'results': _.map(aData, function (oEmailItem) {
var sName = oEmailItem.toLine(false);
return {
'id': sName,
'text': sName,
'c': oEmailItem
};
})
});
});
}
;
$(oElement).addClass('ko-select2').select2({
/**
* @param {{term:string, callback:Function, matcher:Function}} oCall
*/
'query': function (oCall) {
if (!oCall)
{
return;
}
// if (RL.isLocalAutocomplete && false)
// {
// fLazyAutocomplete(oCall);
// }
// else
// {
if (0 === iTimer)
{
fLazyAutocomplete(oCall);
iTimer = window.setTimeout(Utils.emptyFunction, iTimeout);
}
else
{
window.clearInterval(iTimer);
iTimer = window.setTimeout(function () {
fLazyAutocomplete(oCall);
}, iTimeout);
}
// }
},
'formatSelection': function (oItem, oContainer) {
var sR = oItem && oItem.c ? oItem.c.select2Selection(oContainer) : oItem.text;
if (null !== sR)
{
return sR;
}
},
'formatResult': function (oItem, oContainer, oQuery, fEscapeMarkup) {
var sR = oItem && oItem.c ? oItem.c.select2Result(oContainer) : '';
return '' === sR ? fEscapeMarkup(oItem.text) : sR;
},
'createSearchChoice': function (sTerm, aList) {
return 0 === aList.length && oReg.test(sTerm) ? {
'id': sTerm,
'text': sTerm
} : null;
},
'formatNoMatches': sEmptyTranslateFunction,
'formatSearching': function () {
return Utils.i18n('SUGGESTIONS/SEARCHING_DESC');
},
'formatInputTooShort': sEmptyTranslateFunction,
'formatSelectionTooBig': sEmptyTranslateFunction,
'multiple': true,
'tokenSeparators': [',', ';'],
'minimumInputLength': 2,
'selectOnBlur': false,
'closeOnSelect': true,
'openOnEnter': false
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function() {
$(oElement).select2('destroy');
});
$(oElement).on('change', function () {
var
aTags = $(this).select2('data'),
iIndex = 0,
iLen = aTags.length,
oItem = null,
aResult = []
;
for (; iIndex < iLen; iIndex++)
{
oItem = aTags[iIndex];
if (oItem && oItem.id)
{
if (!oItem.c)
{
oItem.c = new EmailModel();
oMatch = oReg2.exec(Utils.trim(oItem.id));
if (oMatch && !Utils.isUnd(oMatch[2]))
{
oItem.c.name = oMatch[1];
oItem.c.email = oMatch[2];
}
else
{
oItem.c.email = oItem.id;
}
}
aResult.push(oItem.c);
}
}
fValueAccessor()(aResult);
});
},
'update': function (oElement, fValueAccessor) {
var
aTags = ko.utils.unwrapObservable(fValueAccessor()),
iIndex = 0,
iLen = aTags.length,
oItem = null,
sName = '',
aResult = []
;
for (; iIndex < iLen; iIndex++)
{
oItem = aTags[iIndex];
sName = oItem.toLine(false);
aResult.push({
'id': sName,
'text': sName,
'c': oItem
});
}
$(oElement).select2('data', aResult);
}
};
ko.bindingHandlers.command = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
var
jqElement = $(oElement),
oCommand = fValueAccessor()
;
if (!oCommand || !oCommand.enabled || !oCommand.canExecute)
{
throw new Error('You are not using command function');
}
jqElement.addClass('command');
ko.bindingHandlers[jqElement.is('form') ? 'submit' : 'click'].init.apply(oViewModel, arguments);
},
'update': function (oElement, fValueAccessor) {
var
bResult = true,
jqElement = $(oElement),
oCommand = fValueAccessor()
;
bResult = oCommand.enabled();
jqElement.toggleClass('command-not-enabled', !bResult);
if (bResult)
{
bResult = oCommand.canExecute();
jqElement.toggleClass('command-can-not-be-execute', !bResult);
}
jqElement.toggleClass('command-disabled disable disabled', !bResult);
if (jqElement.is('input') || jqElement.is('button'))
{
jqElement.prop('disabled', !bResult);
}
}
};
ko.extenders.trimmer = function (oTarget)
{
var oResult = ko.computed({
'read': oTarget,
'write': function (sNewValue) {
oTarget(Utils.trim(sNewValue.toString()));
},
'owner': this
});
oResult(oTarget());
return oResult;
};
ko.extenders.reversible = function (oTarget)
{
var mValue = oTarget();
oTarget.commit = function ()
{
mValue = oTarget();
};
oTarget.reverse = function ()
{
oTarget(mValue);
};
oTarget.commitedValue = function ()
{
return mValue;
};
return oTarget;
};
ko.extenders.toggleSubscribe = function (oTarget, oOptions)
{
oTarget.subscribe(oOptions[1], oOptions[0], 'beforeChange');
oTarget.subscribe(oOptions[2], oOptions[0]);
return oTarget;
};
ko.extenders.falseTimeout = function (oTarget, iOption)
{
oTarget.iTimeout = 0;
oTarget.subscribe(function (bValue) {
if (bValue)
{
window.clearTimeout(oTarget.iTimeout);
oTarget.iTimeout = window.setTimeout(function () {
oTarget(false);
oTarget.iTimeout = 0;
}, Utils.pInt(iOption));
}
});
return oTarget;
};
ko.observable.fn.validateEmail = function ()
{
this.hasError = ko.observable(false);
this.subscribe(function (sValue) {
sValue = Utils.trim(sValue);
this.hasError('' !== sValue && !(/^[^@\s]+@[^@\s]+$/.test(sValue)));
}, this);
this.valueHasMutated();
return this;
};
ko.observable.fn.validateSimpleEmail = function ()
{
this.hasError = ko.observable(false);
this.subscribe(function (sValue) {
sValue = Utils.trim(sValue);
this.hasError('' !== sValue && !(/^.+@.+$/.test(sValue)));
}, this);
this.valueHasMutated();
return this;
};
ko.observable.fn.validateFunc = function (fFunc)
{
this.hasFuncError = ko.observable(false);
if (Utils.isFunc(fFunc))
{
this.subscribe(function (sValue) {
this.hasFuncError(!fFunc(sValue));
}, this);
this.valueHasMutated();
}
return this;
};

274
dev/Common/LinkBuilder.js Normal file
View file

@ -0,0 +1,274 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @constructor
*/
function LinkBuilder()
{
this.sBase = '#/';
this.sCdnStaticDomain = RL.settingsGet('CdnStaticDomain');
this.sVersion = RL.settingsGet('Version');
this.sSpecSuffix = RL.settingsGet('AuthAccountHash') || '0';
this.sServer = (RL.settingsGet('IndexFile') || './') + '?';
this.sCdnStaticDomain = '' === this.sCdnStaticDomain ? this.sCdnStaticDomain :
('/' === this.sCdnStaticDomain.substr(-1) ? this.sCdnStaticDomain : this.sCdnStaticDomain + '/');
}
/**
* @return {string}
*/
LinkBuilder.prototype.root = function ()
{
return this.sBase;
};
/**
* @param {string} sDownload
* @return {string}
*/
LinkBuilder.prototype.attachmentDownload = function (sDownload)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
LinkBuilder.prototype.attachmentPreview = function (sDownload)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/View/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
LinkBuilder.prototype.attachmentPreviewAsPlain = function (sDownload)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sDownload;
};
/**
* @return {string}
*/
LinkBuilder.prototype.upload = function ()
{
return this.sServer + '/Upload/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.uploadBackground = function ()
{
return this.sServer + '/UploadBackground/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.append = function ()
{
return this.sServer + '/Append/' + this.sSpecSuffix + '/';
};
/**
* @param {string} sEmail
* @return {string}
*/
LinkBuilder.prototype.change = function (sEmail)
{
return this.sServer + '/Change/' + this.sSpecSuffix + '/' + window.encodeURIComponent(sEmail) + '/';
};
/**
* @param {string=} sAdd
* @return {string}
*/
LinkBuilder.prototype.ajax = function (sAdd)
{
return this.sServer + '/Ajax/' + this.sSpecSuffix + '/' + sAdd;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
LinkBuilder.prototype.messageViewLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sRequestHash;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
LinkBuilder.prototype.messageDownloadLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sRequestHash;
};
/**
* @return {string}
*/
LinkBuilder.prototype.inbox = function ()
{
return this.sBase + 'mailbox/Inbox';
};
/**
* @param {string=} sScreenName
* @return {string}
*/
LinkBuilder.prototype.settings = function (sScreenName)
{
var sResult = this.sBase + 'settings';
if (!Utils.isUnd(sScreenName) && '' !== sScreenName)
{
sResult += '/' + sScreenName;
}
return sResult;
};
/**
* @param {string} sScreenName
* @return {string}
*/
LinkBuilder.prototype.admin = function (sScreenName)
{
var sResult = this.sBase;
switch (sScreenName) {
case 'AdminDomains':
sResult += 'domains';
break;
case 'AdminSecurity':
sResult += 'security';
break;
case 'AdminLicensing':
sResult += 'licensing';
break;
}
return sResult;
};
/**
* @param {string} sFolder
* @param {number=} iPage
* @param {string=} sSearch
* @return {string}
*/
LinkBuilder.prototype.mailBox = function (sFolder, iPage, sSearch)
{
iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1;
sSearch = Utils.pString(sSearch);
var sResult = this.sBase + 'mailbox/';
if ('' !== sFolder)
{
sResult += encodeURI(sFolder);
}
if (1 < iPage)
{
sResult = sResult.replace(/[\/]+$/, '');
sResult += '/p' + iPage;
}
if ('' !== sSearch)
{
sResult = sResult.replace(/[\/]+$/, '');
sResult += '/' + encodeURI(sSearch);
}
return sResult;
};
/**
* @return {string}
*/
LinkBuilder.prototype.phpInfo = function ()
{
return this.sServer + 'Info';
};
/**
* @param {string} sLang
* @return {string}
*/
LinkBuilder.prototype.langLink = function (sLang)
{
return this.sServer + '/Lang/0/' + encodeURI(sLang) + '/' + this.sVersion + '/';
};
/**
* @param {string} sHash
* @return {string}
*/
LinkBuilder.prototype.getUserPicUrlFromHash = function (sHash)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/UserPic/' + sHash + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.emptyContactPic = function ()
{
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
this.sVersion + '/static/css/images/empty-contact.png';
};
/**
* @param {string} sFileName
* @return {string}
*/
LinkBuilder.prototype.sound = function (sFileName)
{
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
this.sVersion + '/static/sounds/' + sFileName;
};
/**
* @param {string} sTheme
* @return {string}
*/
LinkBuilder.prototype.themePreviewLink = function (sTheme)
{
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
this.sVersion + '/themes/' + encodeURI(sTheme) + '/images/preview.png';
};
/**
* @return {string}
*/
LinkBuilder.prototype.notificationMailIcon = function ()
{
return ('' === this.sCdnStaticDomain ? 'rainloop/v/' : this.sCdnStaticDomain) +
this.sVersion + '/static/css/images/icom-message-notification.png';
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialGoogle = function ()
{
return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialTwitter = function ()
{
return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialFacebook = function ()
{
return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};

95
dev/Common/Plugins.js Normal file
View file

@ -0,0 +1,95 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @type {Object}
*/
Plugins.oViewModelsHooks = {};
/**
* @type {Object}
*/
Plugins.oSimpleHooks = {};
/**
* @param {string} sName
* @param {Function} ViewModel
*/
Plugins.regViewModelHook = function (sName, ViewModel)
{
if (ViewModel)
{
ViewModel.__hookName = sName;
}
};
/**
* @param {string} sName
* @param {Function} fCallback
*/
Plugins.addHook = function (sName, fCallback)
{
if (Utils.isFunc(fCallback))
{
if (!Utils.isArray(Plugins.oSimpleHooks[sName]))
{
Plugins.oSimpleHooks[sName] = [];
}
Plugins.oSimpleHooks[sName].push(fCallback);
}
};
/**
* @param {string} sName
* @param {Array=} aArguments
*/
Plugins.runHook = function (sName, aArguments)
{
if (Utils.isArray(Plugins.oSimpleHooks[sName]))
{
aArguments = aArguments || [];
_.each(Plugins.oSimpleHooks[sName], function (fCallback) {
fCallback.apply(null, aArguments);
});
}
};
/**
* @param {string} sName
* @return {?}
*/
Plugins.mainSettingsGet = function (sName)
{
return RL ? RL.settingsGet(sName) : null;
};
/**
* @param {Function} fCallback
* @param {string} sAction
* @param {Object=} oParameters
* @param {?number=} iTimeout
* @param {string=} sGetAdd = ''
* @param {Array=} aAbortActions = []
*/
Plugins.remoteRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
{
if (RL)
{
RL.remote().defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions);
}
};
/**
* @param {string} sPluginSection
* @param {string} sName
* @return {?}
*/
Plugins.settingsGet = function (sPluginSection, sName)
{
var oPlugin = Plugins.mainSettingsGet('Plugins');
oPlugin = oPlugin && Utils.isUnd(oPlugin[sPluginSection]) ? null : oPlugin[sPluginSection];
return oPlugin ? (Utils.isUnd(oPlugin[sName]) ? null : oPlugin[sName]) : null;
};

525
dev/Common/Selector.js Normal file
View file

@ -0,0 +1,525 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
/**
* @constructor
* @param {koProperty} oKoList
* @param {koProperty} oKoSelectedItem
* @param {string} sItemSelector
* @param {string} sItemSelectedSelector
* @param {string} sItemCheckedSelector
*/
function Selector(oKoList, oKoSelectedItem, sItemSelector, sItemSelectedSelector, sItemCheckedSelector)
{
this.list = oKoList;
this.selectedItem = oKoSelectedItem;
this.selectedItem.extend({'toggleSubscribe': [null,
function (oPrev) {
if (oPrev)
{
oPrev.selected(false);
}
}, function (oNext) {
if (oNext)
{
oNext.selected(true);
}
}
]});
this.oContentVisible = null;
this.oContentScrollable = null;
this.sItemSelector = sItemSelector;
this.sItemSelectedSelector = sItemSelectedSelector;
this.sItemCheckedSelector = sItemCheckedSelector;
this.sLastUid = '';
this.oCallbacks = {};
this.iSelectTimer = 0;
this.bUseKeyboard = true;
this.emptyFunction = function () {};
this.useItemSelectCallback = true;
this.throttleSelection = false;
this.selectedItem.subscribe(function (oItem) {
if (this.useItemSelectCallback)
{
if (this.throttleSelection)
{
this.throttleSelection = false;
this.selectItemCallbacksThrottle(oItem);
}
else
{
this.selectItemCallbacks(oItem);
}
}
}, this);
var
self = this,
aCheckedCache = [],
mSelected = null
;
this.list.subscribe(function () {
var self = this, aItems = this.list();
if (Utils.isArray(aItems))
{
_.each(aItems, function (oItem) {
if (oItem.checked())
{
aCheckedCache.push(self.getItemUid(oItem));
}
if (null === mSelected && oItem.selected())
{
mSelected = self.getItemUid(oItem);
}
});
}
}, this, 'beforeChange');
this.list.subscribe(function (aItems) {
this.useItemSelectCallback = false;
this.selectedItem(null);
if (Utils.isArray(aItems))
{
var self = this, iLen = aCheckedCache.length;
_.each(aItems, function (oItem) {
if (0 < iLen && -1 < Utils.inArray(self.getItemUid(oItem), aCheckedCache))
{
oItem.checked(true);
iLen--;
}
if (null !== mSelected && mSelected === self.getItemUid(oItem))
{
oItem.selected(true);
mSelected = null;
self.selectedItem(oItem);
}
});
}
this.useItemSelectCallback = true;
aCheckedCache = [];
mSelected = null;
}, this);
this.list.setSelectedByUid = function (sUid) {
self.selectByUid(sUid, false);
};
this.selectItemCallbacksThrottle = _.debounce(this.selectItemCallbacks, 300);
}
Selector.prototype.selectItemCallbacks = function (oItem)
{
(this.oCallbacks['onItemSelect'] || this.emptyFunction)(oItem);
};
Selector.prototype.init = function (oContentVisible, oContentScrollable)
{
this.oContentVisible = oContentVisible;
this.oContentScrollable = oContentScrollable;
if (this.oContentVisible && this.oContentScrollable)
{
var
self = this
;
$(this.oContentVisible)
.on('click', this.sItemSelector, function (oEvent) {
self.actionClick(ko.dataFor(this), oEvent);
}).on('click', this.sItemCheckedSelector, function (oEvent) {
var oItem = ko.dataFor(this);
if (oItem)
{
if (oEvent && oEvent.shiftKey)
{
self.actionClick(oItem, oEvent);
}
else
{
self.sLastUid = self.getItemUid(oItem);
if (oItem.selected())
{
oItem.checked(false);
self.selectedItem(null);
}
else
{
oItem.checked(!oItem.checked());
}
}
}
})
;
$(window.document).on('keydown', function (oEvent) {
var bResult = true;
if (oEvent && self.bUseKeyboard && !Utils.inFocus())
{
if (-1 < Utils.inArray(oEvent.keyCode, [Enums.EventKeyCode.Up, Enums.EventKeyCode.Down, Enums.EventKeyCode.Insert,
Enums.EventKeyCode.Home, Enums.EventKeyCode.End, Enums.EventKeyCode.PageUp, Enums.EventKeyCode.PageDown]))
{
self.newSelectPosition(oEvent.keyCode, oEvent.shiftKey);
bResult = false;
}
else if (Enums.EventKeyCode.Delete === oEvent.keyCode && !oEvent.ctrlKey && !oEvent.shiftKey)
{
if (self.oCallbacks['onDelete'])
{
self.oCallbacks['onDelete']();
}
bResult = false;
}
}
return bResult;
});
}
};
Selector.prototype.selectByUid = function (mUid, bUseCallback)
{
bUseCallback = Utils.isUnd(bUseCallback) ? true : !!bUseCallback;
this.useItemSelectCallback = bUseCallback;
var
oItem = _.find(this.list(), function (oItem) {
return mUid === this.getItemUid(oItem);
}, this)
;
if (oItem)
{
this.selectedItem(oItem);
}
this.useItemSelectCallback = true;
};
Selector.prototype.useKeyboard = function (bValue)
{
this.bUseKeyboard = !!bValue;
};
/**
* @param {Object} oItem
* @returns {string}
*/
Selector.prototype.getItemUid = function (oItem)
{
var
sUid = '',
fGetItemUidCallback = this.oCallbacks['onItemGetUid'] || null
;
if (fGetItemUidCallback && oItem)
{
sUid = fGetItemUidCallback(oItem);
}
return sUid.toString();
};
/**
* @param {number} iEventKeyCode
* @param {boolean} bShiftKey
*/
Selector.prototype.newSelectPosition = function (iEventKeyCode, bShiftKey)
{
var
self = this,
iIndex = 0,
iPageStep = 10,
bNext = false,
bStop = false,
oResult = null,
aList = this.list(),
iListLen = aList ? aList.length : 0,
oSelected = this.selectedItem()
;
if (0 < iListLen)
{
if (!oSelected)
{
if (Enums.EventKeyCode.Down === iEventKeyCode || Enums.EventKeyCode.Insert === iEventKeyCode || Enums.EventKeyCode.Home === iEventKeyCode || Enums.EventKeyCode.PageUp === iEventKeyCode)
{
oResult = aList[0];
}
else if (Enums.EventKeyCode.Up === iEventKeyCode || Enums.EventKeyCode.End === iEventKeyCode || Enums.EventKeyCode.PageDown === iEventKeyCode)
{
oResult = aList[aList.length - 1];
}
}
else if (oSelected)
{
if (Enums.EventKeyCode.Down === iEventKeyCode || Enums.EventKeyCode.Up === iEventKeyCode || Enums.EventKeyCode.Insert === iEventKeyCode)
{
_.each(aList, function (oItem) {
if (!bStop)
{
switch (iEventKeyCode) {
case Enums.EventKeyCode.Up:
if (oSelected === oItem)
{
bStop = true;
}
else
{
oResult = oItem;
}
break;
case Enums.EventKeyCode.Down:
case Enums.EventKeyCode.Insert:
if (bNext)
{
oResult = oItem;
bStop = true;
}
else if (oSelected === oItem)
{
bNext = true;
}
break;
}
}
});
}
else if (Enums.EventKeyCode.Home === iEventKeyCode || Enums.EventKeyCode.End === iEventKeyCode)
{
if (Enums.EventKeyCode.Home === iEventKeyCode)
{
oResult = aList[0];
}
else if (Enums.EventKeyCode.End === iEventKeyCode)
{
oResult = aList[aList.length - 1];
}
}
else if (Enums.EventKeyCode.PageDown === iEventKeyCode)
{
for (; iIndex < iListLen; iIndex++)
{
if (oSelected === aList[iIndex])
{
iIndex += iPageStep;
iIndex = iListLen - 1 < iIndex ? iListLen - 1 : iIndex;
oResult = aList[iIndex];
break;
}
}
}
else if (Enums.EventKeyCode.PageUp === iEventKeyCode)
{
for (iIndex = iListLen; iIndex >= 0; iIndex--)
{
if (oSelected === aList[iIndex])
{
iIndex -= iPageStep;
iIndex = 0 > iIndex ? 0 : iIndex;
oResult = aList[iIndex];
break;
}
}
}
}
}
if (oResult)
{
if (oSelected)
{
if (bShiftKey)
{
if (Enums.EventKeyCode.Up === iEventKeyCode || Enums.EventKeyCode.Down === iEventKeyCode)
{
oSelected.checked(!oSelected.checked());
}
}
else if (Enums.EventKeyCode.Insert === iEventKeyCode)
{
oSelected.checked(!oSelected.checked());
}
}
this.throttleSelection = true;
this.selectedItem(oResult);
this.throttleSelection = true;
if (0 !== this.iSelectTimer)
{
window.clearTimeout(this.iSelectTimer);
this.iSelectTimer = window.setTimeout(function () {
self.iSelectTimer = 0;
self.actionClick(oResult);
}, 1000);
}
else
{
this.iSelectTimer = window.setTimeout(function () {
self.iSelectTimer = 0;
}, 200);
this.actionClick(oResult);
}
this.scrollToSelected();
}
else if (oSelected)
{
if (bShiftKey && (Enums.EventKeyCode.Up === iEventKeyCode || Enums.EventKeyCode.Down === iEventKeyCode))
{
oSelected.checked(!oSelected.checked());
}
else if (Enums.EventKeyCode.Insert === iEventKeyCode)
{
oSelected.checked(!oSelected.checked());
}
}
};
/**
* @return {boolean}
*/
Selector.prototype.scrollToSelected = function ()
{
if (!this.oContentVisible || !this.oContentScrollable)
{
return false;
}
var
iOffset = 20,
oSelected = $(this.sItemSelectedSelector, this.oContentScrollable),
oPos = oSelected.position(),
iVisibleHeight = this.oContentVisible.height(),
iSelectedHeight = oSelected.outerHeight()
;
if (oPos && (oPos.top < 0 || oPos.top + iSelectedHeight > iVisibleHeight))
{
if (oPos.top < 0)
{
this.oContentScrollable.scrollTop(this.oContentScrollable.scrollTop() + oPos.top - iOffset);
}
else
{
this.oContentScrollable.scrollTop(this.oContentScrollable.scrollTop() + oPos.top - iVisibleHeight + iSelectedHeight + iOffset);
}
return true;
}
return false;
};
Selector.prototype.eventClickFunction = function (oItem, oEvent)
{
var
sUid = this.getItemUid(oItem),
iIndex = 0,
iLength = 0,
oListItem = null,
sLineUid = '',
bChangeRange = false,
bIsInRange = false,
aList = [],
bChecked = false
;
if (oEvent && oEvent.shiftKey)
{
if ('' !== sUid && '' !== this.sLastUid && sUid !== this.sLastUid)
{
aList = this.list();
bChecked = oItem.checked();
for (iIndex = 0, iLength = aList.length; iIndex < iLength; iIndex++)
{
oListItem = aList[iIndex];
sLineUid = this.getItemUid(oListItem);
bChangeRange = false;
if (sLineUid === this.sLastUid || sLineUid === sUid)
{
bChangeRange = true;
}
if (bChangeRange)
{
bIsInRange = !bIsInRange;
}
if (bIsInRange || bChangeRange)
{
oListItem.checked(bChecked);
}
}
}
}
this.sLastUid = '' === sUid ? '' : sUid;
};
/**
*
* @param {Object} oItem
* @param {Object=} oEvent
*/
Selector.prototype.actionClick = function (oItem, oEvent)
{
if (oItem)
{
var
bClick = true,
sUid = this.getItemUid(oItem)
;
if (oEvent)
{
if (oEvent.shiftKey)
{
bClick = false;
if ('' === this.sLastUid)
{
this.sLastUid = sUid;
}
oItem.checked(!oItem.checked());
this.eventClickFunction(oItem, oEvent);
}
else if (oEvent.ctrlKey)
{
bClick = false;
this.sLastUid = sUid;
oItem.checked(!oItem.checked());
}
}
if (bClick)
{
this.selectedItem(oItem);
this.sLastUid = sUid;
}
}
};
Selector.prototype.on = function (sEventName, fCallback)
{
this.oCallbacks[sEventName] = fCallback;
};

1343
dev/Common/Utils.js Normal file

File diff suppressed because it is too large Load diff

71
dev/Common/_Begin.js Normal file
View file

@ -0,0 +1,71 @@
'use strict';
var
/**
* @type {Object}
*/
Consts = {},
/**
* @type {Object}
*/
Enums = {},
/**
* @type {Object}
*/
NotificationI18N = {},
/**
* @type {Object.<Function>}
*/
Utils = {},
/**
* @type {Object.<Function>}
*/
Plugins = {},
/**
* @type {Object.<Function>}
*/
Base64 = {},
/**
* @type {Object}
*/
Globals = {},
/**
* @type {Object}
*/
ViewModels = {
'settings': [],
'settings-removed': [],
'settings-disabled': []
},
/**
* @type {*}
*/
kn = null,
/**
* @type {Object}
*/
AppData = window['rainloopAppData'] || {},
/**
* @type {Object}
*/
I18n = window['rainloopI18N'] || {},
$html = $('html'),
$window = $(window),
$document = $(window.document),
NotificationClass = window.Notification && window.Notification.requestPermission ? window.Notification : null
;

6
dev/Common/_BeginA.js Normal file
View file

@ -0,0 +1,6 @@
/*jshint onevar: false*/
/**
* @type {?AdminApp}
*/
var RL = null;
/*jshint onevar: true*/

6
dev/Common/_BeginW.js Normal file
View file

@ -0,0 +1,6 @@
/*jshint onevar: false*/
/**
* @type {?RainLoopApp}
*/
var RL = null;
/*jshint onevar: true*/

3
dev/Common/_BootEnd.js Normal file
View file

@ -0,0 +1,3 @@
if (window.SimplePace) {
window.SimplePace.add(10);
}

3
dev/Common/_CoreEnd.js Normal file
View file

@ -0,0 +1,3 @@
if (window.SimplePace) {
window.SimplePace.add(10);
}

57
dev/Common/_End.js Normal file
View file

@ -0,0 +1,57 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
$html.addClass(Globals.bMobileDevice ? 'mobile' : 'no-mobile');
$window.keydown(Utils.killCtrlAandS).keyup(Utils.killCtrlAandS);
$window.unload(function () {
Globals.bUnload = true;
});
// export
window.rl = window.rl || {};
window.rl.addHook = Plugins.addHook;
window.rl.settingsGet = Plugins.mainSettingsGet;
window.rl.remoteRequest = Plugins.remoteRequest;
window.rl.pluginSettingsGet = Plugins.settingsGet;
window.rl.addSettingsViewModel = Utils.addSettingsViewModel;
window.rl.createCommand = Utils.createCommand;
window.rl.EmailModel = EmailModel;
window.rl.Enums = Enums;
window['__RLBOOT'] = function (fCall) {
// boot
$(function () {
if (window['rainloopTEMPLATES'] && window['rainloopTEMPLATES'][0])
{
$('#rl-templates').html(window['rainloopTEMPLATES'][0]);
window.setInterval(function () {
Globals.minuteTick(!Globals.minuteTick());
}, 1000 * 60);
window.setInterval(function () {
Globals.fiveMinuteTick(!Globals.fiveMinuteTick());
}, 1000 * 60 * 5);
_.delay(function () {
window['rainloopAppData'] = {};
window['rainloopI18N'] = {};
window['rainloopTEMPLATES'] = {};
kn.setBoot(RL).bootstart();
$html.addClass('rl-started');
}, 50);
}
else
{
fCall(false);
}
window['__RLBOOT'] = null;
});
};

3
dev/Common/_LibsEnd.js Normal file
View file

@ -0,0 +1,3 @@
if (window.SimplePace) {
window.SimplePace.add(20);
}