Code refactoring

This commit is contained in:
RainLoop Team 2016-06-16 02:36:44 +03:00
parent 60bac7192f
commit 90d95d3ca4
28 changed files with 977 additions and 924 deletions

4
.gitignore vendored
View file

@ -18,4 +18,6 @@
/build/tmp /build/tmp
/data /data
.DS_Store .DS_Store
/tests/fix.php /tests/fix.php
/MULTIPLY
/include.php

View file

@ -9,10 +9,10 @@ import {
import {KeyState} from 'Common/Enums'; import {KeyState} from 'Common/Enums';
import {noop, isNormal, pString, inArray, microtime, timestamp, detectDropdownVisibility, windowResizeCallback} from 'Common/Utils'; import {noop, isNormal, pString, inArray, microtime, timestamp, detectDropdownVisibility, windowResizeCallback} from 'Common/Utils';
import Links from 'Common/Links'; import * as Links from 'Common/Links';
import Events from 'Common/Events'; import * as Settings from 'Storage/Settings';
import * as Events from 'Common/Events';
import Translator from 'Common/Translator'; import Translator from 'Common/Translator';
import Settings from 'Storage/Settings';
import {AbstractBoot} from 'Knoin/AbstractBoot'; import {AbstractBoot} from 'Knoin/AbstractBoot';

View file

@ -3,12 +3,12 @@ import {window, _} from 'common';
import ko from 'ko'; import ko from 'ko';
import progressJs from 'progressJs'; import progressJs from 'progressJs';
import Links from 'Common/Links'; import * as Links from 'Common/Links';
import Translator from 'Common/Translator'; import Translator from 'Common/Translator';
import {StorageResultType, Notification} from 'Common/Enums'; import {StorageResultType, Notification} from 'Common/Enums';
import {pInt, isNormal, isArray, inArray, isUnd} from 'Common/Utils'; import {pInt, isNormal, isArray, inArray, isUnd} from 'Common/Utils';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
import AppStore from 'Stores/Admin/App'; import AppStore from 'Stores/Admin/App';
import DomainStore from 'Stores/Admin/Domain'; import DomainStore from 'Stores/Admin/Domain';

View file

@ -20,11 +20,11 @@ import {
} from 'Common/Globals'; } from 'Common/Globals';
import {UNUSED_OPTION_VALUE} from 'Common/Consts'; import {UNUSED_OPTION_VALUE} from 'Common/Consts';
import Plugins from 'Common/Plugins'; import * as Plugins from 'Common/Plugins';
import Links from 'Common/Links'; import * as Links from 'Common/Links';
import Events from 'Common/Events'; import * as Events from 'Common/Events';
import * as Momentor from 'Common/Momentor';
import Translator from 'Common/Translator'; import Translator from 'Common/Translator';
import Momentor from 'Common/Momentor';
import Cache from 'Common/Cache'; import Cache from 'Common/Cache';
import SocialStore from 'Stores/Social'; import SocialStore from 'Stores/Social';
@ -38,7 +38,7 @@ import MessageStore from 'Stores/User/Message';
import ContactStore from 'Stores/User/Contact'; import ContactStore from 'Stores/User/Contact';
import Local from 'Storage/Client'; import Local from 'Storage/Client';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
import RainLoopStorage from 'Storage/RainLoop'; import RainLoopStorage from 'Storage/RainLoop';
import Remote from 'Remote/User/Ajax'; import Remote from 'Remote/User/Ajax';

View file

@ -1,8 +1,8 @@
import {window, $} from 'common'; import {window, $} from 'common';
import {bMobileDevice, bSafari} from 'Common/Globals'; import {bMobileDevice, bSafari} from 'Common/Globals';
import Links from 'Common/Links'; import * as Links from 'Common/Links';
import Events from 'Common/Events'; import * as Events from 'Common/Events';
import {trim} from 'Common/Utils'; import {trim} from 'Common/Utils';
class Audio class Audio

View file

@ -163,7 +163,9 @@ const Base64 = {
return string; return string;
} }
}; };
module.exports = Base64;
/* jslint bitwise: false */ /* jslint bitwise: false */
/* eslint-enable */ /* eslint-enable */
export const decode = Base64.decode;
export const encode = Base64.encode;
export const urlsafe_encode = Base64.urlsafe_encode;

View file

@ -2,8 +2,8 @@
import {_} from 'common'; import {_} from 'common';
import {Capa, MessageSetAction} from 'Common/Enums'; import {Capa, MessageSetAction} from 'Common/Enums';
import {trim, pInt, isArray} from 'Common/Utils'; import {trim, pInt, isArray} from 'Common/Utils';
import Links from 'Common/Links'; import * as Links from 'Common/Links';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class CacheUserStorage class CacheUserStorage
{ {

View file

@ -22,10 +22,7 @@ class CookieDriver
const storageValue = $.cookie(CLIENT_SIDE_STORAGE_INDEX_NAME); const storageValue = $.cookie(CLIENT_SIDE_STORAGE_INDEX_NAME);
storageResult = null === storageValue ? null : JSON.parse(storageValue); storageResult = null === storageValue ? null : JSON.parse(storageValue);
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
(storageResult || (storageResult = {}))[key] = data; (storageResult || (storageResult = {}))[key] = data;
@ -37,10 +34,7 @@ class CookieDriver
result = true; result = true;
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
return result; return result;
} }
@ -62,10 +56,7 @@ class CookieDriver
result = (storageResult && !isUnd(storageResult[key])) ? storageResult[key] : null; result = (storageResult && !isUnd(storageResult[key])) ? storageResult[key] : null;
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
return result; return result;
} }

View file

@ -22,10 +22,7 @@ class LocalStorageDriver
const storageValue = window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] || null; const storageValue = window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] || null;
storageResult = null === storageValue ? null : JSON.parse(storageValue); storageResult = null === storageValue ? null : JSON.parse(storageValue);
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
(storageResult || (storageResult = {}))[key] = data; (storageResult || (storageResult = {}))[key] = data;
@ -34,10 +31,7 @@ class LocalStorageDriver
window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] = JSON.stringify(storageResult); window.localStorage[CLIENT_SIDE_STORAGE_INDEX_NAME] = JSON.stringify(storageResult);
result = true; result = true;
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
return result; return result;
} }
@ -59,10 +53,7 @@ class LocalStorageDriver
result = (storageResult && !isUnd(storageResult[key])) ? storageResult[key] : null; result = (storageResult && !isUnd(storageResult[key])) ? storageResult[key] : null;
} }
catch (e) catch (e) {/* eslint-disable-line no-empty */}
{
// eslint-disable-line no-empty
}
return result; return result;
} }

View file

@ -1,65 +1,52 @@
import {_} from 'common'; import {_} from 'common';
import {isObject, isUnd} from 'Common/Utils'; import {isObject, isUnd} from 'Common/Utils';
import Plugins from 'Common/Plugins'; import * as Plugins from 'Common/Plugins';
class Events const SUBS = {};
/**
* @param {string|Object} name
* @param {Function} func
* @param {Object=} context
*/
export function sub(name, func, context)
{ {
subs = {}; if (isObject(name))
{
context = func || null;
func = null;
constructor() {} _.each(name, (subFunc, subName) => {
sub(subName, subFunc, context);
/** });
* @param {string|Object} name
* @param {Function} func
* @param {Object=} context
* @return {Events}
*/
sub(name, func, context) {
if (isObject(name))
{
context = func || null;
func = null;
_.each(name, (subFunc, subName) => {
this.sub(subName, subFunc, context);
}, this);
}
else
{
if (isUnd(this.subs[name]))
{
this.subs[name] = [];
}
this.subs[name].push([func, context]);
}
return this;
} }
else
/** {
* @param {string} name if (isUnd(SUBS[name]))
* @param {Array=} args
* @return {Events}
*/
pub(name, args) {
Plugins.runHook('rl-pub', [name, args]);
if (!isUnd(this.subs[name]))
{ {
_.each(this.subs[name], (items) => { SUBS[name] = [];
if (items[0])
{
items[0].apply(items[1] || null, args || []);
}
});
} }
return this; SUBS[name].push([func, context]);
} }
} }
module.exports = new Events(); /**
* @param {string} name
* @param {Array=} args
*/
export function pub(name, args)
{
Plugins.runHook('rl-pub', [name, args]);
if (!isUnd(SUBS[name]))
{
_.each(SUBS[name], (items) => {
if (items[0])
{
items[0].apply(items[1] || null, args || []);
}
});
}
}

View file

@ -1,7 +1,7 @@
import {window, _, $} from 'common'; import {window, _, $} from 'common';
import {oHtmlEditorDefaultConfig, oHtmlEditorLangsMap} from 'Common/Globals'; import {oHtmlEditorDefaultConfig, oHtmlEditorLangsMap} from 'Common/Globals';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class HtmlEditor class HtmlEditor
{ {

View file

@ -1,390 +1,444 @@
import {window} from 'common'; import {window} from 'common';
import {pString, pInt, isUnd, isNormal, trim, encodeURIComponent} from 'Common/Utils'; import {pString, pInt, isUnd, isNormal, trim, encodeURIComponent} from 'Common/Utils';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class Links const ROOT = './';
const HASH_PREFIX = '#/';
const SERVER_PREFIX = './?';
const SUB_QUERY_PREFIX = '&q[]=';
const VERSION = Settings.appSettingsGet('version');
const WEB_PREFIX = Settings.appSettingsGet('webPath') || '';
const VERSION_PREFIX = Settings.appSettingsGet('webVersionPath') || 'rainloop/v/' + VERSION + '/';
const STATIC_PREFIX = VERSION_PREFIX + 'static/';
const ADMIN_HOST_USE = !!Settings.appSettingsGet('adminHostUse');
const ADMIN_PATH = Settings.appSettingsGet('adminPath') || 'admin';
let AUTH_PREFIX = Settings.settingsGet('AuthAccountHash') || '0';
export function populateAuthSuffix()
{ {
constructor() { AUTH_PREFIX = Settings.settingsGet('AuthAccountHash') || '0';
this.sHashPrefix = '#/';
this.sServerPrefix = './?';
this.sVersion = Settings.appSettingsGet('version');
this.sWebPrefix = Settings.appSettingsGet('webPath') || '';
this.sVersionPrefix = Settings.appSettingsGet('webVersionPath') || 'rainloop/v/' + this.sVersion + '/';
this.bAminHostUse = !!Settings.appSettingsGet('adminHostUse');
this.sAdminPath = Settings.appSettingsGet('adminPath') || 'admin';
this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0';
this.sStaticPrefix = this.sVersionPrefix + 'static/';
}
populateAuthSuffix() {
this.sAuthSuffix = Settings.settingsGet('AuthAccountHash') || '0';
}
/**
* @return {string}
*/
subQueryPrefix() {
return '&q[]=';
}
/**
* @param {string=} startupUrl
* @return {string}
*/
root(startupUrl = '') {
return this.sHashPrefix + pString(startupUrl);
}
/**
* @return {string}
*/
rootAdmin() {
return this.bAminHostUse ? './' : this.sServerPrefix + this.sAdminPath;
}
/**
* @return {string}
*/
rootUser(mobile = false) {
return mobile ? './?/Mobile/' : './';
}
/**
* @param {string} type
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentRaw(type, download, customSpecSuffix) {
customSpecSuffix = isUnd(customSpecSuffix) ? this.sAuthSuffix : customSpecSuffix;
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + customSpecSuffix + '/' + type + '/' +
this.subQueryPrefix() + '/' + download;
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentDownload(download, customSpecSuffix) {
return this.attachmentRaw('Download', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentPreview(download, customSpecSuffix) {
return this.attachmentRaw('View', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentThumbnailPreview(download, customSpecSuffix) {
return this.attachmentRaw('ViewThumbnail', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentPreviewAsPlain(download, customSpecSuffix) {
return this.attachmentRaw('ViewAsPlain', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
attachmentFramed(download, customSpecSuffix) {
return this.attachmentRaw('FramedView', download, customSpecSuffix);
}
/**
* @return {string}
*/
upload() {
return this.sServerPrefix + '/Upload/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
}
/**
* @return {string}
*/
uploadContacts() {
return this.sServerPrefix + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
}
/**
* @return {string}
*/
uploadBackground() {
return this.sServerPrefix + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
}
/**
* @return {string}
*/
append() {
return this.sServerPrefix + '/Append/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/';
}
/**
* @param {string} email
* @return {string}
*/
change(email) {
return this.sServerPrefix + '/Change/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + encodeURIComponent(email) + '/';
}
/**
* @param {string} add
* @return {string}
*/
ajax(add) {
return this.sServerPrefix + '/Ajax/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' + add;
}
/**
* @param {string} requestHash
* @return {string}
*/
messageViewLink(requestHash) {
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + requestHash;
}
/**
* @param {string} requestHash
* @return {string}
*/
messageDownloadLink(requestHash) {
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/Download/' + this.subQueryPrefix() + '/' + requestHash;
}
/**
* @param {string} email
* @return {string}
*/
avatarLink(email) {
return this.sServerPrefix + '/Raw/0/Avatar/' + encodeURIComponent(email) + '/';
}
/**
* @param {string} hash
* @return {string}
*/
publicLink(hash) {
return this.sServerPrefix + '/Raw/0/Public/' + hash + '/';
}
/**
* @param {string} hash
* @return {string}
*/
userBackground(hash) {
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix +
'/UserBackground/' + this.subQueryPrefix() + '/' + hash;
}
/**
* @param {string} inboxFolderName = 'INBOX'
* @return {string}
*/
inbox(inboxFolderName = 'INBOX') {
return this.sHashPrefix + 'mailbox/' + inboxFolderName;
}
/**
* @param {string=} screenName
* @return {string}
*/
settings(screenName = '') {
return this.sHashPrefix + 'settings' + (screenName ? '/' + screenName : '');
}
/**
* @return {string}
*/
about() {
return this.sHashPrefix + 'about';
}
/**
* @param {string} screenName
* @return {string}
*/
admin (screenName) {
let result = this.sHashPrefix;
switch (screenName) {
case 'AdminDomains':
result += 'domains';
break;
case 'AdminSecurity':
result += 'security';
break;
case 'AdminLicensing':
result += 'licensing';
break;
}
return result;
}
/**
* @param {string} folder
* @param {number=} page = 1
* @param {string=} search = ''
* @param {string=} threadUid = ''
* @return {string}
*/
mailBox(folder, page = 1, search = '', threadUid = '') {
page = isNormal(page) ? pInt(page) : 1;
search = pString(search);
let result = this.sHashPrefix + 'mailbox/';
if ('' !== folder)
{
const resultThreadUid = pInt(threadUid);
result += window.encodeURI(folder) + (0 < resultThreadUid ? '~' + resultThreadUid : '');
}
if (1 < page)
{
result = result.replace(/[\/]+$/, '');
result += '/p' + page;
}
if ('' !== search)
{
result = result.replace(/[\/]+$/, '');
result += '/' + window.encodeURI(search);
}
return result;
}
/**
* @return {string}
*/
phpInfo() {
return this.sServerPrefix + 'Info';
}
/**
* @param {string} lang
* @param {boolean} admin
* @return {string}
*/
langLink(lang, admin) {
return this.sServerPrefix + '/Lang/0/' + (admin ? 'Admin' : 'App') + '/' + window.encodeURI(lang) + '/' + this.sVersion + '/';
}
/**
* @return {string}
*/
exportContactsVcf() {
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsVcf/';
}
/**
* @return {string}
*/
exportContactsCsv() {
return this.sServerPrefix + '/Raw/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/ContactsCsv/';
}
/**
* @return {string}
*/
emptyContactPic() {
return this.sStaticPrefix + 'css/images/empty-contact.png';
}
/**
* @param {string} fileName
* @return {string}
*/
sound(fileName) {
return this.sStaticPrefix + 'sounds/' + fileName;
}
/**
* @param {string} theme
* @return {string}
*/
themePreviewLink(theme) {
let prefix = this.sVersionPrefix;
if ('@custom' === theme.substr(-7))
{
theme = trim(theme.substring(0, theme.length - 7));
prefix = this.sWebPrefix;
}
return prefix + 'themes/' + window.encodeURI(theme) + '/images/preview.png';
}
/**
* @return {string}
*/
notificationMailIcon() {
return this.sStaticPrefix + 'css/images/icom-message-notification.png';
}
/**
* @return {string}
*/
openPgpJs() {
return this.sStaticPrefix + 'js/min/openpgp.min.js';
}
/**
* @return {string}
*/
openPgpWorkerJs() {
return this.sStaticPrefix + 'js/min/openpgp.worker.min.js';
}
/**
* @return {string}
*/
openPgpWorkerPath() {
return this.sStaticPrefix + 'js/min/';
}
/**
* @param {boolean} xauth = false
* @return {string}
*/
socialGoogle(xauth = false) {
return this.sServerPrefix + 'SocialGoogle' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '') +
(xauth ? '&xauth=1' : '');
}
/**
* @return {string}
*/
socialTwitter() {
return this.sServerPrefix + 'SocialTwitter' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
}
/**
* @return {string}
*/
socialFacebook() {
return this.sServerPrefix + 'SocialFacebook' + ('' !== this.sAuthSuffix ? '/' + this.subQueryPrefix() + '/' + this.sAuthSuffix + '/' : '');
}
} }
module.exports = new Links(); /**
* @return {string}
*/
export function subQueryPrefix()
{
return SUB_QUERY_PREFIX;
}
/**
* @param {string=} startupUrl
* @return {string}
*/
export function root(startupUrl = '')
{
return HASH_PREFIX + pString(startupUrl);
}
/**
* @return {string}
*/
export function rootAdmin()
{
return ADMIN_HOST_USE ? ROOT : SERVER_PREFIX + ADMIN_PATH;
}
/**
* @param {boolean=} mobile = false
* @return {string}
*/
export function rootUser(mobile = false)
{
return mobile ? SERVER_PREFIX + '/Mobile/' : ROOT;
}
/**
* @param {string} type
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentRaw(type, download, customSpecSuffix)
{
customSpecSuffix = isUnd(customSpecSuffix) ? AUTH_PREFIX : customSpecSuffix;
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + customSpecSuffix + '/' + type + '/' + SUB_QUERY_PREFIX + '/' + download;
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentDownload(download, customSpecSuffix)
{
return attachmentRaw('Download', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentPreview(download, customSpecSuffix)
{
return attachmentRaw('View', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentThumbnailPreview(download, customSpecSuffix)
{
return attachmentRaw('ViewThumbnail', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentPreviewAsPlain(download, customSpecSuffix)
{
return attachmentRaw('ViewAsPlain', download, customSpecSuffix);
}
/**
* @param {string} download
* @param {string=} customSpecSuffix
* @return {string}
*/
export function attachmentFramed(download, customSpecSuffix)
{
return attachmentRaw('FramedView', download, customSpecSuffix);
}
/**
* @param {string} type
* @return {string}
*/
export function serverRequest(type)
{
return SERVER_PREFIX + '/' + type + '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/';
}
/**
* @return {string}
*/
export function upload()
{
return serverRequest('Upload');
}
/**
* @return {string}
*/
export function uploadContacts()
{
return serverRequest('UploadContacts');
}
/**
* @return {string}
*/
export function uploadBackground()
{
return serverRequest('UploadBackground');
}
/**
* @return {string}
*/
export function append()
{
return serverRequest('Append');
}
/**
* @param {string} email
* @return {string}
*/
export function change(email)
{
return serverRequest('Change') + encodeURIComponent(email) + '/';
}
/**
* @param {string} add
* @return {string}
*/
export function ajax(add)
{
return serverRequest('Ajax') + add;
}
/**
* @param {string} requestHash
* @return {string}
*/
export function messageViewLink(requestHash)
{
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/ViewAsPlain/' + SUB_QUERY_PREFIX + '/' + requestHash;
}
/**
* @param {string} requestHash
* @return {string}
*/
export function messageDownloadLink(requestHash)
{
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/Download/' + SUB_QUERY_PREFIX + '/' + requestHash;
}
/**
* @param {string} email
* @return {string}
*/
export function avatarLink(email)
{
return SERVER_PREFIX + '/Raw/0/Avatar/' + encodeURIComponent(email) + '/';
}
/**
* @param {string} hash
* @return {string}
*/
export function publicLink(hash)
{
return SERVER_PREFIX + '/Raw/0/Public/' + hash + '/';
}
/**
* @param {string} hash
* @return {string}
*/
export function userBackground(hash)
{
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/UserBackground/' + SUB_QUERY_PREFIX + '/' + hash;
}
/**
* @return {string}
*/
export function phpInfo()
{
return SERVER_PREFIX + '/Info';
}
/**
* @param {string} lang
* @param {boolean} isAdmin
* @return {string}
*/
export function langLink(lang, isAdmin)
{
return SERVER_PREFIX + '/Lang/0/' + (isAdmin ? 'Admin' : 'App') + '/' + window.encodeURI(lang) + '/' + VERSION + '/';
}
/**
* @return {string}
*/
export function exportContactsVcf()
{
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/ContactsVcf/';
}
/**
* @return {string}
*/
export function exportContactsCsv()
{
return SERVER_PREFIX + '/Raw/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/ContactsCsv/';
}
/**
* @param {boolean} xauth = false
* @return {string}
*/
export function socialGoogle(xauth = false)
{
return SERVER_PREFIX + 'SocialGoogle' +
('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '') + (xauth ? '&xauth=1' : '');
}
/**
* @return {string}
*/
export function socialTwitter()
{
return SERVER_PREFIX + 'SocialTwitter' +
('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '');
}
/**
* @return {string}
*/
export function socialFacebook()
{
return SERVER_PREFIX + 'SocialFacebook' +
('' !== AUTH_PREFIX ? '/' + SUB_QUERY_PREFIX + '/' + AUTH_PREFIX + '/' : '');
}
/**
* @param {string} path
* @return {string}
*/
export function staticPrefix(path)
{
return STATIC_PREFIX + path;
}
/**
* @return {string}
*/
export function emptyContactPic()
{
return staticPrefix('css/images/empty-contact.png');
}
/**
* @param {string} fileName
* @return {string}
*/
export function sound(fileName)
{
return staticPrefix('sounds/' + fileName);
}
/**
* @return {string}
*/
export function notificationMailIcon()
{
return staticPrefix('css/images/icom-message-notification.png');
}
/**
* @return {string}
*/
export function openPgpJs()
{
return staticPrefix('js/min/openpgp.min.js');
}
/**
* @return {string}
*/
export function openPgpWorkerJs()
{
return staticPrefix('js/min/openpgp.worker.min.js');
}
/**
* @return {string}
*/
export function openPgpWorkerPath()
{
return staticPrefix('js/min/');
}
/**
* @param {string} theme
* @return {string}
*/
export function themePreviewLink(theme)
{
let prefix = VERSION_PREFIX;
if ('@custom' === theme.substr(-7))
{
theme = trim(theme.substring(0, theme.length - 7));
prefix = WEB_PREFIX;
}
return prefix + 'themes/' + window.encodeURI(theme) + '/images/preview.png';
}
/**
* @param {string} inboxFolderName = 'INBOX'
* @return {string}
*/
export function inbox(inboxFolderName = 'INBOX')
{
return HASH_PREFIX + 'mailbox/' + inboxFolderName;
}
/**
* @param {string=} screenName = ''
* @return {string}
*/
export function settings(screenName = '')
{
return HASH_PREFIX + 'settings' + (screenName ? '/' + screenName : '');
}
/**
* @return {string}
*/
export function about()
{
return HASH_PREFIX + 'about';
}
/**
* @param {string} screenName
* @return {string}
*/
export function admin(screenName)
{
let result = HASH_PREFIX;
switch (screenName) {
case 'AdminDomains':
result += 'domains';
break;
case 'AdminSecurity':
result += 'security';
break;
case 'AdminLicensing':
result += 'licensing';
break;
}
return result;
}
/**
* @param {string} folder
* @param {number=} page = 1
* @param {string=} search = ''
* @param {string=} threadUid = ''
* @return {string}
*/
export function mailBox(folder, page = 1, search = '', threadUid = '')
{
page = isNormal(page) ? pInt(page) : 1;
search = pString(search);
let result = HASH_PREFIX + 'mailbox/';
if ('' !== folder)
{
const resultThreadUid = pInt(threadUid);
result += window.encodeURI(folder) + (0 < resultThreadUid ? '~' + resultThreadUid : '');
}
if (1 < page)
{
result = result.replace(/[\/]+$/, '');
result += '/p' + page;
}
if ('' !== search)
{
result = result.replace(/[\/]+$/, '');
result += '/' + window.encodeURI(search);
}
return result;
}

View file

@ -2,7 +2,7 @@
/* eslint key-spacing: 0 */ /* eslint key-spacing: 0 */
/* eslint quote-props: 0 */ /* eslint quote-props: 0 */
module.exports = { const Mime = {
'eml' : 'message/rfc822', 'eml' : 'message/rfc822',
'mime' : 'message/rfc822', 'mime' : 'message/rfc822',
'txt' : 'text/plain', 'txt' : 'text/plain',
@ -162,3 +162,5 @@ module.exports = {
'odt' : 'application/vnd.oasis.opendocument.text', 'odt' : 'application/vnd.oasis.opendocument.text',
'ods' : 'application/vnd.oasis.opendocument.spreadsheet' 'ods' : 'application/vnd.oasis.opendocument.spreadsheet'
}; };
export {Mime, Mime as default};

View file

@ -2,159 +2,147 @@
import {window, $, _, moment} from 'common'; import {window, $, _, moment} from 'common';
import Translator from 'Common/Translator'; import Translator from 'Common/Translator';
class Momentor let _moment = null;
let _momentNow = 0;
const updateMomentNow = _.debounce(() => {
_moment = moment();
}, 500, true);
const updateMomentNowUnix = _.debounce(() => {
_momentNow = moment().unix();
}, 500, true);
export function momentNow()
{ {
_moment = null; updateMomentNow();
_momentNow = 0; return _moment || moment();
}
constructor() export function momentNowUnix()
{
updateMomentNowUnix();
return _momentNow || 0;
}
/**
* @param {number} date
* @return {string}
*/
export function searchSubtractFormatDateHelper(date)
{
momentNow().clone().subtract('days', date).format('YYYY.MM.DD');
}
/**
* @param {Object} m
* @return {string}
*/
function formatCustomShortDate(m)
{
const now = momentNow();
if (m && now)
{ {
this.updateMomentNow = _.debounce(() => { switch(true)
this._moment = moment();
}, 500, true);
this.updateMomentNowUnix = _.debounce(() => {
this._momentNow = moment().unix();
}, 500, true);
this.format = _.bind(this.format, this);
}
momentNow() {
this.updateMomentNow();
return this._moment || moment();
}
momentNowUnix() {
this.updateMomentNowUnix();
return this._momentNow || 0;
}
/**
* @param {number} date
* @return {string}
*/
searchSubtractFormatDateHelper(date) {
return this.momentNow().clone().subtract('days', date).format('YYYY.MM.DD');
}
/**
* @param {Object} m
* @return {string}
*/
formatCustomShortDate(m) {
const now = this.momentNow();
if (m && now)
{ {
switch(true) case 4 >= now.diff(m, 'hours'):
{ return m.fromNow();
case 4 >= now.diff(m, 'hours'): case now.format('L') === m.format('L'):
return m.fromNow(); return Translator.i18n('MESSAGE_LIST/TODAY_AT', {
case now.format('L') === m.format('L'): TIME: m.format('LT')
return Translator.i18n('MESSAGE_LIST/TODAY_AT', { });
TIME: m.format('LT') case now.clone().subtract('days', 1).format('L') === m.format('L'):
}); return Translator.i18n('MESSAGE_LIST/YESTERDAY_AT', {
case now.clone().subtract('days', 1).format('L') === m.format('L'): TIME: m.format('LT')
return Translator.i18n('MESSAGE_LIST/YESTERDAY_AT', { });
TIME: m.format('LT') case now.year() === m.year():
}); return m.format('D MMM.');
case now.year() === m.year():
return m.format('D MMM.');
}
}
return m ? m.format('LL') : '';
}
/**
* @param {number} timeStampInUTC
* @param {string} format
* @return {string}
*/
format(timeStampInUTC, format) {
let
m = null,
result = ''
;
const now = this.momentNowUnix();
timeStampInUTC = 0 < timeStampInUTC ? timeStampInUTC : (0 === timeStampInUTC ? now : 0);
timeStampInUTC = now < timeStampInUTC ? now : timeStampInUTC;
m = 0 < timeStampInUTC ? moment.unix(timeStampInUTC) : null;
if (m && 1970 === m.year())
{
m = null;
}
if (m)
{
switch (format)
{
case 'FROMNOW':
result = m.fromNow();
break;
case 'SHORT':
result = this.formatCustomShortDate(m);
break;
case 'FULL':
result = m.format('LLL');
break;
default:
result = m.format(format);
break;
}
}
return result;
}
/**
* @param {Object} element
*/
momentToNode(element) {
var
key = '',
time = 0,
$el = $(element)
;
time = $el.data('moment-time');
if (time)
{
key = $el.data('moment-format');
if (key)
{
$el.text(this.format(time, key));
}
key = $el.data('moment-format-title');
if (key)
{
$el.attr('title', this.format(time, key));
}
} }
} }
/** return m ? m.format('LL') : '';
* @param {Object} elements }
*/
momentToNodes(elements) { /**
_.defer(() => { * @param {number} timeStampInUTC
$('.moment', elements).each((index, item) => { * @param {string} formatStr
this.momentToNode(item); * @return {string}
}); */
}); export function format(timeStampInUTC, formatStr)
{
let
m = null,
result = ''
;
const now = momentNowUnix();
timeStampInUTC = 0 < timeStampInUTC ? timeStampInUTC : (0 === timeStampInUTC ? now : 0);
timeStampInUTC = now < timeStampInUTC ? now : timeStampInUTC;
m = 0 < timeStampInUTC ? moment.unix(timeStampInUTC) : null;
if (m && 1970 === m.year())
{
m = null;
} }
reload() { if (m)
this.momentToNodes(window.document); {
switch (formatStr)
{
case 'FROMNOW':
result = m.fromNow();
break;
case 'SHORT':
result = formatCustomShortDate(m);
break;
case 'FULL':
result = m.format('LLL');
break;
default:
result = m.format(formatStr);
break;
}
}
return result;
}
/**
* @param {Object} element
*/
export function momentToNode(element)
{
var
key = '',
time = 0,
$el = $(element)
;
time = $el.data('moment-time');
if (time)
{
key = $el.data('moment-format');
if (key)
{
$el.text(format(time, key));
}
key = $el.data('moment-format-title');
if (key)
{
$el.attr('title', format(time, key));
}
} }
} }
module.exports = new Momentor(); export function reload()
{
_.defer(() => {
$('.moment', window.document).each((index, item) => {
momentToNode(item);
});
});
}

View file

@ -2,106 +2,107 @@
import {_} from 'common'; import {_} from 'common';
import {isFunc, isArray, isUnd} from 'Common/Utils'; import {isFunc, isArray, isUnd} from 'Common/Utils';
import {data as GlobalsData} from 'Common/Globals'; import {data as GlobalsData} from 'Common/Globals';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class Plugins const SIMPLE_HOOKS = {};
const USER_VIEW_MODELS_HOOKS = [];
const ADMIN_VIEW_MODELS_HOOKS = [];
/**
* @param {string} name
* @param {Function} callback
*/
export function addHook(name, callback)
{ {
oSimpleHooks = {}; if (isFunc(callback))
aUserViewModelsHooks = []; {
aAdminViewModelsHooks = []; if (!isArray(SIMPLE_HOOKS[name]))
constructor() {}
/**
* @param {string} name
* @param {Function} callback
*/
addHook(name, callback) {
if (isFunc(callback))
{ {
if (!isArray(this.oSimpleHooks[name])) SIMPLE_HOOKS[name] = [];
{
this.oSimpleHooks[name] = [];
}
this.oSimpleHooks[name].push(callback);
} }
}
/** SIMPLE_HOOKS[name].push(callback);
* @param {string} name
* @param {Array=} args
*/
runHook(name, args = []) {
if (isArray(this.oSimpleHooks[name]))
{
_.each(this.oSimpleHooks[name], (callback) => {
callback.apply(null, args);
});
}
}
/**
* @param {string} name
* @return {?}
*/
mainSettingsGet(name) {
return Settings.settingsGet(name);
}
/**
* @param {Function} callback
* @param {string} action
* @param {Object=} parameters
* @param {?number=} timeout
*/
remoteRequest(callback, action, parameters, timeout) {
if (GlobalsData.__APP__)
{
GlobalsData.__APP__.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout);
}
}
/**
* @param {Function} SettingsViewModelClass
* @param {string} labelName
* @param {string} template
* @param {string} route
*/
addSettingsViewModel(SettingsViewModelClass, template, labelName, route) {
this.aUserViewModelsHooks.push([SettingsViewModelClass, template, labelName, route]);
}
/**
* @param {Function} SettingsViewModelClass
* @param {string} labelName
* @param {string} template
* @param {string} route
*/
addSettingsViewModelForAdmin(SettingsViewModelClass, template, labelName, route) {
this.aAdminViewModelsHooks.push([SettingsViewModelClass, template, labelName, route]);
}
/**
* @param {boolean} admin
*/
runSettingsViewModelHooks(admin) {
const Knoin = require('Knoin/Knoin');
_.each(admin ? this.aAdminViewModelsHooks : this.aUserViewModelsHooks, (view) => {
Knoin.addSettingsViewModel(view[0], view[1], view[2], view[3]);
});
}
/**
* @param {string} pluginSection
* @param {string} name
* @return {?}
*/
settingsGet(pluginSection, name) {
let plugins = Settings.settingsGet('Plugins');
plugins = plugins && !isUnd(plugins[pluginSection]) ? plugins[pluginSection] : null;
return plugins ? (isUnd(plugins[name]) ? null : plugins[name]) : null;
} }
} }
module.exports = new Plugins(); /**
* @param {string} name
* @param {Array=} args = []
*/
export function runHook(name, args = [])
{
if (isArray(SIMPLE_HOOKS[name]))
{
_.each(SIMPLE_HOOKS[name], (callback) => {
callback.apply(null, args);
});
}
}
/**
* @param {string} name
* @return {?}
*/
export function mainSettingsGet(name)
{
return Settings.settingsGet(name);
}
/**
* @param {Function} callback
* @param {string} action
* @param {Object=} parameters
* @param {?number=} timeout
*/
export function remoteRequest(callback, action, parameters, timeout)
{
if (GlobalsData.__APP__)
{
GlobalsData.__APP__.remote().defaultRequest(callback, 'Plugin' + action, parameters, timeout);
}
}
/**
* @param {Function} SettingsViewModelClass
* @param {string} labelName
* @param {string} template
* @param {string} route
*/
export function addSettingsViewModel(SettingsViewModelClass, template, labelName, route)
{
USER_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
}
/**
* @param {Function} SettingsViewModelClass
* @param {string} labelName
* @param {string} template
* @param {string} route
*/
export function addSettingsViewModelForAdmin(SettingsViewModelClass, template, labelName, route)
{
ADMIN_VIEW_MODELS_HOOKS.push([SettingsViewModelClass, template, labelName, route]);
}
/**
* @param {boolean} admin
*/
export function runSettingsViewModelHooks(admin)
{
const Knoin = require('Knoin/Knoin');
_.each(admin ? ADMIN_VIEW_MODELS_HOOKS : USER_VIEW_MODELS_HOOKS, (view) => {
Knoin.addSettingsViewModel(view[0], view[1], view[2], view[3]);
});
}
/**
* @param {string} pluginSection
* @param {string} name
* @return {?}
*/
export function settingsGet(pluginSection, name)
{
let plugins = Settings.settingsGet('Plugins');
plugins = plugins && !isUnd(plugins[pluginSection]) ? plugins[pluginSection] : null;
return plugins ? (isUnd(plugins[name]) ? null : plugins[name]) : null;
}

View file

@ -2,7 +2,7 @@
import {window, $, _} from 'common'; import {window, $, _} from 'common';
import ko from 'ko'; import ko from 'ko';
import {Notification, UploadErrorCode} from 'Common/Enums'; import {Notification, UploadErrorCode} from 'Common/Enums';
import {pInt, microtime, noop, inArray} from 'Common/Utils'; import {pInt, isUnd, isNull, has, bind, microtime, noop, inArray} from 'Common/Utils';
import {$html, bAnimationSupported} from 'Common/Globals'; import {$html, bAnimationSupported} from 'Common/Globals';
class Translator class Translator
@ -13,7 +13,7 @@ class Translator
constructor() { constructor() {
this.data = window.rainloopI18N || {}; this.data = window.rainloopI18N || {};
this.trigger = ko.observable(false); this.trigger = ko.observable(false);
this.i18n = _.bind(this.i18n, this); this.i18n = bind(this.i18n, this);
this.init(); this.init();
} }
@ -30,16 +30,16 @@ class Translator
result = this.data[key] result = this.data[key]
; ;
if (_.isUndefined(result)) if (isUnd(result))
{ {
result = _.isUndefined(defaulValue) ? key : defaulValue; result = isUnd(defaulValue) ? key : defaulValue;
} }
if (!_.isUndefined(valueList) && !_.isNull(valueList)) if (!isUnd(valueList) && !isNull(valueList))
{ {
for (valueName in valueList) for (valueName in valueList)
{ {
if (_.has(valueList, valueName)) if (has(valueList, valueName))
{ {
result = result.replace('%' + valueName + '%', valueList[valueName]); result = result.replace('%' + valueName + '%', valueList[valueName]);
} }
@ -244,8 +244,8 @@ class Translator
} }
defCode = defCode ? (window.parseInt(defCode, 10)) || 0 : 0; defCode = defCode ? (window.parseInt(defCode, 10)) || 0 : 0;
return _.isUndefined(this.notificationI18N[code]) ? ( return isUnd(this.notificationI18N[code]) ? (
defCode && _.isUndefined(this.notificationI18N[defCode]) ? this.notificationI18N[defCode] : '' defCode && isUnd(this.notificationI18N[defCode]) ? this.notificationI18N[defCode] : ''
) : this.notificationI18N[code]; ) : this.notificationI18N[code];
} }

View file

@ -5,10 +5,10 @@ import _ from '_';
import ko from 'ko'; import ko from 'ko';
import {$win, $div, dropdownVisibility, data as GlobalsData} from 'Common/Globals'; import {$win, $div, dropdownVisibility, data as GlobalsData} from 'Common/Globals';
import {ComposeType, EventKeyCode, SaveSettingsStep, FolderType} from 'Common/Enums'; import {ComposeType, EventKeyCode, SaveSettingsStep, FolderType} from 'Common/Enums';
import {Mime} from 'Common/Mime';
const JSEncrypt = require('JSEncrypt'); import JSEncrypt from 'JSEncrypt';
const Autolinker = require('Autolinker'); import Autolinker from 'Autolinker';
const Mime = require('Common/Mime');
const trim = $.trim; const trim = $.trim;
const inArray = $.inArray; const inArray = $.inArray;
@ -17,23 +17,20 @@ const isObject = _.isObject;
const isFunc = _.isFunction; const isFunc = _.isFunction;
const isUnd = _.isUndefined; const isUnd = _.isUndefined;
const isNull = _.isNull; const isNull = _.isNull;
const has = _.has;
const bind = _.bind;
const noop = () => {}; const noop = () => {};
export {trim, inArray, isArray, isObject, isFunc, isUnd, isNull, noop, noop as emptyFunction}; export {trim, inArray, isArray, isObject, isFunc, isUnd, isNull, has, bind, noop, noop as emptyFunction};
/** /**
* @param {Function} callback * @param {Function} callback
*/ */
export function silentTryCatch(callback) export function silentTryCatch(callback)
{ {
try try {
{
callback(); callback();
} } catch (e) {/* eslint-disable-line no-empty */}
catch (e)
{
// eslint-disable-line no-empty
}
} }
/** /**
@ -284,16 +281,6 @@ const timeOutActionSecond = (function () {
export {timeOutAction, timeOutActionSecond}; export {timeOutAction, timeOutActionSecond};
/**
* @param {(Object|null|undefined)} item
* @param {string} prop
* @return {boolean}
*/
export function hos(item, prop)
{
return item && window.Object && window.Object.hasOwnProperty ? window.Object.hasOwnProperty.call(item, prop) : false;
}
/** /**
* @return {boolean} * @return {boolean}
*/ */
@ -326,9 +313,7 @@ export function removeInFocus(force)
{ {
window.document.activeElement.blur(); window.document.activeElement.blur();
} }
} catch (e) { } catch (e) {/* eslint-disable-line no-empty */}
// eslint-disable-line no-empty
}
} }
} }
@ -347,9 +332,7 @@ export function removeSelection()
{ {
window.document.selection.empty(); window.document.selection.empty();
} }
} catch (e) { } catch (e) {/* eslint-disable-line no-empty */}
// eslint-disable-line no-empty
}
} }
/** /**
@ -626,6 +609,122 @@ export function defautOptionsAfterRender(domOption, item)
} }
} }
/**
* @param {string} title
* @param {Object} body
* @param {boolean} isHtml
* @param {boolean} print
*/
export function clearBqSwitcher(body)
{
body.find('blockquote.rl-bq-switcher').removeClass('rl-bq-switcher hidden-bq');
body.find('.rlBlockquoteSwitcher').off('.rlBlockquoteSwitcher').remove();
body.find('[data-html-editor-font-wrapper]').removeAttr('data-html-editor-font-wrapper');
}
/**
* @param {string} title
* @param {Object} body
* @param {boolean} isHtml
* @param {boolean} print
*/
export function previewMessage(title, body, isHtml, print)
{
const
win = window.open(''),
doc = win.document,
bodyClone = body.clone(),
bodyClass = isHtml ? 'html' : 'plain'
;
clearBqSwitcher(bodyClone);
const html = bodyClone ? bodyClone.html() : '';
title = encodeHtml(title);
doc.write(`<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="robots" content="noindex, nofollow, noodp" />
<title>${title}</title>
<style>
html, body {
background-color: #fff;
font-size: 13px;
font-family: arial, sans-serif;
}
a {color: blue; text-decoration: underline}
a:visited {color: #609}
a:active {color: red}
blockquote {border-left: 2px solid black; margin: 0; padding: 0px 10px}
pre {
margin: 0px;
padding: 0px;
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
background: #fff;
border: none;
white-space: pre-wrap;
word-wrap: break-word;
word-break: break-all;
}
body.html pre {
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
white-space: pre-wrap;
word-wrap: break-word;
word-break: normal;
}
body.plain {
padding: 15px;
white-space: pre-wrap;
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
}
body.plain pre {
margin: 0px;
padding: 0px;
background: #fff;
border: none;
font-family: Monaco, Menlo, Consolas, 'Courier New', monospace;
white-space: pre-wrap;
word-wrap: break-word;
word-break: normal;
}
body.plain blockquote {
border-left: 2px solid blue;
color: blue;
}
body.plain blockquote blockquote {
border-left: 2px solid green;
color: green;
}
body.plain blockquote blockquote blockquote {
border-left: 2px solid red;
color: red;
}
</style>
</head>
<body class="${bodyClass}">${html}</body>
</html>`);
doc.close();
if (print)
{
window.setTimeout(() => win.print(), 100);
}
}
/** /**
* @param {Object} viewModel * @param {Object} viewModel
* @param {string} templateID * @param {string} templateID
@ -637,7 +736,7 @@ export function windowPopupKnockout(viewModel, templateID, title, fCallback = nu
const const
win = window.open(''), win = window.open(''),
doc = win.document, doc = win.document,
func = '__OpenerApplyBindingsUid' + fakeMd5() + '__', func = 'openerApplyBindingsUid' + fakeMd5(),
template = $('#' + templateID) template = $('#' + templateID)
; ;
@ -671,7 +770,6 @@ export function windowPopupKnockout(viewModel, templateID, title, fCallback = nu
<html> <html>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="user-scalable=no" /> <meta name="viewport" content="user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="robots" content="noindex, nofollow, noodp" /> <meta name="robots" content="noindex, nofollow, noodp" />
@ -684,7 +782,7 @@ export function windowPopupKnockout(viewModel, templateID, title, fCallback = nu
const script = doc.createElement('script'); const script = doc.createElement('script');
script.type = 'text/javascript'; script.type = 'text/javascript';
script.innerHTML = `if(window&&window.opener&&window.opener['${func}']){window.opener['${func}']();window.opener['${func}']=null}`; script.innerHTML = `if(window&&window.opener&&window.opener['${func}']){window.opener['${func}']();}`;
doc.getElementsByTagName('head')[0].appendChild(script); doc.getElementsByTagName('head')[0].appendChild(script);
} }
@ -1325,19 +1423,6 @@ export function triggerAutocompleteInputChange(delay = false) {
} }
} }
/**
* @param {Object} params
*/
export function setHeadViewport(params)
{
let content = [];
_.each(params, (key, value) => {
content.push('' + key + '=' + value);
});
$('#app-head-viewport').attr('content', content.join(', '));
}
/** /**
* @param {string} fileName * @param {string} fileName
* @return {string} * @return {string}

View file

@ -1,9 +1,7 @@
class AbstractBoot class AbstractBoot
{ {
bootstart() { bootstart() {/* eslint-disable-line no-empty */}
// eslint-disable-line no-empty
}
} }
export {AbstractBoot, AbstractBoot as default}; export {AbstractBoot, AbstractBoot as default};

View file

@ -4,7 +4,6 @@
'use strict'; 'use strict';
var var
window = require('window'),
_ = require('_'), _ = require('_'),
$ = require('$'), $ = require('$'),
ko = require('ko'), ko = require('ko'),
@ -755,33 +754,8 @@
*/ */
MessageModel.prototype.viewPopupMessage = function (bPrint) MessageModel.prototype.viewPopupMessage = function (bPrint)
{ {
Utils.windowPopupKnockout(this.getDataForWindowPopup(), 'PopupsWindowSimpleMessage', this.showLazyExternalImagesInBody();
this.subject(), function (oPopupWin) Utils.previewMessage(this.subject(), this.body, this.isHtml(), bPrint);
{
if (oPopupWin && oPopupWin.document && oPopupWin.document.body)
{
$('img.lazy', oPopupWin.document.body).each(function (iIndex, oImg) {
var
$oImg = $(oImg),
sOrig = $oImg.data('original'),
sSrc = $oImg.attr('src')
;
if (0 <= iIndex && sOrig && !sSrc)
{
$oImg.attr('src', sOrig);
}
});
if (bPrint)
{
window.setTimeout(function () {
oPopupWin.print();
}, 100);
}
}
});
}; };
MessageModel.prototype.printMessage = function () MessageModel.prototype.printMessage = function ()
@ -870,17 +844,26 @@
return this; return this;
}; };
MessageModel.prototype.showLazyExternalImagesInBody = function ()
{
if (this.body)
{
$('.lazy.lazy-inited[data-original]', this.body).each(function () {
$(this).attr('src', $(this).attr('data-original')).removeAttr('data-original');
});
}
};
MessageModel.prototype.showExternalImages = function (bLazy) MessageModel.prototype.showExternalImages = function (bLazy)
{ {
if (this.body && this.body.data('rl-has-images')) if (this.body && this.body.data('rl-has-images'))
{ {
var sAttr = '';
bLazy = Utils.isUnd(bLazy) ? false : bLazy; bLazy = Utils.isUnd(bLazy) ? false : bLazy;
this.hasImages(false); this.hasImages(false);
this.body.data('rl-has-images', false); this.body.data('rl-has-images', false);
sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src'; var sAttr = this.proxy ? 'data-x-additional-src' : 'data-x-src';
$('[' + sAttr + ']', this.body).each(function () { $('[' + sAttr + ']', this.body).each(function () {
if (bLazy && $(this).is('img')) if (bLazy && $(this).is('img'))
{ {
@ -888,7 +871,7 @@
.addClass('lazy') .addClass('lazy')
.attr('data-original', $(this).attr(sAttr)) .attr('data-original', $(this).attr(sAttr))
.removeAttr(sAttr) .removeAttr(sAttr)
; ;
} }
else else
{ {

View file

@ -2,51 +2,45 @@
import {window} from 'common'; import {window} from 'common';
import {isUnd, isNormal, isArray, inArray} from 'Common/Utils'; import {isUnd, isNormal, isArray, inArray} from 'Common/Utils';
class SettingsStorage let SETTINGS = window.__rlah_data() || null;
SETTINGS = isNormal(SETTINGS) ? SETTINGS : {};
let APP_SETTINGS = SETTINGS.System || null;
APP_SETTINGS = isNormal(APP_SETTINGS) ? APP_SETTINGS : {};
/**
* @param {string} name
* @return {*}
*/
export function settingsGet(name)
{ {
settings = {}; return isUnd(SETTINGS[name]) ? null : SETTINGS[name];
appSettings = {};
constructor() {
this.settings = window.__rlah_data() || {};
this.settings = isNormal(this.settings) ? this.settings : {};
this.appSettings = this.settings.System || null;
this.appSettings = isNormal(this.appSettings) ? this.appSettings : {};
}
/**
* @param {string} name
* @return {*}
*/
settingsGet(name) {
return isUnd(this.settings[name]) ? null : this.settings[name];
}
/**
* @param {string} name
* @param {*} value
*/
settingsSet(name, value) {
this.settings[name] = value;
}
/**
* @param {string} name
* @return {*}
*/
appSettingsGet(name) {
return isUnd(this.appSettings[name]) ? null : this.appSettings[name];
}
/**
* @param {string} name
* @return {boolean}
*/
capa(name) {
const values = this.settingsGet('Capa');
return isArray(values) && isNormal(name) && -1 < inArray(name, values);
}
} }
module.exports = new SettingsStorage(); /**
* @param {string} name
* @param {*} value
*/
export function settingsSet(name, value)
{
SETTINGS[name] = value;
}
/**
* @param {string} name
* @return {*}
*/
export function appSettingsGet(name)
{
return isUnd(APP_SETTINGS[name]) ? null : APP_SETTINGS[name];
}
/**
* @param {string} name
* @return {boolean}
*/
export function capa(name)
{
const values = settingsGet('Capa');
return isArray(values) && isNormal(name) && -1 < inArray(name, values);
}

View file

@ -1,7 +1,7 @@
import ko from 'ko'; import ko from 'ko';
import {$html, bMobileDevice} from 'Common/Globals'; import {$html, bMobileDevice} from 'Common/Globals';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
class AbstractAppStore class AbstractAppStore
{ {

View file

@ -1,6 +1,6 @@
import ko from 'ko'; import ko from 'ko';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
import {AbstractAppStore} from 'Stores/AbstractApp'; import {AbstractAppStore} from 'Stores/AbstractApp';

View file

@ -2,7 +2,7 @@
import ko from 'ko'; import ko from 'ko';
import {Focused, KeyState} from 'Common/Enums'; import {Focused, KeyState} from 'Common/Enums';
import {keyScope} from 'Common/Globals'; import {keyScope} from 'Common/Globals';
import Settings from 'Storage/Settings'; import * as Settings from 'Storage/Settings';
import {isNonEmptyArray} from 'Common/Utils'; import {isNonEmptyArray} from 'Common/Utils';
import {AbstractAppStore} from 'Stores/AbstractApp'; import {AbstractAppStore} from 'Stores/AbstractApp';

View file

@ -63,6 +63,14 @@ html.csstransitions.rl-started-delay {
} }
} }
html {
&.rgba.cssanimations.backgroundsize .e-strip-animation {
background-size: 60px 60px;
.rl-strip-animation(0, 0.1);
animation: animate-stripes 2s linear infinite;
}
}
html.rl-anim { html.rl-anim {
&.cssanimations.csstransitions.no-mobile .b-login-content .errorAnimated { &.cssanimations.csstransitions.no-mobile .b-login-content .errorAnimated {
@ -86,12 +94,6 @@ html.rl-anim {
.transition(all 0.3s ease-out); .transition(all 0.3s ease-out);
} }
&.rgba.cssanimations.backgroundsize .e-strip-animation {
background-size: 60px 60px;
.rl-strip-animation(0, 0.1);
animation: animate-stripes 2s linear infinite;
}
&.csstransitions .button-delete-transitions { &.csstransitions .button-delete-transitions {
.transition(all 0.2s linear); .transition(all 0.2s linear);
} }

View file

@ -1117,29 +1117,7 @@
oText = $(oMessage.body).clone(); oText = $(oMessage.body).clone();
if (oText) if (oText)
{ {
oText.find('blockquote.rl-bq-switcher').removeClass('rl-bq-switcher hidden-bq'); Utils.clearBqSwitcher(oText);
oText.find('.rlBlockquoteSwitcher').off('.rlBlockquoteSwitcher').remove();
oText.find('[data-html-editor-font-wrapper]').removeAttr('data-html-editor-font-wrapper');
// (function () {
//
// var oTmp = null, iLimit = 0;
//
// while (true)
// {
// iLimit++;
//
// oTmp = oText.children();
// if (10 > iLimit && oTmp.is('div') && 1 === oTmp.length)
// {
// oTmp.children().unwrap();
// continue;
// }
//
// break;
// }
//
// }());
sText = oText.html(); sText = oText.html();
} }

View file

@ -289,43 +289,40 @@
this.goToUpUpOrDownDown(bV); this.goToUpUpOrDownDown(bV);
}, this)); }, this));
Events Events.sub('mailbox.message-list.selector.go-down', function (bSelect) {
.sub('mailbox.message-list.selector.go-down', function (bSelect) { this.selector.goDown(bSelect);
this.selector.goDown(bSelect); }, this);
}, this)
.sub('mailbox.message-list.selector.go-up', function (bSelect) {
this.selector.goUp(bSelect);
}, this)
;
Events Events.sub('mailbox.message-list.selector.go-up', function (bSelect) {
.sub('mailbox.message.show', function (sFolder, sUid) { this.selector.goUp(bSelect);
}, this);
var oMessage = _.find(this.messageList(), function (oItem) { Events.sub('mailbox.message.show', function (sFolder, sUid) {
return oItem && sFolder === oItem.folderFullNameRaw && sUid === oItem.uid;
});
if ('INBOX' === sFolder) var oMessage = _.find(this.messageList(), function (oItem) {
return oItem && sFolder === oItem.folderFullNameRaw && sUid === oItem.uid;
});
if ('INBOX' === sFolder)
{
kn.setHash(Links.mailBox(sFolder, 1));
}
if (oMessage)
{
this.selector.selectMessageItem(oMessage);
}
else
{
if ('INBOX' !== sFolder)
{ {
kn.setHash(Links.mailBox(sFolder, 1)); kn.setHash(Links.mailBox(sFolder, 1));
} }
if (oMessage) MessageStore.selectMessageByFolderAndUid(sFolder, sUid);
{ }
this.selector.selectMessageItem(oMessage);
}
else
{
if ('INBOX' !== sFolder)
{
kn.setHash(Links.mailBox(sFolder, 1));
}
MessageStore.selectMessageByFolderAndUid(sFolder, sUid); }, this);
}
}, this)
;
MessageStore.messageListEndHash.subscribe(function () { MessageStore.messageListEndHash.subscribe(function () {
this.selector.scrollToTop(); this.selector.scrollToTop();

View file

@ -1,13 +1,12 @@
import window from 'window'; import window from 'window';
import _ from '_';
import $ from '$'; import $ from '$';
import {kill_CtrlA_CtrlS, detectDropdownVisibility, createCommand} from 'Common/Utils'; import {kill_CtrlA_CtrlS, detectDropdownVisibility, createCommand} from 'Common/Utils';
import {$win, $html, data as GlobalsData, bMobileDevice} from 'Common/Globals'; import {$win, $html, data as GlobalsData, bMobileDevice} from 'Common/Globals';
import Plugins from 'Common/Plugins'; import * as Enums from 'Common/Enums';
import * as Plugins from 'Common/Plugins';
import Translator from 'Common/Translator'; import Translator from 'Common/Translator';
import EmailModel from 'Model/Email'; import EmailModel from 'Model/Email';
import * as Enums from 'Common/Enums';
export default (App) => { export default (App) => {
@ -29,17 +28,16 @@ export default (App) => {
const rl = window.rl || {}; const rl = window.rl || {};
rl.i18n = _.bind(Translator.i18n, Translator); rl.i18n = Translator.i18n;
rl.addHook = _.bind(Plugins.addHook, Plugins);
rl.settingsGet = _.bind(Plugins.mainSettingsGet, Plugins);
rl.createCommand = createCommand; rl.createCommand = createCommand;
rl.addSettingsViewModel = _.bind(Plugins.addSettingsViewModel, Plugins); rl.addSettingsViewModel = Plugins.addSettingsViewModel;
rl.addSettingsViewModelForAdmin = _.bind(Plugins.addSettingsViewModelForAdmin, Plugins); rl.addSettingsViewModelForAdmin = Plugins.addSettingsViewModelForAdmin;
rl.pluginRemoteRequest = _.bind(Plugins.remoteRequest, Plugins); rl.addHook = Plugins.addHook;
rl.pluginSettingsGet = _.bind(Plugins.settingsGet, Plugins); rl.settingsGet = Plugins.mainSettingsGet;
rl.pluginSettingsGet = Plugins.settingsGet;
rl.pluginRemoteRequest = Plugins.remoteRequest;
rl.EmailModel = EmailModel; rl.EmailModel = EmailModel;
rl.Enums = Enums; rl.Enums = Enums;
@ -50,21 +48,21 @@ export default (App) => {
$(() => { $(() => {
_.delay(() => { window.setTimeout(() => {
if (window.rainloopTEMPLATES && window.rainloopTEMPLATES[0]) if (window.rainloopTEMPLATES && window.rainloopTEMPLATES[0])
{ {
$('#rl-templates').html(window.rainloopTEMPLATES[0]); $('#rl-templates').html(window.rainloopTEMPLATES[0]);
_.delay(() => { window.setTimeout(() => {
App.bootstart();
$html $html
.removeClass('no-js rl-booted-trigger') .removeClass('no-js rl-booted-trigger')
.addClass('rl-booted') .addClass('rl-booted')
; ;
App.bootstart();
}, 10); }, 10);
} }
else else

View file

@ -9,7 +9,7 @@
<![endif]--> <![endif]-->
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="{{BaseViewport}}" id="app-head-viewport"> <meta name="viewport" content="{{BaseViewport}}">
<meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="google" content="notranslate" /> <meta name="google" content="notranslate" />
<meta name="robots" content="noindex,nofollow,noodp" /> <meta name="robots" content="noindex,nofollow,noodp" />