Merge pull request #1 from RainLoop/master

update fork
This commit is contained in:
Artur 2015-04-16 10:24:35 -03:00
commit c041c50fd0
1172 changed files with 99448 additions and 104818 deletions

3
.gitignore vendored
View file

@ -1,6 +1,9 @@
/.idea
/error.log
/nbproject
/npm-debug.log
/rainloop.sublime-project
/rainloop.sublime-workspace
/rainloop/v/0.0.0/static/css/*.css
/rainloop/v/0.0.0/static/js/*.js
/rainloop/v/0.0.0/static/js/**/*.js

View file

@ -1,7 +1,7 @@
RainLoop Webmail
==================
## About
[![Join the chat at https://gitter.im/RainLoop/rainloop-webmail](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/RainLoop/rainloop-webmail?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Simple, modern & fast web-based email client.
@ -21,4 +21,4 @@ It's not recommended to use in production environment.
**Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0)**
http://creativecommons.org/licenses/by-nc-sa/3.0/
Copyright (c) 2014 Rainloop Team
Copyright (c) 2015 Rainloop Team

76
build/langs.php Normal file
View file

@ -0,0 +1,76 @@
<?php
\define('IS_ADMIN', isset($_GET['admin']) && '1' === (string) $_GET['admin']);
\define('LANGS_PATH', __DIR__.'/../rainloop/v/0.0.0/langs'.(IS_ADMIN ? '/admin' : ''));
function getLangStructure($sLangFile)
{
$sEngLang = \file_get_contents(LANGS_PATH.'/'.$sLangFile);
return $sEngLang ? \parse_ini_string($sEngLang, true) : null;
}
function mergeLangStructure($aFromLang, $aEngLang, &$iCount = 0)
{
$iCount = 0;
foreach ($aEngLang as $sSectionKey => $aSectionValue)
{
foreach (\array_keys($aSectionValue) as $sParamKey)
{
if (isset($aFromLang[$sSectionKey][$sParamKey]))
{
$aEngLang[$sSectionKey][$sParamKey] = $aFromLang[$sSectionKey][$sParamKey];
}
else
{
echo $sSectionKey.'/'.$sParamKey.','."\n";
$iCount++;
}
}
}
return $aEngLang;
}
function saveLangStructure($sLangFile, $aLang)
{
$aResultLines = array();
// $aResultLines[] = '; '.$sLangFile;
foreach ($aLang as $sSectionKey => $aSectionValue)
{
$aResultLines[] = '';
$aResultLines[] = '['.$sSectionKey.']';
foreach ($aSectionValue as $sParamKey => $sParamValue)
{
$aResultLines[] = $sParamKey.' = "'.
\str_replace(array('\\', '"'), array('\\\\', '\\"'), \trim($sParamValue)).'"';
}
}
\file_put_contents(LANGS_PATH.'/'.$sLangFile, implode("\n", $aResultLines));
}
$sNL = "\n";
$aEngLang = \getLangStructure('en.ini');
$aFiles = \glob(LANGS_PATH.'/*.ini');
foreach ($aFiles as $sFile)
{
$iCount = 0;
$sFileName = \basename($sFile);
$aNextLang = \getLangStructure($sFileName);
$aNewLang = \mergeLangStructure($aNextLang, $aEngLang, $iCount);
if (0 === $iCount)
{
echo $sFileName.': ok'.$sNL;
}
else
{
echo $sFileName.': changed ('.$iCount.')'.$sNL;
}
// \saveLangStructure($sFileName, $aNewLang);
}

View file

@ -1,26 +1,23 @@
************************************************************************
*
* ownCloud - RainLoop Webmail mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*
************************************************************************
REQUIREMENTS:
- Installed and configured RainLoop Webmail (standalone)
- ownCloud version 6 or higher
- Both apps (RainLoop & ownCloud) running on the same domain
INSTALL:
- Unpack the RainLoop Webmail application package in the apps directory of your OwnCloud instance
CONFIGURATION:
- ownCloud:
1) In the Apps > Enable 'RainLoop' plugin
2) In the Settings > Admin > Enter "RainLoop Webmail URL" and "Absolute (full) path to RainLoop Webmail installation"
3) In the Settings > Personal > Type your mail server email (login) and password
************************************************************************
*
* ownCloud - RainLoop Webmail package
*
* @author RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*
************************************************************************
REQUIREMENTS:
- ownCloud version 6 or higher
INSTALL:
- Unpack the RainLoop Webmail application package in the apps directory of your OwnCloud instance
CONFIGURATION:
- ownCloud:
1) In the Apps > Enable 'RainLoop' plugin
2) In the Settings > Personal > Type your mail server email (login) and password

View file

@ -1,20 +1,19 @@
<?php
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
OCP\User::checkAdminUser();
OCP\Util::addScript('rainloop', 'admin');
$oTemplate = new OCP\Template('rainloop', 'admin');
$oTemplate->assign('rainloop-url', OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$oTemplate->assign('rainloop-path', OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$oTemplate->assign('rainloop-autologin', OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false));
return $oTemplate->fetchPage();
<?php
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
OCP\User::checkAdminUser();
OCP\Util::addScript('rainloop', 'admin');
$oTemplate = new OCP\Template('rainloop', 'admin-local');
$oTemplate->assign('rainloop-admin-panel-link', OC_RainLoop_Helper::getAppUrl().'?admin');
$oTemplate->assign('rainloop-autologin', OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false));
return $oTemplate->fetchPage();

View file

@ -4,7 +4,7 @@
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
@ -17,22 +17,20 @@ $sUrl = '';
$sPath = '';
$bAutologin = false;
if (isset($_POST['appname'], $_POST['rainloop-url'], $_POST['rainloop-path']) && 'rainloop' === $_POST['appname'])
if (isset($_POST['appname']) && 'rainloop' === $_POST['appname'])
{
OCP\Config::setAppValue('rainloop', 'rainloop-url', $_POST['rainloop-url']);
OCP\Config::setAppValue('rainloop', 'rainloop-path', $_POST['rainloop-path']);
OCP\Config::setAppValue('rainloop', 'rainloop-autologin', isset($_POST['rainloop-autologin']) ?
'1' === $_POST['rainloop-autologin'] : false);
$sUrl = OCP\Config::getAppValue('rainloop', 'rainloop-url', '');
$sPath = OCP\Config::getAppValue('rainloop', 'rainloop-path', '');
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
}
else
{
OC_JSON::error(array('Message' => 'Invalid Argument(s)', 'Url' => $sUrl, 'Path' => $sPath));
sleep(1);
OC_JSON::error(array('Message' => 'Invalid Argument(s)'));
return false;
}
OCP\JSON::success(array('Message' => 'Saved successfully', 'Url' => $sUrl, 'Path' => $sPath));
sleep(1);
OCP\JSON::success(array('Message' => 'Saved successfully'));
return true;

View file

@ -4,7 +4,7 @@
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
@ -37,9 +37,11 @@ if (isset($_POST['appname'], $_POST['rainloop-password'], $_POST['rainloop-email
}
else
{
sleep(1);
OC_JSON::error(array('Message' => 'Invalid argument(s)', 'Email' => $sEmail));
return false;
}
sleep(1);
OCP\JSON::success(array('Message' => 'Saved successfully', 'Email' => $sEmail));
return true;

View file

@ -0,0 +1,34 @@
<?php
if (@file_exists(__DIR__.'/app/index.php'))
{
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
OC_RainLoop_Helper::regRainLoopDataFunction();
if (isset($_GET['OwnCloudAuth']))
{
$sEmail = '';
$sEncodedPassword = '';
$sUser = OCP\User::getUser();
if (OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false))
{
$sEmail = $sUser;
$sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', '');
}
else
{
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
$sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
}
$sDecodedPassword = OC_RainLoop_Helper::decodePassword($sEncodedPassword, md5($sEmail));
$_ENV['___rainloop_owncloud_email'] = $sEmail;
$_ENV['___rainloop_owncloud_password'] = $sDecodedPassword;
}
include __DIR__.'/app/index.php';
}

View file

@ -4,7 +4,7 @@
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/owncloud
*/
@ -17,22 +17,18 @@ OCP\App::registerPersonal('rainloop', 'personal');
if (OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false))
{
OCP\Util::connectHook('OC_User', 'post_login', 'OC_RainLoop_Helper', 'login');
OCP\Util::connectHook('OC_User', 'logout', 'OC_RainLoop_Helper', 'logout');
OCP\Util::connectHook('OC_User', 'post_setPassword', 'OC_RainLoop_Helper', 'changePassword');
}
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
OCP\Util::connectHook('OC_User', 'logout', 'OC_RainLoop_Helper', 'logout');
if (('' !== $sUrl && '' !== $sPath) || OC_User::isAdminUser(OC_User::getUser()))
{
OCP\Util::addScript('rainloop', 'rainloop');
OCP\Util::addScript('rainloop', 'rainloop');
OCP\App::addNavigationEntry(array(
'id' => 'rainloop_index',
'order' => 10,
'href' => OCP\Util::linkToRoute('rainloop_index'),
'icon' => OCP\Util::imagePath('rainloop', 'mail.png'),
'name' => 'Email'
));
OCP\App::addNavigationEntry(array(
'id' => 'rainloop_index',
'order' => 10,
'href' => OCP\Util::linkTo('rainloop', 'index.php'),
'icon' => OCP\Util::imagePath('rainloop', 'mail.png'),
'name' => 'Email'
));
}

View file

@ -2,9 +2,12 @@
<info>
<id>rainloop</id>
<name>RainLoop</name>
<description>RainLoop Webmail</description>
<description>Simple, modern and fast web-based email client.</description>
<version>0.0</version>
<licence>CC BY-NC-SA 3.0</licence>
<author>RainLoop Team</author>
<require>6.0</require>
<dependencies>
<php min-version="5.3"/>
</dependencies>
</info>

View file

@ -0,0 +1,13 @@
<?php
$this->create('rainloop_index', '/')
->actionInclude('rainloop/index.php');
$this->create('rainloop_app', '/app/')
->actionInclude('rainloop/app.php');
$this->create('rainloop_ajax_personal', 'ajax/personal.php')
->actionInclude('rainloop/ajax/personal.php');
$this->create('rainloop_ajax_admin', 'ajax/admin.php')
->actionInclude('rainloop/ajax/admin.php');

View file

@ -0,0 +1,6 @@
/*
Empty style sheet!
Only needed to give you the opportunity to theme the owncloud part
of the rainloop app with the theming system integrated in ownCoud
if the rainloop app is activated.
*/

View file

@ -4,7 +4,7 @@
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
@ -13,41 +13,15 @@ OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('rainloop');
OCP\App::setActiveNavigationEntry('rainloop_index');
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
// Load the empty file ../css/style.css, that's needed to allow theming of
// the ownCloud header and navigation if rainloop is the active app.
OCP\Util::addStyle('rainloop', 'style');
if ('' === $sUrl || '' === $sPath)
{
$oTemplate = new OCP\Template('rainloop', 'index-empty', 'user');
}
else
{
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
OC_Config::setValue('xframe_restriction', false);
$sUrl = OC_RainLoop_Helper::normalizeUrl(OC_RainLoop_Helper::getAppUrl());
$sUser = OCP\User::getUser();
if ($bAutologin)
{
$sEmail = $sUser;
$sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', '');
}
else
{
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
$sEncodedPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
}
$sDecodedPassword = OC_RainLoop_Helper::decodePassword($sEncodedPassword, md5($sEmail));
$sSsoHash = OC_RainLoop_Helper::getSsoHash($sPath, $sEmail, $sDecodedPassword);
$sUrl = OC_RainLoop_Helper::normalizeUrl($sUrl);
$sResultUrl = empty($sSsoHash) ? $sUrl.'?sso' : $sUrl.'?sso&hash='.$sSsoHash;
$oTemplate = new OCP\Template('rainloop', 'index', 'user');
$oTemplate->assign('rainloop-url', $sResultUrl);
}
$oTemplate = new OCP\Template('rainloop', 'index', 'user');
$oTemplate->assign('rainloop-iframe-url', OC_RainLoop_Helper::normalizeUrl($sUrl).'?OwnCloudAuth');
$oTemplate->printpage();

View file

@ -1,13 +1,13 @@
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
$(function() {
RainLoopFormHelper('#mail-rainloop-admin-form', 'admin.php');
});
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
$(function() {
RainLoopFormHelper('#mail-rainloop-admin-form', 'admin.php');
});

View file

@ -1,13 +1,13 @@
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
$(function() {
RainLoopFormHelper('#mail-rainloop-personal-form', 'personal.php');
});
/**
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
$(function() {
RainLoopFormHelper('#mail-rainloop-personal-form', 'personal.php');
});

View file

@ -2,6 +2,23 @@
class OC_RainLoop_Helper
{
/**
* @return string
*/
public static function getAppUrl()
{
if (class_exists('\\OCP\\Util'))
{
return OCP\Util::linkToRoute('rainloop_app');
}
$sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': trim($_SERVER['REQUEST_URI']);
$sRequestUri = preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri);
$sRequestUri = $sRequestUri.'apps/rainloop/app/';
return '/'.ltrim($sRequestUri, '/\\');
}
/**
* @param string $sPath
* @param string $sEmail
@ -16,6 +33,8 @@ class OC_RainLoop_Helper
$sPath = rtrim(trim($sPath), '\\/').'/index.php';
if (file_exists($sPath))
{
self::regRainLoopDataFunction();
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include $sPath;
@ -82,14 +101,8 @@ class OC_RainLoop_Helper
$sEmail = $sUser;
$sPassword = $aParams['password'];
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
if ('' !== $sUrl && '' !== $sPath)
{
$sPassword = self::encodePassword($sPassword, md5($sEmail));
return OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', $sPassword);
}
return OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-autologin-password',
self::encodePassword($sPassword, md5($sEmail)));
}
return false;
@ -97,8 +110,24 @@ class OC_RainLoop_Helper
public static function logout()
{
return OCP\Config::setUserValue(
OCP\Config::setUserValue(
OCP\User::getUser(), 'rainloop', 'rainloop-autologin-password', '');
$sApiPath = __DIR__.'/../app/index.php';
if (file_exists($sApiPath))
{
self::regRainLoopDataFunction();
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include $sApiPath;
if (class_exists('\\RainLoop\\Api'))
{
\RainLoop\Api::LogoutCurrentLogginedUser();
}
}
return true;
}
public static function changePassword($aParams)
@ -110,18 +139,115 @@ class OC_RainLoop_Helper
$sEmail = $sUser;
$sPassword = $aParams['password'];
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
OCP\Util::writeLog('rainloop', 'rainloop|login: Setting new RainLoop password for '.$sEmail, OCP\Util::DEBUG);
if ('' !== $sUrl && '' !== $sPath)
{
OCP\Util::writeLog('rainloop', 'rainloop|login: Setting new RainLoop password for '.$sEmail, OCP\Util::DEBUG);
OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-autologin-password',
self::encodePassword($sPassword, md5($sEmail)));
$sPassword = self::encodePassword($sPassword, md5($sEmail));
return OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password', $sPassword);
}
OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password',
self::encodePassword($sPassword, md5($sEmail)));
return true;
}
return false;
}
public static function regRainLoopDataFunction()
{
if (!@function_exists('__get_custom_data_full_path'))
{
$_ENV['RAINLOOP_OWNCLOUD'] = true;
function __get_custom_data_full_path()
{
$sData = __DIR__.'/../../data/';
if (class_exists('OC_Config'))
{
$sData = rtrim(trim(OC_Config::getValue('datadirectory', '')), '\\/').'/';
}
return @is_dir($sData) ? $sData.'rainloop-storage' : '';
}
}
}
public static function mimeContentType($filename) {
$mime_types = array(
'woff' => 'application/font-woff',
'txt' => 'text/plain',
'htm' => 'text/html',
'html' => 'text/html',
'php' => 'text/html',
'css' => 'text/css',
'js' => 'application/javascript',
'json' => 'application/json',
'xml' => 'application/xml',
'swf' => 'application/x-shockwave-flash',
'flv' => 'video/x-flv',
// images
'png' => 'image/png',
'jpe' => 'image/jpeg',
'jpeg' => 'image/jpeg',
'jpg' => 'image/jpeg',
'gif' => 'image/gif',
'bmp' => 'image/bmp',
'ico' => 'image/vnd.microsoft.icon',
'tiff' => 'image/tiff',
'tif' => 'image/tiff',
'svg' => 'image/svg+xml',
'svgz' => 'image/svg+xml',
// archives
'zip' => 'application/zip',
'rar' => 'application/x-rar-compressed',
'exe' => 'application/x-msdownload',
'msi' => 'application/x-msdownload',
'cab' => 'application/vnd.ms-cab-compressed',
// audio/video
'mp3' => 'audio/mpeg',
'qt' => 'video/quicktime',
'mov' => 'video/quicktime',
// adobe
'pdf' => 'application/pdf',
'psd' => 'image/vnd.adobe.photoshop',
'ai' => 'application/postscript',
'eps' => 'application/postscript',
'ps' => 'application/postscript',
// ms office
'doc' => 'application/msword',
'rtf' => 'application/rtf',
'xls' => 'application/vnd.ms-excel',
'ppt' => 'application/vnd.ms-powerpoint',
// open office
'odt' => 'application/vnd.oasis.opendocument.text',
'ods' => 'application/vnd.oasis.opendocument.spreadsheet',
);
if (0 < strpos($filename, '.'))
{
$ext = strtolower(array_pop(explode('.',$filename)));
if (array_key_exists($ext, $mime_types))
{
return $mime_types[$ext];
}
else if (function_exists('finfo_open'))
{
$finfo = finfo_open(FILEINFO_MIME);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);
return $mimetype;
}
}
return 'application/octet-stream';
}
}

View file

@ -4,7 +4,7 @@
* ownCloud - RainLoop mail plugin
*
* @author RainLoop Team
* @copyright 2014 RainLoop Team
* @copyright 2015 RainLoop Team
*
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/
@ -14,11 +14,7 @@ OCP\App::checkAppEnabled('rainloop');
OCP\Util::addScript('rainloop', 'personal');
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
if ($bAutologin || '' === $sUrl || '' === $sPath)
if (OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false))
{
$oTemplate = new OCP\Template('rainloop', 'empty');
}

View file

@ -6,17 +6,15 @@
<fieldset class="personalblock">
<h2><?php p($l->t('RainLoop Webmail')); ?></h2>
<br />
<?php if ($_['rainloop-admin-panel-link']): ?>
<p>
<a href="<?php echo $_['rainloop-admin-panel-link'] ?>" target="_blank" style="text-decoration: underline">
<?php p($l->t('Go to RainLoop Webmail admin panel')); ?>
</a>
</p>
<br />
<?php endif; ?>
<p>
<?php p($l->t('RainLoop Webmail URL')); ?>:
<br />
<input type="text" style="width:300px;" id="rainloop-url" name="rainloop-url" value="<?php echo $_['rainloop-url']; ?>" placeholder="https://" />
<br />
<br />
<?php p($l->t('Absolute (full) path to RainLoop Webmail installation')); ?>:
<br />
<input type="text" style="width:300px;" id="rainloop-path" name="rainloop-path" value="<?php echo $_['rainloop-path']; ?>" />
<br />
<br />
<input type="checkbox" id="rainloop-autologin" id="rainloop-autologin" name="rainloop-autologin" value="1" <?php if ($_['rainloop-autologin']): ?>checked="checked"<?php endif; ?> />
<label for="rainloop-autologin">
<?php p($l->t('Automatically login with ownCloud user credentials')); ?>

View file

@ -1,3 +1,3 @@
<div style="box-sizing: border-box; width: 100%; height: 100%; padding: 0px; margin: 0px; background-color: #383c43; position: relative; overflow: hidden;"
><iframe id="rliframe" style="border: none; width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px;" tabindex="-1" frameborder="0"
src="<?php echo $_['rainloop-url']; ?>"></iframe></div><?php OCP\Util::addScript('rainloop', 'resize');
<div style="box-sizing: border-box; width: 100%; height: 100%; padding: 0px; margin: 0px; background-color: #383c43; position: relative; overflow: hidden;"
><iframe id="rliframe" style="border: none; width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px;" tabindex="-1" frameborder="0"
src="<?php echo $_['rainloop-iframe-url']; ?>"></iframe></div><?php OCP\Util::addScript('rainloop', 'resize');

View file

@ -38,6 +38,11 @@
<param name="plugin-name" value="google-analytics"/>
</antcall>
</target>
<target name="piwik-analytics">
<antcall target="_build_plugin_">
<param name="plugin-name" value="piwik-analytics"/>
</antcall>
</target>
<target name="convert-headers-styles">
<antcall target="_build_plugin_">
<param name="plugin-name" value="convert-headers-styles"/>
@ -98,5 +103,10 @@
<param name="plugin-name" value="custom-login-mapping"/>
</antcall>
</target>
<target name="video-on-login-screen">
<antcall target="_build_plugin_">
<param name="plugin-name" value="video-on-login-screen"/>
</antcall>
</target>
</project>

View file

@ -7,11 +7,14 @@
window = require('window'),
_ = require('_'),
$ = require('$'),
key = require('key'),
Globals = require('Common/Globals'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder'),
Links = require('Common/Links'),
Events = require('Common/Events'),
Translator = require('Common/Translator'),
Settings = require('Storage/Settings'),
@ -44,11 +47,42 @@
oEvent.originalEvent.lineno,
window.location && window.location.toString ? window.location.toString() : '',
Globals.$html.attr('class'),
Utils.microtime() - Globals.now
Utils.microtime() - Globals.startMicrotime
);
}
});
Globals.$win.on('resize', function () {
Events.pub('window.resize');
});
Events.sub('window.resize', _.throttle(function () {
var
iH = Globals.$win.height(),
iW = Globals.$win.height()
;
if (Globals.$win.__sizes[0] !== iH || Globals.$win.__sizes[1] !== iW)
{
Globals.$win.__sizes[0] = iH;
Globals.$win.__sizes[1] = iW;
Events.pub('window.resize.real');
}
}, 50));
// DEBUG
// Events.sub({
// 'window.resize': function () {
// window.console.log('window.resize');
// },
// 'window.resize.real': function () {
// window.console.log('window.resize.real');
// }
// });
Globals.$doc.on('keydown', function (oEvent) {
if (oEvent && oEvent.ctrlKey)
{
@ -60,6 +94,14 @@
Globals.$html.removeClass('rl-ctrl-key-pressed');
}
});
Globals.$doc.on('mousemove keypress click', _.debounce(function () {
Events.pub('rl.auto-logout-refresh');
}, 5000));
key('esc, enter', Enums.KeyState.All, _.bind(function () {
Utils.detectDropdownVisibility();
}, this));
}
_.extend(AbstractApp.prototype, AbstractBoot.prototype);
@ -117,23 +159,55 @@
return true;
};
AbstractApp.prototype.googlePreviewSupportedCache = null;
/**
* @return {boolean}
*/
AbstractApp.prototype.googlePreviewSupported = function ()
{
if (null === this.googlePreviewSupportedCache)
{
this.googlePreviewSupportedCache = !!Settings.settingsGet('AllowGoogleSocial') &&
!!Settings.settingsGet('AllowGoogleSocialPreview');
}
return this.googlePreviewSupportedCache;
};
/**
* @param {string} sTitle
*/
AbstractApp.prototype.setTitle = function (sTitle)
AbstractApp.prototype.setWindowTitle = function (sTitle)
{
sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') +
Settings.settingsGet('Title') || '';
window.document.title = '';
window.document.title = sTitle + ' ...';
window.document.title = sTitle;
};
AbstractApp.prototype.redirectToAdminPanel = function ()
{
_.delay(function () {
window.location.href = Links.rootAdmin();
}, 100);
};
AbstractApp.prototype.clearClientSideToken = function ()
{
if (window.__rlah_clear)
{
window.__rlah_clear();
}
};
/**
* @param {boolean=} bAdmin = false
* @param {boolean=} bLogout = false
* @param {boolean=} bClose = false
*/
AbstractApp.prototype.loginAndLogoutReload = function (bLogout, bClose)
AbstractApp.prototype.loginAndLogoutReload = function (bAdmin, bLogout, bClose)
{
var
kn = require('Knoin/Knoin'),
@ -144,12 +218,19 @@
bLogout = Utils.isUnd(bLogout) ? false : !!bLogout;
bClose = Utils.isUnd(bClose) ? false : !!bClose;
if (bLogout)
{
this.clearClientSideToken();
}
if (bLogout && bClose && window.close)
{
window.close();
}
if (bLogout && '' !== sCustomLogoutLink && window.location.href !== sCustomLogoutLink)
sCustomLogoutLink = sCustomLogoutLink || (bAdmin ? Links.rootAdmin() : Links.rootUser());
if (bLogout && window.location.href !== sCustomLogoutLink)
{
_.delay(function () {
if (bInIframe && window.parent)
@ -165,7 +246,7 @@
else
{
kn.routeOff();
kn.setHash(LinkBuilder.root(), true);
kn.setHash(Links.root(), true);
kn.routeOff();
_.delay(function () {
@ -190,15 +271,32 @@
{
Events.pub('rl.bootstart');
var ssm = require('ssm');
var
ssm = require('ssm'),
ko = require('ko')
;
Utils.initOnStartOrLangChange(function () {
Utils.initNotificationLanguage();
}, null);
ko.components.register('SaveTrigger', require('Component/SaveTrigger'));
ko.components.register('Input', require('Component/Input'));
ko.components.register('Select', require('Component/Select'));
ko.components.register('TextArea', require('Component/TextArea'));
ko.components.register('Radio', require('Component/Radio'));
_.delay(function () {
Utils.windowResize();
}, 1000);
ko.components.register('x-script', require('Component/Script'));
if (Settings.settingsGet('MaterialDesign') && Globals.bAnimationSupported)
{
ko.components.register('Checkbox', require('Component/MaterialDesign/Checkbox'));
}
else
{
// ko.components.register('Checkbox', require('Component/Classic/Checkbox'));
ko.components.register('Checkbox', require('Component/Checkbox'));
}
Translator.initOnStartOrLangChange(Translator.initNotificationLanguage, Translator);
_.delay(Utils.windowResizeCallback, 1000);
ssm.addState({
'id': 'mobile',
@ -261,6 +359,10 @@
});
ssm.ready();
require('Stores/Language').populate();
require('Stores/Theme').populate();
require('Stores/Social').populate();
};
module.exports = AbstractApp;

View file

@ -11,11 +11,17 @@
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder'),
Links = require('Common/Links'),
Translator = require('Common/Translator'),
Settings = require('Storage/Settings'),
Data = require('Storage/Admin/Data'),
Remote = require('Storage/Admin/Remote'),
AppStore = require('Stores/Admin/App'),
DomainStore = require('Stores/Admin/Domain'),
PluginStore = require('Stores/Admin/Plugin'),
LicenseStore = require('Stores/Admin/License'),
PackageStore = require('Stores/Admin/Package'),
CoreStore = require('Stores/Admin/Core'),
Remote = require('Remote/Admin/Ajax'),
kn = require('Knoin/Knoin'),
AbstractApp = require('App/Abstract')
@ -37,17 +43,12 @@
return Remote;
};
AdminApp.prototype.data = function ()
{
return Data;
};
AdminApp.prototype.reloadDomainList = function ()
{
Data.domainsLoading(true);
DomainStore.domains.loading(true);
Remote.domainList(function (sResult, oData) {
Data.domainsLoading(false);
DomainStore.domains.loading(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
var aList = _.map(oData.Result, function (bEnabled, sName) {
@ -58,17 +59,18 @@
};
}, this);
Data.domains(aList);
DomainStore.domains(aList);
}
});
};
AdminApp.prototype.reloadPluginList = function ()
{
Data.pluginsLoading(true);
PluginStore.plugins.loading(true);
Remote.pluginList(function (sResult, oData) {
Data.pluginsLoading(false);
PluginStore.plugins.loading(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
@ -80,31 +82,31 @@
};
}, this);
Data.plugins(aList);
PluginStore.plugins(aList);
}
});
};
AdminApp.prototype.reloadPackagesList = function ()
{
Data.packagesLoading(true);
Data.packagesReal(true);
PackageStore.packages.loading(true);
PackageStore.packagesReal(true);
Remote.packagesList(function (sResult, oData) {
Data.packagesLoading(false);
PackageStore.packages.loading(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
Data.packagesReal(!!oData.Result.Real);
Data.packagesMainUpdatable(!!oData.Result.MainUpdatable);
PackageStore.packagesReal(!!oData.Result.Real);
PackageStore.packagesMainUpdatable(!!oData.Result.MainUpdatable);
var
aList = [],
aLoading = {}
;
_.each(Data.packages(), function (oItem) {
_.each(PackageStore.packages(), function (oItem) {
if (oItem && oItem['loading']())
{
aLoading[oItem['file']] = oItem;
@ -123,33 +125,34 @@
}));
}
Data.packages(aList);
PackageStore.packages(aList);
}
else
{
Data.packagesReal(false);
PackageStore.packagesReal(false);
}
});
};
AdminApp.prototype.updateCoreData = function ()
{
Data.coreUpdating(true);
CoreStore.coreUpdating(true);
Remote.updateCoreData(function (sResult, oData) {
Data.coreUpdating(false);
Data.coreRemoteVersion('');
Data.coreRemoteRelease('');
Data.coreVersionCompare(-2);
CoreStore.coreUpdating(false);
CoreStore.coreVersion('');
CoreStore.coreRemoteVersion('');
CoreStore.coreRemoteRelease('');
CoreStore.coreVersionCompare(-2);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
Data.coreReal(true);
CoreStore.coreReal(true);
window.location.reload();
}
else
{
Data.coreReal(false);
CoreStore.coreReal(false);
}
});
@ -157,28 +160,36 @@
AdminApp.prototype.reloadCoreData = function ()
{
Data.coreChecking(true);
Data.coreReal(true);
CoreStore.coreChecking(true);
CoreStore.coreReal(true);
Remote.coreData(function (sResult, oData) {
Data.coreChecking(false);
CoreStore.coreChecking(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
Data.coreReal(!!oData.Result.Real);
Data.coreUpdatable(!!oData.Result.Updatable);
Data.coreAccess(!!oData.Result.Access);
Data.coreRemoteVersion(oData.Result.RemoteVersion || '');
Data.coreRemoteRelease(oData.Result.RemoteRelease || '');
Data.coreVersionCompare(Utils.pInt(oData.Result.VersionCompare));
CoreStore.coreReal(!!oData.Result.Real);
CoreStore.coreChannel(oData.Result.Channel || 'stable');
CoreStore.coreType(oData.Result.Type || 'stable');
CoreStore.coreUpdatable(!!oData.Result.Updatable);
CoreStore.coreAccess(!!oData.Result.Access);
CoreStore.coreWarning(!!oData.Result.Warning);
CoreStore.coreVersion(oData.Result.Version || '');
CoreStore.coreRemoteVersion(oData.Result.RemoteVersion || '');
CoreStore.coreRemoteRelease(oData.Result.RemoteRelease || '');
CoreStore.coreVersionCompare(Utils.pInt(oData.Result.VersionCompare));
}
else
{
Data.coreReal(false);
Data.coreRemoteVersion('');
Data.coreRemoteRelease('');
Data.coreVersionCompare(-2);
CoreStore.coreReal(false);
CoreStore.coreChannel('stable');
CoreStore.coreType('stable');
CoreStore.coreWarning(false);
CoreStore.coreVersion('');
CoreStore.coreRemoteVersion('');
CoreStore.coreRemoteRelease('');
CoreStore.coreVersionCompare(-2);
}
});
};
@ -191,18 +202,22 @@
{
bForce = Utils.isUnd(bForce) ? false : !!bForce;
Data.licensingProcess(true);
Data.licenseError('');
LicenseStore.licensingProcess(true);
LicenseStore.licenseError('');
Remote.licensing(function (sResult, oData) {
Data.licensingProcess(false);
LicenseStore.licensingProcess(false);
if (Enums.StorageResultType.Success === sResult && oData && oData.Result && Utils.isNormal(oData.Result['Expired']))
{
Data.licenseValid(true);
Data.licenseExpired(Utils.pInt(oData.Result['Expired']));
Data.licenseError('');
LicenseStore.licenseValid(true);
LicenseStore.licenseExpired(Utils.pInt(oData.Result['Expired']));
LicenseStore.licenseError('');
Data.licensing(true);
LicenseStore.licensing(true);
AppStore.prem(true);
}
else
{
@ -211,19 +226,19 @@
Enums.Notification.LicensingExpired
]))
{
Data.licenseError(Utils.getNotification(Utils.pInt(oData.ErrorCode)));
Data.licensing(true);
LicenseStore.licenseError(Translator.getNotification(Utils.pInt(oData.ErrorCode)));
LicenseStore.licensing(true);
}
else
{
if (Enums.StorageResultType.Abort === sResult)
{
Data.licenseError(Utils.getNotification(Enums.Notification.LicensingServerIsUnavailable));
Data.licensing(true);
LicenseStore.licenseError(Translator.getNotification(Enums.Notification.LicensingServerIsUnavailable));
LicenseStore.licensing(true);
}
else
{
Data.licensing(false);
LicenseStore.licensing(false);
}
}
}
@ -234,14 +249,15 @@
{
AbstractApp.prototype.bootstart.call(this);
Data.populateDataOnStart();
require('Stores/Admin/App').populate();
require('Stores/Admin/Capa').populate();
kn.hideLoading();
if (!Settings.settingsGet('AllowAdminPanel'))
{
kn.routeOff();
kn.setHash(LinkBuilder.root(), true);
kn.setHash(Links.root(), true);
kn.routeOff();
_.defer(function () {

File diff suppressed because it is too large Load diff

1533
dev/App/User.js Normal file

File diff suppressed because it is too large Load diff

186
dev/Common/Audio.js Normal file
View file

@ -0,0 +1,186 @@
(function () {
'use strict';
var
window = require('window'),
$ = require('$'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Links = require('Common/Links'),
Events = require('Common/Events')
;
/**
* @constructor
*/
function Audio()
{
var self = this;
// this.userMedia = window.navigator.getUserMedia || window.navigator.webkitGetUserMedia ||
// window.navigator.mozGetUserMedia || window.navigator.msGetUserMedia;
//
// this.audioContext = window.AudioContext || window.webkitAudioContext;
// if (!this.audioContext || !window.Float32Array)
// {
// this.audioContext = null;
// this.userMedia = null;
// }
this.player = this.createNewObject();
this.supported = !Globals.bMobileDevice && !Globals.bSafari && !!this.player && !!this.player.play;
if (this.supported && this.player.canPlayType)
{
this.supportedMp3 = '' !== this.player.canPlayType('audio/mpeg;').replace(/no/, '');
this.supportedWav = '' !== this.player.canPlayType('audio/wav; codecs="1"').replace(/no/, '');
this.supportedOgg = '' !== this.player.canPlayType('audio/ogg; codecs="vorbis"').replace(/no/, '');
this.supportedNotification = this.supported && this.supportedMp3;
}
if (!this.player || (!this.supportedMp3 && !this.supportedOgg && !this.supportedWav))
{
this.supported = false;
this.supportedMp3 = false;
this.supportedOgg = false;
this.supportedWav = false;
this.supportedNotification = false;
}
if (this.supported)
{
$(this.player).on('ended error', function () {
self.stop();
});
Events.sub('audio.api.stop', function () {
self.stop();
});
}
}
Audio.prototype.player = null;
Audio.prototype.notificator = null;
Audio.prototype.supported = false;
Audio.prototype.supportedMp3 = false;
Audio.prototype.supportedOgg = false;
Audio.prototype.supportedWav = false;
Audio.prototype.supportedNotification = false;
// Audio.prototype.record = function ()
// {
// this.getUserMedia({audio:true}, function () {
// window.console.log(arguments);
// }, function(oError) {
// window.console.log(arguments);
// });
// };
Audio.prototype.createNewObject = function ()
{
var player = window.Audio ? new window.Audio() : null;
if (player && player.canPlayType && player.pause && player.play)
{
player.preload = 'none';
player.loop = false;
player.autoplay = false;
player.muted = false;
}
return player;
};
Audio.prototype.paused = function ()
{
return this.supported ? !!this.player.paused : true;
};
Audio.prototype.stop = function ()
{
if (this.supported && this.player.pause)
{
this.player.pause();
}
Events.pub('audio.stop');
};
Audio.prototype.pause = Audio.prototype.stop;
Audio.prototype.clearName = function (sName, sExt)
{
sExt = sExt || '';
sName = Utils.isUnd(sName) ? '' : Utils.trim(sName);
if (sExt && '.' + sExt === sName.toLowerCase().substr((sExt.length + 1) * -1))
{
sName = Utils.trim(sName.substr(0, sName.length - 4));
}
if ('' === sName)
{
sName = 'audio';
}
return sName;
};
Audio.prototype.playMp3 = function (sUrl, sName)
{
if (this.supported && this.supportedMp3)
{
this.player.src = sUrl;
this.player.play();
Events.pub('audio.start', [this.clearName(sName, 'mp3'), 'mp3']);
}
};
Audio.prototype.playOgg = function (sUrl, sName)
{
if (this.supported && this.supportedOgg)
{
this.player.src = sUrl;
this.player.play();
sName = this.clearName(sName, 'oga');
sName = this.clearName(sName, 'ogg');
Events.pub('audio.start', [sName, 'ogg']);
}
};
Audio.prototype.playWav = function (sUrl, sName)
{
if (this.supported && this.supportedWav)
{
this.player.src = sUrl;
this.player.play();
Events.pub('audio.start', [this.clearName(sName, 'wav'), 'wav']);
}
};
Audio.prototype.playNotification = function ()
{
if (this.supported && this.supportedMp3)
{
if (!this.notificator)
{
this.notificator = this.createNewObject();
this.notificator.src = Links.sound('new-mail.mp3');
}
if (this.notificator && this.notificator.play)
{
this.notificator.play();
}
}
};
module.exports = new Audio();
}());

View file

@ -1,3 +1,4 @@
// Base64 encode / decode
// http://www.webtoolkit.info/

View file

@ -1,4 +1,3 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function () {
@ -9,7 +8,7 @@
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder'),
Links = require('Common/Links'),
Settings = require('Storage/Settings')
;
@ -17,7 +16,7 @@
/**
* @constructor
*/
function CacheAppStorage()
function CacheUserStorage()
{
this.oFoldersCache = {};
this.oFoldersNamesCache = {};
@ -34,54 +33,49 @@
/**
* @type {boolean}
*/
CacheAppStorage.prototype.bCapaGravatar = false;
CacheUserStorage.prototype.bCapaGravatar = false;
/**
* @type {Object}
*/
CacheAppStorage.prototype.oFoldersCache = {};
CacheUserStorage.prototype.oFoldersCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oFoldersNamesCache = {};
CacheUserStorage.prototype.oFoldersNamesCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oFolderHashCache = {};
CacheUserStorage.prototype.oFolderHashCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oFolderUidNextCache = {};
CacheUserStorage.prototype.oFolderUidNextCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oMessageListHashCache = {};
CacheUserStorage.prototype.oMessageListHashCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oMessageFlagsCache = {};
CacheUserStorage.prototype.oMessageFlagsCache = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oBodies = {};
CacheUserStorage.prototype.oNewMessage = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oNewMessage = {};
CacheUserStorage.prototype.oRequestedMessage = {};
/**
* @type {Object}
*/
CacheAppStorage.prototype.oRequestedMessage = {};
CacheAppStorage.prototype.clear = function ()
CacheUserStorage.prototype.clear = function ()
{
this.oFoldersCache = {};
this.oFoldersNamesCache = {};
@ -89,19 +83,17 @@
this.oFolderUidNextCache = {};
this.oMessageListHashCache = {};
this.oMessageFlagsCache = {};
this.oBodies = {};
};
/**
* @param {string} sEmail
* @param {Function} fCallback
* @return {string}
*/
CacheAppStorage.prototype.getUserPic = function (sEmail, fCallback)
CacheUserStorage.prototype.getUserPic = function (sEmail, fCallback)
{
sEmail = Utils.trim(sEmail);
fCallback(this.bCapaGravatar && '' !== sEmail ? LinkBuilder.avatarLink(sEmail) : '', sEmail);
fCallback(this.bCapaGravatar && '' !== sEmail ? Links.avatarLink(sEmail) : '', sEmail);
};
/**
@ -109,7 +101,7 @@
* @param {string} sUid
* @return {string}
*/
CacheAppStorage.prototype.getMessageKey = function (sFolderFullNameRaw, sUid)
CacheUserStorage.prototype.getMessageKey = function (sFolderFullNameRaw, sUid)
{
return sFolderFullNameRaw + '#' + sUid;
};
@ -118,7 +110,7 @@
* @param {string} sFolder
* @param {string} sUid
*/
CacheAppStorage.prototype.addRequestedMessage = function (sFolder, sUid)
CacheUserStorage.prototype.addRequestedMessage = function (sFolder, sUid)
{
this.oRequestedMessage[this.getMessageKey(sFolder, sUid)] = true;
};
@ -128,7 +120,7 @@
* @param {string} sUid
* @return {boolean}
*/
CacheAppStorage.prototype.hasRequestedMessage = function (sFolder, sUid)
CacheUserStorage.prototype.hasRequestedMessage = function (sFolder, sUid)
{
return true === this.oRequestedMessage[this.getMessageKey(sFolder, sUid)];
};
@ -137,7 +129,7 @@
* @param {string} sFolderFullNameRaw
* @param {string} sUid
*/
CacheAppStorage.prototype.addNewMessageCache = function (sFolderFullNameRaw, sUid)
CacheUserStorage.prototype.addNewMessageCache = function (sFolderFullNameRaw, sUid)
{
this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)] = true;
};
@ -146,7 +138,7 @@
* @param {string} sFolderFullNameRaw
* @param {string} sUid
*/
CacheAppStorage.prototype.hasNewMessageAndRemoveFromCache = function (sFolderFullNameRaw, sUid)
CacheUserStorage.prototype.hasNewMessageAndRemoveFromCache = function (sFolderFullNameRaw, sUid)
{
if (this.oNewMessage[this.getMessageKey(sFolderFullNameRaw, sUid)])
{
@ -157,16 +149,29 @@
return false;
};
CacheAppStorage.prototype.clearNewMessageCache = function ()
CacheUserStorage.prototype.clearNewMessageCache = function ()
{
this.oNewMessage = {};
};
/**
* @type {string}
*/
CacheUserStorage.prototype.sInboxFolderName = '';
/**
* @return {string}
*/
CacheUserStorage.prototype.getFolderInboxName = function ()
{
return '' === this.sInboxFolderName ? 'INBOX' : this.sInboxFolderName;
};
/**
* @param {string} sFolderHash
* @return {string}
*/
CacheAppStorage.prototype.getFolderFullNameRaw = function (sFolderHash)
CacheUserStorage.prototype.getFolderFullNameRaw = function (sFolderHash)
{
return '' !== sFolderHash && this.oFoldersNamesCache[sFolderHash] ? this.oFoldersNamesCache[sFolderHash] : '';
};
@ -175,16 +180,20 @@
* @param {string} sFolderHash
* @param {string} sFolderFullNameRaw
*/
CacheAppStorage.prototype.setFolderFullNameRaw = function (sFolderHash, sFolderFullNameRaw)
CacheUserStorage.prototype.setFolderFullNameRaw = function (sFolderHash, sFolderFullNameRaw)
{
this.oFoldersNamesCache[sFolderHash] = sFolderFullNameRaw;
if ('INBOX' === sFolderFullNameRaw || '' === this.sInboxFolderName)
{
this.sInboxFolderName = sFolderFullNameRaw;
}
};
/**
* @param {string} sFolderFullNameRaw
* @return {string}
*/
CacheAppStorage.prototype.getFolderHash = function (sFolderFullNameRaw)
CacheUserStorage.prototype.getFolderHash = function (sFolderFullNameRaw)
{
return '' !== sFolderFullNameRaw && this.oFolderHashCache[sFolderFullNameRaw] ? this.oFolderHashCache[sFolderFullNameRaw] : '';
};
@ -193,7 +202,7 @@
* @param {string} sFolderFullNameRaw
* @param {string} sFolderHash
*/
CacheAppStorage.prototype.setFolderHash = function (sFolderFullNameRaw, sFolderHash)
CacheUserStorage.prototype.setFolderHash = function (sFolderFullNameRaw, sFolderHash)
{
this.oFolderHashCache[sFolderFullNameRaw] = sFolderHash;
};
@ -202,7 +211,7 @@
* @param {string} sFolderFullNameRaw
* @return {string}
*/
CacheAppStorage.prototype.getFolderUidNext = function (sFolderFullNameRaw)
CacheUserStorage.prototype.getFolderUidNext = function (sFolderFullNameRaw)
{
return '' !== sFolderFullNameRaw && this.oFolderUidNextCache[sFolderFullNameRaw] ? this.oFolderUidNextCache[sFolderFullNameRaw] : '';
};
@ -211,7 +220,7 @@
* @param {string} sFolderFullNameRaw
* @param {string} sUidNext
*/
CacheAppStorage.prototype.setFolderUidNext = function (sFolderFullNameRaw, sUidNext)
CacheUserStorage.prototype.setFolderUidNext = function (sFolderFullNameRaw, sUidNext)
{
this.oFolderUidNextCache[sFolderFullNameRaw] = sUidNext;
};
@ -220,7 +229,7 @@
* @param {string} sFolderFullNameRaw
* @return {?FolderModel}
*/
CacheAppStorage.prototype.getFolderFromCacheList = function (sFolderFullNameRaw)
CacheUserStorage.prototype.getFolderFromCacheList = function (sFolderFullNameRaw)
{
return '' !== sFolderFullNameRaw && this.oFoldersCache[sFolderFullNameRaw] ? this.oFoldersCache[sFolderFullNameRaw] : null;
};
@ -229,7 +238,7 @@
* @param {string} sFolderFullNameRaw
* @param {?FolderModel} oFolder
*/
CacheAppStorage.prototype.setFolderToCacheList = function (sFolderFullNameRaw, oFolder)
CacheUserStorage.prototype.setFolderToCacheList = function (sFolderFullNameRaw, oFolder)
{
this.oFoldersCache[sFolderFullNameRaw] = oFolder;
};
@ -237,7 +246,7 @@
/**
* @param {string} sFolderFullNameRaw
*/
CacheAppStorage.prototype.removeFolderFromCacheList = function (sFolderFullNameRaw)
CacheUserStorage.prototype.removeFolderFromCacheList = function (sFolderFullNameRaw)
{
this.setFolderToCacheList(sFolderFullNameRaw, null);
};
@ -247,7 +256,7 @@
* @param {string} sUid
* @return {?Array}
*/
CacheAppStorage.prototype.getMessageFlagsFromCache = function (sFolderFullName, sUid)
CacheUserStorage.prototype.getMessageFlagsFromCache = function (sFolderFullName, sUid)
{
return this.oMessageFlagsCache[sFolderFullName] && this.oMessageFlagsCache[sFolderFullName][sUid] ?
this.oMessageFlagsCache[sFolderFullName][sUid] : null;
@ -258,7 +267,7 @@
* @param {string} sUid
* @param {Array} aFlagsCache
*/
CacheAppStorage.prototype.setMessageFlagsToCache = function (sFolderFullName, sUid, aFlagsCache)
CacheUserStorage.prototype.setMessageFlagsToCache = function (sFolderFullName, sUid, aFlagsCache)
{
if (!this.oMessageFlagsCache[sFolderFullName])
{
@ -271,7 +280,7 @@
/**
* @param {string} sFolderFullName
*/
CacheAppStorage.prototype.clearMessageFlagsFromCacheByFolder = function (sFolderFullName)
CacheUserStorage.prototype.clearMessageFlagsFromCacheByFolder = function (sFolderFullName)
{
this.oMessageFlagsCache[sFolderFullName] = {};
};
@ -279,35 +288,47 @@
/**
* @param {(MessageModel|null)} oMessage
*/
CacheAppStorage.prototype.initMessageFlagsFromCache = function (oMessage)
CacheUserStorage.prototype.initMessageFlagsFromCache = function (oMessage)
{
if (oMessage)
{
var
self = this,
aFlags = this.getMessageFlagsFromCache(oMessage.folderFullNameRaw, oMessage.uid),
sUid = oMessage.uid,
aFlags = this.getMessageFlagsFromCache(oMessage.folderFullNameRaw, sUid),
mUnseenSubUid = null,
mFlaggedSubUid = null
;
if (aFlags && 0 < aFlags.length)
{
oMessage.unseen(!!aFlags[0]);
oMessage.flagged(!!aFlags[1]);
oMessage.answered(!!aFlags[2]);
oMessage.forwarded(!!aFlags[3]);
oMessage.isReadReceipt(!!aFlags[4]);
if (!oMessage.__simple_message__)
{
oMessage.unseen(!!aFlags[0]);
oMessage.answered(!!aFlags[2]);
oMessage.forwarded(!!aFlags[3]);
oMessage.isReadReceipt(!!aFlags[4]);
oMessage.deletedMark(!!aFlags[5]);
}
}
if (0 < oMessage.threads().length)
{
mUnseenSubUid = _.find(oMessage.threads(), function (iSubUid) {
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
mUnseenSubUid = _.find(oMessage.threads(), function (sSubUid) {
if (sUid === sSubUid){
return false;
}
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, sSubUid);
return aFlags && 0 < aFlags.length && !!aFlags[0];
});
mFlaggedSubUid = _.find(oMessage.threads(), function (iSubUid) {
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, iSubUid);
mFlaggedSubUid = _.find(oMessage.threads(), function (sSubUid) {
if (sUid === sSubUid){
return false;
}
var aFlags = self.getMessageFlagsFromCache(oMessage.folderFullNameRaw, sSubUid);
return aFlags && 0 < aFlags.length && !!aFlags[1];
});
@ -320,23 +341,25 @@
/**
* @param {(MessageModel|null)} oMessage
*/
CacheAppStorage.prototype.storeMessageFlagsToCache = function (oMessage)
CacheUserStorage.prototype.storeMessageFlagsToCache = function (oMessage)
{
if (oMessage)
{
this.setMessageFlagsToCache(
oMessage.folderFullNameRaw,
oMessage.uid,
[oMessage.unseen(), oMessage.flagged(), oMessage.answered(), oMessage.forwarded(), oMessage.isReadReceipt()]
[oMessage.unseen(), oMessage.flagged(), oMessage.answered(), oMessage.forwarded(),
oMessage.isReadReceipt(), oMessage.deletedMark()]
);
}
};
/**
* @param {string} sFolder
* @param {string} sUid
* @param {Array} aFlags
*/
CacheAppStorage.prototype.storeMessageFlagsToCacheByFolderAndUid = function (sFolder, sUid, aFlags)
CacheUserStorage.prototype.storeMessageFlagsToCacheByFolderAndUid = function (sFolder, sUid, aFlags)
{
if (Utils.isArray(aFlags) && 0 < aFlags.length)
{
@ -344,6 +367,43 @@
}
};
module.exports = new CacheAppStorage();
/**
* @param {string} sFolder
* @param {string} sUid
* @param {number} iSetAction
*/
CacheUserStorage.prototype.storeMessageFlagsToCacheBySetAction = function (sFolder, sUid, iSetAction)
{
var iUnread = 0, aFlags = this.getMessageFlagsFromCache(sFolder, sUid);
if (Utils.isArray(aFlags) && 0 < aFlags.length)
{
if (aFlags[0])
{
iUnread = 1;
}
switch (iSetAction)
{
case Enums.MessageSetAction.SetSeen:
aFlags[0] = false;
break;
case Enums.MessageSetAction.UnsetSeen:
aFlags[0] = true;
break;
case Enums.MessageSetAction.SetFlag:
aFlags[1] = true;
break;
case Enums.MessageSetAction.UnsetFlag:
aFlags[1] = false;
break;
}
this.setMessageFlagsToCache(sFolder, sUid, aFlags);
}
return iUnread;
};
module.exports = new CacheUserStorage();
}());

View file

@ -1,4 +1,3 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function () {
@ -15,7 +14,7 @@
/**
* @constructor
*/
function CookieLocalDriver()
function CookieDriver()
{
}
@ -23,7 +22,7 @@
* @static
* @return {boolean}
*/
CookieLocalDriver.supported = function ()
CookieDriver.supported = function ()
{
return !!(window.navigator && window.navigator.cookieEnabled);
};
@ -33,7 +32,7 @@
* @param {*} mData
* @return {boolean}
*/
CookieLocalDriver.prototype.set = function (sKey, mData)
CookieDriver.prototype.set = function (sKey, mData)
{
var
mStorageValue = $.cookie(Consts.Values.ClientSideStorageIndexName),
@ -71,7 +70,7 @@
* @param {string} sKey
* @return {*}
*/
CookieLocalDriver.prototype.get = function (sKey)
CookieDriver.prototype.get = function (sKey)
{
var
mStorageValue = $.cookie(Consts.Values.ClientSideStorageIndexName),
@ -95,6 +94,6 @@
return mResult;
};
module.exports = CookieLocalDriver;
module.exports = CookieDriver;
}());

View file

@ -1,4 +1,3 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function () {
@ -15,7 +14,7 @@
/**
* @constructor
*/
function LocalStorageLocalDriver()
function LocalStorageDriver()
{
}
@ -23,7 +22,7 @@
* @static
* @return {boolean}
*/
LocalStorageLocalDriver.supported = function ()
LocalStorageDriver.supported = function ()
{
return !!window.localStorage;
};
@ -33,7 +32,7 @@
* @param {*} mData
* @return {boolean}
*/
LocalStorageLocalDriver.prototype.set = function (sKey, mData)
LocalStorageDriver.prototype.set = function (sKey, mData)
{
var
mStorageValue = window.localStorage[Consts.Values.ClientSideStorageIndexName] || null,
@ -69,7 +68,7 @@
* @param {string} sKey
* @return {*}
*/
LocalStorageLocalDriver.prototype.get = function (sKey)
LocalStorageDriver.prototype.get = function (sKey)
{
var
mStorageValue = window.localStorage[Consts.Values.ClientSideStorageIndexName] || null,
@ -93,6 +92,6 @@
return mResult;
};
module.exports = LocalStorageLocalDriver;
module.exports = LocalStorageDriver;
}());

View file

@ -81,6 +81,12 @@
*/
Consts.Values.ImapDefaulSecurePort = 993;
/**
* @const
* @type {number}
*/
Consts.Values.SieveDefaulPort = 4190;
/**
* @const
* @type {number}
@ -115,7 +121,14 @@
* @const
* @type {string}
*/
Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=';
Consts.Values.RainLoopTrialKey = 'RAINLOOP-TRIAL-KEY';
/**
* @const
* @type {string}
*/
// Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD/il4QJ8AAAAASUVORK5CYII=';
Consts.DataImages.UserDotPic = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAuCAYAAABXuSs3AAAHHklEQVRoQ7VZW08bVxCeXRuwIbTGXIwNtBBaqjwgVUiR8lDlbza9qe1DpVZ9aNQ/0KpPeaJK07SpcuEeCEmUAObm21bfrL9lONjexSYrWfbunj37zXdmvpkz9oIgCKTD0Wg0xPd94TDP83Q0zvWa50vzklSrdanVanqf4/D84GBGr+F+Op3S8fqoJxLOdnZgTvsO/nYhenHA+UC7CWF1uXwkb9++ldPTUwVerVbVqFQqpR8YPjQ0JCMjI5LNDijoRgP3PQVu5+5Eor2XGLg7IV4GkIdHJ/LmzRs5ODiIwNbrdR0O0GCcq4Xz4eFhmZyclP7+tDQaIik/BG5XKQn4SwG3zJTLZXn9+rUclI8UHD5YVoDDN8bSzXhONwL48fFxGR4eilzFZT1uFRIB5yT8BqCdnR3Z3d0VP9Un6XRawYJpggVrZBv38ME4XKtUKnLt2jUplUoy1PR/l3U7T6sVSAQcgMAkj8PDQ9ne3pajoyMRL7zeKsYZWHgWYDGmv78/mmdwcFA+mJlSgziHDWrERrsjEXDXegTi1tZW+DLxI2bxIrqFNYTXyDyCFweMAHCwb8e4RnTNuOsqe3t7sra21pTD0Kct666E8XlcZyzw9/RUUXK5nK5oUinUQI6TQ3cynO/v78vq6qrKXCNwlTiJJpyNGc3nZHp6uqV2dwrQWOCtZBDAV1ZWwsQk7f0wiQn5kffbAu/0/KWBYzIC1+XukfGx0RGZmppKlC2tIV0Bh4aDcZW7HhkfH8urLLZL7T2pihvlkMNnz56FiadHxicL41IsFpN41bkxsYxbRdFo9jwB8KdPn14J8KnSpBQKhQs63nPmbCVRcBUAR2Lq1VVmpksyMTFxAXjcEsQybiegESionjx5osCZOeNe1O4+EhCAX7bQSgQcxRHTMgAgcz5+/Dis/hL4uHU3/B4YGNASGHIKxuEql0k+l05AeIAF1vPnz5VxFFmdDlaJrMtZITJeSsXCOTlMunKxjLtMYOKNjQ158eJFuAuKkUOb5sEwgff19SkJUBVkThZUbnXZrtCKBQ6gbnWIkjZpyne3ejAWoGnA7Icz6irvBLgbOMicCM6TkxPx/LAkbXfgWcsazuE2kFRsKD5Z+CiqDumKncpZvieWcS6dDVD8xiYCNflpJdwcdwJOf9airLmVQ7DPzMxIYWLsXGXoVqLt5k0M3K3JUVPDZdbWNzsCp48TPFdvdnZWUz32nDha7bJ63kgAJPzSdRks9/Kf9xMJAQ1gq2NpaUmy2Yz4zar4nQC3xb99AQwCcGzLAAwuhG8YiWvcOKts+r4GOe5nMhm5efOm9lUA3E3vSZJRrKvE0fnPv//Jy5cvo5cTHIPQbSjhOoqq69evS19f6lxDKK4+sVhigZPtKJqbrQeqxd5+WR4+fKgqgT0k2XX3nhiPgETWXFhYkFzuPZ2yVq1GTSOXpE47/VjgNnD4m4GG7/LhsTx69EiwD4Vr2MwIIxgbAH18fKx1yfz8vEogNvGtWnCuhLZa9UTAreVWFsHy/b/+Vrbdl7E5REMQD2jDoUbByty+/ZnU64GkU2HzyJLhktU1cLv8nARgkYS2d3ajAgwG8qU2oLmDZ92CMaOjo7K4uCiZgbDWaRWgnZhPxLhrMUCvr69riwKZk1LHF7XqrWAO9hJxH6ozNzcnCx/PqztZg9mf6SQMscCtm2C5ke4BGMlHWTUp36036AJajDVrFMzBrhhWslQsSrFYiOqVpMriNYIgqFRq2j3FAb/zffT6zuxFXxsNzs3NTXn16lW4gYiW96w1FyedF+83xG/2FNGCRpU4NjamMsn+OZ9xE5RXqdaDdPpib6RWCzuwKF9RxqI2AVNQBwQYJoK0wdBejnqtEikP3pfP51XjUTESl12FqJEKxsEorARYDD44ONTeID7YpsEnrRvQfWAI2e8WfDaTUSIwJ0iBCmFOtOUAHvVMPp/TPwvYFVYFIuP8l+DBgwdaa2Miqwa0GgYwfeMltovbDfh6c1vIgMYcliSsKv4IWFr6VDHxvldvBAH+1sA+cnl5WYOPmmr9ir+1l9I0Cgz0yjhXjfJJ0JROnmezWbl165ayr/5fqwcBNr7IfhjMqKcvESSM4eRcCasQ3bDNObmKPLdGUGpZsN24cUNLBm9zazu4d++e6qpNBFaTuUS26U5dpuR1CxyA7J9ddrMRqlz4pwLLYawymPd++/2PADt2ugcGwq9gCCdhQ96C6xWwa6j1ceuq+I0EhW0i8MAIVJfeL3d/DVD8EKi12P6/2S2jV/EccVB54O/ejz/9HGCpoBBMta5rXMXLu53D1XAwjhXwvvv+h4BAXVe4bOu3O3ChxF08LiZFG3fel199G9CH3fLyqv24NcB44MRhpdK788U3CpyKwsCw590xmfSpzsBt0Fqc3ud3vtZigxWcVZCklVpSiN0w3q5E/h9TGMIUuA3+EQAAAABJRU5ErkJggg==';
/**
* @const

View file

@ -5,6 +5,26 @@
var Enums = {};
/**
* @enum {string}
*/
Enums.FileType = {
'Unknown': 'unknown',
'Text': 'text',
'Html': 'html',
'Code': 'code',
'Eml': 'eml',
'WordText': 'word-text',
'Pdf': 'pdf',
'Image': 'image',
'Audio': 'audio',
'Video': 'video',
'Sheet': 'sheet',
'Presentation': 'presentation',
'Certificate': 'certificate',
'Archive': 'archive'
};
/**
* @enum {string}
*/
@ -15,6 +35,16 @@
'Unload': 'unload'
};
/**
* @enum {string}
*/
Enums.Focused = {
'None': 'none',
'MessageList': 'message-list',
'MessageView': 'message-view',
'FolderList': 'folder-list'
};
/**
* @enum {number}
*/
@ -36,15 +66,19 @@
* @enum {string}
*/
Enums.Capa = {
'Prem': 'PREM',
'TwoFactor': 'TWO_FACTOR',
'TwoFactorForce': 'TWO_FACTOR_FORCE',
'OpenPGP': 'OPEN_PGP',
'Prefetch': 'PREFETCH',
'Gravatar': 'GRAVATAR',
'Themes': 'THEMES',
'UserBackground': 'USER_BACKGROUND',
'Sieve': 'SIEVE',
'Filters': 'FILTERS',
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS',
'AdditionalIdentities': 'ADDITIONAL_IDENTITIES'
'AttachmentThumbnails': 'ATTACHMENT_THUMBNAILS',
'Templates': 'TEMPLATES',
'AutoLogout': 'AUTOLOGOUT',
'AdditionalAccounts': 'ADDITIONAL_ACCOUNTS'
};
/**
@ -144,7 +178,11 @@
'MessagesInboxLastHash': 1,
'MailBoxListSize': 2,
'ExpandedFolders': 3,
'FolderListSize': 4
'FolderListSize': 4,
'MessageListSize': 5,
'LastReplyAction': 6,
'LastSignMe': 7,
'ComposeLastIdentityID': 8
};
/**
@ -196,7 +234,7 @@
/**
* @enum {number}
*/
Enums.DesktopNotifications = {
Enums.DesktopNotification = {
'Allowed': 0,
'NotAllowed': 1,
'Denied': 2,
@ -217,15 +255,9 @@
*/
Enums.EditorDefaultType = {
'Html': 'Html',
'Plain': 'Plain'
};
/**
* @enum {string}
*/
Enums.CustomThemeType = {
'Light': 'Light',
'Dark': 'Dark'
'Plain': 'Plain',
'HtmlForced': 'HtmlForced',
'PlainForced': 'PlainForced'
};
/**
@ -257,22 +289,14 @@
'FalseResult': 0
};
/**
* @enum {string}
*/
Enums.InterfaceAnimation = {
'None': 'None',
'Normal': 'Normal',
'Full': 'Full'
};
/**
* @enum {number}
*/
Enums.Layout = {
'NoPreview': 0,
'SidePreview': 1,
'BottomPreview': 2
'BottomPreview': 2,
'Mobile': 3
};
/**
@ -280,7 +304,6 @@
*/
Enums.FilterConditionField = {
'From': 'From',
'To': 'To',
'Recipient': 'Recipient',
'Subject': 'Subject'
};
@ -300,8 +323,10 @@
*/
Enums.FiltersAction = {
'None': 'None',
'Move': 'Move',
'MoveTo': 'MoveTo',
'Discard': 'Discard',
'Vacation': 'Vacation',
'Reject': 'Reject',
'Forward': 'Forward'
};
@ -309,8 +334,8 @@
* @enum {string}
*/
Enums.FilterRulesType = {
'And': 'And',
'Or': 'Or'
'All': 'All',
'Any': 'Any'
};
/**
@ -393,6 +418,10 @@
'CantSendMessage': 302,
'InvalidRecipients': 303,
'CantSaveFilters': 351,
'CantGetFilters': 352,
'FiltersAreNotCorrect': 355,
'CantCreateFolder': 400,
'CantRenameFolder': 401,
'CantDeleteFolder': 402,
@ -415,12 +444,20 @@
'LicensingBanned': 712,
'DemoSendMessageError': 750,
'DemoAccountError': 751,
'AccountAlreadyExists': 801,
'AccountDoesNotExist': 802,
'MailServerError': 901,
'ClientViewError': 902,
'InvalidInputArgument': 903,
'AjaxFalse': 950,
'AjaxAbort': 951,
'AjaxParse': 952,
'AjaxTimeout': 953,
'UnknownNotification': 999,
'UnknownError': 999
};

View file

@ -28,12 +28,24 @@
*/
Events.prototype.sub = function (sName, fFunc, oContext)
{
if (Utils.isUnd(this.oSubs[sName]))
if (Utils.isObject(sName))
{
this.oSubs[sName] = [];
}
oContext = fFunc || null;
fFunc = null;
this.oSubs[sName].push([fFunc, oContext]);
_.each(sName, function (fSubFunc, sSubName) {
this.sub(sSubName, fSubFunc, oContext);
}, this);
}
else
{
if (Utils.isUnd(this.oSubs[sName]))
{
this.oSubs[sName] = [];
}
this.oSubs[sName].push([fFunc, oContext]);
}
return this;
};

View file

@ -18,33 +18,21 @@
Globals.$win = $(window);
Globals.$doc = $(window.document);
Globals.$html = $('html');
Globals.$body = $('body');
Globals.$div = $('<div></div>');
/**
* @type {?}
*/
Globals.now = (new window.Date()).getTime();
Globals.$win.__sizes = [0, 0];
/**
* @type {?}
*/
Globals.momentTrigger = ko.observable(true);
Globals.startMicrotime = (new window.Date()).getTime();
/**
* @type {?}
*/
Globals.dropdownVisibility = ko.observable(false).extend({'rateLimit': 0});
/**
* @type {?}
*/
Globals.tooltipTrigger = ko.observable(false).extend({'rateLimit': 0});
/**
* @type {?}
*/
Globals.langChangeTrigger = ko.observable(true);
/**
* @type {boolean}
*/
@ -73,22 +61,34 @@
/**
* @type {string}
*/
Globals.sUserAgent = (window.navigator.userAgent || '').toLowerCase();
Globals.sUserAgent = 'navigator' in window && 'userAgent' in window.navigator &&
window.navigator.userAgent.toLowerCase() || '';
/**
* @type {boolean}
*/
Globals.bIsiOSDevice = -1 < Globals.sUserAgent.indexOf('iphone') || -1 < Globals.sUserAgent.indexOf('ipod') || -1 < Globals.sUserAgent.indexOf('ipad');
Globals.bIE = Globals.sUserAgent.indexOf('msie') > -1;
/**
* @type {boolean}
*/
Globals.bIsAndroidDevice = -1 < Globals.sUserAgent.indexOf('android');
Globals.bChrome = Globals.sUserAgent.indexOf('chrome') > -1;
/**
* @type {boolean}
*/
Globals.bMobileDevice = Globals.bIsiOSDevice || Globals.bIsAndroidDevice;
Globals.bSafari = !Globals.bChrome && Globals.sUserAgent.indexOf('safari') > -1;
/**
* @type {boolean}
*/
Globals.bMobileDevice =
/android/i.test(Globals.sUserAgent) ||
/iphone/i.test(Globals.sUserAgent) ||
/ipod/i.test(Globals.sUserAgent) ||
/ipad/i.test(Globals.sUserAgent) ||
/blackberry/i.test(Globals.sUserAgent)
;
/**
* @type {boolean}
@ -103,18 +103,14 @@
/**
* @type {boolean}
*/
Globals.bAnimationSupported = !Globals.bMobileDevice && Globals.$html.hasClass('csstransitions');
Globals.bAnimationSupported = !Globals.bMobileDevice && Globals.$html.hasClass('csstransitions') &&
Globals.$html.hasClass('cssanimations');
/**
* @type {boolean}
*/
Globals.bXMLHttpRequestSupported = !!window.XMLHttpRequest;
/**
* @type {string}
*/
Globals.sAnimationType = '';
/**
* @type {*}
*/
@ -131,23 +127,26 @@
'toolbarGroups': [
{name: 'spec'},
{name: 'styles'},
{name: 'basicstyles', groups: ['basicstyles', 'cleanup']},
{name: 'basicstyles', groups: ['basicstyles', 'cleanup', 'bidi']},
{name: 'colors'},
{name: 'paragraph', groups: ['list', 'indent', 'blocks', 'align']},
{name: 'links'},
{name: 'insert'},
{name: 'document', groups: ['mode', 'document', 'doctools']},
{name: 'others'}
// {name: 'document', groups: ['mode', 'document', 'doctools']}
],
'removePlugins': 'liststyle,tabletools,contextmenu', //blockquote
'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll',
'removePlugins': 'liststyle',
'removeButtons': 'Format,Undo,Redo,Cut,Copy,Paste,Anchor,Strike,Subscript,Superscript,Image,SelectAll,Source',
'removeDialogTabs': 'link:advanced;link:target;image:advanced;images:advanced',
'extraPlugins': 'plain',
'extraPlugins': 'plain,signature',
'allowedContent': true,
'autoParagraph': false,
'extraAllowedContent': true,
'fillEmptyBlocks': false,
'ignoreEmptyParagraph': true,
'font_defaultLabel': 'Arial',
'fontSize_defaultLabel': '13',
@ -158,6 +157,7 @@
* @type {Object}
*/
Globals.oHtmlEditorLangsMap = {
'bg': 'bg',
'de': 'de',
'es': 'es',
'fr': 'fr',
@ -168,6 +168,7 @@
'ja-jp': 'ja',
'ko': 'ko',
'ko-kr': 'ko',
'lt': 'lt',
'lv': 'lv',
'nl': 'nl',
'no': 'no',
@ -178,9 +179,11 @@
'ro': 'ro',
'ru': 'ru',
'sk': 'sk',
'sv': 'sv',
'tr': 'tr',
'ua': 'ru',
'zh': 'zh',
'zh-tw': 'zh',
'zh-cn': 'zh-cn'
};
@ -191,10 +194,6 @@
});
}
Globals.oI18N = window['rainloopI18N'] || {};
Globals.oNotificationI18N = {};
Globals.aBootstrapDropdowns = [];
Globals.aViewModels = {
@ -212,6 +211,10 @@
return 0 < Globals.popupVisibilityNames().length;
}, this);
Globals.popupVisibility.subscribe(function (bValue) {
Globals.$html.toggleClass('rl-modal', bValue);
});
// keys
Globals.keyScopeReal = ko.observable(Enums.KeyState.All);
Globals.keyScopeFake = ko.observable(Enums.KeyState.All);
@ -266,14 +269,13 @@
});
Globals.keyScopeReal.subscribe(function (sValue) {
// window.console.log(sValue);
// window.console.log('keyScope=' + sValue); // DEBUG
key.setScope(sValue);
});
Globals.dropdownVisibility.subscribe(function (bValue) {
if (bValue)
{
Globals.tooltipTrigger(!Globals.tooltipTrigger());
Globals.keyScope(Enums.KeyState.Menu);
}
else if (Enums.KeyState.Menu === key.getScope())

View file

@ -8,6 +8,7 @@
_ = require('_'),
Globals = require('Common/Globals'),
Settings = require('Storage/Settings')
;
@ -30,6 +31,9 @@
this.resize = _.throttle(_.bind(this.resize, this), 100);
this.__inited = false;
this.__initedData = null;
this.init();
}
@ -61,6 +65,23 @@
return this.editor ? 'wysiwyg' === this.editor.mode : false;
};
/**
* @param {string} sSignature
* @param {bool} bHtml
* @param {bool} bInsertBefore
*/
HtmlEditor.prototype.setSignature = function (sSignature, bHtml, bInsertBefore)
{
if (this.editor)
{
this.editor.execCommand('insertSignature', {
'isHtml': bHtml,
'insertBefore': bInsertBefore,
'signature': sSignature
});
}
};
/**
* @return {boolean}
*/
@ -78,66 +99,122 @@
};
/**
* @param {boolean=} bWrapIsHtml = false
* @param {string} sText
* @return {string}
*/
HtmlEditor.prototype.getData = function (bWrapIsHtml)
HtmlEditor.prototype.clearSignatureSigns = function (sText)
{
if (this.editor)
{
if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain)
{
return this.editor.__plain.getRawData();
}
return bWrapIsHtml ?
'<div data-html-editor-font-wrapper="true" style="font-family: arial, sans-serif; font-size: 13px;">' +
this.editor.getData() + '</div>' : this.editor.getData();
}
return '';
return sText.replace(/(\u0002|\u0003|\u200C|\u200D)/g, '');
};
HtmlEditor.prototype.modeToggle = function (bPlain)
/**
* @param {boolean=} bWrapIsHtml = false
* @param {boolean=} bClearSignatureSigns = false
* @return {string}
*/
HtmlEditor.prototype.getData = function (bWrapIsHtml, bClearSignatureSigns)
{
var sResult = '';
if (this.editor)
{
try
{
if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain)
{
sResult = this.editor.__plain.getRawData();
}
else
{
sResult = bWrapIsHtml ?
'<div data-html-editor-font-wrapper="true" style="font-family: arial, sans-serif; font-size: 13px;">' +
this.editor.getData() + '</div>' : this.editor.getData();
}
}
catch (e) {}
if (bClearSignatureSigns)
{
sResult = this.clearSignatureSigns(sResult);
}
}
return sResult;
};
/**
* @param {boolean=} bWrapIsHtml = false
* @param {boolean=} bClearSignatureSigns = false
* @return {string}
*/
HtmlEditor.prototype.getDataWithHtmlMark = function (bWrapIsHtml, bClearSignatureSigns)
{
return (this.isHtml() ? ':HTML:' : '') + this.getData(bWrapIsHtml, bClearSignatureSigns);
};
HtmlEditor.prototype.modeToggle = function (bPlain, bResize)
{
if (this.editor)
{
if (bPlain)
{
if ('plain' === this.editor.mode)
try {
if (bPlain)
{
this.editor.setMode('wysiwyg');
if ('plain' === this.editor.mode)
{
this.editor.setMode('wysiwyg');
}
}
}
else
{
if ('wysiwyg' === this.editor.mode)
else
{
this.editor.setMode('plain');
if ('wysiwyg' === this.editor.mode)
{
this.editor.setMode('plain');
}
}
}
} catch(e) {}
this.resize();
if (bResize)
{
this.resize();
}
}
};
HtmlEditor.prototype.setHtmlOrPlain = function (sText, bFocus)
{
if (':HTML:' === sText.substr(0, 6))
{
this.setHtml(sText.substr(6), bFocus);
}
else
{
this.setPlain(sText, bFocus);
}
};
HtmlEditor.prototype.setHtml = function (sHtml, bFocus)
{
if (this.editor)
if (this.editor && this.__inited)
{
this.modeToggle(true);
this.editor.setData(sHtml);
try {
this.editor.setData(sHtml);
} catch (e) {}
if (bFocus)
{
this.focus();
}
}
else
{
this.__initedData = [true, sHtml, bFocus];
}
};
HtmlEditor.prototype.setPlain = function (sPlain, bFocus)
{
if (this.editor)
if (this.editor && this.__inited)
{
this.modeToggle(false);
if ('plain' === this.editor.mode && this.editor.plugins.plain && this.editor.__plain)
@ -146,7 +223,9 @@
}
else
{
this.editor.setData(sPlain);
try {
this.editor.setData(sPlain);
} catch (e) {}
}
if (bFocus)
@ -154,11 +233,15 @@
this.focus();
}
}
else
{
this.__initedData = [false, sPlain, bFocus];
}
};
HtmlEditor.prototype.init = function ()
{
if (this.$element && this.$element[0])
if (this.$element && this.$element[0] && !this.editor)
{
var
self = this,
@ -167,13 +250,23 @@
var
oConfig = Globals.oHtmlEditorDefaultConfig,
sLanguage = Settings.settingsGet('Language'),
bSource = !!Settings.settingsGet('AllowHtmlEditorSourceButton')
bSource = !!Settings.settingsGet('AllowHtmlEditorSourceButton'),
bBiti = !!Settings.settingsGet('AllowHtmlEditorBitiButtons')
;
if (bSource && oConfig.toolbarGroups && !oConfig.toolbarGroups.__SourceInited)
if ((bSource || !bBiti) && !oConfig.toolbarGroups.__cfgInited)
{
oConfig.toolbarGroups.__SourceInited = true;
oConfig.toolbarGroups.push({name: 'document', groups: ['mode', 'document', 'doctools']});
oConfig.toolbarGroups.__cfgInited = true;
if (bSource)
{
oConfig.removeButtons = oConfig.removeButtons.replace(',Source', '');
}
if (!bBiti)
{
oConfig.removePlugins += (oConfig.removePlugins ? ',' : '') + 'bidi';
}
}
oConfig.enterMode = window.CKEDITOR.ENTER_BR;
@ -185,6 +278,19 @@
window.CKEDITOR.env.isCompatible = true;
}
// oConfig.allowedContent = {
// $1: {
// elements: window.CKEDITOR.dtd,
// attributes: true,
// styles: true,
// classes: true
// }
// };
//
// oConfig.disallowedContent = 'script; style; iframe; frame; *[on*]';
window.CKEDITOR.dtd.$removeEmpty['p'] = 1;
self.editor = window.CKEDITOR.appendTo(self.$element[0], oConfig);
self.editor.on('key', function(oEvent) {
@ -216,12 +322,31 @@
{
self.editor.on('instanceReady', function () {
if (self.editor.removeMenuItem)
{
self.editor.removeMenuItem('cut');
self.editor.removeMenuItem('copy');
self.editor.removeMenuItem('paste');
}
self.editor.setKeystroke(window.CKEDITOR.CTRL + 65 /* A */, 'selectAll');
self.editor.editable().addClass('cke_enable_context_menu');
self.fOnReady();
self.__resizable = true;
self.__inited = true;
self.resize();
if (self.__initedData)
{
if (self.__initedData[0])
{
self.setHtml(self.__initedData[1], self.__initedData[2]);
}
else
{
self.setPlain(self.__initedData[1], self.__initedData[2]);
}
}
});
}
}
@ -242,7 +367,9 @@
{
if (this.editor)
{
this.editor.focus();
try {
this.editor.focus();
} catch (e) {}
}
};
@ -250,7 +377,9 @@
{
if (this.editor)
{
this.editor.focusManager.blur(true);
try {
this.editor.focusManager.blur(true);
} catch (e) {}
}
};
@ -258,11 +387,19 @@
{
if (this.editor && this.__resizable)
{
try
{
try {
this.editor.resize(this.$element.width(), this.$element.innerHeight());
}
catch (e) {}
} catch (e) {}
}
};
HtmlEditor.prototype.setReadOnly = function (bValue)
{
if (this.editor)
{
try {
this.editor.setReadOnly(!!bValue);
} catch (e) {}
}
};
@ -271,7 +408,6 @@
this.setHtml('', bFocus);
};
module.exports = HtmlEditor;
}());

View file

@ -1,335 +0,0 @@
(function () {
'use strict';
var
Utils = require('Common/Utils')
;
/**
* @constructor
*/
function LinkBuilder()
{
var Settings = require('Storage/Settings');
this.sBase = '#/';
this.sServer = './?';
this.sVersion = Settings.settingsGet('Version');
this.sSpecSuffix = Settings.settingsGet('AuthAccountHash') || '0';
this.sStaticPrefix = Settings.settingsGet('StaticPrefix') || 'rainloop/v/' + this.sVersion + '/static/';
}
/**
* @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.uploadContacts = function ()
{
return this.sServer + '/UploadContacts/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.uploadBackground = function ()
{
return this.sServer + '/UploadBackground/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.append = function ()
{
return this.sServer + '/Append/' + this.sSpecSuffix + '/';
};
/**
* @param {string} sEmail
* @return {string}
*/
LinkBuilder.prototype.change = function (sEmail)
{
return this.sServer + '/Change/' + this.sSpecSuffix + '/' + Utils.encodeURIComponent(sEmail) + '/';
};
/**
* @param {string=} sAdd
* @return {string}
*/
LinkBuilder.prototype.ajax = function (sAdd)
{
return this.sServer + '/Ajax/' + this.sSpecSuffix + '/' + sAdd;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
LinkBuilder.prototype.messageViewLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ViewAsPlain/' + sRequestHash;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
LinkBuilder.prototype.messageDownloadLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/Download/' + sRequestHash;
};
/**
* @param {string} sEmail
* @return {string}
*/
LinkBuilder.prototype.avatarLink = function (sEmail)
{
return this.sServer + '/Raw/0/Avatar/' + Utils.encodeURIComponent(sEmail) + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.inbox = function ()
{
return this.sBase + 'mailbox/Inbox';
};
/**
* @return {string}
*/
LinkBuilder.prototype.messagePreview = function ()
{
return this.sBase + 'mailbox/message-preview';
};
/**
* @param {string=} sScreenName
* @return {string}
*/
LinkBuilder.prototype.settings = function (sScreenName)
{
var sResult = this.sBase + 'settings';
if (!Utils.isUnd(sScreenName) && '' !== sScreenName)
{
sResult += '/' + sScreenName;
}
return sResult;
};
/**
* @return {string}
*/
LinkBuilder.prototype.about = function ()
{
return this.sBase + 'about';
};
/**
* @param {string} sScreenName
* @return {string}
*/
LinkBuilder.prototype.admin = function (sScreenName)
{
var sResult = this.sBase;
switch (sScreenName) {
case 'AdminDomains':
sResult += 'domains';
break;
case 'AdminSecurity':
sResult += 'security';
break;
case 'AdminLicensing':
sResult += 'licensing';
break;
}
return sResult;
};
/**
* @param {string} sFolder
* @param {number=} iPage = 1
* @param {string=} sSearch = ''
* @return {string}
*/
LinkBuilder.prototype.mailBox = function (sFolder, iPage, sSearch)
{
iPage = Utils.isNormal(iPage) ? Utils.pInt(iPage) : 1;
sSearch = Utils.pString(sSearch);
var sResult = this.sBase + 'mailbox/';
if ('' !== sFolder)
{
sResult += encodeURI(sFolder);
}
if (1 < iPage)
{
sResult = sResult.replace(/[\/]+$/, '');
sResult += '/p' + iPage;
}
if ('' !== sSearch)
{
sResult = sResult.replace(/[\/]+$/, '');
sResult += '/' + encodeURI(sSearch);
}
return sResult;
};
/**
* @return {string}
*/
LinkBuilder.prototype.phpInfo = function ()
{
return this.sServer + 'Info';
};
/**
* @param {string} sLang
* @return {string}
*/
LinkBuilder.prototype.langLink = function (sLang)
{
return this.sServer + '/Lang/0/' + encodeURI(sLang) + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsVcf = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsVcf/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.exportContactsCsv = function ()
{
return this.sServer + '/Raw/' + this.sSpecSuffix + '/ContactsCsv/';
};
/**
* @return {string}
*/
LinkBuilder.prototype.emptyContactPic = function ()
{
return this.sStaticPrefix + 'css/images/empty-contact.png';
};
/**
* @param {string} sFileName
* @return {string}
*/
LinkBuilder.prototype.sound = function (sFileName)
{
return this.sStaticPrefix + 'sounds/' + sFileName;
};
/**
* @param {string} sTheme
* @return {string}
*/
LinkBuilder.prototype.themePreviewLink = function (sTheme)
{
var sPrefix = 'rainloop/v/' + this.sVersion + '/';
if ('@custom' === sTheme.substr(-7))
{
sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7));
sPrefix = '';
}
return sPrefix + 'themes/' + encodeURI(sTheme) + '/images/preview.png';
};
/**
* @return {string}
*/
LinkBuilder.prototype.notificationMailIcon = function ()
{
return this.sStaticPrefix + 'css/images/icom-message-notification.png';
};
/**
* @return {string}
*/
LinkBuilder.prototype.openPgpJs = function ()
{
return this.sStaticPrefix + 'js/min/openpgp.js';
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialGoogle = function ()
{
return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialTwitter = function ()
{
return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
LinkBuilder.prototype.socialFacebook = function ()
{
return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.sSpecSuffix + '/' : '');
};
module.exports = new LinkBuilder();
}());

394
dev/Common/Links.js Normal file
View file

@ -0,0 +1,394 @@
(function () {
'use strict';
var
window = require('window'),
Utils = require('Common/Utils')
;
/**
* @constructor
*/
function Links()
{
var Settings = require('Storage/Settings');
this.sBase = '#/';
this.sServer = './?';
this.sVersion = Settings.settingsGet('Version');
this.sSpecSuffix = Settings.settingsGet('AuthAccountHash') || '0';
this.sWebPrefix = Settings.settingsGet('WebPath') || '';
this.sVersionPrefix = Settings.settingsGet('WebVersionPath') || 'rainloop/v/' + this.sVersion + '/';
this.sStaticPrefix = this.sVersionPrefix + 'static/';
}
/**
* @return {string}
*/
Links.prototype.subQueryPrefix = function ()
{
return '&q[]=';
};
/**
* @return {string}
*/
Links.prototype.root = function ()
{
return this.sBase;
};
/**
* @return {string}
*/
Links.prototype.rootAdmin = function ()
{
return this.sServer + '/Admin/';
};
/**
* @return {string}
*/
Links.prototype.rootUser = function ()
{
return './';
};
/**
* @param {string} sDownload
* @return {string}
*/
Links.prototype.attachmentDownload = function (sDownload)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/Download/' + this.subQueryPrefix() + '/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
Links.prototype.attachmentPreview = function (sDownload)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/View/' + this.subQueryPrefix() + '/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
Links.prototype.attachmentThumbnailPreview = function (sDownload)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ViewThumbnail/' + this.subQueryPrefix() + '/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
Links.prototype.attachmentPreviewAsPlain = function (sDownload)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sDownload;
};
/**
* @param {string} sDownload
* @return {string}
*/
Links.prototype.attachmentFramed = function (sDownload)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/FramedView/' + this.subQueryPrefix() + '/' + sDownload;
};
/**
* @return {string}
*/
Links.prototype.upload = function ()
{
return this.sServer + '/Upload/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
Links.prototype.uploadContacts = function ()
{
return this.sServer + '/UploadContacts/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
Links.prototype.uploadBackground = function ()
{
return this.sServer + '/UploadBackground/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/';
};
/**
* @return {string}
*/
Links.prototype.append = function ()
{
return this.sServer + '/Append/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/';
};
/**
* @param {string} sEmail
* @return {string}
*/
Links.prototype.change = function (sEmail)
{
return this.sServer + '/Change/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' + Utils.encodeURIComponent(sEmail) + '/';
};
/**
* @param {string=} sAdd
* @return {string}
*/
Links.prototype.ajax = function (sAdd)
{
return this.sServer + '/Ajax/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' + sAdd;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
Links.prototype.messageViewLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ViewAsPlain/' + this.subQueryPrefix() + '/' + sRequestHash;
};
/**
* @param {string} sRequestHash
* @return {string}
*/
Links.prototype.messageDownloadLink = function (sRequestHash)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/Download/' + this.subQueryPrefix() + '/' + sRequestHash;
};
/**
* @param {string} sEmail
* @return {string}
*/
Links.prototype.avatarLink = function (sEmail)
{
return this.sServer + '/Raw/0/Avatar/' + Utils.encodeURIComponent(sEmail) + '/';
};
/**
* @param {string} sHash
* @return {string}
*/
Links.prototype.publicLink = function (sHash)
{
return this.sServer + '/Raw/0/Public/' + sHash + '/';
};
/**
* @param {string} sHash
* @return {string}
*/
Links.prototype.userBackground = function (sHash)
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix +
'/UserBackground/' + this.subQueryPrefix() + '/' + sHash;
};
/**
* @param {string} sInboxFolderName = 'INBOX'
* @return {string}
*/
Links.prototype.inbox = function (sInboxFolderName)
{
sInboxFolderName = Utils.isUnd(sInboxFolderName) ? 'INBOX' : sInboxFolderName;
return this.sBase + 'mailbox/' + sInboxFolderName;
};
/**
* @param {string=} sScreenName
* @return {string}
*/
Links.prototype.settings = function (sScreenName)
{
var sResult = this.sBase + 'settings';
if (!Utils.isUnd(sScreenName) && '' !== sScreenName)
{
sResult += '/' + sScreenName;
}
return sResult;
};
/**
* @return {string}
*/
Links.prototype.about = function ()
{
return this.sBase + 'about';
};
/**
* @param {string} sScreenName
* @return {string}
*/
Links.prototype.admin = function (sScreenName)
{
var sResult = this.sBase;
switch (sScreenName) {
case 'AdminDomains':
sResult += 'domains';
break;
case 'AdminSecurity':
sResult += 'security';
break;
case 'AdminLicensing':
sResult += 'licensing';
break;
}
return sResult;
};
/**
* @param {string} sFolder
* @param {number=} iPage = 1
* @param {string=} sSearch = ''
* @return {string}
*/
Links.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}
*/
Links.prototype.phpInfo = function ()
{
return this.sServer + 'Info';
};
/**
* @param {string} sLang
* @return {string}
*/
Links.prototype.langLink = function (sLang, bAdmin)
{
return this.sServer + '/Lang/0/' + (bAdmin ? 'Admin' : 'App') + '/' + encodeURI(sLang) + '/' + this.sVersion + '/';
};
/**
* @return {string}
*/
Links.prototype.exportContactsVcf = function ()
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ContactsVcf/';
};
/**
* @return {string}
*/
Links.prototype.exportContactsCsv = function ()
{
return this.sServer + '/Raw/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/ContactsCsv/';
};
/**
* @return {string}
*/
Links.prototype.emptyContactPic = function ()
{
return this.sStaticPrefix + 'css/images/empty-contact.png';
};
/**
* @param {string} sFileName
* @return {string}
*/
Links.prototype.sound = function (sFileName)
{
return this.sStaticPrefix + 'sounds/' + sFileName;
};
/**
* @param {string} sTheme
* @return {string}
*/
Links.prototype.themePreviewLink = function (sTheme)
{
var sPrefix = this.sVersionPrefix;
if ('@custom' === sTheme.substr(-7))
{
sTheme = Utils.trim(sTheme.substring(0, sTheme.length - 7));
sPrefix = this.sWebPrefix;
}
return sPrefix + 'themes/' + window.encodeURI(sTheme) + '/images/preview.png';
};
/**
* @return {string}
*/
Links.prototype.notificationMailIcon = function ()
{
return this.sStaticPrefix + 'css/images/icom-message-notification.png';
};
/**
* @return {string}
*/
Links.prototype.openPgpJs = function ()
{
return this.sStaticPrefix + 'js/min/openpgp.js';
};
/**
* @return {string}
*/
Links.prototype.socialGoogle = function ()
{
return this.sServer + 'SocialGoogle' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
Links.prototype.socialTwitter = function ()
{
return this.sServer + 'SocialTwitter' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : '');
};
/**
* @return {string}
*/
Links.prototype.socialFacebook = function ()
{
return this.sServer + 'SocialFacebook' + ('' !== this.sSpecSuffix ? '/' + this.subQueryPrefix() + '/' + this.sSpecSuffix + '/' : '');
};
module.exports = new Links();
}());

168
dev/Common/Mime.js Normal file
View file

@ -0,0 +1,168 @@
(function () {
'use strict';
module.exports = {
'eml' : 'message/rfc822',
'mime' : 'message/rfc822',
'txt' : 'text/plain',
'text' : 'text/plain',
'def' : 'text/plain',
'list' : 'text/plain',
'in' : 'text/plain',
'ini' : 'text/plain',
'log' : 'text/plain',
'sql' : 'text/plain',
'cfg' : 'text/plain',
'conf' : 'text/plain',
'asc' : 'text/plain',
'rtx' : 'text/richtext',
'vcard' : 'text/vcard',
'vcf' : 'text/vcard',
'htm' : 'text/html',
'html' : 'text/html',
'csv' : 'text/csv',
'ics' : 'text/calendar',
'ifb' : 'text/calendar',
'xml' : 'text/xml',
'json' : 'application/json',
'swf' : 'application/x-shockwave-flash',
'hlp' : 'application/winhlp',
'wgt' : 'application/widget',
'chm' : 'application/vnd.ms-htmlhelp',
'p10' : 'application/pkcs10',
'p7c' : 'application/pkcs7-mime',
'p7m' : 'application/pkcs7-mime',
'p7s' : 'application/pkcs7-signature',
'torrent' : 'application/x-bittorrent',
// scripts
'js' : 'application/javascript',
'pl' : 'text/perl',
'css' : 'text/css',
'asp' : 'text/asp',
'php' : 'application/x-httpd-php',
'php3' : 'application/x-httpd-php',
'php4' : 'application/x-httpd-php',
'php5' : 'application/x-httpd-php',
'phtml' : 'application/x-httpd-php',
// images
'png' : 'image/png',
'jpg' : 'image/jpeg',
'jpeg' : 'image/jpeg',
'jpe' : 'image/jpeg',
'jfif' : 'image/jpeg',
'gif' : 'image/gif',
'bmp' : 'image/bmp',
'cgm' : 'image/cgm',
'ief' : 'image/ief',
'ico' : 'image/x-icon',
'tif' : 'image/tiff',
'tiff' : 'image/tiff',
'svg' : 'image/svg+xml',
'svgz' : 'image/svg+xml',
'djv' : 'image/vnd.djvu',
'djvu' : 'image/vnd.djvu',
'webp' : 'image/webp',
// archives
'zip' : 'application/zip',
'7z' : 'application/x-7z-compressed',
'rar' : 'application/x-rar-compressed',
'exe' : 'application/x-msdownload',
'dll' : 'application/x-msdownload',
'scr' : 'application/x-msdownload',
'com' : 'application/x-msdownload',
'bat' : 'application/x-msdownload',
'msi' : 'application/x-msdownload',
'cab' : 'application/vnd.ms-cab-compressed',
'gz' : 'application/x-gzip',
'tgz' : 'application/x-gzip',
'bz' : 'application/x-bzip',
'bz2' : 'application/x-bzip2',
'deb' : 'application/x-debian-package',
// fonts
'psf' : 'application/x-font-linux-psf',
'otf' : 'application/x-font-otf',
'pcf' : 'application/x-font-pcf',
'snf' : 'application/x-font-snf',
'ttf' : 'application/x-font-ttf',
'ttc' : 'application/x-font-ttf',
// audio
'mp3' : 'audio/mpeg',
'amr' : 'audio/amr',
'aac' : 'audio/x-aac',
'aif' : 'audio/x-aiff',
'aifc' : 'audio/x-aiff',
'aiff' : 'audio/x-aiff',
'wav' : 'audio/x-wav',
'wma' : 'audio/x-ms-wma',
'wax' : 'audio/x-ms-wax',
'midi' : 'audio/midi',
'mp4a' : 'audio/mp4',
'ogg' : 'audio/ogg',
'weba' : 'audio/webm',
'ra' : 'audio/x-pn-realaudio',
'ram' : 'audio/x-pn-realaudio',
'rmp' : 'audio/x-pn-realaudio-plugin',
'm3u' : 'audio/x-mpegurl',
// video
'flv' : 'video/x-flv',
'qt' : 'video/quicktime',
'mov' : 'video/quicktime',
'wmv' : 'video/windows-media',
'avi' : 'video/x-msvideo',
'mpg' : 'video/mpeg',
'mpeg' : 'video/mpeg',
'mpe' : 'video/mpeg',
'm1v' : 'video/mpeg',
'm2v' : 'video/mpeg',
'3gp' : 'video/3gpp',
'3g2' : 'video/3gpp2',
'h261' : 'video/h261',
'h263' : 'video/h263',
'h264' : 'video/h264',
'jpgv' : 'video/jpgv',
'mp4' : 'video/mp4',
'mp4v' : 'video/mp4',
'mpg4' : 'video/mp4',
'ogv' : 'video/ogg',
'webm' : 'video/webm',
'm4v' : 'video/x-m4v',
'asf' : 'video/x-ms-asf',
'asx' : 'video/x-ms-asf',
'wm' : 'video/x-ms-wm',
'wmx' : 'video/x-ms-wmx',
'wvx' : 'video/x-ms-wvx',
'movie' : 'video/x-sgi-movie',
// adobe
'pdf' : 'application/pdf',
'psd' : 'image/vnd.adobe.photoshop',
'ai' : 'application/postscript',
'eps' : 'application/postscript',
'ps' : 'application/postscript',
// ms office
'doc' : 'application/msword',
'dot' : 'application/msword',
'rtf' : 'application/rtf',
'xls' : 'application/vnd.ms-excel',
'ppt' : 'application/vnd.ms-powerpoint',
'docx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'xlsx' : 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'dotx' : 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'pptx' : 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
// open office
'odt' : 'application/vnd.oasis.opendocument.text',
'ods' : 'application/vnd.oasis.opendocument.spreadsheet'
};
}());

188
dev/Common/Momentor.js Normal file
View file

@ -0,0 +1,188 @@
(function () {
'use strict';
var
window = require('window'),
$ = require('$'),
_ = require('_'),
moment = require('moment'),
Translator = require('Common/Translator')
;
/**
* @constructor
*/
function Momentor()
{
this.format = _.bind(this.format, this);
this.updateMomentNow = _.debounce(_.bind(function () {
this._moment = moment();
}, this), 500, true);
this.updateMomentNowUnix = _.debounce(_.bind(function () {
this._momentNow = moment().unix();
}, this), 500, true);
}
Momentor.prototype._moment = null;
Momentor.prototype._momentNow = 0;
Momentor.prototype.momentNow = function ()
{
this.updateMomentNow();
return this._moment || moment();
};
Momentor.prototype.momentNowUnix = function ()
{
this.updateMomentNowUnix();
return this._momentNow || 0;
};
Momentor.prototype.searchSubtractFormatDateHelper = function (iDate)
{
var oM = this.momentNow();
return oM.clone().subtract('days', iDate).format('YYYY.MM.DD');
};
/**
* @param {Object} oMoment
* @return {string}
*/
Momentor.prototype.formatCustomShortDate = function (oMoment)
{
var
sResult = '',
oMomentNow = this.momentNow()
;
if (oMoment && oMomentNow)
{
if (4 >= oMomentNow.diff(oMoment, 'hours'))
{
sResult = oMoment.fromNow();
}
else if (oMomentNow.format('L') === oMoment.format('L'))
{
sResult = Translator.i18n('MESSAGE_LIST/TODAY_AT', {
'TIME': oMoment.format('LT')
});
}
else if (oMomentNow.clone().subtract('days', 1).format('L') === oMoment.format('L'))
{
sResult = Translator.i18n('MESSAGE_LIST/YESTERDAY_AT', {
'TIME': oMoment.format('LT')
});
}
else if (oMomentNow.year() === oMoment.year())
{
sResult = oMoment.format('D MMM.');
}
else
{
sResult = oMoment.format('LL');
}
}
return sResult;
};
/**
* @param {number} iTimeStampInUTC
* @param {string} sFormat
* @return {string}
*/
Momentor.prototype.format = function (iTimeStampInUTC, sFormat)
{
var
oM = null,
sResult = '',
iNow = this.momentNowUnix()
;
iTimeStampInUTC = 0 < iTimeStampInUTC ? iTimeStampInUTC : (0 === iTimeStampInUTC ? iNow : 0);
iTimeStampInUTC = iNow < iTimeStampInUTC ? iNow : iTimeStampInUTC;
oM = 0 < iTimeStampInUTC ? moment.unix(iTimeStampInUTC) : null;
if (oM && 1970 === oM.year())
{
oM = null;
}
if (oM)
{
switch (sFormat)
{
case 'FROMNOW':
sResult = oM.fromNow();
break;
case 'SHORT':
sResult = this.formatCustomShortDate(oM);
break;
case 'FULL':
sResult = oM.format('LLL');
break;
default:
sResult = oM.format(sFormat);
break;
}
}
return sResult;
};
/**
* @param {Object} oElement
*/
Momentor.prototype.momentToNode = function (oElement)
{
var
sKey = '',
iTime = 0,
$oEl = $(oElement)
;
iTime = $oEl.data('moment-time');
if (iTime)
{
sKey = $oEl.data('moment-format');
if (sKey)
{
$oEl.text(this.format(iTime, sKey));
}
sKey = $oEl.data('moment-format-title');
if (sKey)
{
$oEl.attr('title', this.format(iTime, sKey));
}
}
};
/**
* @param {Object} oElements
*/
Momentor.prototype.momentToNodes = function (oElements)
{
var self = this;
_.defer(function () {
$('.moment', oElements).each(function () {
self.momentToNode(this);
});
});
};
Momentor.prototype.reload = function ()
{
this.momentToNodes(window.document);
};
module.exports = new Momentor();
}());

View file

@ -16,8 +16,10 @@
function Plugins()
{
this.oSettings = require('Storage/Settings');
this.oViewModelsHooks = {};
this.oSimpleHooks = {};
this.aUserViewModelsHooks = [];
this.aAdminViewModelsHooks = [];
}
/**
@ -26,9 +28,14 @@
Plugins.prototype.oSettings = {};
/**
* @type {Object}
* @type {Array}
*/
Plugins.prototype.oViewModelsHooks = {};
Plugins.prototype.aUserViewModelsHooks = [];
/**
* @type {Array}
*/
Plugins.prototype.aAdminViewModelsHooks = [];
/**
* @type {Object}
@ -82,17 +89,44 @@
* @param {string} sAction
* @param {Object=} oParameters
* @param {?number=} iTimeout
* @param {string=} sGetAdd = ''
* @param {Array=} aAbortActions = []
*/
Plugins.prototype.remoteRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
Plugins.prototype.remoteRequest = function (fCallback, sAction, oParameters, iTimeout)
{
if (Globals.__APP__)
{
Globals.__APP__.remote().defaultRequest(fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions);
Globals.__APP__.remote().defaultRequest(fCallback, 'Plugin' + sAction, oParameters, iTimeout);
}
};
/**
* @param {Function} SettingsViewModelClass
* @param {string} sLabelName
* @param {string} sTemplate
* @param {string} sRoute
*/
Plugins.prototype.addSettingsViewModel = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute)
{
this.aUserViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]);
};
/**
* @param {Function} SettingsViewModelClass
* @param {string} sLabelName
* @param {string} sTemplate
* @param {string} sRoute
*/
Plugins.prototype.addSettingsViewModelForAdmin = function (SettingsViewModelClass, sTemplate, sLabelName, sRoute)
{
this.aAdminViewModelsHooks.push([SettingsViewModelClass, sTemplate, sLabelName, sRoute]);
};
Plugins.prototype.runSettingsViewModelHooks = function (bAdmin)
{
_.each(bAdmin ? this.aAdminViewModelsHooks : this.aUserViewModelsHooks, function (aView) {
require('Knoin/Knoin').addSettingsViewModel(aView[0], aView[1], aView[2], aView[3]);
});
};
/**
* @param {string} sPluginSection
* @param {string} sName

View file

@ -17,12 +17,13 @@
* @constructor
* @param {koProperty} oKoList
* @param {koProperty} oKoSelectedItem
* @param {koProperty} oKoFocusedItem
* @param {string} sItemSelector
* @param {string} sItemSelectedSelector
* @param {string} sItemCheckedSelector
* @param {string} sItemFocusedSelector
*/
function Selector(oKoList, oKoSelectedItem,
function Selector(oKoList, oKoSelectedItem, oKoFocusedItem,
sItemSelector, sItemSelectedSelector, sItemCheckedSelector, sItemFocusedSelector)
{
this.list = oKoList;
@ -37,8 +38,8 @@
return 0 < this.listChecked().length;
}, this);
this.focusedItem = ko.observable(null);
this.selectedItem = oKoSelectedItem;
this.focusedItem = oKoFocusedItem || ko.observable(null);
this.selectedItem = oKoSelectedItem || ko.observable(null);
this.selectedItemUseCallback = true;
this.itemSelectedThrottle = _.debounce(_.bind(this.itemSelected, this), 300);
@ -48,14 +49,17 @@
{
if (null === this.selectedItem())
{
this.selectedItem.valueHasMutated();
if (this.selectedItem.valueHasMutated)
{
this.selectedItem.valueHasMutated();
}
}
else
{
this.selectedItem(null);
}
}
else if (this.bAutoSelect && this.focusedItem())
else if (this.autoSelect() && this.focusedItem())
{
this.selectedItem(this.focusedItem());
}
@ -84,7 +88,7 @@
}, this);
this.selectedItem.extend({'toggleSubscribe': [null,
this.selectedItem = this.selectedItem.extend({'toggleSubscribe': [null,
function (oPrev) {
if (oPrev)
{
@ -98,7 +102,7 @@
}
]});
this.focusedItem.extend({'toggleSubscribe': [null,
this.focusedItem = this.focusedItem.extend({'toggleSubscribe': [null,
function (oPrev) {
if (oPrev)
{
@ -112,6 +116,8 @@
}
]});
this.iSelectNextHelper = 0;
this.iFocusedNextHelper = 0;
this.oContentVisible = null;
this.oContentScrollable = null;
@ -121,10 +127,10 @@
this.sItemFocusedSelector = sItemFocusedSelector;
this.sLastUid = '';
this.bAutoSelect = true;
this.oCallbacks = {};
this.emptyFunction = function () {};
this.emptyTrueFunction = function () { return true; };
this.focusedItem.subscribe(function (oItem) {
if (oItem)
@ -218,7 +224,7 @@
this.selectedItemUseCallback = true;
if (!bChecked && !bSelected && this.bAutoSelect)
if (!bChecked && !bSelected && this.autoSelect())
{
if (self.focusedItem())
{
@ -253,6 +259,39 @@
self.focusedItem(self.selectedItem());
}
}
if ((0 !== this.iSelectNextHelper || 0 !== this.iFocusedNextHelper) && 0 < aItems.length && !self.focusedItem())
{
oTemp = null;
if (0 !== this.iFocusedNextHelper)
{
oTemp = aItems[-1 === this.iFocusedNextHelper ? aItems.length - 1 : 0] || null;
}
if (!oTemp && 0 !== this.iSelectNextHelper)
{
oTemp = aItems[-1 === this.iSelectNextHelper ? aItems.length - 1 : 0] || null;
}
if (oTemp)
{
if (0 !== this.iSelectNextHelper)
{
self.selectedItem(oTemp || null);
}
self.focusedItem(oTemp || null);
self.scrollToFocused();
_.delay(function () {
self.scrollToFocused();
}, 100);
}
this.iSelectNextHelper = 0;
this.iFocusedNextHelper = 0;
}
}
aCache = [];
@ -291,6 +330,12 @@
this.newSelectPosition(Enums.EventKeyCode.Up, false, bForceSelect);
};
Selector.prototype.unselect = function ()
{
this.selectedItem(null);
this.focusedItem(null);
};
Selector.prototype.init = function (oContentVisible, oContentScrollable, sKeyScope)
{
this.oContentVisible = oContentVisible;
@ -348,7 +393,6 @@
key('up, shift+up, down, shift+down, home, end, pageup, pagedown, insert, space', sKeyScope, function (event, handler) {
if (event && handler && handler.shortcut)
{
// TODO
var iKey = 0;
switch (handler.shortcut)
{
@ -390,14 +434,25 @@
}
};
Selector.prototype.autoSelect = function (bValue)
/**
* @return {boolean}
*/
Selector.prototype.autoSelect = function ()
{
this.bAutoSelect = !!bValue;
return !!(this.oCallbacks['onAutoSelect'] || this.emptyTrueFunction)();
};
/**
* @param {boolean}
*/
Selector.prototype.doUpUpOrDownDown = function (bUp)
{
(this.oCallbacks['onUpUpOrDownDown'] || this.emptyTrueFunction)(!!bUp);
};
/**
* @param {Object} oItem
* @returns {string}
* @return {string}
*/
Selector.prototype.getItemUid = function (oItem)
{
@ -478,6 +533,11 @@
}
}
});
if (!oResult && (Enums.EventKeyCode.Down === iEventKeyCode || Enums.EventKeyCode.Up === iEventKeyCode))
{
this.doUpUpOrDownDown(Enums.EventKeyCode.Up === iEventKeyCode);
}
}
else if (Enums.EventKeyCode.Home === iEventKeyCode || Enums.EventKeyCode.End === iEventKeyCode)
{
@ -538,7 +598,7 @@
}
}
if ((this.bAutoSelect || !!bForceSelect) &&
if ((this.autoSelect() || !!bForceSelect) &&
!this.isListChecked() && Enums.EventKeyCode.Space !== iEventKeyCode)
{
this.selectedItem(oResult);
@ -607,7 +667,7 @@
return false;
}
if (bFast)
if (bFast || 50 > this.oContentScrollable.scrollTop())
{
this.oContentScrollable.scrollTop(0);
}
@ -682,7 +742,7 @@
if (oEvent)
{
if (oEvent.shiftKey && !oEvent.ctrlKey && !oEvent.altKey)
if (oEvent.shiftKey && !(oEvent.ctrlKey || oEvent.metaKey) && !oEvent.altKey)
{
bClick = false;
if ('' === this.sLastUid)
@ -695,7 +755,7 @@
this.focusedItem(oItem);
}
else if (oEvent.ctrlKey && !oEvent.shiftKey && !oEvent.altKey)
else if ((oEvent.ctrlKey || oEvent.metaKey) && !oEvent.shiftKey && !oEvent.altKey)
{
bClick = false;
this.focusedItem(oItem);

321
dev/Common/Translator.js Normal file
View file

@ -0,0 +1,321 @@
(function () {
'use strict';
var
window = require('window'),
$ = require('$'),
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals')
;
/**
* @constructor
*/
function Translator()
{
this.data = window['rainloopI18N'] || {};
this.notificationI18N = {};
this.trigger = ko.observable(false);
this.i18n = _.bind(this.i18n, this);
}
Translator.prototype.data = {};
Translator.prototype.notificationI18N = {};
/**
* @param {string} sKey
* @param {Object=} oValueList
* @param {string=} sDefaulValue
* @return {string}
*/
Translator.prototype.i18n = function (sKey, oValueList, sDefaulValue)
{
var
sValueName = '',
sResult = _.isUndefined(this.data[sKey]) ? (_.isUndefined(sDefaulValue) ? sKey : sDefaulValue) : this.data[sKey]
;
if (!_.isUndefined(oValueList) && !_.isNull(oValueList))
{
for (sValueName in oValueList)
{
if (_.has(oValueList, sValueName))
{
sResult = sResult.replace('%' + sValueName + '%', oValueList[sValueName]);
}
}
}
return sResult;
};
/**
* @param {Object} oElement
*/
Translator.prototype.i18nToNode = function (oElement)
{
var
sKey = '',
$oEl = $(oElement)
;
sKey = $oEl.data('i18n');
if (sKey)
{
if ('[' === sKey.substr(0, 1))
{
switch (sKey.substr(0, 6))
{
case '[html]':
$oEl.html(this.i18n(sKey.substr(6)));
break;
case '[place':
$oEl.attr('placeholder', this.i18n(sKey.substr(13)));
break;
case '[title':
$oEl.attr('title', this.i18n(sKey.substr(7)));
break;
}
}
else
{
$oEl.text(this.i18n(sKey));
}
}
};
/**
* @param {Object} oElements
* @param {boolean=} bAnimate = false
*/
Translator.prototype.i18nToNodes = function (oElements, bAnimate)
{
var self = this;
_.defer(function () {
$('[data-i18n]', oElements).each(function () {
self.i18nToNode(this);
});
if (bAnimate && Globals.bAnimationSupported)
{
$('.i18n-animation[data-i18n]', oElements).letterfx({
'fx': 'fall fade', 'backwards': false, 'timing': 50, 'fx_duration': '50ms', 'letter_end': 'restore', 'element_end': 'restore'
});
}
});
};
Translator.prototype.reloadData = function ()
{
if (window['rainloopI18N'])
{
this.data = window['rainloopI18N'] || {};
this.i18nToNodes(window.document, true);
require('Common/Momentor').reload();
this.trigger(!this.trigger());
}
window['rainloopI18N'] = null;
};
Translator.prototype.initNotificationLanguage = function ()
{
var oN = this.notificationI18N || {};
oN[Enums.Notification.InvalidToken] = this.i18n('NOTIFICATIONS/INVALID_TOKEN');
oN[Enums.Notification.AuthError] = this.i18n('NOTIFICATIONS/AUTH_ERROR');
oN[Enums.Notification.AccessError] = this.i18n('NOTIFICATIONS/ACCESS_ERROR');
oN[Enums.Notification.ConnectionError] = this.i18n('NOTIFICATIONS/CONNECTION_ERROR');
oN[Enums.Notification.CaptchaError] = this.i18n('NOTIFICATIONS/CAPTCHA_ERROR');
oN[Enums.Notification.SocialFacebookLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_FACEBOOK_LOGIN_ACCESS_DISABLE');
oN[Enums.Notification.SocialTwitterLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_TWITTER_LOGIN_ACCESS_DISABLE');
oN[Enums.Notification.SocialGoogleLoginAccessDisable] = this.i18n('NOTIFICATIONS/SOCIAL_GOOGLE_LOGIN_ACCESS_DISABLE');
oN[Enums.Notification.DomainNotAllowed] = this.i18n('NOTIFICATIONS/DOMAIN_NOT_ALLOWED');
oN[Enums.Notification.AccountNotAllowed] = this.i18n('NOTIFICATIONS/ACCOUNT_NOT_ALLOWED');
oN[Enums.Notification.AccountTwoFactorAuthRequired] = this.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_REQUIRED');
oN[Enums.Notification.AccountTwoFactorAuthError] = this.i18n('NOTIFICATIONS/ACCOUNT_TWO_FACTOR_AUTH_ERROR');
oN[Enums.Notification.CouldNotSaveNewPassword] = this.i18n('NOTIFICATIONS/COULD_NOT_SAVE_NEW_PASSWORD');
oN[Enums.Notification.CurrentPasswordIncorrect] = this.i18n('NOTIFICATIONS/CURRENT_PASSWORD_INCORRECT');
oN[Enums.Notification.NewPasswordShort] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_SHORT');
oN[Enums.Notification.NewPasswordWeak] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_WEAK');
oN[Enums.Notification.NewPasswordForbidden] = this.i18n('NOTIFICATIONS/NEW_PASSWORD_FORBIDDENT');
oN[Enums.Notification.ContactsSyncError] = this.i18n('NOTIFICATIONS/CONTACTS_SYNC_ERROR');
oN[Enums.Notification.CantGetMessageList] = this.i18n('NOTIFICATIONS/CANT_GET_MESSAGE_LIST');
oN[Enums.Notification.CantGetMessage] = this.i18n('NOTIFICATIONS/CANT_GET_MESSAGE');
oN[Enums.Notification.CantDeleteMessage] = this.i18n('NOTIFICATIONS/CANT_DELETE_MESSAGE');
oN[Enums.Notification.CantMoveMessage] = this.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
oN[Enums.Notification.CantCopyMessage] = this.i18n('NOTIFICATIONS/CANT_MOVE_MESSAGE');
oN[Enums.Notification.CantSaveMessage] = this.i18n('NOTIFICATIONS/CANT_SAVE_MESSAGE');
oN[Enums.Notification.CantSendMessage] = this.i18n('NOTIFICATIONS/CANT_SEND_MESSAGE');
oN[Enums.Notification.InvalidRecipients] = this.i18n('NOTIFICATIONS/INVALID_RECIPIENTS');
oN[Enums.Notification.CantSaveFilters] = this.i18n('NOTIFICATIONS/CANT_SAVE_FILTERS');
oN[Enums.Notification.CantGetFilters] = this.i18n('NOTIFICATIONS/CANT_GET_FILTERS');
oN[Enums.Notification.FiltersAreNotCorrect] = this.i18n('NOTIFICATIONS/FILTERS_ARE_NOT_CORRECT');
oN[Enums.Notification.CantCreateFolder] = this.i18n('NOTIFICATIONS/CANT_CREATE_FOLDER');
oN[Enums.Notification.CantRenameFolder] = this.i18n('NOTIFICATIONS/CANT_RENAME_FOLDER');
oN[Enums.Notification.CantDeleteFolder] = this.i18n('NOTIFICATIONS/CANT_DELETE_FOLDER');
oN[Enums.Notification.CantDeleteNonEmptyFolder] = this.i18n('NOTIFICATIONS/CANT_DELETE_NON_EMPTY_FOLDER');
oN[Enums.Notification.CantSubscribeFolder] = this.i18n('NOTIFICATIONS/CANT_SUBSCRIBE_FOLDER');
oN[Enums.Notification.CantUnsubscribeFolder] = this.i18n('NOTIFICATIONS/CANT_UNSUBSCRIBE_FOLDER');
oN[Enums.Notification.CantSaveSettings] = this.i18n('NOTIFICATIONS/CANT_SAVE_SETTINGS');
oN[Enums.Notification.CantSavePluginSettings] = this.i18n('NOTIFICATIONS/CANT_SAVE_PLUGIN_SETTINGS');
oN[Enums.Notification.DomainAlreadyExists] = this.i18n('NOTIFICATIONS/DOMAIN_ALREADY_EXISTS');
oN[Enums.Notification.CantInstallPackage] = this.i18n('NOTIFICATIONS/CANT_INSTALL_PACKAGE');
oN[Enums.Notification.CantDeletePackage] = this.i18n('NOTIFICATIONS/CANT_DELETE_PACKAGE');
oN[Enums.Notification.InvalidPluginPackage] = this.i18n('NOTIFICATIONS/INVALID_PLUGIN_PACKAGE');
oN[Enums.Notification.UnsupportedPluginPackage] = this.i18n('NOTIFICATIONS/UNSUPPORTED_PLUGIN_PACKAGE');
oN[Enums.Notification.LicensingServerIsUnavailable] = this.i18n('NOTIFICATIONS/LICENSING_SERVER_IS_UNAVAILABLE');
oN[Enums.Notification.LicensingExpired] = this.i18n('NOTIFICATIONS/LICENSING_EXPIRED');
oN[Enums.Notification.LicensingBanned] = this.i18n('NOTIFICATIONS/LICENSING_BANNED');
oN[Enums.Notification.DemoSendMessageError] = this.i18n('NOTIFICATIONS/DEMO_SEND_MESSAGE_ERROR');
oN[Enums.Notification.DemoAccountError] = this.i18n('NOTIFICATIONS/DEMO_ACCOUNT_ERROR');
oN[Enums.Notification.AccountAlreadyExists] = this.i18n('NOTIFICATIONS/ACCOUNT_ALREADY_EXISTS');
oN[Enums.Notification.AccountDoesNotExist] = this.i18n('NOTIFICATIONS/ACCOUNT_DOES_NOT_EXIST');
oN[Enums.Notification.MailServerError] = this.i18n('NOTIFICATIONS/MAIL_SERVER_ERROR');
oN[Enums.Notification.InvalidInputArgument] = this.i18n('NOTIFICATIONS/INVALID_INPUT_ARGUMENT');
oN[Enums.Notification.UnknownNotification] = this.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
oN[Enums.Notification.UnknownError] = this.i18n('NOTIFICATIONS/UNKNOWN_ERROR');
};
/**
* @param {Function} fCallback
* @param {Object} oScope
* @param {Function=} fLangCallback
*/
Translator.prototype.initOnStartOrLangChange = function (fCallback, oScope, fLangCallback)
{
if (fCallback)
{
fCallback.call(oScope);
}
if (fLangCallback)
{
this.trigger.subscribe(function () {
if (fCallback)
{
fCallback.call(oScope);
}
fLangCallback.call(oScope);
});
}
else if (fCallback)
{
this.trigger.subscribe(fCallback, oScope);
}
};
/**
* @param {number} iCode
* @param {*=} mMessage = ''
* @param {*=} mDefCode = null
* @return {string}
*/
Translator.prototype.getNotification = function (iCode, mMessage, mDefCode)
{
iCode = window.parseInt(iCode, 10) || 0;
if (Enums.Notification.ClientViewError === iCode && mMessage)
{
return mMessage;
}
return _.isUndefined(this.notificationI18N[iCode]) ? (
mDefCode && _.isUndefined(this.notificationI18N[mDefCode]) ? this.notificationI18N[mDefCode] : ''
) : this.notificationI18N[iCode];
};
/**
* @param {*} mCode
* @return {string}
*/
Translator.prototype.getUploadErrorDescByCode = function (mCode)
{
var sResult = '';
switch (window.parseInt(mCode, 10) || 0) {
case Enums.UploadErrorCode.FileIsTooBig:
sResult = this.i18n('UPLOAD/ERROR_FILE_IS_TOO_BIG');
break;
case Enums.UploadErrorCode.FilePartiallyUploaded:
sResult = this.i18n('UPLOAD/ERROR_FILE_PARTIALLY_UPLOADED');
break;
case Enums.UploadErrorCode.FileNoUploaded:
sResult = this.i18n('UPLOAD/ERROR_NO_FILE_UPLOADED');
break;
case Enums.UploadErrorCode.MissingTempFolder:
sResult = this.i18n('UPLOAD/ERROR_MISSING_TEMP_FOLDER');
break;
case Enums.UploadErrorCode.FileOnSaveingError:
sResult = this.i18n('UPLOAD/ERROR_ON_SAVING_FILE');
break;
case Enums.UploadErrorCode.FileType:
sResult = this.i18n('UPLOAD/ERROR_FILE_TYPE');
break;
default:
sResult = this.i18n('UPLOAD/ERROR_UNKNOWN');
break;
}
return sResult;
};
/**
* @param {boolean} bAdmin
* @param {string} sLanguage
* @param {Function=} fDone
* @param {Function=} fFail
*/
Translator.prototype.reload = function (bAdmin, sLanguage, fDone, fFail)
{
var
self = this,
$html = $('html'),
fEmptyFunction = function () {},
iStart = (new Date()).getTime()
;
$html.addClass('rl-changing-language');
$.ajax({
'url': require('Common/Links').langLink(sLanguage, bAdmin),
'dataType': 'script',
'cache': true
})
.fail(fFail || fEmptyFunction)
.done(function () {
_.delay(function () {
self.reloadData();
(fDone || fEmptyFunction)();
$html.removeClass('rl-changing-language');
}, 500 < (new Date()).getTime() - iStart ? 1 : 500);
})
;
};
module.exports = new Translator();
}());

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,66 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AbstractComponent = require('Component/Abstract')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractComponent
*/
function AbstracCheckbox(oParams)
{
AbstractComponent.call(this);
this.value = oParams.value;
if (Utils.isUnd(this.value) || !this.value.subscribe)
{
this.value = ko.observable(Utils.isUnd(this.value) ? false : !!this.value);
}
this.enable = oParams.enable;
if (Utils.isUnd(this.enable) || !this.enable.subscribe)
{
this.enable = ko.observable(Utils.isUnd(this.enable) ? true : !!this.enable);
}
this.disable = oParams.disable;
if (Utils.isUnd(this.disable) || !this.disable.subscribe)
{
this.disable = ko.observable(Utils.isUnd(this.disable) ? false : !!this.disable);
}
this.label = oParams.label || '';
this.inline = Utils.isUnd(oParams.inline) ? false : oParams.inline;
this.readOnly = Utils.isUnd(oParams.readOnly) ? false : !!oParams.readOnly;
this.inverted = Utils.isUnd(oParams.inverted) ? false : !!oParams.inverted;
this.labeled = !Utils.isUnd(oParams.label);
}
_.extend(AbstracCheckbox.prototype, AbstractComponent.prototype);
AbstracCheckbox.prototype.click = function() {
if (!this.readOnly && this.enable() && !this.disable())
{
this.value(!this.value());
}
};
AbstracCheckbox.componentExportHelper = AbstractComponent.componentExportHelper;
module.exports = AbstracCheckbox;
}());

View file

@ -0,0 +1,65 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AbstractComponent = require('Component/Abstract')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractComponent
*/
function AbstracRadio(oParams)
{
AbstractComponent.call(this);
this.values = ko.observableArray([]);
this.value = oParams.value;
if (Utils.isUnd(this.value) || !this.value.subscribe)
{
this.value = ko.observable('');
}
this.inline = Utils.isUnd(oParams.inline) ? false : oParams.inline;
this.readOnly = Utils.isUnd(oParams.readOnly) ? false : !!oParams.readOnly;
if (oParams.values)
{
var aValues = _.map(oParams.values, function (sLabel, sValue) {
return {
'label': sLabel,
'value': sValue
};
});
this.values(aValues);
}
this.click = _.bind(this.click, this);
}
AbstracRadio.prototype.click = function(oValue) {
if (!this.readOnly && oValue)
{
this.value(oValue.value);
}
};
_.extend(AbstracRadio.prototype, AbstractComponent.prototype);
AbstracRadio.componentExportHelper = AbstractComponent.componentExportHelper;
module.exports = AbstracRadio;
}());

76
dev/Component/Abstract.js Normal file
View file

@ -0,0 +1,76 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils')
;
/**
* @constructor
*/
function AbstractComponent()
{
this.disposable = [];
}
/**
* @type {Array}
*/
AbstractComponent.prototype.disposable = [];
AbstractComponent.prototype.dispose = function ()
{
_.each(this.disposable, function (fFuncToDispose) {
if (fFuncToDispose && fFuncToDispose.dispose)
{
fFuncToDispose.dispose();
}
});
};
/**
* @param {*} ClassObject
* @param {string} sTemplateID
* @return {Object}
*/
AbstractComponent.componentExportHelper = function (ClassObject, sTemplateID) {
var oComponent = {
viewModel: {
createViewModel: function(oParams, oComponentInfo) {
oParams = oParams || {};
oParams.element = null;
if (oComponentInfo.element)
{
oParams.component = oComponentInfo;
oParams.element = $(oComponentInfo.element);
require('Common/Translator').i18nToNodes(oParams.element);
if (!Utils.isUnd(oParams.inline) && ko.unwrap(oParams.inline))
{
oParams.element.css('display', 'inline-block');
}
}
return new ClassObject(oParams);
}
}
};
oComponent['template'] = sTemplateID ? {
element: sTemplateID
} : '<b></b>';
return oComponent;
};
module.exports = AbstractComponent;
}());

View file

@ -0,0 +1,92 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
AbstractComponent = require('Component/Abstract')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractComponent
*/
function AbstractInput(oParams)
{
AbstractComponent.call(this);
this.value = oParams.value || '';
this.size = oParams.size || 0;
this.label = oParams.label || '';
this.preLabel = oParams.preLabel || '';
this.enable = Utils.isUnd(oParams.enable) ? true : oParams.enable;
this.trigger = oParams.trigger && oParams.trigger.subscribe ? oParams.trigger : null;
this.placeholder = oParams.placeholder || '';
this.labeled = !Utils.isUnd(oParams.label);
this.preLabeled = !Utils.isUnd(oParams.preLabel);
this.triggered = !Utils.isUnd(oParams.trigger) && !!this.trigger;
this.classForTrigger = ko.observable('');
this.className = ko.computed(function () {
var
iSize = ko.unwrap(this.size),
sSuffixValue = this.trigger ?
' ' + Utils.trim('settings-saved-trigger-input ' + this.classForTrigger()) : ''
;
return (0 < iSize ? 'span' + iSize : '') + sSuffixValue;
}, this);
if (!Utils.isUnd(oParams.width) && oParams.element)
{
oParams.element.find('input,select,textarea').css('width', oParams.width);
}
this.disposable.push(this.className);
if (this.trigger)
{
this.setTriggerState(this.trigger());
this.disposable.push(
this.trigger.subscribe(this.setTriggerState, this)
);
}
}
AbstractInput.prototype.setTriggerState = function (nValue)
{
switch (Utils.pInt(nValue))
{
case Enums.SaveSettingsStep.TrueResult:
this.classForTrigger('success');
break;
case Enums.SaveSettingsStep.FalseResult:
this.classForTrigger('error');
break;
default:
this.classForTrigger('');
break;
}
};
_.extend(AbstractInput.prototype, AbstractComponent.prototype);
AbstractInput.componentExportHelper = AbstractComponent.componentExportHelper;
module.exports = AbstractInput;
}());

29
dev/Component/Checkbox.js Normal file
View file

@ -0,0 +1,29 @@
(function () {
'use strict';
var
_ = require('_'),
AbstracCheckbox = require('Component/AbstracCheckbox')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstracCheckbox
*/
function CheckboxComponent(oParams)
{
AbstracCheckbox.call(this, oParams);
}
_.extend(CheckboxComponent.prototype, AbstracCheckbox.prototype);
module.exports = AbstracCheckbox.componentExportHelper(
CheckboxComponent, 'CheckboxComponent');
}());

View file

@ -0,0 +1,29 @@
(function () {
'use strict';
var
_ = require('_'),
AbstracCheckbox = require('Component/AbstracCheckbox')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstracCheckbox
*/
function ClassicCheckboxComponent(oParams)
{
AbstracCheckbox.call(this, oParams);
}
_.extend(ClassicCheckboxComponent.prototype, AbstracCheckbox.prototype);
module.exports = AbstracCheckbox.componentExportHelper(
ClassicCheckboxComponent, 'CheckboxClassicComponent');
}());

29
dev/Component/Input.js Normal file
View file

@ -0,0 +1,29 @@
(function () {
'use strict';
var
_ = require('_'),
AbstractInput = require('Component/AbstractInput')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractInput
*/
function InputComponent(oParams)
{
AbstractInput.call(this, oParams);
}
_.extend(InputComponent.prototype, AbstractInput.prototype);
module.exports = AbstractInput.componentExportHelper(
InputComponent, 'InputComponent');
}());

View file

@ -0,0 +1,66 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
AbstracCheckbox = require('Component/AbstracCheckbox')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstracCheckbox
*/
function CheckboxMaterialDesignComponent(oParams)
{
AbstracCheckbox.call(this, oParams);
this.animationBox = ko.observable(false).extend({'falseTimeout': 200});
this.animationCheckmark = ko.observable(false).extend({'falseTimeout': 200});
this.animationBoxSetTrue = _.bind(this.animationBoxSetTrue, this);
this.animationCheckmarkSetTrue = _.bind(this.animationCheckmarkSetTrue, this);
this.disposable.push(
this.value.subscribe(function (bValue) {
this.triggerAnimation(bValue);
}, this)
);
}
_.extend(CheckboxMaterialDesignComponent.prototype, AbstracCheckbox.prototype);
CheckboxMaterialDesignComponent.prototype.animationBoxSetTrue = function()
{
this.animationBox(true);
};
CheckboxMaterialDesignComponent.prototype.animationCheckmarkSetTrue = function()
{
this.animationCheckmark(true);
};
CheckboxMaterialDesignComponent.prototype.triggerAnimation = function(bBox)
{
if (bBox)
{
this.animationBoxSetTrue();
_.delay(this.animationCheckmarkSetTrue, 200);
}
else
{
this.animationCheckmarkSetTrue();
_.delay(this.animationBoxSetTrue, 200);
}
};
module.exports = AbstracCheckbox.componentExportHelper(
CheckboxMaterialDesignComponent, 'CheckboxMaterialDesignComponent');
}());

29
dev/Component/Radio.js Normal file
View file

@ -0,0 +1,29 @@
(function () {
'use strict';
var
_ = require('_'),
AbstracRadio = require('Component/AbstracRadio')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstracRadio
*/
function RadioComponent(oParams)
{
AbstracRadio.call(this, oParams);
}
_.extend(RadioComponent.prototype, AbstracRadio.prototype);
module.exports = AbstracRadio.componentExportHelper(
RadioComponent, 'RadioComponent');
}());

View file

@ -0,0 +1,94 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
AbstractComponent = require('Component/Abstract')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractComponent
*/
function SaveTriggerComponent(oParams)
{
AbstractComponent.call(this);
this.element = oParams.element || null;
this.value = oParams.value && oParams.value.subscribe ? oParams.value : null;
if (this.element)
{
if (this.value)
{
this.element.css('display', 'inline-block');
if (oParams.verticalAlign)
{
this.element.css('vertical-align', oParams.verticalAlign);
}
this.setState(this.value());
this.disposable.push(
this.value.subscribe(this.setState, this)
);
}
else
{
this.element.hide();
}
}
}
SaveTriggerComponent.prototype.setState = function (nValue)
{
switch (Utils.pInt(nValue))
{
case Enums.SaveSettingsStep.TrueResult:
this.element
.find('.animated,.error').hide().removeClass('visible')
.end()
.find('.success').show().addClass('visible')
;
break;
case Enums.SaveSettingsStep.FalseResult:
this.element
.find('.animated,.success').hide().removeClass('visible')
.end()
.find('.error').show().addClass('visible')
;
break;
case Enums.SaveSettingsStep.Animate:
this.element
.find('.error,.success').hide().removeClass('visible')
.end()
.find('.animated').show().addClass('visible')
;
break;
default:
case Enums.SaveSettingsStep.Idle:
this.element
.find('.animated').hide()
.end()
.find('.error,.success').removeClass('visible')
;
break;
}
};
_.extend(SaveTriggerComponent.prototype, AbstractComponent.prototype);
module.exports = AbstractComponent.componentExportHelper(
SaveTriggerComponent, 'SaveTriggerComponent');
}());

52
dev/Component/Script.js Normal file
View file

@ -0,0 +1,52 @@
(function () {
'use strict';
var
_ = require('_'),
$ = require('$'),
AbstractComponent = require('Component/Abstract')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractComponent
*/
function ScriptComponent(oParams)
{
AbstractComponent.call(this);
if (oParams.component && oParams.component.templateNodes && oParams.element &&
oParams.element[0] && oParams.element[0].outerHTML)
{
var sScript = oParams.element[0].outerHTML;
sScript = sScript
.replace(/<x-script/i, '<script')
.replace(/<b><\/b><\/x-script>/i, '</script>')
;
if (sScript)
{
oParams.element.text('');
oParams.element.replaceWith(
$(sScript).text(oParams.component.templateNodes[0] &&
oParams.component.templateNodes[0].nodeValue ?
oParams.component.templateNodes[0].nodeValue : ''));
}
else
{
oParams.element.remove();
}
}
}
_.extend(ScriptComponent.prototype, AbstractComponent.prototype);
module.exports = AbstractComponent.componentExportHelper(ScriptComponent);
}());

38
dev/Component/Select.js Normal file
View file

@ -0,0 +1,38 @@
(function () {
'use strict';
var
_ = require('_'),
Utils = require('Common/Utils'),
AbstractInput = require('Component/AbstractInput')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractInput
*/
function SelectComponent(oParams)
{
AbstractInput.call(this, oParams);
this.options = oParams.options || '';
this.optionsText = oParams.optionsText || null;
this.optionsValue = oParams.optionsValue || null;
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
}
_.extend(SelectComponent.prototype, AbstractInput.prototype);
module.exports = AbstractInput.componentExportHelper(
SelectComponent, 'SelectComponent');
}());

34
dev/Component/TextArea.js Normal file
View file

@ -0,0 +1,34 @@
(function () {
'use strict';
var
_ = require('_'),
Utils = require('Common/Utils'),
AbstractInput = require('Component/AbstractInput')
;
/**
* @constructor
*
* @param {Object} oParams
*
* @extends AbstractInput
*/
function TextAreaComponent(oParams)
{
AbstractInput.call(this, oParams);
this.rows = oParams.rows || 5;
this.spellcheck = Utils.isUnd(oParams.spellcheck) ? false : !!oParams.spellcheck;
}
_.extend(TextAreaComponent.prototype, AbstractInput.prototype);
module.exports = AbstractInput.componentExportHelper(
TextAreaComponent, 'TextAreaComponent');
}());

51
dev/External/Opentip.js vendored Normal file
View file

@ -0,0 +1,51 @@
(function () {
'use strict';
var
window = require('window'),
Opentip = window.Opentip
;
Opentip.styles.rainloop = {
'extends': 'standard',
'fixed': true,
'target': true,
'delay': 0.2,
'hideDelay': 0,
'hideEffect': 'fade',
'hideEffectDuration': 0.2,
'showEffect': 'fade',
'showEffectDuration': 0.2,
'showOn': 'mouseover click',
'removeElementsOnHide': true,
'background': '#fff',
'shadow': false,
'borderColor': '#999',
'borderRadius': 2,
'borderWidth': 1
};
Opentip.styles.rainloopTip = {
'extends': 'rainloop',
'delay': 0.4,
'group': 'rainloopTips'
};
Opentip.styles.rainloopErrorTip = {
'extends': 'rainloop',
'className': 'rainloopErrorTip'
};
module.exports = Opentip;
}());

699
dev/External/ko.js vendored
View file

@ -1,118 +1,212 @@
(function (module, ko) {
(function (ko) {
'use strict';
var
window = require('window'),
_ = require('_'),
$ = require('$')
$ = require('$'),
Opentip = require('Opentip'),
fDisposalTooltipHelper = function (oElement) {
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
if (oElement && oElement.__opentip)
{
oElement.__opentip.deactivate();
}
});
}
;
ko.bindingHandlers.editor = {
'init': function (oElement, fValueAccessor) {
var
fValue = fValueAccessor(),
oEditor = null,
fUpdateEditorValue = function () {
if (oEditor)
{
oEditor.setHtmlOrPlain(fValue());
}
},
fUpdateKoValue = function () {
if (oEditor && oEditor.__inited)
{
fValue(oEditor.getDataWithHtmlMark());
}
},
HtmlEditor = require('Common/HtmlEditor')
;
if (fValue)
{
oEditor = new HtmlEditor(oElement, fUpdateKoValue, fUpdateEditorValue, fUpdateKoValue);
fValue.__editor = oEditor;
fValue.__fetchEditorValue = fUpdateKoValue;
fValue.__updateEditorValue = fUpdateEditorValue;
fValue.subscribe(fUpdateEditorValue);
fUpdateEditorValue();
}
}
};
ko.bindingHandlers.tooltip = {
'init': function (oElement, fValueAccessor) {
var
Globals = require('Common/Globals'),
Utils = require('Common/Utils')
;
if (!Globals.bMobileDevice)
{
var
$oEl = $(oElement),
sClass = $oEl.data('tooltip-class') || '',
sPlacement = $oEl.data('tooltip-placement') || 'top'
;
$oEl.tooltip({
'delay': {
'show': 500,
'hide': 100
},
'html': true,
'container': 'body',
'placement': sPlacement,
'trigger': 'hover',
'title': function () {
return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' : '<span class="tooltip-class ' + sClass + '">' +
Utils.i18n(ko.utils.unwrapObservable(fValueAccessor())) + '</span>';
}
}).click(function () {
$oEl.tooltip('hide');
});
Globals.tooltipTrigger.subscribe(function () {
$oEl.tooltip('hide');
});
}
}
};
ko.bindingHandlers.tooltip2 = {
'init': function (oElement, fValueAccessor) {
var
Globals = require('Common/Globals'),
$oEl = $(oElement),
sClass = $oEl.data('tooltip-class') || '',
sPlacement = $oEl.data('tooltip-placement') || 'top'
;
$oEl.tooltip({
'delay': {
'show': 500,
'hide': 100
},
'html': true,
'container': 'body',
'placement': sPlacement,
'title': function () {
return $oEl.is('.disabled') || Globals.dropdownVisibility() ? '' :
'<span class="tooltip-class ' + sClass + '">' + fValueAccessor()() + '</span>';
}
}).click(function () {
$oEl.tooltip('hide');
});
Globals.tooltipTrigger.subscribe(function () {
$oEl.tooltip('hide');
});
}
};
ko.bindingHandlers.tooltip3 = {
'init': function (oElement) {
var
bi18n = true,
sValue = '',
Translator = null,
$oEl = $(oElement),
fValue = fValueAccessor(),
bMobile = 'on' === ($oEl.data('tooltip-mobile') || 'off'),
Globals = require('Common/Globals')
;
$oEl.tooltip({
'container': 'body',
'trigger': 'hover manual',
'title': function () {
return $oEl.data('tooltip3-data') || '';
if (!Globals.bMobileDevice || bMobile)
{
bi18n = 'on' === ($oEl.data('tooltip-i18n') || 'on');
sValue = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue);
oElement.__opentip = new Opentip(oElement, {
'style': 'rainloopTip',
'element': oElement,
'tipJoint': $oEl.data('tooltip-join') || 'bottom'
});
Globals.dropdownVisibility.subscribe(function (bV) {
if (bV) {
oElement.__opentip.hide();
}
});
if ('' === sValue)
{
oElement.__opentip.hide();
oElement.__opentip.deactivate();
oElement.__opentip.setContent('');
}
else
{
oElement.__opentip.activate();
}
if (bi18n)
{
Translator = require('Common/Translator');
oElement.__opentip.setContent(Translator.i18n(sValue));
Translator.trigger.subscribe(function () {
oElement.__opentip.setContent(Translator.i18n(sValue));
});
Globals.dropdownVisibility.subscribe(function () {
if (oElement && oElement.__opentip)
{
oElement.__opentip.setContent(require('Common/Translator').i18n(sValue));
}
});
}
else
{
oElement.__opentip.setContent(sValue);
}
}
},
'update': function (oElement, fValueAccessor) {
var
bi18n = true,
sValue = '',
$oEl = $(oElement),
fValue = fValueAccessor(),
bMobile = 'on' === ($oEl.data('tooltip-mobile') || 'off'),
Globals = require('Common/Globals')
;
if ((!Globals.bMobileDevice || bMobile) && oElement.__opentip)
{
bi18n = 'on' === ($oEl.data('tooltip-i18n') || 'on');
sValue = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue);
if (sValue)
{
oElement.__opentip.setContent(
bi18n ? require('Common/Translator').i18n(sValue) : sValue);
oElement.__opentip.activate();
}
else
{
oElement.__opentip.hide();
oElement.__opentip.deactivate();
oElement.__opentip.setContent('');
}
}
}
};
ko.bindingHandlers.tooltipErrorTip = {
'init': function (oElement) {
var $oEl = $(oElement);
oElement.__opentip = new Opentip(oElement, {
'style': 'rainloopErrorTip',
'hideOn': 'mouseout click',
'element': oElement,
'tipJoint': $oEl.data('tooltip-join') || 'top'
});
oElement.__opentip.deactivate();
$(window.document).on('click', function () {
if (oElement && oElement.__opentip)
{
oElement.__opentip.hide();
}
});
$(window.document).click(function () {
$oEl.tooltip('hide');
});
Globals.tooltipTrigger.subscribe(function () {
$oEl.tooltip('hide');
});
fDisposalTooltipHelper(oElement);
},
'update': function (oElement, fValueAccessor) {
var sValue = ko.utils.unwrapObservable(fValueAccessor());
if ('' === sValue)
var
$oEl = $(oElement),
fValue = fValueAccessor(),
sValue = !ko.isObservable(fValue) && _.isFunction(fValue) ? fValue() : ko.unwrap(fValue),
oOpenTips = oElement.__opentip
;
if (oOpenTips)
{
$(oElement).data('tooltip3-data', '').tooltip('hide');
}
else
{
$(oElement).data('tooltip3-data', sValue).tooltip('show');
if ('' === sValue)
{
oOpenTips.hide();
oOpenTips.deactivate();
oOpenTips.setContent('');
}
else
{
_.delay(function () {
if ($oEl.is(':visible'))
{
oOpenTips.setContent(sValue);
oOpenTips.activate();
oOpenTips.show();
}
else
{
oOpenTips.hide();
oOpenTips.deactivate();
oOpenTips.setContent('');
}
}, 100);
}
}
}
};
@ -120,25 +214,33 @@
ko.bindingHandlers.registrateBootstrapDropdown = {
'init': function (oElement) {
var Globals = require('Common/Globals');
Globals.aBootstrapDropdowns.push($(oElement));
if (Globals && Globals.aBootstrapDropdowns)
{
Globals.aBootstrapDropdowns.push($(oElement));
$(oElement).click(function () {
require('Common/Utils').detectDropdownVisibility();
});
// ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
// });
}
}
};
ko.bindingHandlers.openDropdownTrigger = {
'update': function (oElement, fValueAccessor) {
if (ko.utils.unwrapObservable(fValueAccessor()))
if (ko.unwrap(fValueAccessor()))
{
var
$el = $(oElement),
Utils = require('Common/Utils')
;
if (!$el.hasClass('open'))
var $oEl = $(oElement);
if (!$oEl.hasClass('open'))
{
$el.find('.dropdown-toggle').dropdown('toggle');
Utils.detectDropdownVisibility();
$oEl.find('.dropdown-toggle').dropdown('toggle');
}
$oEl.find('.dropdown-toggle').focus();
require('Common/Utils').detectDropdownVisibility();
fValueAccessor()(false);
}
}
@ -154,7 +256,11 @@
ko.bindingHandlers.popover = {
'init': function (oElement, fValueAccessor) {
$(oElement).popover(ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).popover(ko.unwrap(fValueAccessor()));
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).popover('destroy');
});
}
};
@ -163,22 +269,22 @@
var Utils = require('Common/Utils');
if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
{
oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
oElement.styleSheet.cssText = ko.unwrap(fValueAccessor());
}
else
{
$(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).text(ko.unwrap(fValueAccessor()));
}
},
'update': function (oElement, fValueAccessor) {
var Utils = require('Common/Utils');
if (oElement && oElement.styleSheet && !Utils.isUnd(oElement.styleSheet.cssText))
{
oElement.styleSheet.cssText = ko.utils.unwrapObservable(fValueAccessor());
oElement.styleSheet.cssText = ko.unwrap(fValueAccessor());
}
else
{
$(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).text(ko.unwrap(fValueAccessor()));
}
}
};
@ -204,31 +310,39 @@
ko.bindingHandlers.onEnter = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress', function (oEvent) {
$(oElement).on('keypress.koOnEnter', function (oEvent) {
if (oEvent && 13 === window.parseInt(oEvent.keyCode, 10))
{
$(oElement).trigger('change');
fValueAccessor().call(oViewModel);
}
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).off('keypress.koOnEnter');
});
}
};
ko.bindingHandlers.onEsc = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor, oViewModel) {
$(oElement).on('keypress', function (oEvent) {
$(oElement).on('keypress.koOnEsc', function (oEvent) {
if (oEvent && 27 === window.parseInt(oEvent.keyCode, 10))
{
$(oElement).trigger('change');
fValueAccessor().call(oViewModel);
}
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).off('keypress.koOnEsc');
});
}
};
ko.bindingHandlers.clickOnTrue = {
'update': function (oElement, fValueAccessor) {
if (ko.utils.unwrapObservable(fValueAccessor()))
if (ko.unwrap(fValueAccessor()))
{
$(oElement).click();
}
@ -245,51 +359,85 @@
$(oElement).toggleClass('fade', !Globals.bMobileDevice).modal({
'keyboard': false,
'show': ko.utils.unwrapObservable(fValueAccessor())
'show': ko.unwrap(fValueAccessor())
})
.on('shown', function () {
Utils.windowResize();
})
.find('.close').click(function () {
.on('shown.koModal', Utils.windowResizeCallback)
.find('.close').on('click.koModal', function () {
fValueAccessor()(false);
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement)
.off('shown.koModal')
.find('.close')
.off('click.koModal')
;
});
},
'update': function (oElement, fValueAccessor) {
$(oElement).modal(ko.utils.unwrapObservable(fValueAccessor()) ? 'show' : 'hide');
var Globals = require('Common/Globals');
$(oElement).modal(!!ko.unwrap(fValueAccessor()) ? 'show' : 'hide');
if (Globals.$html.hasClass('rl-anim'))
{
Globals.$html.addClass('rl-modal-animation');
_.delay(function () {
Globals.$html.removeClass('rl-modal-animation');
}, 400);
}
}
};
ko.bindingHandlers.moment = {
'init': function (oElement, fValueAccessor) {
require('Common/Momentor').momentToNode(
$(oElement).addClass('moment').data('moment-time', ko.unwrap(fValueAccessor()))
);
},
'update': function (oElement, fValueAccessor) {
require('Common/Momentor').momentToNode(
$(oElement).data('moment-time', ko.unwrap(fValueAccessor()))
);
}
};
ko.bindingHandlers.i18nInit = {
'init': function (oElement) {
var Utils = require('Common/Utils');
Utils.i18nToNode(oElement);
require('Common/Translator').i18nToNodes(oElement);
}
};
ko.bindingHandlers.translatorInit = {
'init': function (oElement) {
require('Common/Translator').i18nToNodes(oElement);
}
};
ko.bindingHandlers.i18nUpdate = {
'update': function (oElement, fValueAccessor) {
var Utils = require('Common/Utils');
ko.utils.unwrapObservable(fValueAccessor());
Utils.i18nToNode(oElement);
ko.unwrap(fValueAccessor());
require('Common/Translator').i18nToNodes(oElement);
}
};
ko.bindingHandlers.link = {
'update': function (oElement, fValueAccessor) {
$(oElement).attr('href', ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).attr('href', ko.unwrap(fValueAccessor()));
}
};
ko.bindingHandlers.title = {
'update': function (oElement, fValueAccessor) {
$(oElement).attr('title', ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).attr('title', ko.unwrap(fValueAccessor()));
}
};
ko.bindingHandlers.textF = {
'init': function (oElement, fValueAccessor) {
$(oElement).text(ko.utils.unwrapObservable(fValueAccessor()));
$(oElement).text(ko.unwrap(fValueAccessor()));
}
};
@ -299,9 +447,36 @@
}
};
ko.bindingHandlers.initFixedTrigger = {
'init': function (oElement, fValueAccessor) {
var
aValues = ko.unwrap(fValueAccessor()),
$oContainer = null,
$oElement = $(oElement),
oOffset = null,
iTop = aValues[1] || 0
;
$oContainer = $(aValues[0] || null);
$oContainer = $oContainer[0] ? $oContainer : null;
if ($oContainer)
{
$(window).resize(function () {
oOffset = $oContainer.offset();
if (oOffset && oOffset.top)
{
$oElement.css('top', oOffset.top + iTop);
}
});
}
}
};
ko.bindingHandlers.initResizeTrigger = {
'init': function (oElement, fValueAccessor) {
var aValues = ko.utils.unwrapObservable(fValueAccessor());
var aValues = ko.unwrap(fValueAccessor());
$(oElement).css({
'height': aValues[1],
'min-height': aValues[1]
@ -312,7 +487,7 @@
var
Utils = require('Common/Utils'),
Globals = require('Common/Globals'),
aValues = ko.utils.unwrapObservable(fValueAccessor()),
aValues = ko.unwrap(fValueAccessor()),
iValue = Utils.pInt(aValues[1]),
iSize = 0,
iOffset = $(oElement).offset().top
@ -338,16 +513,18 @@
ko.bindingHandlers.appendDom = {
'update': function (oElement, fValueAccessor) {
$(oElement).hide().empty().append(ko.utils.unwrapObservable(fValueAccessor())).show();
$(oElement).hide().empty().append(ko.unwrap(fValueAccessor())).show();
}
};
ko.bindingHandlers.draggable = {
'init': function (oElement, fValueAccessor, fAllBindingsAccessor) {
var
Globals = require('Common/Globals'),
Utils = require('Common/Utils')
;
if (!Globals.bMobileDevice)
{
var
@ -419,9 +596,16 @@
return fValueAccessor()(oEvent && oEvent.target ? ko.dataFor(oEvent.target) : null);
};
$(oElement).draggable(oConf).on('mousedown', function () {
$(oElement).draggable(oConf).on('mousedown.koDraggable', function () {
Utils.removeInFocus();
});
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement)
.off('mousedown.koDraggable')
.draggable('destroy')
;
});
}
}
};
@ -463,6 +647,10 @@
}
$(oElement).droppable(oConf);
ko.utils.domNodeDisposal.addDisposeCallback(oElement, function () {
$(oElement).droppable('destroy');
});
}
}
}
@ -504,7 +692,7 @@
},
'update': function (oElement, fValueAccessor) {
var
mValue = ko.utils.unwrapObservable(fValueAccessor()),
mValue = ko.unwrap(fValueAccessor()),
$oEl = $(oElement)
;
@ -575,9 +763,9 @@
fAllBindings = fAllBindingsAccessor(),
fAutoCompleteSource = fAllBindings['autoCompleteSource'] || null,
fFocusCallback = function (bValue) {
if (fValue && fValue.focusTrigger)
if (fValue && fValue.focused)
{
fValue.focusTrigger(bValue);
fValue.focused(!!bValue);
}
}
;
@ -588,6 +776,13 @@
'focusCallback': fFocusCallback,
'inputDelimiters': [',', ';'],
'autoCompleteSource': fAutoCompleteSource,
// 'elementHook': function (oEl, oItem) {
// if (oEl && oItem)
// {
// oEl.addClass('pgp');
// window.console.log(arguments);
// }
// },
'parseHook': function (aInput) {
return _.map(aInput, function (sInputValue) {
@ -612,14 +807,20 @@
fValue(oEvent.target.value);
}, this)
});
if (fValue && fValue.focused && fValue.focused.subscribe)
{
fValue.focused.subscribe(function (bValue) {
$oEl.inputosaurus(!!bValue ? 'focus' : 'blur');
});
}
},
'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
'update': function (oElement, fValueAccessor) {
var
$oEl = $(oElement),
fAllValueFunc = fAllBindingsAccessor(),
fEmailsTagsFilter = fAllValueFunc['emailsTagsFilter'] || null,
sValue = ko.utils.unwrapObservable(fValueAccessor())
fValue = fValueAccessor(),
sValue = ko.unwrap(fValue)
;
if ($oEl.data('EmailsTagsValue') !== sValue)
@ -628,85 +829,6 @@
$oEl.data('EmailsTagsValue', sValue);
$oEl.inputosaurus('refresh');
}
if (fEmailsTagsFilter && ko.utils.unwrapObservable(fEmailsTagsFilter))
{
$oEl.inputosaurus('focus');
}
}
};
ko.bindingHandlers.contactTags = {
'init': function(oElement, fValueAccessor, fAllBindingsAccessor) {
var
Utils = require('Common/Utils'),
ContactTagModel = require('Model/ContactTag'),
$oEl = $(oElement),
fValue = fValueAccessor(),
fAllBindings = fAllBindingsAccessor(),
fAutoCompleteSource = fAllBindings['autoCompleteSource'] || null,
fFocusCallback = function (bValue) {
if (fValue && fValue.focusTrigger)
{
fValue.focusTrigger(bValue);
}
}
;
$oEl.inputosaurus({
'parseOnBlur': true,
'allowDragAndDrop': false,
'focusCallback': fFocusCallback,
'inputDelimiters': [',', ';'],
'outputDelimiter': ',',
'autoCompleteSource': fAutoCompleteSource,
'parseHook': function (aInput) {
return _.map(aInput, function (sInputValue) {
var
sValue = Utils.trim(sInputValue),
oTag = null
;
if ('' !== sValue)
{
oTag = new ContactTagModel();
oTag.name(sValue);
return [oTag.toLine(false), oTag];
}
return [sValue, null];
});
},
'change': _.bind(function (oEvent) {
$oEl.data('ContactTagsValue', oEvent.target.value);
fValue(oEvent.target.value);
}, this)
});
},
'update': function (oElement, fValueAccessor, fAllBindingsAccessor) {
var
$oEl = $(oElement),
fAllValueFunc = fAllBindingsAccessor(),
fContactTagsFilter = fAllValueFunc['contactTagsFilter'] || null,
sValue = ko.utils.unwrapObservable(fValueAccessor())
;
if ($oEl.data('ContactTagsValue') !== sValue)
{
$oEl.val(sValue);
$oEl.data('ContactTagsValue', sValue);
$oEl.inputosaurus('refresh');
}
if (fContactTagsFilter && ko.utils.unwrapObservable(fContactTagsFilter))
{
$oEl.inputosaurus('focus');
}
}
};
@ -752,6 +874,8 @@
}
};
// extenders
ko.extenders.trimmer = function (oTarget)
{
var
@ -796,6 +920,56 @@
return oResult;
};
ko.extenders.limitedList = function (oTarget, mList)
{
var
Utils = require('Common/Utils'),
oResult = ko.computed({
'read': oTarget,
'write': function (sNewValue) {
var
sCurrentValue = ko.unwrap(oTarget),
aList = ko.unwrap(mList)
;
if (Utils.isNonEmptyArray(aList))
{
if (-1 < Utils.inArray(sNewValue, aList))
{
oTarget(sNewValue);
}
else if (-1 < Utils.inArray(sCurrentValue, aList))
{
oTarget(sCurrentValue + ' ');
oTarget(sCurrentValue);
}
else
{
oTarget(aList[0] + ' ');
oTarget(aList[0]);
}
}
else
{
oTarget('');
}
}
}).extend({'notify': 'always'})
;
oResult(oTarget());
if (!oResult.valueHasMutated)
{
oResult.valueHasMutated = function () {
oTarget.valueHasMutated();
};
}
return oResult;
};
ko.extenders.reversible = function (oTarget)
{
var mValue = oTarget();
@ -826,25 +1000,87 @@
return oTarget;
};
ko.extenders.toggleSubscribeProperty = function (oTarget, oOptions)
{
var sProp = oOptions[1];
if (sProp)
{
oTarget.subscribe(function (oPrev) {
if (oPrev && oPrev[sProp])
{
oPrev[sProp](false);
}
}, oOptions[0], 'beforeChange');
oTarget.subscribe(function (oNext) {
if (oNext && oNext[sProp])
{
oNext[sProp](true);
}
}, oOptions[0]);
}
return oTarget;
};
ko.extenders.falseTimeout = function (oTarget, iOption)
{
var Utils = require('Common/Utils');
oTarget.iTimeout = 0;
oTarget.iFalseTimeoutTimeout = 0;
oTarget.subscribe(function (bValue) {
if (bValue)
{
window.clearTimeout(oTarget.iTimeout);
oTarget.iTimeout = window.setTimeout(function () {
window.clearTimeout(oTarget.iFalseTimeoutTimeout);
oTarget.iFalseTimeoutTimeout = window.setTimeout(function () {
oTarget(false);
oTarget.iTimeout = 0;
}, Utils.pInt(iOption));
oTarget.iFalseTimeoutTimeout = 0;
}, require('Common/Utils').pInt(iOption));
}
});
return oTarget;
};
ko.extenders.specialThrottle = function (oTarget, iOption)
{
oTarget.iSpecialThrottleTimeoutValue = require('Common/Utils').pInt(iOption);
if (0 < oTarget.iSpecialThrottleTimeoutValue)
{
oTarget.iSpecialThrottleTimeout = 0;
oTarget.valueForRead = ko.observable(!!oTarget()).extend({'throttle': 10});
return ko.computed({
'read': oTarget.valueForRead,
'write': function (bValue) {
if (bValue)
{
oTarget.valueForRead(bValue);
}
else
{
if (oTarget.valueForRead())
{
window.clearTimeout(oTarget.iSpecialThrottleTimeout);
oTarget.iSpecialThrottleTimeout = window.setTimeout(function () {
oTarget.valueForRead(false);
oTarget.iSpecialThrottleTimeout = 0;
}, oTarget.iSpecialThrottleTimeoutValue);
}
else
{
oTarget.valueForRead(bValue);
}
}
}
});
}
return oTarget;
};
// functions
ko.observable.fn.validateNone = function ()
{
this.hasError = ko.observable(false);
@ -881,6 +1117,25 @@
return this;
};
ko.observable.fn.deleteAccessHelper = function ()
{
this.extend({'falseTimeout': 3000}).extend({'toggleSubscribe': [null,
function (oPrev) {
if (oPrev && oPrev.deleteAccess)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext && oNext.deleteAccess)
{
oNext.deleteAccess(true);
}
}
]});
return this;
};
ko.observable.fn.validateFunc = function (fFunc)
{
var Utils = require('Common/Utils');
@ -901,4 +1156,4 @@
module.exports = ko;
}(module, ko));
}(ko));

123
dev/Helper/Message.js Normal file
View file

@ -0,0 +1,123 @@
(function () {
'use strict';
var
Utils = require('Common/Utils'),
EmailModel = require('Model/Email')
;
/**
* @constructor
*/
function MessageHelper() {}
/**
* @param {Array.<EmailModel>} aEmail
* @param {boolean=} bFriendlyView
* @param {boolean=} bWrapWithLink = false
* @return {string}
*/
MessageHelper.prototype.emailArrayToString = function (aEmail, bFriendlyView, bWrapWithLink)
{
var
aResult = [],
iIndex = 0,
iLen = 0
;
if (Utils.isNonEmptyArray(aEmail))
{
for (iIndex = 0, iLen = aEmail.length; iIndex < iLen; iIndex++)
{
aResult.push(aEmail[iIndex].toLine(bFriendlyView, bWrapWithLink));
}
}
return aResult.join(', ');
};
/**
* @param {Array.<EmailModel>} aEmails
* @return {string}
*/
MessageHelper.prototype.emailArrayToStringClear = function (aEmails)
{
var
aResult = [],
iIndex = 0,
iLen = 0
;
if (Utils.isNonEmptyArray(aEmails))
{
for (iIndex = 0, iLen = aEmails.length; iIndex < iLen; iIndex++)
{
if (aEmails[iIndex] && aEmails[iIndex].email && '' !== aEmails[iIndex].name)
{
aResult.push(aEmails[iIndex].email);
}
}
}
return aResult.join(', ');
};
/**
* @param {?Array} aJson
* @return {Array.<EmailModel>}
*/
MessageHelper.prototype.emailArrayFromJson = function (aJson)
{
var
iIndex = 0,
iLen = 0,
oEmailModel = null,
aResult = []
;
if (Utils.isNonEmptyArray(aJson))
{
for (iIndex = 0, iLen = aJson.length; iIndex < iLen; iIndex++)
{
oEmailModel = EmailModel.newInstanceFromJson(aJson[iIndex]);
if (oEmailModel)
{
aResult.push(oEmailModel);
}
}
}
return aResult;
};
/**
* @param {Array.<EmailModel>} aInputEmails
* @param {Object} oUnic
* @param {Array} aLocalEmails
*/
MessageHelper.prototype.replyHelper = function (aInputEmails, oUnic, aLocalEmails)
{
if (aInputEmails && 0 < aInputEmails.length)
{
var
iIndex = 0,
iLen = aInputEmails.length
;
for (; iIndex < iLen; iIndex++)
{
if (Utils.isUnd(oUnic[aInputEmails[iIndex].email]))
{
oUnic[aInputEmails[iIndex].email] = true;
aLocalEmails.push(aInputEmails[iIndex]);
}
}
}
};
module.exports = new MessageHelper();
}());

View file

@ -0,0 +1,49 @@
(function () {
'use strict';
var
_ = require('_'),
Utils = require('Common/Utils')
;
/**
* @constructor
*
* @param {string} sModelName
*/
function AbstractModel(sModelName)
{
this.sModelName = sModelName || '';
this.disposables = [];
}
/**
* @param {Array|Object} mInputValue
*/
AbstractModel.prototype.regDisposables = function (mInputValue)
{
if (Utils.isArray(mInputValue))
{
_.each(mInputValue, function (mValue) {
this.disposables.push(mValue);
}, this);
}
else if (mInputValue)
{
this.disposables.push(mInputValue);
}
};
AbstractModel.prototype.onDestroy = function ()
{
Utils.disposeObject(this);
};
module.exports = AbstractModel;
}());

View file

@ -139,6 +139,9 @@
ViewModelClass.__builded = true;
ViewModelClass.__vm = oViewModel;
oViewModel.onShowTrigger = ko.observable(false);
oViewModel.onHideTrigger = ko.observable(false);
oViewModel.viewModelName = ViewModelClass.__name;
oViewModel.viewModelNames = ViewModelClass.__names;
@ -167,11 +170,25 @@
Globals.popupVisibilityNames.push(this.viewModelName);
oViewModel.viewModelDom.css('z-index', 3000 + Globals.popupVisibilityNames().length + 10);
Utils.delegateRun(this, 'onFocus', [], 500);
// Utils.delegateRun(this, 'onShow'); // moved to showScreenPopup function (for parameters)
if (this.onShowTrigger)
{
this.onShowTrigger(!this.onShowTrigger());
}
Utils.delegateRun(this, 'onShowWithDelay', [], 500);
}
else
{
Utils.delegateRun(this, 'onHide');
Utils.delegateRun(this, 'onHideWithDelay', [], 500);
if (this.onHideTrigger)
{
this.onHideTrigger(!this.onHideTrigger());
}
this.restoreKeyScope();
_.each(this.viewModelNames, function (sName) {
@ -181,8 +198,6 @@
Globals.popupVisibilityNames.remove(this.viewModelName);
oViewModel.viewModelDom.css('z-index', 2000);
Globals.tooltipTrigger(!Globals.tooltipTrigger());
_.delay(function () {
self.viewModelDom.hide();
}, 300);
@ -196,7 +211,7 @@
});
ko.applyBindingAccessorsToNode(oViewModelDom[0], {
'i18nInit': true,
'translatorInit': true,
'template': function () { return {'name': oViewModel.viewModelTemplate()};}
}, oViewModel);
@ -243,6 +258,7 @@
if (ViewModelClassToShow.__vm && ViewModelClassToShow.__dom)
{
ViewModelClassToShow.__vm.modalVisibility(true);
Utils.delegateRun(ViewModelClassToShow.__vm, 'onShow', aParameters || []);
_.each(ViewModelClassToShow.__names, function (sName) {
@ -270,6 +286,7 @@
var
self = this,
oScreen = null,
bSameScreen= false,
oCross = null
;
@ -293,6 +310,8 @@
if (oScreen && oScreen.__started)
{
bSameScreen = this.oCurrentScreen && oScreen === this.oCurrentScreen;
if (!oScreen.__builded)
{
oScreen.__builded = true;
@ -310,9 +329,15 @@
_.defer(function () {
// hide screen
if (self.oCurrentScreen)
if (self.oCurrentScreen && !bSameScreen)
{
Utils.delegateRun(self.oCurrentScreen, 'onHide');
Utils.delegateRun(self.oCurrentScreen, 'onHideWithDelay', [], 500);
if (self.oCurrentScreen.onHideTrigger)
{
self.oCurrentScreen.onHideTrigger(!self.oCurrentScreen.onHideTrigger());
}
if (Utils.isNonEmptyArray(self.oCurrentScreen.viewModels()))
{
@ -323,7 +348,14 @@
{
ViewModelClass.__dom.hide();
ViewModelClass.__vm.viewModelVisibility(false);
Utils.delegateRun(ViewModelClass.__vm, 'onHide');
Utils.delegateRun(ViewModelClass.__vm, 'onHideWithDelay', [], 500);
if (ViewModelClass.__vm.onHideTrigger)
{
ViewModelClass.__vm.onHideTrigger(!ViewModelClass.__vm.onHideTrigger());
}
}
});
@ -334,9 +366,13 @@
self.oCurrentScreen = oScreen;
// show screen
if (self.oCurrentScreen)
if (self.oCurrentScreen && !bSameScreen)
{
Utils.delegateRun(self.oCurrentScreen, 'onShow');
if (self.oCurrentScreen.onShowTrigger)
{
self.oCurrentScreen.onShowTrigger(!self.oCurrentScreen.onShowTrigger());
}
Plugins.runHook('screen-on-show', [self.oCurrentScreen.screenName(), self.oCurrentScreen]);
@ -351,7 +387,12 @@
ViewModelClass.__vm.viewModelVisibility(true);
Utils.delegateRun(ViewModelClass.__vm, 'onShow');
Utils.delegateRun(ViewModelClass.__vm, 'onFocus', [], 200);
if (ViewModelClass.__vm.onShowTrigger)
{
ViewModelClass.__vm.onShowTrigger(!ViewModelClass.__vm.onShowTrigger());
}
Utils.delegateRun(ViewModelClass.__vm, 'onShowWithDelay', [], 200);
_.each(ViewModelClass.__names, function (sName) {
Plugins.runHook('view-model-on-show', [sName, ViewModelClass.__vm]);
@ -427,7 +468,11 @@
_.delay(function () {
Globals.$html.removeClass('rl-started-trigger').addClass('rl-started');
}, 50);
}, 100);
_.delay(function () {
Globals.$html.addClass('rl-started-delay');
}, 200);
};
/**

View file

@ -4,9 +4,12 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils')
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -14,15 +17,23 @@
*
* @param {string} sEmail
* @param {boolean=} bCanBeDelete = true
* @param {number=} iCount = 0
*/
function AccountModel(sEmail, bCanBeDelete)
function AccountModel(sEmail, bCanBeDelete, iCount)
{
AbstractModel.call(this, 'AccountModel');
this.email = sEmail;
this.count = ko.observable(iCount || 0);
this.deleteAccess = ko.observable(false);
this.canBeDalete = ko.observable(Utils.isUnd(bCanBeDelete) ? true : !!bCanBeDelete);
this.canBeDeleted = ko.observable(Utils.isUnd(bCanBeDelete) ? true : !!bCanBeDelete);
this.canBeEdit = this.canBeDeleted;
}
_.extend(AccountModel.prototype, AbstractModel.prototype);
/**
* @type {string}
*/
@ -33,7 +44,7 @@
*/
AccountModel.prototype.changeAccountLink = function ()
{
return require('Common/LinkBuilder').change(this.email);
return require('Common/Links').change(this.email);
};
module.exports = AccountModel;

View file

@ -5,10 +5,16 @@
var
window = require('window'),
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder')
Links = require('Common/Links'),
Audio = require('Common/Audio'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -16,12 +22,19 @@
*/
function AttachmentModel()
{
AbstractModel.call(this, 'AttachmentModel');
this.checked = ko.observable(false);
this.mimeType = '';
this.fileName = '';
this.fileNameExt = '';
this.fileType = Enums.FileType.Unknown;
this.estimatedSize = 0;
this.friendlySize = '';
this.isInline = false;
this.isLinked = false;
this.isThumbnail = false;
this.cid = '';
this.cidWithOutTags = '';
this.contentLocation = '';
@ -29,8 +42,11 @@
this.folder = '';
this.uid = '';
this.mimeIndex = '';
this.framed = false;
}
_.extend(AttachmentModel.prototype, AbstractModel.prototype);
/**
* @static
* @param {AjaxJsonAttachment} oJsonAttachment
@ -44,10 +60,13 @@
AttachmentModel.prototype.mimeType = '';
AttachmentModel.prototype.fileName = '';
AttachmentModel.prototype.fileType = '';
AttachmentModel.prototype.fileNameExt = '';
AttachmentModel.prototype.estimatedSize = 0;
AttachmentModel.prototype.friendlySize = '';
AttachmentModel.prototype.isInline = false;
AttachmentModel.prototype.isLinked = false;
AttachmentModel.prototype.isThumbnail = false;
AttachmentModel.prototype.cid = '';
AttachmentModel.prototype.cidWithOutTags = '';
AttachmentModel.prototype.contentLocation = '';
@ -55,6 +74,7 @@
AttachmentModel.prototype.folder = '';
AttachmentModel.prototype.uid = '';
AttachmentModel.prototype.mimeIndex = '';
AttachmentModel.prototype.framed = false;
/**
* @param {AjaxJsonAttachment} oJsonAttachment
@ -64,11 +84,12 @@
var bResult = false;
if (oJsonAttachment && 'Object/Attachment' === oJsonAttachment['@Object'])
{
this.mimeType = (oJsonAttachment.MimeType || '').toLowerCase();
this.fileName = oJsonAttachment.FileName;
this.mimeType = Utils.trim((oJsonAttachment.MimeType || '').toLowerCase());
this.fileName = Utils.trim(oJsonAttachment.FileName);
this.estimatedSize = Utils.pInt(oJsonAttachment.EstimatedSize);
this.isInline = !!oJsonAttachment.IsInline;
this.isLinked = !!oJsonAttachment.IsLinked;
this.isThumbnail = !!oJsonAttachment.IsThumbnail;
this.cid = oJsonAttachment.CID;
this.contentLocation = oJsonAttachment.ContentLocation;
this.download = oJsonAttachment.Download;
@ -76,10 +97,14 @@
this.folder = oJsonAttachment.Folder;
this.uid = oJsonAttachment.Uid;
this.mimeIndex = oJsonAttachment.MimeIndex;
this.framed = !!oJsonAttachment.Framed;
this.friendlySize = Utils.friendlySize(this.estimatedSize);
this.cidWithOutTags = this.cid.replace(/^<+/, '').replace(/>+$/, '');
this.fileNameExt = Utils.getFileExtension(this.fileName);
this.fileType = AttachmentModel.staticFileType(this.fileNameExt, this.mimeType);
bResult = true;
}
@ -91,9 +116,42 @@
*/
AttachmentModel.prototype.isImage = function ()
{
return -1 < Utils.inArray(this.mimeType.toLowerCase(),
['image/png', 'image/jpg', 'image/jpeg', 'image/gif']
);
return Enums.FileType.Image === this.fileType;
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.isMp3 = function ()
{
return Enums.FileType.Audio === this.fileType &&
'mp3' === this.fileNameExt;
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.isOgg = function ()
{
return Enums.FileType.Audio === this.fileType &&
('oga' === this.fileNameExt || 'ogg' === this.fileNameExt);
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.isWav = function ()
{
return Enums.FileType.Audio === this.fileType &&
'wav' === this.fileNameExt;
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.hasThumbnail = function ()
{
return this.isThumbnail;
};
/**
@ -101,8 +159,12 @@
*/
AttachmentModel.prototype.isText = function ()
{
return 'text/' === this.mimeType.substr(0, 5) &&
-1 === Utils.inArray(this.mimeType, ['text/html']);
return Enums.FileType.Text === this.fileType ||
Enums.FileType.Eml === this.fileType ||
Enums.FileType.Certificate === this.fileType ||
Enums.FileType.Html === this.fileType ||
Enums.FileType.Code === this.fileType
;
};
/**
@ -110,7 +172,35 @@
*/
AttachmentModel.prototype.isPdf = function ()
{
return Globals.bAllowPdfPreview && 'application/pdf' === this.mimeType;
return Enums.FileType.Pdf === this.fileType;
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.isFramed = function ()
{
return this.framed && (Globals.__APP__ && Globals.__APP__.googlePreviewSupported()) &&
!(this.isPdf() && Globals.bAllowPdfPreview) && !this.isText() && !this.isImage();
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.hasPreview = function ()
{
return this.isImage() || (this.isPdf() && Globals.bAllowPdfPreview) || this.isText() || this.isFramed();
};
/**
* @return {boolean}
*/
AttachmentModel.prototype.hasPreplay = function ()
{
return (Audio.supportedMp3 && this.isMp3()) ||
(Audio.supportedOgg && this.isOgg()) ||
(Audio.supportedWav && this.isWav())
;
};
/**
@ -118,7 +208,7 @@
*/
AttachmentModel.prototype.linkDownload = function ()
{
return LinkBuilder.attachmentDownload(this.download);
return Links.attachmentDownload(this.download);
};
/**
@ -126,7 +216,32 @@
*/
AttachmentModel.prototype.linkPreview = function ()
{
return LinkBuilder.attachmentPreview(this.download);
return Links.attachmentPreview(this.download);
};
/**
* @return {string}
*/
AttachmentModel.prototype.linkThumbnail = function ()
{
return this.hasThumbnail() ? Links.attachmentThumbnailPreview(this.download) : '';
};
/**
* @return {string}
*/
AttachmentModel.prototype.linkThumbnailPreviewStyle = function ()
{
var sLink = this.linkThumbnail();
return '' === sLink ? '' : 'background:url(' + sLink + ')';
};
/**
* @return {string}
*/
AttachmentModel.prototype.linkFramed = function ()
{
return Links.attachmentFramed(this.download);
};
/**
@ -134,7 +249,30 @@
*/
AttachmentModel.prototype.linkPreviewAsPlain = function ()
{
return LinkBuilder.attachmentPreviewAsPlain(this.download);
return Links.attachmentPreviewAsPlain(this.download);
};
/**
* @return {string}
*/
AttachmentModel.prototype.linkPreviewMain = function ()
{
var sResult = '';
switch (true)
{
case this.isImage():
case this.isPdf() && Globals.bAllowPdfPreview:
sResult = this.linkPreview();
break;
case this.isText():
sResult = this.linkPreviewAsPlain();
break;
case this.isFramed():
sResult = this.linkFramed();
break;
}
return sResult;
};
/**
@ -167,57 +305,86 @@
return true;
};
AttachmentModel.prototype.iconClass = function ()
/**
* @param {string} sExt
* @param {string} sMimeType
* @return {string}
*/
AttachmentModel.staticFileType = _.memoize(function (sExt, sMimeType)
{
sExt = Utils.trim(sExt).toLowerCase();
sMimeType = Utils.trim(sMimeType).toLowerCase();
var
aParts = this.mimeType.toLocaleString().split('/'),
sClass = 'icon-file'
sResult = Enums.FileType.Unknown,
aMimeTypeParts = sMimeType.split('/')
;
if (aParts && aParts[1])
switch (true)
{
if ('image' === aParts[0])
{
sClass = 'icon-file-image';
}
else if ('text' === aParts[0])
{
sClass = 'icon-file-text';
}
else if ('audio' === aParts[0])
{
sClass = 'icon-file-music';
}
else if ('video' === aParts[0])
{
sClass = 'icon-file-movie';
}
else if (-1 < Utils.inArray(aParts[1],
['zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed']))
{
sClass = 'icon-file-zip';
}
// else if (-1 < Utils.inArray(aParts[1],
// ['pdf', 'x-pdf']))
// {
// sClass = 'icon-file-pdf';
// }
// else if (-1 < Utils.inArray(aParts[1], [
// 'exe', 'x-exe', 'x-winexe', 'bat'
// ]))
// {
// sClass = 'icon-console';
// }
else if (-1 < Utils.inArray(aParts[1], [
case 'image' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'png', 'jpg', 'jpeg', 'gif', 'bmp'
]):
sResult = Enums.FileType.Image;
break;
case 'audio' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'mp3', 'ogg', 'oga', 'wav'
]):
sResult = Enums.FileType.Audio;
break;
case 'video' === aMimeTypeParts[0] || -1 < Utils.inArray(sExt, [
'mkv', 'avi'
]):
sResult = Enums.FileType.Video;
break;
case -1 < Utils.inArray(sExt, [
'php', 'js', 'css'
]):
sResult = Enums.FileType.Code;
break;
case 'eml' === sExt || -1 < Utils.inArray(sMimeType, [
'message/delivery-status', 'message/rfc822'
]):
sResult = Enums.FileType.Eml;
break;
case ('text' === aMimeTypeParts[0] && 'html' !== aMimeTypeParts[1]) || -1 < Utils.inArray(sExt, [
'txt', 'log'
]):
sResult = Enums.FileType.Text;
break;
case ('text/html' === sMimeType) || -1 < Utils.inArray(sExt, [
'html'
]):
sResult = Enums.FileType.Html;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2', 'x-zip', 'x-7z', 'x-rar', 'x-tar', 'x-gzip', 'x-bzip', 'x-bzip2', 'x-zip-compressed', 'x-7z-compressed', 'x-rar-compressed'
]) || -1 < Utils.inArray(sExt, [
'zip', '7z', 'tar', 'rar', 'gzip', 'bzip', 'bzip2'
]):
sResult = Enums.FileType.Archive;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], ['pdf', 'x-pdf']) || -1 < Utils.inArray(sExt, [
'pdf'
]):
sResult = Enums.FileType.Pdf;
break;
case -1 < Utils.inArray(sMimeType, [
'application/pgp-signature', 'application/pkcs7-signature', 'application/pgp-keys'
]) || -1 < Utils.inArray(sExt, [
'asc', 'pem', 'ppk'
]):
sResult = Enums.FileType.Certificate;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'rtf', 'msword', 'vnd.msword', 'vnd.openxmlformats-officedocument.wordprocessingml.document',
'vnd.openxmlformats-officedocument.wordprocessingml.template',
'vnd.ms-word.document.macroEnabled.12',
'vnd.ms-word.template.macroEnabled.12'
]))
{
sClass = 'icon-file-text';
}
else if (-1 < Utils.inArray(aParts[1], [
]):
sResult = Enums.FileType.WordText;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'excel', 'ms-excel', 'vnd.ms-excel',
'vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'vnd.openxmlformats-officedocument.spreadsheetml.template',
@ -225,11 +392,10 @@
'vnd.ms-excel.template.macroEnabled.12',
'vnd.ms-excel.addin.macroEnabled.12',
'vnd.ms-excel.sheet.binary.macroEnabled.12'
]))
{
sClass = 'icon-file-excel';
}
else if (-1 < Utils.inArray(aParts[1], [
]):
sResult = Enums.FileType.Sheet;
break;
case -1 < Utils.inArray(aMimeTypeParts[1], [
'powerpoint', 'ms-powerpoint', 'vnd.ms-powerpoint',
'vnd.openxmlformats-officedocument.presentationml.presentation',
'vnd.openxmlformats-officedocument.presentationml.template',
@ -238,15 +404,142 @@
'vnd.ms-powerpoint.presentation.macroEnabled.12',
'vnd.ms-powerpoint.template.macroEnabled.12',
'vnd.ms-powerpoint.slideshow.macroEnabled.12'
]))
{
]):
sResult = Enums.FileType.Presentation;
break;
}
return sResult;
});
/**
* @param {string} sFileType
* @return {string}
*/
AttachmentModel.staticIconClass = _.memoize(function (sFileType)
{
var
sText = '',
sClass = 'icon-file'
;
switch (sFileType)
{
case Enums.FileType.Text:
case Enums.FileType.Eml:
case Enums.FileType.WordText:
sClass = 'icon-file-text';
break;
case Enums.FileType.Html:
case Enums.FileType.Code:
sClass = 'icon-file-code';
break;
case Enums.FileType.Image:
sClass = 'icon-file-image';
break;
case Enums.FileType.Audio:
sClass = 'icon-file-music';
break;
case Enums.FileType.Video:
sClass = 'icon-file-movie';
break;
case Enums.FileType.Archive:
sClass = 'icon-file-zip';
break;
case Enums.FileType.Certificate:
sClass = 'icon-file-certificate';
break;
case Enums.FileType.Sheet:
sClass = 'icon-file-excel';
break;
case Enums.FileType.Presentation:
sClass = 'icon-file-chart-graph';
break;
case Enums.FileType.Pdf:
sText = 'pdf';
sClass = 'icon-none';
break;
}
return [sClass, sText];
});
/**
* @param {string} sFileType
* @return {string}
*/
AttachmentModel.staticCombinedIconClass = function (aData)
{
var
sClass = '',
aTypes = []
;
if (Utils.isNonEmptyArray(aData))
{
sClass = 'icon-attachment';
aTypes = _.uniq(_.compact(_.map(aData, function (aItem) {
return aItem ? AttachmentModel.staticFileType(
Utils.getFileExtension(aItem[0]), aItem[1]) : '';
})));
if (aTypes && 1 === aTypes.length && aTypes[0])
{
switch (aTypes[0])
{
case Enums.FileType.Text:
case Enums.FileType.WordText:
sClass = 'icon-file-text';
break;
case Enums.FileType.Html:
case Enums.FileType.Code:
sClass = 'icon-file-code';
break;
case Enums.FileType.Image:
sClass = 'icon-file-image';
break;
case Enums.FileType.Audio:
sClass = 'icon-file-music';
break;
case Enums.FileType.Video:
sClass = 'icon-file-movie';
break;
case Enums.FileType.Archive:
sClass = 'icon-file-zip';
break;
case Enums.FileType.Certificate:
sClass = 'icon-file-certificate';
break;
case Enums.FileType.Sheet:
sClass = 'icon-file-excel';
break;
case Enums.FileType.Presentation:
sClass = 'icon-file-chart-graph';
break;
}
}
}
return sClass;
};
/**
* @return {string}
*/
AttachmentModel.prototype.iconClass = function ()
{
return AttachmentModel.staticIconClass(this.fileType)[0];
};
/**
* @return {string}
*/
AttachmentModel.prototype.iconText = function ()
{
return AttachmentModel.staticIconClass(this.fileType)[1];
};
module.exports = AttachmentModel;
}());

View file

@ -4,9 +4,14 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils')
Utils = require('Common/Utils'),
AttachmentModel = require('Model/Attachment'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -21,6 +26,8 @@
*/
function ComposeAttachmentModel(sId, sFileName, nSize, bInline, bLinked, sCID, sContentLocation)
{
AbstractModel.call(this, 'ComposeAttachmentModel');
this.id = sId;
this.isInline = Utils.isUnd(bInline) ? false : !!bInline;
this.isLinked = Utils.isUnd(bLinked) ? false : !!bLinked;
@ -32,18 +39,46 @@
this.size = ko.observable(Utils.isUnd(nSize) ? null : nSize);
this.tempName = ko.observable('');
this.progress = ko.observable('');
this.progress = ko.observable(0);
this.error = ko.observable('');
this.waiting = ko.observable(true);
this.uploading = ko.observable(false);
this.enabled = ko.observable(true);
this.complete = ko.observable(false);
this.progressText = ko.computed(function () {
var iP = this.progress();
return 0 === iP ? '' : '' + (98 < iP ? 100 : iP) + '%';
}, this);
this.progressStyle = ko.computed(function () {
var iP = this.progress();
return 0 === iP ? '' : 'width:' + (98 < iP ? 100 : iP) + '%';
}, this);
this.title = ko.computed(function () {
var sError = this.error();
return '' !== sError ? sError : this.fileName();
}, this);
this.friendlySize = ko.computed(function () {
var mSize = this.size();
return null === mSize ? '' : Utils.friendlySize(this.size());
}, this);
this.mimeType = ko.computed(function () {
return Utils.mimeContentType(this.fileName());
}, this);
this.fileExt = ko.computed(function () {
return Utils.getFileExtension(this.fileName());
}, this);
this.regDisposables([this.progressText, this.progressStyle, this.title, this.friendlySize, this.mimeType, this.fileExt]);
}
_.extend(ComposeAttachmentModel.prototype, AbstractModel.prototype);
ComposeAttachmentModel.prototype.id = '';
ComposeAttachmentModel.prototype.isInline = false;
ComposeAttachmentModel.prototype.isLinked = false;
@ -54,6 +89,7 @@
/**
* @param {AjaxJsonComposeAttachment} oJsonAttachment
* @return {boolean}
*/
ComposeAttachmentModel.prototype.initByUploadJson = function (oJsonAttachment)
{
@ -71,6 +107,24 @@
return bResult;
};
/**
* @return {string}
*/
ComposeAttachmentModel.prototype.iconClass = function ()
{
return AttachmentModel.staticIconClass(
AttachmentModel.staticFileType(this.fileExt(), this.mimeType()))[0];
};
/**
* @return {string}
*/
ComposeAttachmentModel.prototype.iconText = function ()
{
return AttachmentModel.staticIconClass(
AttachmentModel.staticFileType(this.fileExt(), this.mimeType()))[1];
};
module.exports = ComposeAttachmentModel;
}());

View file

@ -9,7 +9,9 @@
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder')
Links = require('Common/Links'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -17,10 +19,11 @@
*/
function ContactModel()
{
AbstractModel.call(this, 'ContactModel');
this.idContact = 0;
this.display = '';
this.properties = [];
this.tags = '';
this.readOnly = false;
this.focused = ko.observable(false);
@ -29,6 +32,8 @@
this.deleted = ko.observable(false);
}
_.extend(ContactModel.prototype, AbstractModel.prototype);
/**
* @return {Array|null}
*/
@ -71,7 +76,6 @@
this.idContact = Utils.pInt(oItem['IdContact']);
this.display = Utils.pString(oItem['Display']);
this.readOnly = !!oItem['ReadOnly'];
this.tags = '';
if (Utils.isNonEmptyArray(oItem['Properties']))
{
@ -83,11 +87,6 @@
}, this);
}
if (Utils.isNonEmptyArray(oItem['Tags']))
{
this.tags = oItem['Tags'].join(',');
}
bResult = true;
}
@ -99,7 +98,7 @@
*/
ContactModel.prototype.srcAttr = function ()
{
return LinkBuilder.emptyContactPic();
return Links.emptyContactPic();
};
/**
@ -113,7 +112,7 @@
/**
* @return string
*/
ContactModel.prototype.lineAsCcc = function ()
ContactModel.prototype.lineAsCss = function ()
{
var aResult = [];
if (this.deleted())

View file

@ -4,10 +4,14 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils')
Utils = require('Common/Utils'),
Translator = require('Common/Translator'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -20,6 +24,8 @@
*/
function ContactPropertyModel(iType, sTypeStr, sValue, bFocused, sPlaceholder)
{
AbstractModel.call(this, 'ContactPropertyModel');
this.type = ko.observable(Utils.isUnd(iType) ? Enums.ContactPropertyType.Unknown : iType);
this.typeStr = ko.observable(Utils.isUnd(sTypeStr) ? '' : sTypeStr);
this.focused = ko.observable(Utils.isUnd(bFocused) ? false : !!bFocused);
@ -29,14 +35,18 @@
this.placeholderValue = ko.computed(function () {
var sPlaceholder = this.placeholder();
return sPlaceholder ? Utils.i18n(sPlaceholder) : '';
return sPlaceholder ? Translator.i18n(sPlaceholder) : '';
}, this);
this.largeValue = ko.computed(function () {
return Enums.ContactPropertyType.Note === this.type();
}, this);
this.regDisposables([this.placeholderValue, this.largeValue]);
}
_.extend(ContactPropertyModel.prototype, AbstractModel.prototype);
module.exports = ContactPropertyModel;
}());

View file

@ -1,58 +0,0 @@
(function () {
'use strict';
var
ko = require('ko'),
Utils = require('Common/Utils')
;
/**
* @constructor
*/
function ContactTagModel()
{
this.idContactTag = 0;
this.name = ko.observable('');
this.readOnly = false;
}
ContactTagModel.prototype.parse = function (oItem)
{
var bResult = false;
if (oItem && 'Object/Tag' === oItem['@Object'])
{
this.idContact = Utils.pInt(oItem['IdContactTag']);
this.name(Utils.pString(oItem['Name']));
this.readOnly = !!oItem['ReadOnly'];
bResult = true;
}
return bResult;
};
/**
* @param {string} sSearch
* @return {boolean}
*/
ContactTagModel.prototype.filterHelper = function (sSearch)
{
return this.name().toLowerCase().indexOf(sSearch.toLowerCase()) !== -1;
};
/**
* @param {boolean=} bEncodeHtml = false
* @return {string}
*/
ContactTagModel.prototype.toLine = function (bEncodeHtml)
{
return (Utils.isUnd(bEncodeHtml) ? false : !!bEncodeHtml) ?
Utils.encodeHtml(this.name()) : this.name();
};
module.exports = ContactTagModel;
}());

View file

@ -10,13 +10,17 @@
/**
* @param {string=} sEmail
* @param {string=} sName
* @param {string=} sDkimStatus
* @param {string=} sDkimValue
*
* @constructor
*/
function EmailModel(sEmail, sName)
function EmailModel(sEmail, sName, sDkimStatus, sDkimValue)
{
this.email = sEmail || '';
this.name = sName || '';
this.dkimStatus = sDkimStatus || 'none';
this.dkimValue = sDkimValue || '';
this.clearDuplicateName();
}
@ -42,14 +46,27 @@
*/
EmailModel.prototype.email = '';
/**
* @type {string}
*/
EmailModel.prototype.dkimStatus = 'none';
/**
* @type {string}
*/
EmailModel.prototype.dkimValue = '';
EmailModel.prototype.clear = function ()
{
this.email = '';
this.name = '';
this.dkimStatus = 'none';
this.dkimValue = '';
};
/**
* @returns {boolean}
* @return {boolean}
*/
EmailModel.prototype.validate = function ()
{
@ -92,7 +109,7 @@
sString = Utils.trim(sString);
var
mRegex = /(?:"([^"]+)")? ?<?(.*?@[^>,]+)>?,? ?/g,
mRegex = /(?:"([^"]+)")? ?[<]?(.*?@[^>,]+)>?,? ?/g,
mMatch = mRegex.exec(sString)
;
@ -121,6 +138,8 @@
{
this.name = Utils.trim(oJsonEmail.Name);
this.email = Utils.trim(oJsonEmail.Email);
this.dkimStatus = Utils.trim(oJsonEmail.DkimStatus || '');
this.dkimValue = Utils.trim(oJsonEmail.DkimValue || '');
bResult = '' !== this.email;
this.clearDuplicateName();
@ -335,14 +354,6 @@
return true;
};
/**
* @return {string}
*/
EmailModel.prototype.inputoTagLine = function ()
{
return 0 < this.name.length ? this.name + ' (' + this.email + ')' : this.email;
};
module.exports = EmailModel;
}());

View file

@ -4,11 +4,18 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
FilterConditionModel = require('Model/FilterCondition')
Translator = require('Common/Translator'),
Cache = require('Common/Cache'),
FilterConditionModel = require('Model/FilterCondition'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -16,36 +23,78 @@
*/
function FilterModel()
{
this.isNew = ko.observable(true);
AbstractModel.call(this, 'FilterModel');
this.enabled = ko.observable(true);
this.name = ko.observable('');
this.id = '';
this.conditionsType = ko.observable(Enums.FilterRulesType.And);
this.name = ko.observable('');
this.name.error = ko.observable(false);
this.name.focused = ko.observable(false);
this.conditions = ko.observableArray([]);
this.conditions.subscribe(function () {
Utils.windowResize();
});
this.conditionsType = ko.observable(Enums.FilterRulesType.Any);
// Actions
this.actionMarkAsRead = ko.observable(false);
this.actionSkipOtherFilters = ko.observable(true);
this.actionValue = ko.observable('');
this.actionValue.error = ko.observable(false);
this.actionType = ko.observable(Enums.FiltersAction.Move);
this.actionTypeOptions = [ // TODO i18n
{'id': Enums.FiltersAction.None, 'name': 'Action - None'},
{'id': Enums.FiltersAction.Move, 'name': 'Action - Move to'},
// {'id': Enums.FiltersAction.Forward, 'name': 'Action - Forward to'},
{'id': Enums.FiltersAction.Discard, 'name': 'Action - Discard'}
];
this.actionValueSecond = ko.observable('');
this.actionValueThird = ko.observable('');
this.actionMarkAsRead = ko.observable(false);
this.actionKeep = ko.observable(true);
this.actionNoStop = ko.observable(false);
this.actionType = ko.observable(Enums.FiltersAction.MoveTo);
this.actionType.subscribe(function () {
this.actionValue('');
this.actionValue.error(false);
this.actionValueSecond('');
this.actionValueThird('');
}, this);
var fGetRealFolderName = function (sFolderFullNameRaw) {
var oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
return oFolder ? oFolder.fullName.replace(
'.' === oFolder.delimiter ? /\./ : /[\\\/]+/, ' / ') : sFolderFullNameRaw;
};
this.nameSub = ko.computed(function () {
var
sResult = '',
sActionValue = this.actionValue()
;
switch (this.actionType())
{
case Enums.FiltersAction.MoveTo:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_MOVE_TO', {
'FOLDER': fGetRealFolderName(sActionValue)
});
break;
case Enums.FiltersAction.Forward:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_FORWARD_TO', {
'EMAIL': sActionValue
});
break;
case Enums.FiltersAction.Vacation:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_VACATION_MESSAGE');
break;
case Enums.FiltersAction.Reject:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_REJECT');
break;
case Enums.FiltersAction.Discard:
sResult = Translator.i18n('SETTINGS_FILTERS/SUBNAME_DISCARD');
break;
}
return sResult ? '(' + sResult + ')' : '';
this.actionMarkAsReadVisiblity = ko.computed(function () {
return -1 < Utils.inArray(this.actionType(), [
Enums.FiltersAction.None, Enums.FiltersAction.Forward, Enums.FiltersAction.Move
]);
}, this);
this.actionTemplate = ko.computed(function () {
@ -54,26 +103,129 @@
switch (this.actionType())
{
default:
case Enums.FiltersAction.Move:
sTemplate = 'SettingsFiltersActionValueAsFolders';
case Enums.FiltersAction.MoveTo:
sTemplate = 'SettingsFiltersActionMoveToFolder';
break;
case Enums.FiltersAction.Forward:
sTemplate = 'SettingsFiltersActionWithValue';
sTemplate = 'SettingsFiltersActionForward';
break;
case Enums.FiltersAction.Vacation:
sTemplate = 'SettingsFiltersActionVacation';
break;
case Enums.FiltersAction.Reject:
sTemplate = 'SettingsFiltersActionReject';
break;
case Enums.FiltersAction.None:
sTemplate = 'SettingsFiltersActionNone';
break;
case Enums.FiltersAction.Discard:
sTemplate = 'SettingsFiltersActionNoValue';
sTemplate = 'SettingsFiltersActionDiscard';
break;
}
return sTemplate;
}, this);
this.regDisposables(this.conditions.subscribe(Utils.windowResizeCallback));
this.regDisposables(this.name.subscribe(function (sValue) {
this.name.error('' === sValue);
}, this));
this.regDisposables(this.actionValue.subscribe(function (sValue) {
this.actionValue.error('' === sValue);
}, this));
this.regDisposables([this.actionNoStop, this.actionTemplate]);
this.deleteAccess = ko.observable(false);
this.canBeDeleted = ko.observable(true);
}
_.extend(FilterModel.prototype, AbstractModel.prototype);
FilterModel.prototype.generateID = function ()
{
this.id = Utils.fakeMd5();
};
FilterModel.prototype.verify = function ()
{
if ('' === this.name())
{
this.name.error(true);
return false;
}
if (0 < this.conditions().length)
{
if (_.find(this.conditions(), function (oCond) {
return oCond && !oCond.verify();
}))
{
return false;
}
}
if ('' === this.actionValue())
{
if (-1 < Utils.inArray(this.actionType(), [
Enums.FiltersAction.MoveTo,
Enums.FiltersAction.Forward,
Enums.FiltersAction.Reject,
Enums.FiltersAction.Vacation
]))
{
this.actionValue.error(true);
return false;
}
}
if (Enums.FiltersAction.Forward === this.actionType() &&
-1 === this.actionValue().indexOf('@'))
{
this.actionValue.error(true);
return false;
}
this.name.error(false);
this.actionValue.error(false);
return true;
};
FilterModel.prototype.toJson = function ()
{
return {
'ID': this.id,
'Enabled': this.enabled() ? '1' : '0',
'Name': this.name(),
'ConditionsType': this.conditionsType(),
'Conditions': _.map(this.conditions(), function (oItem) {
return oItem.toJson();
}),
'ActionValue': this.actionValue(),
'ActionValueSecond': this.actionValueSecond(),
'ActionValueThird': this.actionValueThird(),
'ActionType': this.actionType(),
'Stop': this.actionNoStop() ? '0' : '1',
'Keep': this.actionKeep() ? '1' : '0',
'MarkAsRead': this.actionMarkAsRead() ? '1' : '0'
};
};
FilterModel.prototype.addCondition = function ()
{
this.conditions.push(new FilterConditionModel(this.conditions));
this.conditions.push(new FilterConditionModel());
};
FilterModel.prototype.removeCondition = function (oConditionToDelete)
{
this.conditions.remove(oConditionToDelete);
Utils.delegateRunOnDestroy(oConditionToDelete);
};
FilterModel.prototype.parse = function (oItem)
@ -81,7 +233,32 @@
var bResult = false;
if (oItem && 'Object/Filter' === oItem['@Object'])
{
this.id = Utils.pString(oItem['ID']);
this.name(Utils.pString(oItem['Name']));
this.enabled(!!oItem['Enabled']);
this.conditionsType(Utils.pString(oItem['ConditionsType']));
this.conditions([]);
if (Utils.isNonEmptyArray(oItem['Conditions']))
{
this.conditions(_.compact(_.map(oItem['Conditions'], function (aData) {
var oFilterCondition = new FilterConditionModel();
return oFilterCondition && oFilterCondition.parse(aData) ?
oFilterCondition : null;
})));
}
this.actionType(Utils.pString(oItem['ActionType']));
this.actionValue(Utils.pString(oItem['ActionValue']));
this.actionValueSecond(Utils.pString(oItem['ActionValueSecond']));
this.actionValueThird(Utils.pString(oItem['ActionValueThird']));
this.actionNoStop(!oItem['Stop']);
this.actionKeep(!!oItem['Keep']);
this.actionMarkAsRead(!!oItem['MarkAsRead']);
bResult = true;
}
@ -89,6 +266,39 @@
return bResult;
};
FilterModel.prototype.cloneSelf = function ()
{
var oClone = new FilterModel();
oClone.id = this.id;
oClone.enabled(this.enabled());
oClone.name(this.name());
oClone.name.error(this.name.error());
oClone.conditionsType(this.conditionsType());
oClone.actionMarkAsRead(this.actionMarkAsRead());
oClone.actionType(this.actionType());
oClone.actionValue(this.actionValue());
oClone.actionValue.error(this.actionValue.error());
oClone.actionValueSecond(this.actionValueSecond());
oClone.actionValueThird(this.actionValueThird());
oClone.actionKeep(this.actionKeep());
oClone.actionNoStop(this.actionNoStop());
oClone.conditions(_.map(this.conditions(), function (oCondition) {
return oCondition.cloneSelf();
}));
return oClone;
};
module.exports = FilterModel;
}());

View file

@ -4,38 +4,26 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums')
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
* @param {*} oKoList
* @constructor
*/
function FilterConditionModel(oKoList)
function FilterConditionModel()
{
this.parentList = oKoList;
AbstractModel.call(this, 'FilterConditionModel');
this.field = ko.observable(Enums.FilterConditionField.From);
this.fieldOptions = [ // TODO i18n
{'id': Enums.FilterConditionField.From, 'name': 'From'},
{'id': Enums.FilterConditionField.Recipient, 'name': 'Recipient (To or CC)'},
{'id': Enums.FilterConditionField.To, 'name': 'To'},
{'id': Enums.FilterConditionField.Subject, 'name': 'Subject'}
];
this.type = ko.observable(Enums.FilterConditionType.EqualTo);
this.typeOptions = [ // TODO i18n
{'id': Enums.FilterConditionType.EqualTo, 'name': 'Equal To'},
{'id': Enums.FilterConditionType.NotEqualTo, 'name': 'Not Equal To'},
{'id': Enums.FilterConditionType.Contains, 'name': 'Contains'},
{'id': Enums.FilterConditionType.NotContains, 'name': 'Not Contains'}
];
this.type = ko.observable(Enums.FilterConditionType.Contains);
this.value = ko.observable('');
this.value.error = ko.observable(false);
this.template = ko.computed(function () {
@ -50,11 +38,55 @@
return sTemplate;
}, this);
this.regDisposables([this.template]);
}
FilterConditionModel.prototype.removeSelf = function ()
_.extend(FilterConditionModel.prototype, AbstractModel.prototype);
FilterConditionModel.prototype.verify = function ()
{
this.parentList.remove(this);
if ('' === this.value())
{
this.value.error(true);
return false;
}
return true;
};
FilterConditionModel.prototype.parse = function (oItem)
{
if (oItem && oItem['Field'] && oItem['Type'])
{
this.field(Utils.pString(oItem['Field']));
this.type(Utils.pString(oItem['Type']));
this.value(Utils.pString(oItem['Value']));
return true;
}
return false;
};
FilterConditionModel.prototype.toJson = function ()
{
return {
'Field': this.field(),
'Type': this.type(),
'Value': this.value()
};
};
FilterConditionModel.prototype.cloneSelf = function ()
{
var oClone = new FilterConditionModel();
oClone.field(this.field());
oClone.type(this.type());
oClone.value(this.value());
return oClone;
};
module.exports = FilterConditionModel;

View file

@ -8,9 +8,13 @@
ko = require('ko'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Events = require('Common/Events')
Events = require('Common/Events'),
Translator = require('Common/Translator'),
Cache = require('Common/Cache'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -18,6 +22,8 @@
*/
function FolderModel()
{
AbstractModel.call(this, 'FolderModel');
this.name = ko.observable('');
this.fullName = '';
this.fullNameRaw = '';
@ -49,6 +55,8 @@
this.collapsedPrivate = ko.observable(true);
}
_.extend(FolderModel.prototype, AbstractModel.prototype);
/**
* @static
* @param {AjaxJsonFolder} oJsonFolder
@ -65,6 +73,12 @@
*/
FolderModel.prototype.initComputed = function ()
{
var sInboxFolderName = Cache.getFolderInboxName();
this.isInbox = ko.computed(function () {
return Enums.FolderType.Inbox === this.type();
}, this);
this.hasSubScribedSubfolders = ko.computed(function () {
return !!_.find(this.subFolders(), function (oFolder) {
return oFolder.subScribed() && !oFolder.isSystemFolder();
@ -76,12 +90,14 @@
}, this);
this.visible = ko.computed(function () {
var
bSubScribed = this.subScribed(),
bSubFolders = this.hasSubScribedSubfolders()
;
return (bSubScribed || (bSubFolders && (!this.existen || !this.selectable)));
}, this);
this.isSystemFolder = ko.computed(function () {
@ -115,7 +131,7 @@
}
},
'owner': this
});
}).extend({'notify': 'always'});
this.messageCountUnread = ko.computed({
'read': this.privateMessageCountUnread,
@ -130,7 +146,7 @@
}
},
'owner': this
});
}).extend({'notify': 'always'});
this.printableUnreadCount = ko.computed(function () {
var
@ -159,11 +175,11 @@
var
bSystem = this.isSystemFolder()
;
return !bSystem && 0 === this.subFolders().length && 'INBOX' !== this.fullNameRaw;
return !bSystem && 0 === this.subFolders().length && sInboxFolderName !== this.fullNameRaw;
}, this);
this.canBeSubScribed = ko.computed(function () {
return !this.isSystemFolder() && this.selectable && 'INBOX' !== this.fullNameRaw;
return !this.isSystemFolder() && this.selectable && sInboxFolderName !== this.fullNameRaw;
}, this);
// this.visible.subscribe(function () {
@ -174,7 +190,7 @@
this.localName = ko.computed(function () {
Globals.langChangeTrigger();
Translator.trigger();
var
iType = this.type(),
@ -186,22 +202,22 @@
switch (iType)
{
case Enums.FolderType.Inbox:
sName = Utils.i18n('FOLDER_LIST/INBOX_NAME');
sName = Translator.i18n('FOLDER_LIST/INBOX_NAME');
break;
case Enums.FolderType.SentItems:
sName = Utils.i18n('FOLDER_LIST/SENT_NAME');
sName = Translator.i18n('FOLDER_LIST/SENT_NAME');
break;
case Enums.FolderType.Draft:
sName = Utils.i18n('FOLDER_LIST/DRAFTS_NAME');
sName = Translator.i18n('FOLDER_LIST/DRAFTS_NAME');
break;
case Enums.FolderType.Spam:
sName = Utils.i18n('FOLDER_LIST/SPAM_NAME');
sName = Translator.i18n('FOLDER_LIST/SPAM_NAME');
break;
case Enums.FolderType.Trash:
sName = Utils.i18n('FOLDER_LIST/TRASH_NAME');
sName = Translator.i18n('FOLDER_LIST/TRASH_NAME');
break;
case Enums.FolderType.Archive:
sName = Utils.i18n('FOLDER_LIST/ARCHIVE_NAME');
sName = Translator.i18n('FOLDER_LIST/ARCHIVE_NAME');
break;
}
}
@ -212,7 +228,7 @@
this.manageFolderSystemName = ko.computed(function () {
Globals.langChangeTrigger();
Translator.trigger();
var
sSuffix = '',
@ -225,22 +241,22 @@
switch (iType)
{
case Enums.FolderType.Inbox:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/INBOX_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/INBOX_NAME') + ')';
break;
case Enums.FolderType.SentItems:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/SENT_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/SENT_NAME') + ')';
break;
case Enums.FolderType.Draft:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/DRAFTS_NAME') + ')';
break;
case Enums.FolderType.Spam:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/SPAM_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/SPAM_NAME') + ')';
break;
case Enums.FolderType.Trash:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/TRASH_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/TRASH_NAME') + ')';
break;
case Enums.FolderType.Archive:
sSuffix = '(' + Utils.i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
sSuffix = '(' + Translator.i18n('FOLDER_LIST/ARCHIVE_NAME') + ')';
break;
}
}
@ -319,7 +335,11 @@
*/
FolderModel.prototype.initByJson = function (oJsonFolder)
{
var bResult = false;
var
bResult = false,
sInboxFolderName = Cache.getFolderInboxName()
;
if (oJsonFolder && 'Object/Folder' === oJsonFolder['@Object'])
{
this.name(oJsonFolder.Name);
@ -332,7 +352,7 @@
this.existen = !!oJsonFolder.IsExists;
this.subScribed(!!oJsonFolder.IsSubscribed);
this.type('INBOX' === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
this.type(sInboxFolderName === this.fullNameRaw ? Enums.FolderType.Inbox : Enums.FolderType.User);
bResult = true;
}

View file

@ -4,45 +4,47 @@
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils')
AbstractModel = require('Knoin/AbstractModel')
;
/**
* @param {string} sId
* @param {string} sEmail
* @param {boolean=} bCanBeDelete = true
* @constructor
*/
function IdentityModel(sId, sEmail, bCanBeDelete)
function IdentityModel(sId, sEmail)
{
this.id = sId;
AbstractModel.call(this, 'IdentityModel');
this.id = ko.observable(sId);
this.email = ko.observable(sEmail);
this.name = ko.observable('');
this.replyTo = ko.observable('');
this.bcc = ko.observable('');
this.signature = ko.observable('');
this.signatureInsertBefore = ko.observable(false);
this.deleteAccess = ko.observable(false);
this.canBeDalete = ko.observable(bCanBeDelete);
this.canBeDeleted = ko.computed(function () {
return '' !== this.id();
}, this);
}
_.extend(IdentityModel.prototype, AbstractModel.prototype);
IdentityModel.prototype.formattedName = function ()
{
var sName = this.name();
return '' === sName ? this.email() : sName + ' <' + this.email() + '>';
};
var
sName = this.name(),
sEmail = this.email()
;
IdentityModel.prototype.formattedNameForCompose = function ()
{
var sName = this.name();
return '' === sName ? this.email() : sName + ' (' + this.email() + ')';
};
IdentityModel.prototype.formattedNameForEmail = function ()
{
var sName = this.name();
return '' === sName ? this.email() : '"' + Utils.quoteName(sName) + '" <' + this.email() + '>';
return ('' !== sName) ? sName + ' (' + sEmail + ')' : sEmail;
};
module.exports = IdentityModel;

File diff suppressed because it is too large Load diff

89
dev/Model/MessageFull.js Normal file
View file

@ -0,0 +1,89 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
// MessageHelper = require('Helper/Message'),
MessageSimpleModel = require('Model/MessageSimple')
;
/**
* @constructor
*/
function MessageFullModel()
{
MessageSimpleModel.call(this, 'MessageFullModel');
}
_.extend(MessageFullModel.prototype, MessageSimpleModel.prototype);
MessageFullModel.prototype.priority = 0;
MessageFullModel.prototype.hash = '';
MessageFullModel.prototype.requestHash = '';
MessageFullModel.prototype.proxy = false;
MessageFullModel.prototype.hasAttachments = false;
MessageFullModel.prototype.clear = function ()
{
MessageSimpleModel.prototype.clear.call(this);
this.priority = 0;
this.hash = '';
this.requestHash = '';
this.proxy = false;
this.hasAttachments = false;
};
/**
* @param {AjaxJsonMessage} oJson
* @return {boolean}
*/
MessageFullModel.prototype.initByJson = function (oJson)
{
var bResult = false;
if (oJson && 'Object/Message' === oJson['@Object'])
{
if (MessageSimpleModel.prototype.initByJson.call(this, oJson))
{
this.priority = Utils.pInt(oJson.Priority);
this.priority = Utils.inArray(this.priority, [Enums.MessagePriority.High, Enums.MessagePriority.Low]) ?
this.priority : Enums.MessagePriority.Normal;
this.hash = Utils.pString(oJson.Hash);
this.requestHash = Utils.pString(oJson.RequestHash);
this.proxy = !!oJson.ExternalProxy;
this.hasAttachments = !!oJson.HasAttachments;
bResult = true;
}
}
return bResult;
};
/**
* @static
* @param {AjaxJsonMessage} oJson
* @return {?MessageFullModel}
*/
MessageFullModel.newInstanceFromJson = function (oJson)
{
var oItem = oJson ? new MessageFullModel() : null;
return oItem && oItem.initByJson(oJson) ? oItem : null;
};
module.exports = MessageFullModel;
}());

174
dev/Model/MessageSimple.js Normal file
View file

@ -0,0 +1,174 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
MessageHelper = require('Helper/Message'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
* @param {string=} sSuperName
* @constructor
*/
function MessageSimpleModel(sSuperName)
{
AbstractModel.call(this, sSuperName || 'MessageSimpleModel');
this.flagged = ko.observable(false);
this.selected = ko.observable(false);
}
_.extend(MessageSimpleModel.prototype, AbstractModel.prototype);
MessageSimpleModel.prototype.__simple_message__ = true;
MessageSimpleModel.prototype.folder = '';
MessageSimpleModel.prototype.folderFullNameRaw = '';
MessageSimpleModel.prototype.uid = '';
MessageSimpleModel.prototype.subject = '';
MessageSimpleModel.prototype.to = [];
MessageSimpleModel.prototype.from = [];
MessageSimpleModel.prototype.cc = [];
MessageSimpleModel.prototype.bcc = [];
MessageSimpleModel.prototype.replyTo = [];
MessageSimpleModel.prototype.deliveredTo = [];
MessageSimpleModel.prototype.fromAsString = '';
MessageSimpleModel.prototype.fromAsStringClear = '';
MessageSimpleModel.prototype.toAsString = '';
MessageSimpleModel.prototype.toAsStringClear = '';
MessageSimpleModel.prototype.senderAsString = '';
MessageSimpleModel.prototype.senderAsStringClear = '';
MessageSimpleModel.prototype.size = 0;
MessageSimpleModel.prototype.timestamp = 0;
MessageSimpleModel.prototype.clear = function ()
{
this.folder = '';
this.folderFullNameRaw = '';
this.uid = '';
this.subject = '';
this.to = [];
this.from = [];
this.cc = [];
this.bcc = [];
this.replyTo = [];
this.deliveredTo = [];
this.fromAsString = '';
this.fromAsStringClear = '';
this.toAsString = '';
this.toAsStringClear = '';
this.senderAsString = '';
this.senderAsStringClear = '';
this.size = 0;
this.timestamp = 0;
this.flagged(false);
this.selected(false);
};
/**
* @param {Object} oJson
* @return {boolean}
*/
MessageSimpleModel.prototype.initByJson = function (oJson)
{
var bResult = false;
if (oJson && 'Object/Message' === oJson['@Object'])
{
this.folder = Utils.pString(oJson.Folder);
this.folderFullNameRaw = this.folder;
this.uid = Utils.pString(oJson.Uid);
this.subject = Utils.pString(oJson.Subject);
if (Utils.isArray(oJson.SubjectParts))
{
this.subjectPrefix = Utils.pString(oJson.SubjectParts[0]);
this.subjectSuffix = Utils.pString(oJson.SubjectParts[1]);
}
else
{
this.subjectPrefix = '';
this.subjectSuffix = this.subject;
}
this.from = MessageHelper.emailArrayFromJson(oJson.From);
this.to = MessageHelper.emailArrayFromJson(oJson.To);
this.cc = MessageHelper.emailArrayFromJson(oJson.Cc);
this.bcc = MessageHelper.emailArrayFromJson(oJson.Bcc);
this.replyTo = MessageHelper.emailArrayFromJson(oJson.ReplyTo);
this.deliveredTo = MessageHelper.emailArrayFromJson(oJson.DeliveredTo);
this.size = Utils.pInt(oJson.Size);
this.timestamp = Utils.pInt(oJson.DateTimeStampInUTC);
this.fromAsString = MessageHelper.emailArrayToString(this.from, true);
this.fromAsStringClear = MessageHelper.emailArrayToStringClear(this.from);
this.toAsString = MessageHelper.emailArrayToString(this.to, true);
this.toAsStringClear = MessageHelper.emailArrayToStringClear(this.to);
this.flagged(false);
this.selected(false);
this.populateSenderEmail();
bResult = true;
}
return bResult;
};
MessageSimpleModel.prototype.populateSenderEmail = function (bDraftOrSentFolder)
{
this.senderAsString = this.fromAsString;
this.senderAsStringClear = this.fromAsStringClear;
if (bDraftOrSentFolder)
{
this.senderAsString = this.toAsString;
this.senderAsStringClear = this.toAsStringClear;
}
};
/**
* @return {Array}
*/
MessageSimpleModel.prototype.threads = function ()
{
return [];
};
/**
* @static
* @param {Object} oJson
* @return {?MessageSimpleModel}
*/
MessageSimpleModel.newInstanceFromJson = function (oJson)
{
var oItem = oJson ? new MessageSimpleModel() : null;
return oItem && oItem.initByJson(oJson) ? oItem : null;
};
module.exports = MessageSimpleModel;
}());

View file

@ -4,7 +4,10 @@
'use strict';
var
ko = require('ko')
_ = require('_'),
ko = require('ko'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
@ -19,6 +22,8 @@
*/
function OpenPgpKeyModel(iIndex, sGuID, sID, sUserID, sEmail, bIsPrivate, sArmor)
{
AbstractModel.call(this, 'OpenPgpKeyModel');
this.index = iIndex;
this.id = sID;
this.guid = sGuID;
@ -30,6 +35,8 @@
this.deleteAccess = ko.observable(false);
}
_.extend(OpenPgpKeyModel.prototype, AbstractModel.prototype);
OpenPgpKeyModel.prototype.index = 0;
OpenPgpKeyModel.prototype.id = '';
OpenPgpKeyModel.prototype.guid = '';

77
dev/Model/Template.js Normal file
View file

@ -0,0 +1,77 @@
(function () {
'use strict';
var
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils'),
AbstractModel = require('Knoin/AbstractModel')
;
/**
* @constructor
*
* @param {string} sID
* @param {string} sName
* @param {string} sBody
*/
function TemplateModel(sID, sName, sBody)
{
AbstractModel.call(this, 'TemplateModel');
this.id = sID;
this.name = sName;
this.body = sBody;
this.populated = true;
this.deleteAccess = ko.observable(false);
}
_.extend(TemplateModel.prototype, AbstractModel.prototype);
/**
* @type {string}
*/
TemplateModel.prototype.id = '';
/**
* @type {string}
*/
TemplateModel.prototype.name = '';
/**
* @type {string}
*/
TemplateModel.prototype.body = '';
/**
* @type {boolean}
*/
TemplateModel.prototype.populated = true;
/**
* @type {boolean}
*/
TemplateModel.prototype.parse = function (oItem)
{
var bResult = false;
if (oItem && 'Object/Template' === oItem['@Object'])
{
this.id = Utils.pString(oItem['ID']);
this.name = Utils.pString(oItem['Name']);
this.body = Utils.pString(oItem['Body']);
this.populated = !!oItem['Populated'];
bResult = true;
}
return bResult;
};
module.exports = TemplateModel;
}());

View file

@ -0,0 +1,165 @@
(function () {
'use strict';
var
$ = require('$'),
_ = require('_'),
Q = require('Q'),
Consts = require('Common/Consts'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Links = require('Common/Links'),
Settings = require('Storage/Settings'),
AbstractBasicPromises = require('Promises/AbstractBasic')
;
/**
* @constructor
*/
function AbstractAjaxPromises()
{
AbstractBasicPromises.call(this);
this.clear();
}
_.extend(AbstractAjaxPromises.prototype, AbstractBasicPromises.prototype);
AbstractAjaxPromises.prototype.oRequests = {};
AbstractAjaxPromises.prototype.clear = function ()
{
this.oRequests = {};
};
AbstractAjaxPromises.prototype.abort = function (sAction, bClearOnly)
{
if (this.oRequests[sAction])
{
if (!bClearOnly && this.oRequests[sAction].abort)
{
this.oRequests[sAction].__aborted__ = true;
this.oRequests[sAction].abort();
}
this.oRequests[sAction] = null;
delete this.oRequests[sAction];
}
return this;
};
AbstractAjaxPromises.prototype.ajaxRequest = function (sAction, bPost, iTimeOut, oParameters, sAdditionalGetString, fTrigger)
{
var
oH = null,
self = this,
iStart = Utils.microtime(),
oDeferred = Q.defer()
;
iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : Consts.Defaults.DefaultAjaxTimeout;
sAdditionalGetString = Utils.isUnd(sAdditionalGetString) ? '' : Utils.pString(sAdditionalGetString);
if (bPost)
{
oParameters['XToken'] = Settings.settingsGet('Token');
}
this.setTrigger(fTrigger, true);
oH = $.ajax({
'type': bPost ? 'POST' : 'GET',
'url': Links.ajax(sAdditionalGetString),
'async': true,
'dataType': 'json',
'data': bPost ? (oParameters || {}) : {},
'timeout': iTimeOut,
'global': true
}).always(function (oData, sTextStatus) {
var bCached = false;
if (oData && oData['Time'])
{
bCached = Utils.pInt(oData['Time']) > Utils.microtime() - iStart;
}
if ('success' === sTextStatus)
{
if (oData && oData.Result && sAction === oData.Action)
{
oData.__cached__ = bCached;
oDeferred.resolve(oData);
}
else if (oData && oData.Action)
{
oDeferred.reject(oData.ErrorCode ? oData.ErrorCode : Enums.Notification.AjaxFalse);
}
else
{
oDeferred.reject(Enums.Notification.AjaxParse);
}
}
else if ('timeout' === sTextStatus)
{
oDeferred.reject(Enums.Notification.AjaxTimeout);
}
else if ('abort' === sTextStatus)
{
if (!oData || !oData.__aborted__)
{
oDeferred.reject(Enums.Notification.AjaxAbort);
}
}
else
{
oDeferred.reject(Enums.Notification.AjaxParse);
}
if (self.oRequests[sAction])
{
self.oRequests[sAction] = null;
delete self.oRequests[sAction];
}
self.setTrigger(fTrigger, false);
});
if (oH)
{
if (this.oRequests[sAction])
{
this.oRequests[sAction] = null;
delete this.oRequests[sAction];
}
this.oRequests[sAction] = oH;
}
return oDeferred.promise;
};
AbstractAjaxPromises.prototype.getRequest = function (sAction, fTrigger, sAdditionalGetString, iTimeOut)
{
sAdditionalGetString = Utils.isUnd(sAdditionalGetString) ? '' : Utils.pString(sAdditionalGetString);
sAdditionalGetString = sAction + '/' + sAdditionalGetString;
return this.ajaxRequest(sAction, false, iTimeOut, null, sAdditionalGetString, fTrigger);
};
AbstractAjaxPromises.prototype.postRequest = function (sAction, fTrigger, oParameters, iTimeOut)
{
oParameters = oParameters || {};
oParameters['Action'] = sAction;
return this.ajaxRequest(sAction, true, iTimeOut, oParameters, '', fTrigger);
};
module.exports = AbstractAjaxPromises;
}());

View file

@ -0,0 +1,56 @@
(function () {
'use strict';
var
_ = require('_'),
Q = require('Q'),
Utils = require('Common/Utils')
;
/**
* @constructor
*/
function AbstractBasicPromises()
{
this.oPromisesStack = {};
}
AbstractBasicPromises.prototype.func = function (fFunc)
{
fFunc();
return this;
};
AbstractBasicPromises.prototype.fastResolve = function (mData)
{
var oDeferred = Q.defer();
oDeferred.resolve(mData);
return oDeferred.promise;
};
AbstractBasicPromises.prototype.fastReject = function (mData)
{
var oDeferred = Q.defer();
oDeferred.reject(mData);
return oDeferred.promise;
};
AbstractBasicPromises.prototype.setTrigger = function (mTrigger, bValue)
{
if (mTrigger)
{
_.each(Utils.isArray(mTrigger) ? mTrigger : [mTrigger], function (fTrigger) {
if (fTrigger)
{
fTrigger(!!bValue);
}
});
}
};
module.exports = AbstractBasicPromises;
}());

195
dev/Promises/User/Ajax.js Normal file
View file

@ -0,0 +1,195 @@
(function () {
'use strict';
var
window = require('window'),
_ = require('_'),
// Enums = require('Common/Enums'),
// Utils = require('Common/Utils'),
// Base64 = require('Common/Base64'),
// Cache = require('Common/Cache'),
// Links = require('Common/Links'),
//
// AppStore = require('Stores/User/App'),
// SettingsStore = require('Stores/User/Settings'),
MessageSimpleModel = require('Model/MessageSimple'),
PromisesPopulator = require('Promises/User/Populator'),
AbstractAjaxPromises = require('Promises/AbstractAjax')
;
/**
* @constructor
* @extends AbstractAjaxPromises
*/
function UserAjaxUserPromises()
{
AbstractAjaxPromises.call(this);
this.messageListSimpleHash = '';
this.messageListSimpleCache = null;
}
_.extend(UserAjaxUserPromises.prototype, AbstractAjaxPromises.prototype);
UserAjaxUserPromises.prototype.messageListSimple = function (sFolder, aUids, fTrigger)
{
var self = this, sHash = sFolder + '~' + aUids.join('/');
if (sHash === this.messageListSimpleHash && this.messageListSimpleCache)
{
return this.fastResolve(this.messageListSimpleCache);
}
return this.abort('MessageListSimple')
.postRequest('MessageListSimple', fTrigger, {
'Folder': sFolder,
'Uids': aUids
}).then(function (oData) {
self.messageListSimpleHash = sHash;
self.messageListSimpleCache = _.compact(_.map(oData.Result, function (aItem) {
return MessageSimpleModel.newInstanceFromJson(aItem);
}));
return self.messageListSimpleCache;
}, function (iError) {
self.messageListSimpleHash = '';
self.messageListSimpleCache = null;
return self.fastReject(iError);
})
;
};
UserAjaxUserPromises.prototype.foldersReload = function (fTrigger)
{
return this.abort('Folders')
.postRequest('Folders', fTrigger).then(function (oData) {
PromisesPopulator.foldersList(oData.Result);
PromisesPopulator.foldersAdditionalParameters(oData.Result);
return true;
});
};
UserAjaxUserPromises.prototype._folders_timeout_ = 0;
UserAjaxUserPromises.prototype.foldersReloadWithTimeout = function (fTrigger)
{
this.setTrigger(fTrigger, true);
var self = this;
window.clearTimeout(this._folders_timeout_);
this._folders_timeout_ = window.setTimeout(function () {
self.foldersReload(fTrigger);
}, 500);
};
UserAjaxUserPromises.prototype.folderDelete = function (sFolderFullNameRaw, fTrigger)
{
return this.postRequest('FolderDelete', fTrigger, {
'Folder': sFolderFullNameRaw
});
};
UserAjaxUserPromises.prototype.folderCreate = function (sNewFolderName, sParentName, fTrigger)
{
return this.postRequest('FolderCreate', fTrigger, {
'Folder': sNewFolderName,
'Parent': sParentName
});
};
UserAjaxUserPromises.prototype.folderRename = function (sPrevFolderFullNameRaw, sNewFolderName, fTrigger)
{
return this.postRequest('FolderRename', fTrigger, {
'Folder': sPrevFolderFullNameRaw,
'NewFolderName': sNewFolderName
});
};
UserAjaxUserPromises.prototype.attachmentsActions = function (sAction, aHashes, fTrigger)
{
return this.postRequest('AttachmentsActions', fTrigger, {
'Action': sAction,
'Hashes': aHashes
});
};
UserAjaxUserPromises.prototype.welcomeClose = function ()
{
return this.postRequest('WelcomeClose');
};
// UserAjaxUserPromises.prototype.messageList = function (sFolderFullNameRaw, iOffset, iLimit, sSearch, fTrigger)
// {
// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
// sSearch = Utils.pString(sSearch);
// iOffset = Utils.pInt(iOffset);
// iLimit = Utils.pInt(iLimit);
//
// var sFolderHash = Cache.getFolderHash(sFolderFullNameRaw);
//
// if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:')))
// {
// return this.abort('MessageList')
// .getRequest('MessageList', fTrigger,
// Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
// sFolderFullNameRaw,
// iOffset,
// iLimit,
// sSearch,
// AppStore.projectHash(),
// sFolderHash,
// Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
// ''
// ].join(String.fromCharCode(0))))
// .then(PromisesPopulator.messageList);
// }
// else
// {
// return this.abort('MessageList')
// .postRequest('MessageList', fTrigger,{
// 'Folder': sFolderFullNameRaw,
// 'Offset': iOffset,
// 'Limit': iLimit,
// 'Search': sSearch,
// 'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
// 'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
// })
// .then(PromisesPopulator.messageList);
// }
//
// return this.fastReject(Enums.Notification.UnknownError);
// };
//
// UserAjaxUserPromises.prototype.message = function (sFolderFullNameRaw, iUid, fTrigger)
// {
// sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
// iUid = Utils.pInt(iUid);
//
// if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 >= iUid)
// {
// return this.abort('Message')
// .getRequest('Message', fTrigger,
// Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
// sFolderFullNameRaw, iUid,
// AppStore.projectHash(),
// AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
// ].join(String.fromCharCode(0))))
// .then(function (oData) {
// return oData;
// });
// }
//
// return this.fastReject(Enums.Notification.UnknownError);
// };
module.exports = new UserAjaxUserPromises();
}());

View file

@ -0,0 +1,199 @@
(function () {
'use strict';
var
_ = require('_'),
Consts = require('Common/Consts'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Cache = require('Common/Cache'),
AppStore = require('Stores/User/App'),
FolderStore = require('Stores/User/Folder'),
Settings = require('Storage/Settings'),
Local = require('Storage/Client'),
FolderModel = require('Model/Folder'),
AbstractBasicPromises = require('Promises/AbstractBasic')
;
/**
* @constructor
*/
function PromisesUserPopulator()
{
AbstractBasicPromises.call(this);
}
_.extend(PromisesUserPopulator.prototype, AbstractBasicPromises.prototype);
/**
* @param {string} sFullNameHash
* @return {boolean}
*/
PromisesUserPopulator.prototype.isFolderExpanded = function (sFullNameHash)
{
var aExpandedList = Local.get(Enums.ClientSideKeyName.ExpandedFolders);
return Utils.isArray(aExpandedList) && -1 !== _.indexOf(aExpandedList, sFullNameHash);
};
/**
* @param {string} sFolderFullNameRaw
* @return {string}
*/
PromisesUserPopulator.prototype.normalizeFolder = function (sFolderFullNameRaw)
{
return ('' === sFolderFullNameRaw || Consts.Values.UnuseOptionValue === sFolderFullNameRaw ||
null !== Cache.getFolderFromCacheList(sFolderFullNameRaw)) ? sFolderFullNameRaw : '';
};
/**
* @param {string} sNamespace
* @param {Array} aFolders
* @return {Array}
*/
PromisesUserPopulator.prototype.folderResponseParseRec = function (sNamespace, aFolders)
{
var
self = this,
iIndex = 0,
iLen = 0,
oFolder = null,
oCacheFolder = null,
sFolderFullNameRaw = '',
aSubFolders = [],
aList = []
;
for (iIndex = 0, iLen = aFolders.length; iIndex < iLen; iIndex++)
{
oFolder = aFolders[iIndex];
if (oFolder)
{
sFolderFullNameRaw = oFolder.FullNameRaw;
oCacheFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw);
if (!oCacheFolder)
{
oCacheFolder = FolderModel.newInstanceFromJson(oFolder);
if (oCacheFolder)
{
Cache.setFolderToCacheList(sFolderFullNameRaw, oCacheFolder);
Cache.setFolderFullNameRaw(oCacheFolder.fullNameHash, sFolderFullNameRaw, oCacheFolder);
}
}
if (oCacheFolder)
{
oCacheFolder.collapsed(!self.isFolderExpanded(oCacheFolder.fullNameHash));
if (oFolder.Extended)
{
if (oFolder.Extended.Hash)
{
Cache.setFolderHash(oCacheFolder.fullNameRaw, oFolder.Extended.Hash);
}
if (Utils.isNormal(oFolder.Extended.MessageCount))
{
oCacheFolder.messageCountAll(oFolder.Extended.MessageCount);
}
if (Utils.isNormal(oFolder.Extended.MessageUnseenCount))
{
oCacheFolder.messageCountUnread(oFolder.Extended.MessageUnseenCount);
}
}
aSubFolders = oFolder['SubFolders'];
if (aSubFolders && 'Collection/FolderCollection' === aSubFolders['@Object'] &&
aSubFolders['@Collection'] && Utils.isArray(aSubFolders['@Collection']))
{
oCacheFolder.subFolders(
this.folderResponseParseRec(sNamespace, aSubFolders['@Collection']));
}
aList.push(oCacheFolder);
}
}
}
return aList;
};
PromisesUserPopulator.prototype.foldersList = function (oData)
{
if (oData && 'Collection/FolderCollection' === oData['@Object'] &&
oData['@Collection'] && Utils.isArray(oData['@Collection']))
{
FolderStore.folderList(this.folderResponseParseRec(
Utils.isUnd(oData.Namespace) ? '' : oData.Namespace, oData['@Collection']));
}
};
PromisesUserPopulator.prototype.foldersAdditionalParameters = function (oData)
{
if (oData && oData && 'Collection/FolderCollection' === oData['@Object'] &&
oData['@Collection'] && Utils.isArray(oData['@Collection']))
{
if (!Utils.isUnd(oData.Namespace))
{
FolderStore.namespace = oData.Namespace;
}
AppStore.threadsAllowed(
!!Settings.settingsGet('UseImapThread') &&
oData.IsThreadsSupported && true);
FolderStore.folderList.optimized(!!oData.Optimized);
var bUpdate = false;
if (oData['SystemFolders'] && '' === '' +
Settings.settingsGet('SentFolder') +
Settings.settingsGet('DraftFolder') +
Settings.settingsGet('SpamFolder') +
Settings.settingsGet('TrashFolder') +
Settings.settingsGet('ArchiveFolder') +
Settings.settingsGet('NullFolder'))
{
// TODO Magic Numbers
Settings.settingsSet('SentFolder', oData['SystemFolders'][2] || null);
Settings.settingsSet('DraftFolder', oData['SystemFolders'][3] || null);
Settings.settingsSet('SpamFolder', oData['SystemFolders'][4] || null);
Settings.settingsSet('TrashFolder', oData['SystemFolders'][5] || null);
Settings.settingsSet('ArchiveFolder', oData['SystemFolders'][12] || null);
bUpdate = true;
}
FolderStore.sentFolder(this.normalizeFolder(Settings.settingsGet('SentFolder')));
FolderStore.draftFolder(this.normalizeFolder(Settings.settingsGet('DraftFolder')));
FolderStore.spamFolder(this.normalizeFolder(Settings.settingsGet('SpamFolder')));
FolderStore.trashFolder(this.normalizeFolder(Settings.settingsGet('TrashFolder')));
FolderStore.archiveFolder(this.normalizeFolder(Settings.settingsGet('ArchiveFolder')));
if (bUpdate)
{
require('Remote/User/Ajax').saveSystemFolders(Utils.emptyFunction, {
'SentFolder': FolderStore.sentFolder(),
'DraftFolder': FolderStore.draftFolder(),
'SpamFolder': FolderStore.spamFolder(),
'TrashFolder': FolderStore.trashFolder(),
'ArchiveFolder': FolderStore.archiveFolder(),
'NullFolder': 'NullFolder'
});
}
Local.set(Enums.ClientSideKeyName.FoldersLashHash, oData.FoldersHash);
}
};
module.exports = new PromisesUserPopulator();
}());

311
dev/Remote/AbstractAjax.js Normal file
View file

@ -0,0 +1,311 @@
(function () {
'use strict';
var
window = require('window'),
_ = require('_'),
$ = require('$'),
Consts = require('Common/Consts'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Plugins = require('Common/Plugins'),
Links = require('Common/Links'),
Settings = require('Storage/Settings')
;
/**
* @constructor
*/
function AbstractAjaxRemote()
{
this.oRequests = {};
}
AbstractAjaxRemote.prototype.oRequests = {};
/**
* @param {?Function} fCallback
* @param {string} sRequestAction
* @param {string} sType
* @param {?AjaxJsonDefaultResponse} oData
* @param {boolean} bCached
* @param {*=} oRequestParameters
*/
AbstractAjaxRemote.prototype.defaultResponse = function (fCallback, sRequestAction, sType, oData, bCached, oRequestParameters)
{
var
fCall = function () {
if (Enums.StorageResultType.Success !== sType && Globals.bUnload)
{
sType = Enums.StorageResultType.Unload;
}
if (Enums.StorageResultType.Success === sType && oData && !oData.Result)
{
if (oData && -1 < Utils.inArray(oData.ErrorCode, [
Enums.Notification.AuthError, Enums.Notification.AccessError,
Enums.Notification.ConnectionError, Enums.Notification.DomainNotAllowed, Enums.Notification.AccountNotAllowed,
Enums.Notification.MailServerError, Enums.Notification.UnknownNotification, Enums.Notification.UnknownError
]))
{
Globals.iAjaxErrorCount++;
}
if (oData && Enums.Notification.InvalidToken === oData.ErrorCode)
{
Globals.iTokenErrorCount++;
}
if (Consts.Values.TokenErrorLimit < Globals.iTokenErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.loginAndLogoutReload)
{
Globals.__APP__.loginAndLogoutReload(false, true);
}
}
if (oData.ClearAuth || oData.Logout || Consts.Values.AjaxErrorLimit < Globals.iAjaxErrorCount)
{
if (Globals.__APP__ && Globals.__APP__.clearClientSideToken)
{
Globals.__APP__.clearClientSideToken();
if (!oData.ClearAuth && Globals.__APP__.loginAndLogoutReload)
{
Globals.__APP__.loginAndLogoutReload(false, true);
}
}
}
}
else if (Enums.StorageResultType.Success === sType && oData && oData.Result)
{
Globals.iAjaxErrorCount = 0;
Globals.iTokenErrorCount = 0;
}
if (fCallback)
{
Plugins.runHook('ajax-default-response', [sRequestAction, Enums.StorageResultType.Success === sType ? oData : null, sType, bCached, oRequestParameters]);
fCallback(
sType,
Enums.StorageResultType.Success === sType ? oData : null,
bCached,
sRequestAction,
oRequestParameters
);
}
}
;
switch (sType)
{
case 'success':
sType = Enums.StorageResultType.Success;
break;
case 'abort':
sType = Enums.StorageResultType.Abort;
break;
default:
sType = Enums.StorageResultType.Error;
break;
}
if (Enums.StorageResultType.Error === sType)
{
_.delay(fCall, 300);
}
else
{
fCall();
}
};
/**
* @param {?Function} fResultCallback
* @param {Object} oParameters
* @param {?number=} iTimeOut = 20000
* @param {string=} sGetAdd = ''
* @param {Array=} aAbortActions = []
* @return {jQuery.jqXHR}
*/
AbstractAjaxRemote.prototype.ajaxRequest = function (fResultCallback, oParameters, iTimeOut, sGetAdd, aAbortActions)
{
var
self = this,
bPost = '' === sGetAdd,
oHeaders = {},
iStart = (new window.Date()).getTime(),
oDefAjax = null,
sAction = ''
;
oParameters = oParameters || {};
iTimeOut = Utils.isNormal(iTimeOut) ? iTimeOut : 20000;
sGetAdd = Utils.isUnd(sGetAdd) ? '' : Utils.pString(sGetAdd);
aAbortActions = Utils.isArray(aAbortActions) ? aAbortActions : [];
sAction = oParameters.Action || '';
if (sAction && 0 < aAbortActions.length)
{
_.each(aAbortActions, function (sActionToAbort) {
if (self.oRequests[sActionToAbort])
{
self.oRequests[sActionToAbort].__aborted = true;
if (self.oRequests[sActionToAbort].abort)
{
self.oRequests[sActionToAbort].abort();
}
self.oRequests[sActionToAbort] = null;
}
});
}
if (bPost)
{
oParameters['XToken'] = Settings.settingsGet('Token');
}
oDefAjax = $.ajax({
'type': bPost ? 'POST' : 'GET',
'url': Links.ajax(sGetAdd),
'async': true,
'dataType': 'json',
'data': bPost ? oParameters : {},
'headers': oHeaders,
'timeout': iTimeOut,
'global': true
});
oDefAjax.always(function (oData, sType) {
var bCached = false;
if (oData && oData['Time'])
{
bCached = Utils.pInt(oData['Time']) > (new window.Date()).getTime() - iStart;
}
if (sAction && self.oRequests[sAction])
{
if (self.oRequests[sAction].__aborted)
{
sType = 'abort';
}
self.oRequests[sAction] = null;
}
self.defaultResponse(fResultCallback, sAction, sType, oData, bCached, oParameters);
});
if (sAction && 0 < aAbortActions.length && -1 < Utils.inArray(sAction, aAbortActions))
{
if (this.oRequests[sAction])
{
this.oRequests[sAction].__aborted = true;
if (this.oRequests[sAction].abort)
{
this.oRequests[sAction].abort();
}
this.oRequests[sAction] = null;
}
this.oRequests[sAction] = oDefAjax;
}
return oDefAjax;
};
/**
* @param {?Function} fCallback
* @param {string} sAction
* @param {Object=} oParameters
* @param {?number=} iTimeout
* @param {string=} sGetAdd = ''
* @param {Array=} aAbortActions = []
*/
AbstractAjaxRemote.prototype.defaultRequest = function (fCallback, sAction, oParameters, iTimeout, sGetAdd, aAbortActions)
{
oParameters = oParameters || {};
oParameters.Action = sAction;
sGetAdd = Utils.pString(sGetAdd);
Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
return this.ajaxRequest(fCallback, oParameters,
Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
};
/**
* @param {?Function} fCallback
*/
AbstractAjaxRemote.prototype.noop = function (fCallback)
{
this.defaultRequest(fCallback, 'Noop');
};
/**
* @param {?Function} fCallback
* @param {string} sMessage
* @param {string} sFileName
* @param {number} iLineNo
* @param {string} sLocation
* @param {string} sHtmlCapa
* @param {number} iTime
*/
AbstractAjaxRemote.prototype.jsError = function (fCallback, sMessage, sFileName, iLineNo, sLocation, sHtmlCapa, iTime)
{
this.defaultRequest(fCallback, 'JsError', {
'Message': sMessage,
'FileName': sFileName,
'LineNo': iLineNo,
'Location': sLocation,
'HtmlCapa': sHtmlCapa,
'TimeOnPage': iTime
});
};
/**
* @param {?Function} fCallback
* @param {string} sType
* @param {Array=} mData = null
* @param {boolean=} bIsError = false
*/
AbstractAjaxRemote.prototype.jsInfo = function (fCallback, sType, mData, bIsError)
{
this.defaultRequest(fCallback, 'JsInfo', {
'Type': sType,
'Data': mData,
'IsError': (Utils.isUnd(bIsError) ? false : !!bIsError) ? '1' : '0'
});
};
/**
* @param {?Function} fCallback
*/
AbstractAjaxRemote.prototype.getPublicKey = function (fCallback)
{
this.defaultRequest(fCallback, 'GetPublicKey');
};
/**
* @param {?Function} fCallback
* @param {string} sVersion
*/
AbstractAjaxRemote.prototype.jsVersion = function (fCallback, sVersion)
{
this.defaultRequest(fCallback, 'Version', {
'Version': sVersion
});
};
module.exports = AbstractAjaxRemote;
}());

View file

@ -1,4 +1,3 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function () {
@ -7,21 +6,21 @@
var
_ = require('_'),
AbstractRemoteStorage = require('Storage/AbstractRemote')
AbstractAjaxRemote = require('Remote/AbstractAjax')
;
/**
* @constructor
* @extends AbstractRemoteStorage
* @extends AbstractAjaxRemote
*/
function RemoteAdminStorage()
{
AbstractRemoteStorage.call(this);
AbstractAjaxRemote.call(this);
this.oRequests = {};
}
_.extend(RemoteAdminStorage.prototype, AbstractRemoteStorage.prototype);
_.extend(RemoteAdminStorage.prototype, AbstractAjaxRemote.prototype);
/**
* @param {?Function} fCallback
@ -210,38 +209,57 @@
};
RemoteAdminStorage.prototype.createOrUpdateDomain = function (fCallback,
bCreate, sName, sIncHost, iIncPort, sIncSecure, bIncShortLogin,
sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, sWhiteList)
bCreate, sName,
sIncHost, iIncPort, sIncSecure, bIncShortLogin,
bUseSieve, sSieveAllowRaw, sSieveHost, iSievePort, sSieveSecure,
sOutHost, iOutPort, sOutSecure, bOutShortLogin, bOutAuth, bOutPhpMail,
sWhiteList)
{
this.defaultRequest(fCallback, 'AdminDomainSave', {
'Create': bCreate ? '1' : '0',
'Name': sName,
'IncHost': sIncHost,
'IncPort': iIncPort,
'IncSecure': sIncSecure,
'IncShortLogin': bIncShortLogin ? '1' : '0',
'UseSieve': bUseSieve ? '1' : '0',
'SieveAllowRaw': sSieveAllowRaw ? '1' : '0',
'SieveHost': sSieveHost,
'SievePort': iSievePort,
'SieveSecure': sSieveSecure,
'OutHost': sOutHost,
'OutPort': iOutPort,
'OutSecure': sOutSecure,
'OutShortLogin': bOutShortLogin ? '1' : '0',
'OutAuth': bOutAuth ? '1' : '0',
'OutUsePhpMail': bOutPhpMail ? '1' : '0',
'WhiteList': sWhiteList
});
};
RemoteAdminStorage.prototype.testConnectionForDomain = function (fCallback, sName,
sIncHost, iIncPort, sIncSecure,
sOutHost, iOutPort, sOutSecure, bOutAuth)
bUseSieve, sSieveHost, iSievePort, sSieveSecure,
sOutHost, iOutPort, sOutSecure, bOutAuth, bOutPhpMail)
{
this.defaultRequest(fCallback, 'AdminDomainTest', {
'Name': sName,
'IncHost': sIncHost,
'IncPort': iIncPort,
'IncSecure': sIncSecure,
'UseSieve': bUseSieve ? '1' : '0',
'SieveHost': sSieveHost,
'SievePort': iSievePort,
'SieveSecure': sSieveSecure,
'OutHost': sOutHost,
'OutPort': iOutPort,
'OutSecure': sOutSecure,
'OutAuth': bOutAuth ? '1' : '0'
'OutAuth': bOutAuth ? '1' : '0',
'OutUsePhpMail': bOutPhpMail ? '1' : '0'
});
};

View file

@ -1,4 +1,3 @@
/* RainLoop Webmail (c) RainLoop Team | Licensed under CC BY-NC-SA 3.0 */
(function () {
@ -11,30 +10,34 @@
Consts = require('Common/Consts'),
Base64 = require('Common/Base64'),
Settings = require('Storage/Settings'),
Cache = require('Storage/App/Cache'),
Data = require('Storage/App/Data'),
Cache = require('Common/Cache'),
Links = require('Common/Links'),
AbstractRemoteStorage = require('Storage/AbstractRemote')
Settings = require('Storage/Settings'),
AppStore = require('Stores/User/App'),
SettingsStore = require('Stores/User/Settings'),
AbstractAjaxRemote = require('Remote/AbstractAjax')
;
/**
* @constructor
* @extends AbstractRemoteStorage
*/
function RemoteAppStorage()
function RemoteUserAjax()
{
AbstractRemoteStorage.call(this);
AbstractAjaxRemote.call(this);
this.oRequests = {};
}
_.extend(RemoteAppStorage.prototype, AbstractRemoteStorage.prototype);
_.extend(RemoteUserAjax.prototype, AbstractAjaxRemote.prototype);
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.folders = function (fCallback)
RemoteUserAjax.prototype.folders = function (fCallback)
{
this.defaultRequest(fCallback, 'Folders', {
'SentFolder': Settings.settingsGet('SentFolder'),
@ -55,7 +58,7 @@
* @param {string=} sAdditionalCode
* @param {boolean=} bAdditionalCodeSignMe
*/
RemoteAppStorage.prototype.login = function (fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe)
RemoteUserAjax.prototype.login = function (fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe)
{
this.defaultRequest(fCallback, 'Login', {
'Email': sEmail,
@ -71,7 +74,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.getTwoFactor = function (fCallback)
RemoteUserAjax.prototype.getTwoFactor = function (fCallback)
{
this.defaultRequest(fCallback, 'GetTwoFactorInfo');
};
@ -79,7 +82,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.createTwoFactor = function (fCallback)
RemoteUserAjax.prototype.createTwoFactor = function (fCallback)
{
this.defaultRequest(fCallback, 'CreateTwoFactorSecret');
};
@ -87,7 +90,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.clearTwoFactor = function (fCallback)
RemoteUserAjax.prototype.clearTwoFactor = function (fCallback)
{
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
};
@ -95,7 +98,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.showTwoFactorSecret = function (fCallback)
RemoteUserAjax.prototype.showTwoFactorSecret = function (fCallback)
{
this.defaultRequest(fCallback, 'ShowTwoFactorSecret');
};
@ -104,7 +107,7 @@
* @param {?Function} fCallback
* @param {string} sCode
*/
RemoteAppStorage.prototype.testTwoFactor = function (fCallback, sCode)
RemoteUserAjax.prototype.testTwoFactor = function (fCallback, sCode)
{
this.defaultRequest(fCallback, 'TestTwoFactorInfo', {
'Code': sCode
@ -115,7 +118,7 @@
* @param {?Function} fCallback
* @param {boolean} bEnable
*/
RemoteAppStorage.prototype.enableTwoFactor = function (fCallback, bEnable)
RemoteUserAjax.prototype.enableTwoFactor = function (fCallback, bEnable)
{
this.defaultRequest(fCallback, 'EnableTwoFactor', {
'Enable': bEnable ? '1' : '0'
@ -125,7 +128,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.clearTwoFactorInfo = function (fCallback)
RemoteUserAjax.prototype.clearTwoFactorInfo = function (fCallback)
{
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
};
@ -133,7 +136,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.contactsSync = function (fCallback)
RemoteUserAjax.prototype.contactsSync = function (fCallback)
{
this.defaultRequest(fCallback, 'ContactsSync', null, Consts.Defaults.ContactsSyncAjaxTimeout);
};
@ -145,7 +148,7 @@
* @param {string} sUser
* @param {string} sPassword
*/
RemoteAppStorage.prototype.saveContactsSyncData = function (fCallback, bEnable, sUrl, sUser, sPassword)
RemoteUserAjax.prototype.saveContactsSyncData = function (fCallback, bEnable, sUrl, sUser, sPassword)
{
this.defaultRequest(fCallback, 'SaveContactsSyncData', {
'Enable': bEnable ? '1' : '0',
@ -158,15 +161,17 @@
/**
* @param {?Function} fCallback
* @param {string} sEmail
* @param {string} sLogin
* @param {string} sPassword
* @param {boolean=} bNew
*/
RemoteAppStorage.prototype.accountAdd = function (fCallback, sEmail, sLogin, sPassword)
RemoteUserAjax.prototype.accountSetup = function (fCallback, sEmail, sPassword, bNew)
{
this.defaultRequest(fCallback, 'AccountAdd', {
bNew = Utils.isUnd(bNew) ? true : !!bNew;
this.defaultRequest(fCallback, 'AccountSetup', {
'Email': sEmail,
'Login': sLogin,
'Password': sPassword
'Password': sPassword,
'New': bNew ? '1' : '0'
});
};
@ -174,13 +179,26 @@
* @param {?Function} fCallback
* @param {string} sEmailToDelete
*/
RemoteAppStorage.prototype.accountDelete = function (fCallback, sEmailToDelete)
RemoteUserAjax.prototype.accountDelete = function (fCallback, sEmailToDelete)
{
this.defaultRequest(fCallback, 'AccountDelete', {
'EmailToDelete': sEmailToDelete
});
};
/**
* @param {?Function} fCallback
* @param {Array} aAccounts
* @param {Array} aIdentities
*/
RemoteUserAjax.prototype.accountsAndIdentitiesSortOrder = function (fCallback, aAccounts, aIdentities)
{
this.defaultRequest(fCallback, 'AccountsAndIdentitiesSortOrder', {
'Accounts': aAccounts,
'Identities': aIdentities
});
};
/**
* @param {?Function} fCallback
* @param {string} sId
@ -188,15 +206,20 @@
* @param {string} sName
* @param {string} sReplyTo
* @param {string} sBcc
* @param {string} sSignature
* @param {boolean} bSignatureInsertBefore
*/
RemoteAppStorage.prototype.identityUpdate = function (fCallback, sId, sEmail, sName, sReplyTo, sBcc)
RemoteUserAjax.prototype.identityUpdate = function (fCallback, sId, sEmail, sName, sReplyTo, sBcc,
sSignature, bSignatureInsertBefore)
{
this.defaultRequest(fCallback, 'IdentityUpdate', {
'Id': sId,
'Email': sEmail,
'Name': sName,
'ReplyTo': sReplyTo,
'Bcc': sBcc
'Bcc': sBcc,
'Signature': sSignature,
'SignatureInsertBefore': bSignatureInsertBefore ? '1' : '0'
});
};
@ -204,7 +227,7 @@
* @param {?Function} fCallback
* @param {string} sIdToDelete
*/
RemoteAppStorage.prototype.identityDelete = function (fCallback, sIdToDelete)
RemoteUserAjax.prototype.identityDelete = function (fCallback, sIdToDelete)
{
this.defaultRequest(fCallback, 'IdentityDelete', {
'IdToDelete': sIdToDelete
@ -214,11 +237,95 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.accountsAndIdentities = function (fCallback)
RemoteUserAjax.prototype.accountsAndIdentities = function (fCallback)
{
this.defaultRequest(fCallback, 'AccountsAndIdentities');
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.accountsCounts = function (fCallback)
{
this.defaultRequest(fCallback, 'AccountsCounts');
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.filtersSave = function (fCallback,
aFilters, sRaw, bRawIsActive)
{
this.defaultRequest(fCallback, 'FiltersSave', {
'Raw': sRaw,
'RawIsActive': bRawIsActive ? '1' : '0',
'Filters': _.map(aFilters, function (oItem) {
return oItem.toJson();
})
});
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.filtersGet = function (fCallback)
{
this.defaultRequest(fCallback, 'Filters', {});
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.templates = function (fCallback)
{
this.defaultRequest(fCallback, 'Templates', {});
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.templateGetById = function (fCallback, sID)
{
this.defaultRequest(fCallback, 'TemplateGetByID', {
'ID': sID
});
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.templateDelete = function (fCallback, sID)
{
this.defaultRequest(fCallback, 'TemplateDelete', {
'IdToDelete': sID
});
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.templateSetup = function (fCallback, sID, sName, sBody)
{
this.defaultRequest(fCallback, 'TemplateSetup', {
'ID': sID,
'Name': sName,
'Body': sBody
});
};
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {Array} aUids
*/
RemoteUserAjax.prototype.messageListSimple = function (fCallback, sFolderFullNameRaw, aUids)
{
return this.defaultRequest(fCallback, 'MessageListSimple', {
'Folder': Utils.pString(sFolderFullNameRaw),
'Uids': aUids
}, Consts.Defaults.DefaultAjaxTimeout, '', ['MessageListSimple']);
};
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
@ -227,7 +334,7 @@
* @param {string=} sSearch = ''
* @param {boolean=} bSilent = false
*/
RemoteAppStorage.prototype.messageList = function (fCallback, sFolderFullNameRaw, iOffset, iLimit, sSearch, bSilent)
RemoteUserAjax.prototype.messageList = function (fCallback, sFolderFullNameRaw, iOffset, iLimit, sSearch, bSilent)
{
sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
@ -242,30 +349,29 @@
if ('' !== sFolderHash && ('' === sSearch || -1 === sSearch.indexOf('is:')))
{
this.defaultRequest(fCallback, 'MessageList', {},
return this.defaultRequest(fCallback, 'MessageList', {},
'' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout,
'MessageList/' + Base64.urlsafe_encode([
'MessageList/' + Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
sFolderFullNameRaw,
iOffset,
iLimit,
sSearch,
Data.projectHash(),
AppStore.projectHash(),
sFolderHash,
'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
Data.threading() && Data.useThreads() ? '1' : '0',
Data.threading() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0',
''
].join(String.fromCharCode(0))), bSilent ? [] : ['MessageList']);
}
else
{
this.defaultRequest(fCallback, 'MessageList', {
return this.defaultRequest(fCallback, 'MessageList', {
'Folder': sFolderFullNameRaw,
'Offset': iOffset,
'Limit': iLimit,
'Search': sSearch,
'UidNext': 'INBOX' === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
'UseThreads': Data.threading() && Data.useThreads() ? '1' : '0',
'ExpandedThreadUid': Data.threading() && sFolderFullNameRaw === Data.messageListThreadFolder() ? Data.messageListThreadUids().join(',') : ''
'UidNext': Cache.getFolderInboxName() === sFolderFullNameRaw ? Cache.getFolderUidNext(sFolderFullNameRaw) : '',
'UseThreads': AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
}, '' === sSearch ? Consts.Defaults.DefaultAjaxTimeout : Consts.Defaults.SearchAjaxTimeout, '', bSilent ? [] : ['MessageList']);
}
};
@ -274,7 +380,7 @@
* @param {?Function} fCallback
* @param {Array} aDownloads
*/
RemoteAppStorage.prototype.messageUploadAttachments = function (fCallback, aDownloads)
RemoteUserAjax.prototype.messageUploadAttachments = function (fCallback, aDownloads)
{
this.defaultRequest(fCallback, 'MessageUploadAttachments', {
'Attachments': aDownloads
@ -287,7 +393,7 @@
* @param {number} iUid
* @return {boolean}
*/
RemoteAppStorage.prototype.message = function (fCallback, sFolderFullNameRaw, iUid)
RemoteUserAjax.prototype.message = function (fCallback, sFolderFullNameRaw, iUid)
{
sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
iUid = Utils.pInt(iUid);
@ -295,11 +401,11 @@
if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 < iUid)
{
this.defaultRequest(fCallback, 'Message', {}, null,
'Message/' + Base64.urlsafe_encode([
'Message/' + Links.subQueryPrefix() + '/' + Base64.urlsafe_encode([
sFolderFullNameRaw,
iUid,
Data.projectHash(),
Data.threading() && Data.useThreads() ? '1' : '0'
AppStore.projectHash(),
AppStore.threadsAllowed() && SettingsStore.useThreads() ? '1' : '0'
].join(String.fromCharCode(0))), ['Message']);
return true;
@ -308,11 +414,40 @@
return false;
};
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {number} iUid
* @return {boolean}
*/
RemoteUserAjax.prototype.messageThreadsFromCache = function (fCallback, sFolderFullNameRaw, iUid)
{
sFolderFullNameRaw = Utils.pString(sFolderFullNameRaw);
iUid = Utils.pInt(iUid);
if (Cache.getFolderFromCacheList(sFolderFullNameRaw) && 0 < iUid)
{
var sFolderHash = Cache.getFolderHash(sFolderFullNameRaw);
if (sFolderHash)
{
this.defaultRequest(fCallback, 'MessageThreadsFromCache', {
'Folder': sFolderFullNameRaw,
'FolderHash': sFolderHash,
'Uid': iUid
});
return true;
}
}
return false;
};
/**
* @param {?Function} fCallback
* @param {Array} aExternals
*/
RemoteAppStorage.prototype.composeUploadExternals = function (fCallback, aExternals)
RemoteUserAjax.prototype.composeUploadExternals = function (fCallback, aExternals)
{
this.defaultRequest(fCallback, 'ComposeUploadExternals', {
'Externals': aExternals
@ -324,7 +459,7 @@
* @param {string} sUrl
* @param {string} sAccessToken
*/
RemoteAppStorage.prototype.composeUploadDrive = function (fCallback, sUrl, sAccessToken)
RemoteUserAjax.prototype.composeUploadDrive = function (fCallback, sUrl, sAccessToken)
{
this.defaultRequest(fCallback, 'ComposeUploadDrive', {
'AccessToken': sAccessToken,
@ -337,7 +472,7 @@
* @param {string} sFolder
* @param {Array=} aList = []
*/
RemoteAppStorage.prototype.folderInformation = function (fCallback, sFolder, aList)
RemoteUserAjax.prototype.folderInformation = function (fCallback, sFolder, aList)
{
var
bRequest = true,
@ -375,12 +510,12 @@
this.defaultRequest(fCallback, 'FolderInformation', {
'Folder': sFolder,
'FlagsUids': Utils.isArray(aUids) ? aUids.join(',') : '',
'UidNext': 'INBOX' === sFolder ? Cache.getFolderUidNext(sFolder) : ''
'UidNext': Cache.getFolderInboxName() === sFolder ? Cache.getFolderUidNext(sFolder) : ''
});
}
else if (Data.useThreads())
else if (SettingsStore.useThreads())
{
require('App/App').reloadFlagsCurrentMessageListAndMessageFromCache();
require('App/User').reloadFlagsCurrentMessageListAndMessageFromCache();
}
};
@ -388,7 +523,7 @@
* @param {?Function} fCallback
* @param {Array} aFolders
*/
RemoteAppStorage.prototype.folderInformationMultiply = function (fCallback, aFolders)
RemoteUserAjax.prototype.folderInformationMultiply = function (fCallback, aFolders)
{
this.defaultRequest(fCallback, 'FolderInformationMultiply', {
'Folders': aFolders
@ -398,7 +533,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.logout = function (fCallback)
RemoteUserAjax.prototype.logout = function (fCallback)
{
this.defaultRequest(fCallback, 'Logout');
};
@ -409,7 +544,7 @@
* @param {Array} aUids
* @param {boolean} bSetFlagged
*/
RemoteAppStorage.prototype.messageSetFlagged = function (fCallback, sFolderFullNameRaw, aUids, bSetFlagged)
RemoteUserAjax.prototype.messageSetFlagged = function (fCallback, sFolderFullNameRaw, aUids, bSetFlagged)
{
this.defaultRequest(fCallback, 'MessageSetFlagged', {
'Folder': sFolderFullNameRaw,
@ -424,7 +559,7 @@
* @param {Array} aUids
* @param {boolean} bSetSeen
*/
RemoteAppStorage.prototype.messageSetSeen = function (fCallback, sFolderFullNameRaw, aUids, bSetSeen)
RemoteUserAjax.prototype.messageSetSeen = function (fCallback, sFolderFullNameRaw, aUids, bSetSeen)
{
this.defaultRequest(fCallback, 'MessageSetSeen', {
'Folder': sFolderFullNameRaw,
@ -438,7 +573,7 @@
* @param {string} sFolderFullNameRaw
* @param {boolean} bSetSeen
*/
RemoteAppStorage.prototype.messageSetSeenToAll = function (fCallback, sFolderFullNameRaw, bSetSeen)
RemoteUserAjax.prototype.messageSetSeenToAll = function (fCallback, sFolderFullNameRaw, bSetSeen)
{
this.defaultRequest(fCallback, 'MessageSetSeenToAll', {
'Folder': sFolderFullNameRaw,
@ -448,10 +583,10 @@
/**
* @param {?Function} fCallback
* @param {string} sIdentityID
* @param {string} sMessageFolder
* @param {string} sMessageUid
* @param {string} sDraftFolder
* @param {string} sFrom
* @param {string} sTo
* @param {string} sCc
* @param {string} sBcc
@ -462,24 +597,27 @@
* @param {(Array|null)} aDraftInfo
* @param {string} sInReplyTo
* @param {string} sReferences
* @param {boolean} bMarkAsImportant
*/
RemoteAppStorage.prototype.saveMessage = function (fCallback, sMessageFolder, sMessageUid, sDraftFolder,
sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences)
RemoteUserAjax.prototype.saveMessage = function (fCallback, sIdentityID, sMessageFolder, sMessageUid, sDraftFolder,
sTo, sCc, sBcc, sReplyTo, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences, bMarkAsImportant)
{
this.defaultRequest(fCallback, 'SaveMessage', {
'IdentityID': sIdentityID,
'MessageFolder': sMessageFolder,
'MessageUid': sMessageUid,
'DraftFolder': sDraftFolder,
'From': sFrom,
'To': sTo,
'Cc': sCc,
'Bcc': sBcc,
'ReplyTo': sReplyTo,
'Subject': sSubject,
'TextIsHtml': bTextIsHtml ? '1' : '0',
'Text': sText,
'DraftInfo': aDraftInfo,
'InReplyTo': sInReplyTo,
'References': sReferences,
'MarkAsImportant': bMarkAsImportant ? '1' : '0',
'Attachments': aAttachments
}, Consts.Defaults.SaveMessageAjaxTimeout);
};
@ -493,7 +631,7 @@
* @param {string} sSubject
* @param {string} sText
*/
RemoteAppStorage.prototype.sendReadReceiptMessage = function (fCallback, sMessageFolder, sMessageUid, sReadReceipt, sSubject, sText)
RemoteUserAjax.prototype.sendReadReceiptMessage = function (fCallback, sMessageFolder, sMessageUid, sReadReceipt, sSubject, sText)
{
this.defaultRequest(fCallback, 'SendReadReceiptMessage', {
'MessageFolder': sMessageFolder,
@ -506,13 +644,14 @@
/**
* @param {?Function} fCallback
* @param {string} sIdentityID
* @param {string} sMessageFolder
* @param {string} sMessageUid
* @param {string} sSentFolder
* @param {string} sFrom
* @param {string} sTo
* @param {string} sCc
* @param {string} sBcc
* @param {string} sReplyTo
* @param {string} sSubject
* @param {boolean} bTextIsHtml
* @param {string} sText
@ -520,26 +659,32 @@
* @param {(Array|null)} aDraftInfo
* @param {string} sInReplyTo
* @param {string} sReferences
* @param {boolean} bRequestDsn
* @param {boolean} bRequestReadReceipt
* @param {boolean} bMarkAsImportant
*/
RemoteAppStorage.prototype.sendMessage = function (fCallback, sMessageFolder, sMessageUid, sSentFolder,
sFrom, sTo, sCc, sBcc, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences, bRequestReadReceipt)
RemoteUserAjax.prototype.sendMessage = function (fCallback, sIdentityID, sMessageFolder, sMessageUid, sSentFolder,
sTo, sCc, sBcc, sReplyTo, sSubject, bTextIsHtml, sText, aAttachments, aDraftInfo, sInReplyTo, sReferences,
bRequestDsn, bRequestReadReceipt, bMarkAsImportant)
{
this.defaultRequest(fCallback, 'SendMessage', {
'IdentityID': sIdentityID,
'MessageFolder': sMessageFolder,
'MessageUid': sMessageUid,
'SentFolder': sSentFolder,
'From': sFrom,
'To': sTo,
'Cc': sCc,
'Bcc': sBcc,
'ReplyTo': sReplyTo,
'Subject': sSubject,
'TextIsHtml': bTextIsHtml ? '1' : '0',
'Text': sText,
'DraftInfo': aDraftInfo,
'InReplyTo': sInReplyTo,
'References': sReferences,
'Dsn': bRequestDsn ? '1' : '0',
'ReadReceiptRequest': bRequestReadReceipt ? '1' : '0',
'MarkAsImportant': bMarkAsImportant ? '1' : '0',
'Attachments': aAttachments
}, Consts.Defaults.SendMessageAjaxTimeout);
};
@ -548,7 +693,7 @@
* @param {?Function} fCallback
* @param {Object} oData
*/
RemoteAppStorage.prototype.saveSystemFolders = function (fCallback, oData)
RemoteUserAjax.prototype.saveSystemFolders = function (fCallback, oData)
{
this.defaultRequest(fCallback, 'SystemFoldersUpdate', oData);
};
@ -557,7 +702,7 @@
* @param {?Function} fCallback
* @param {Object} oData
*/
RemoteAppStorage.prototype.saveSettings = function (fCallback, oData)
RemoteUserAjax.prototype.saveSettings = function (fCallback, oData)
{
this.defaultRequest(fCallback, 'SettingsUpdate', oData);
};
@ -567,7 +712,7 @@
* @param {string} sPrevPassword
* @param {string} sNewPassword
*/
RemoteAppStorage.prototype.changePassword = function (fCallback, sPrevPassword, sNewPassword)
RemoteUserAjax.prototype.changePassword = function (fCallback, sPrevPassword, sNewPassword)
{
this.defaultRequest(fCallback, 'ChangePassword', {
'PrevPassword': sPrevPassword,
@ -575,48 +720,11 @@
});
};
/**
* @param {?Function} fCallback
* @param {string} sNewFolderName
* @param {string} sParentName
*/
RemoteAppStorage.prototype.folderCreate = function (fCallback, sNewFolderName, sParentName)
{
this.defaultRequest(fCallback, 'FolderCreate', {
'Folder': sNewFolderName,
'Parent': sParentName
}, null, '', ['Folders']);
};
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
*/
RemoteAppStorage.prototype.folderDelete = function (fCallback, sFolderFullNameRaw)
{
this.defaultRequest(fCallback, 'FolderDelete', {
'Folder': sFolderFullNameRaw
}, null, '', ['Folders']);
};
/**
* @param {?Function} fCallback
* @param {string} sPrevFolderFullNameRaw
* @param {string} sNewFolderName
*/
RemoteAppStorage.prototype.folderRename = function (fCallback, sPrevFolderFullNameRaw, sNewFolderName)
{
this.defaultRequest(fCallback, 'FolderRename', {
'Folder': sPrevFolderFullNameRaw,
'NewFolderName': sNewFolderName
}, null, '', ['Folders']);
};
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
*/
RemoteAppStorage.prototype.folderClear = function (fCallback, sFolderFullNameRaw)
RemoteUserAjax.prototype.folderClear = function (fCallback, sFolderFullNameRaw)
{
this.defaultRequest(fCallback, 'FolderClear', {
'Folder': sFolderFullNameRaw
@ -628,7 +736,7 @@
* @param {string} sFolderFullNameRaw
* @param {boolean} bSubscribe
*/
RemoteAppStorage.prototype.folderSetSubscribe = function (fCallback, sFolderFullNameRaw, bSubscribe)
RemoteUserAjax.prototype.folderSetSubscribe = function (fCallback, sFolderFullNameRaw, bSubscribe)
{
this.defaultRequest(fCallback, 'FolderSubscribe', {
'Folder': sFolderFullNameRaw,
@ -643,7 +751,7 @@
* @param {Array} aUids
* @param {string=} sLearning
*/
RemoteAppStorage.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids, sLearning)
RemoteUserAjax.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids, sLearning)
{
this.defaultRequest(fCallback, 'MessageMove', {
'FromFolder': sFolder,
@ -659,7 +767,7 @@
* @param {string} sToFolder
* @param {Array} aUids
*/
RemoteAppStorage.prototype.messagesCopy = function (fCallback, sFolder, sToFolder, aUids)
RemoteUserAjax.prototype.messagesCopy = function (fCallback, sFolder, sToFolder, aUids)
{
this.defaultRequest(fCallback, 'MessageCopy', {
'FromFolder': sFolder,
@ -673,7 +781,7 @@
* @param {string} sFolder
* @param {Array} aUids
*/
RemoteAppStorage.prototype.messagesDelete = function (fCallback, sFolder, aUids)
RemoteUserAjax.prototype.messagesDelete = function (fCallback, sFolder, aUids)
{
this.defaultRequest(fCallback, 'MessageDelete', {
'Folder': sFolder,
@ -684,7 +792,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.appDelayStart = function (fCallback)
RemoteUserAjax.prototype.appDelayStart = function (fCallback)
{
this.defaultRequest(fCallback, 'AppDelayStart');
};
@ -692,7 +800,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.quota = function (fCallback)
RemoteUserAjax.prototype.quota = function (fCallback)
{
this.defaultRequest(fCallback, 'Quota');
};
@ -703,7 +811,7 @@
* @param {number} iLimit
* @param {string} sSearch
*/
RemoteAppStorage.prototype.contacts = function (fCallback, iOffset, iLimit, sSearch)
RemoteUserAjax.prototype.contacts = function (fCallback, iOffset, iLimit, sSearch)
{
this.defaultRequest(fCallback, 'Contacts', {
'Offset': iOffset,
@ -714,13 +822,15 @@
/**
* @param {?Function} fCallback
* @param {string} sRequestUid
* @param {string} sUid
* @param {Array} aProperties
*/
RemoteAppStorage.prototype.contactSave = function (fCallback, sRequestUid, sUid, sTags, aProperties)
RemoteUserAjax.prototype.contactSave = function (fCallback, sRequestUid, sUid, aProperties)
{
this.defaultRequest(fCallback, 'ContactSave', {
'RequestUid': sRequestUid,
'Uid': Utils.trim(sUid),
'Tags': Utils.trim(sTags),
'Properties': aProperties
});
};
@ -729,7 +839,7 @@
* @param {?Function} fCallback
* @param {Array} aUids
*/
RemoteAppStorage.prototype.contactsDelete = function (fCallback, aUids)
RemoteUserAjax.prototype.contactsDelete = function (fCallback, aUids)
{
this.defaultRequest(fCallback, 'ContactsDelete', {
'Uids': aUids.join(',')
@ -741,7 +851,7 @@
* @param {string} sQuery
* @param {number} iPage
*/
RemoteAppStorage.prototype.suggestions = function (fCallback, sQuery, iPage)
RemoteUserAjax.prototype.suggestions = function (fCallback, sQuery, iPage)
{
this.defaultRequest(fCallback, 'Suggestions', {
'Query': sQuery,
@ -752,7 +862,15 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.facebookUser = function (fCallback)
RemoteUserAjax.prototype.clearUserBackground = function (fCallback)
{
this.defaultRequest(fCallback, 'ClearUserBackground');
};
/**
* @param {?Function} fCallback
*/
RemoteUserAjax.prototype.facebookUser = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialFacebookUserInformation');
};
@ -760,7 +878,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.facebookDisconnect = function (fCallback)
RemoteUserAjax.prototype.facebookDisconnect = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialFacebookDisconnect');
};
@ -768,7 +886,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.twitterUser = function (fCallback)
RemoteUserAjax.prototype.twitterUser = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialTwitterUserInformation');
};
@ -776,7 +894,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.twitterDisconnect = function (fCallback)
RemoteUserAjax.prototype.twitterDisconnect = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialTwitterDisconnect');
};
@ -784,7 +902,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.googleUser = function (fCallback)
RemoteUserAjax.prototype.googleUser = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialGoogleUserInformation');
};
@ -792,7 +910,7 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.googleDisconnect = function (fCallback)
RemoteUserAjax.prototype.googleDisconnect = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialGoogleDisconnect');
};
@ -800,11 +918,11 @@
/**
* @param {?Function} fCallback
*/
RemoteAppStorage.prototype.socialUsers = function (fCallback)
RemoteUserAjax.prototype.socialUsers = function (fCallback)
{
this.defaultRequest(fCallback, 'SocialUsers');
};
module.exports = new RemoteAppStorage();
module.exports = new RemoteUserAjax();
}());

View file

@ -10,7 +10,7 @@
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder'),
Links = require('Common/Links'),
kn = require('Knoin/Knoin'),
AbstractScreen = require('Knoin/AbstractScreen')
@ -103,7 +103,7 @@
RoutedSettingsViewModel.__vm = oSettingsScreen;
ko.applyBindingAccessorsToNode(oViewModelDom[0], {
'i18nInit': true,
'translatorInit': true,
'template': function () { return {'name': RoutedSettingsViewModel.__rlSettingsData.Template}; }
}, oSettingsScreen);
@ -133,7 +133,7 @@
{
self.oCurrentSubScreen.viewModelDom.show();
Utils.delegateRun(self.oCurrentSubScreen, 'onShow');
Utils.delegateRun(self.oCurrentSubScreen, 'onFocus', [], 200);
Utils.delegateRun(self.oCurrentSubScreen, 'onShowWithDelay', [], 200);
_.each(self.menu(), function (oItem) {
oItem.selected(oSettingsScreen && oSettingsScreen.__rlSettingsData && oItem.route === oSettingsScreen.__rlSettingsData.Route);
@ -149,7 +149,7 @@
}
else
{
kn.setHash(LinkBuilder.settings(), false, true);
kn.setHash(Links.settings(), false, true);
}
};

View file

@ -24,7 +24,7 @@
LoginAdminScreen.prototype.onShow = function ()
{
require('App/Admin').setTitle('');
require('App/Admin').setWindowTitle('');
};
module.exports = LoginAdminScreen;

View file

@ -8,6 +8,8 @@
kn = require('Knoin/Knoin'),
Plugins = require('Common/Plugins'),
AbstractSettings = require('Screen/AbstractSettings')
;
@ -31,37 +33,39 @@
SettingsAdminScreen.prototype.setupSettings = function (fCallback)
{
kn.addSettingsViewModel(require('Settings/Admin/General'),
'AdminSettingsGeneral', 'General', 'general', true);
'AdminSettingsGeneral', 'TABS_LABELS/LABEL_GENERAL_NAME', 'general', true);
kn.addSettingsViewModel(require('Settings/Admin/Login'),
'AdminSettingsLogin', 'Login', 'login');
'AdminSettingsLogin', 'TABS_LABELS/LABEL_LOGIN_NAME', 'login');
kn.addSettingsViewModel(require('Settings/Admin/Branding'),
'AdminSettingsBranding', 'Branding', 'branding');
'AdminSettingsBranding', 'TABS_LABELS/LABEL_BRANDING_NAME', 'branding');
kn.addSettingsViewModel(require('Settings/Admin/Contacts'),
'AdminSettingsContacts', 'Contacts', 'contacts');
'AdminSettingsContacts', 'TABS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
kn.addSettingsViewModel(require('Settings/Admin/Domains'),
'AdminSettingsDomains', 'Domains', 'domains');
'AdminSettingsDomains', 'TABS_LABELS/LABEL_DOMAINS_NAME', 'domains');
kn.addSettingsViewModel(require('Settings/Admin/Security'),
'AdminSettingsSecurity', 'Security', 'security');
'AdminSettingsSecurity', 'TABS_LABELS/LABEL_SECURITY_NAME', 'security');
kn.addSettingsViewModel(require('Settings/Admin/Social'),
'AdminSettingsSocial', 'Social', 'social');
'AdminSettingsSocial', 'TABS_LABELS/LABEL_INTEGRATION_NAME', 'integrations');
kn.addSettingsViewModel(require('Settings/Admin/Plugins'),
'AdminSettingsPlugins', 'Plugins', 'plugins');
'AdminSettingsPlugins', 'TABS_LABELS/LABEL_PLUGINS_NAME', 'plugins');
kn.addSettingsViewModel(require('Settings/Admin/Packages'),
'AdminSettingsPackages', 'Packages', 'packages');
'AdminSettingsPackages', 'TABS_LABELS/LABEL_PACKAGES_NAME', 'packages');
kn.addSettingsViewModel(require('Settings/Admin/Licensing'),
'AdminSettingsLicensing', 'Licensing', 'licensing');
'AdminSettingsLicensing', 'TABS_LABELS/LABEL_LICENSING_NAME', 'licensing');
kn.addSettingsViewModel(require('Settings/Admin/About'),
'AdminSettingsAbout', 'About', 'about');
'AdminSettingsAbout', 'TABS_LABELS/LABEL_ABOUT_NAME', 'about');
Plugins.runSettingsViewModelHooks(true);
if (fCallback)
{
@ -71,7 +75,7 @@
SettingsAdminScreen.prototype.onShow = function ()
{
require('App/Admin').setTitle('');
require('App/Admin').setWindowTitle('');
};
module.exports = SettingsAdminScreen;

View file

@ -1,32 +0,0 @@
(function () {
'use strict';
var
_ = require('_'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function AboutAppScreen()
{
AbstractScreen.call(this, 'about', [
require('View/App/About')
]);
}
_.extend(AboutAppScreen.prototype, AbstractScreen.prototype);
AboutAppScreen.prototype.onShow = function ()
{
require('App/App').setTitle('RainLoop');
};
module.exports = AboutAppScreen;
}());

View file

@ -1,32 +0,0 @@
(function () {
'use strict';
var
_ = require('_'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function LoginAppScreen()
{
AbstractScreen.call(this, 'login', [
require('View/App/Login')
]);
}
_.extend(LoginAppScreen.prototype, AbstractScreen.prototype);
LoginAppScreen.prototype.onShow = function ()
{
require('App/App').setTitle('');
};
module.exports = LoginAppScreen;
}());

View file

@ -1,196 +0,0 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Events = require('Common/Events'),
Settings = require('Storage/Settings'),
Data = require('Storage/App/Data'),
Cache = require('Storage/App/Cache'),
Remote = require('Storage/App/Remote'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function MailBoxAppScreen()
{
AbstractScreen.call(this, 'mailbox', [
require('View/App/MailBox/SystemDropDown'),
require('View/App/MailBox/FolderList'),
require('View/App/MailBox/MessageList'),
require('View/App/MailBox/MessageView')
]);
this.oLastRoute = {};
}
_.extend(MailBoxAppScreen.prototype, AbstractScreen.prototype);
/**
* @type {Object}
*/
MailBoxAppScreen.prototype.oLastRoute = {};
MailBoxAppScreen.prototype.setNewTitle = function ()
{
var
sEmail = Data.accountEmail(),
nFoldersInboxUnreadCount = Data.foldersInboxUnreadCount()
;
require('App/App').setTitle(('' === sEmail ? '' :
(0 < nFoldersInboxUnreadCount ? '(' + nFoldersInboxUnreadCount + ') ' : ' ') + sEmail + ' - ') + Utils.i18n('TITLES/MAILBOX'));
};
MailBoxAppScreen.prototype.onShow = function ()
{
this.setNewTitle();
Globals.keyScope(Enums.KeyState.MessageList);
};
/**
* @param {string} sFolderHash
* @param {number} iPage
* @param {string} sSearch
* @param {boolean=} bPreview = false
*/
MailBoxAppScreen.prototype.onRoute = function (sFolderHash, iPage, sSearch, bPreview)
{
if (Utils.isUnd(bPreview) ? false : !!bPreview)
{
if (Enums.Layout.NoPreview === Data.layout() && !Data.message())
{
require('App/App').historyBack();
}
}
else
{
var
sFolderFullNameRaw = Cache.getFolderFullNameRaw(sFolderHash),
oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw)
;
if (oFolder)
{
Data
.currentFolder(oFolder)
.messageListPage(iPage)
.messageListSearch(sSearch)
;
if (Enums.Layout.NoPreview === Data.layout() && Data.message())
{
Data.message(null);
}
require('App/App').reloadMessageList();
}
}
};
MailBoxAppScreen.prototype.onStart = function ()
{
var
fResizeFunction = function () {
Utils.windowResize();
}
;
if (Settings.capa(Enums.Capa.AdditionalAccounts) || Settings.capa(Enums.Capa.AdditionalIdentities))
{
require('App/App').accountsAndIdentities();
}
_.delay(function () {
if ('INBOX' !== Data.currentFolderFullNameRaw())
{
require('App/App').folderInformation('INBOX');
}
}, 1000);
_.delay(function () {
require('App/App').quota();
}, 5000);
_.delay(function () {
Remote.appDelayStart(Utils.emptyFunction);
}, 35000);
Globals.$html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === Data.layout());
Data.folderList.subscribe(fResizeFunction);
Data.messageList.subscribe(fResizeFunction);
Data.message.subscribe(fResizeFunction);
Data.layout.subscribe(function (nValue) {
Globals.$html.toggleClass('rl-no-preview-pane', Enums.Layout.NoPreview === nValue);
});
Events.sub('mailbox.inbox-unread-count', function (nCount) {
Data.foldersInboxUnreadCount(nCount);
});
Data.foldersInboxUnreadCount.subscribe(function () {
this.setNewTitle();
}, this);
};
/**
* @return {Array}
*/
MailBoxAppScreen.prototype.routes = function ()
{
var
fNormP = function () {
return ['Inbox', 1, '', true];
},
fNormS = function (oRequest, oVals) {
oVals[0] = Utils.pString(oVals[0]);
oVals[1] = Utils.pInt(oVals[1]);
oVals[1] = 0 >= oVals[1] ? 1 : oVals[1];
oVals[2] = Utils.pString(oVals[2]);
if ('' === oRequest)
{
oVals[0] = 'Inbox';
oVals[1] = 1;
}
return [decodeURI(oVals[0]), oVals[1], decodeURI(oVals[2]), false];
},
fNormD = function (oRequest, oVals) {
oVals[0] = Utils.pString(oVals[0]);
oVals[1] = Utils.pString(oVals[1]);
if ('' === oRequest)
{
oVals[0] = 'Inbox';
}
return [decodeURI(oVals[0]), 1, decodeURI(oVals[1]), false];
}
;
return [
[/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)\/(.+)\/?$/, {'normalize_': fNormS}],
[/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)$/, {'normalize_': fNormS}],
[/^([a-zA-Z0-9]+)\/(.+)\/?$/, {'normalize_': fNormD}],
[/^message-preview$/, {'normalize_': fNormP}],
[/^([^\/]*)$/, {'normalize_': fNormS}]
];
};
module.exports = MailBoxAppScreen;
}());

View file

@ -1,132 +0,0 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Globals = require('Common/Globals'),
Settings = require('Storage/Settings'),
kn = require('Knoin/Knoin'),
AbstractSettingsScreen = require('Screen/AbstractSettings')
;
/**
* @constructor
* @extends AbstractSettingsScreen
*/
function SettingsAppScreen()
{
AbstractSettingsScreen.call(this, [
require('View/App/Settings/SystemDropDown'),
require('View/App/Settings/Menu'),
require('View/App/Settings/Pane')
]);
Utils.initOnStartOrLangChange(function () {
this.sSettingsTitle = Utils.i18n('TITLES/SETTINGS');
}, this, function () {
this.setSettingsTitle();
});
}
_.extend(SettingsAppScreen.prototype, AbstractSettingsScreen.prototype);
/**
* @param {Function=} fCallback
*/
SettingsAppScreen.prototype.setupSettings = function (fCallback)
{
kn.addSettingsViewModel(require('Settings/App/General'),
'SettingsGeneral', 'SETTINGS_LABELS/LABEL_GENERAL_NAME', 'general', true);
if (Settings.settingsGet('ContactsIsAllowed'))
{
kn.addSettingsViewModel(require('Settings/App/Contacts'),
'SettingsContacts', 'SETTINGS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
}
if (Settings.capa(Enums.Capa.AdditionalAccounts))
{
kn.addSettingsViewModel(require('Settings/App/Accounts'),
'SettingsAccounts', 'SETTINGS_LABELS/LABEL_ACCOUNTS_NAME', 'accounts');
}
if (Settings.capa(Enums.Capa.AdditionalIdentities))
{
kn.addSettingsViewModel(require('Settings/App/Identities'),
'SettingsIdentities', 'SETTINGS_LABELS/LABEL_IDENTITIES_NAME', 'identities');
}
else
{
kn.addSettingsViewModel(require('Settings/App/Identity'),
'SettingsIdentity', 'SETTINGS_LABELS/LABEL_IDENTITY_NAME', 'identity');
}
if (Settings.capa(Enums.Capa.Filters))
{
kn.addSettingsViewModel(require('Settings/App/Filters'),
'SettingsFilters', 'SETTINGS_LABELS/LABEL_FILTERS_NAME', 'filters');
}
if (Settings.capa(Enums.Capa.TwoFactor))
{
kn.addSettingsViewModel(require('Settings/App/Security'),
'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
}
if (Settings.settingsGet('AllowGoogleSocial') ||
Settings.settingsGet('AllowFacebookSocial') ||
Settings.settingsGet('AllowTwitterSocial'))
{
kn.addSettingsViewModel(require('Settings/App/Social'),
'SettingsSocial', 'SETTINGS_LABELS/LABEL_SOCIAL_NAME', 'social');
}
if (Settings.settingsGet('ChangePasswordIsAllowed'))
{
kn.addSettingsViewModel(require('Settings/App/ChangePassword'),
'SettingsChangePassword', 'SETTINGS_LABELS/LABEL_CHANGE_PASSWORD_NAME', 'change-password');
}
kn.addSettingsViewModel(require('Settings/App/Folders'),
'SettingsFolders', 'SETTINGS_LABELS/LABEL_FOLDERS_NAME', 'folders');
if (Settings.capa(Enums.Capa.Themes))
{
kn.addSettingsViewModel(require('Settings/App/Themes'),
'SettingsThemes', 'SETTINGS_LABELS/LABEL_THEMES_NAME', 'themes');
}
if (Settings.capa(Enums.Capa.OpenPGP))
{
kn.addSettingsViewModel(require('Settings/App/OpenPGP'),
'SettingsOpenPGP', 'SETTINGS_LABELS/LABEL_OPEN_PGP_NAME', 'openpgp');
}
if (fCallback)
{
fCallback();
}
};
SettingsAppScreen.prototype.onShow = function ()
{
this.setSettingsTitle();
Globals.keyScope(Enums.KeyState.Settings);
};
SettingsAppScreen.prototype.setSettingsTitle = function ()
{
require('App/App').setTitle(this.sSettingsTitle);
};
module.exports = SettingsAppScreen;
}());

32
dev/Screen/User/About.js Normal file
View file

@ -0,0 +1,32 @@
(function () {
'use strict';
var
_ = require('_'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function AboutUserScreen()
{
AbstractScreen.call(this, 'about', [
require('View/User/About')
]);
}
_.extend(AboutUserScreen.prototype, AbstractScreen.prototype);
AboutUserScreen.prototype.onShow = function ()
{
require('App/User').setWindowTitle('RainLoop');
};
module.exports = AboutUserScreen;
}());

32
dev/Screen/User/Login.js Normal file
View file

@ -0,0 +1,32 @@
(function () {
'use strict';
var
_ = require('_'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function LoginUserScreen()
{
AbstractScreen.call(this, 'login', [
require('View/User/Login')
]);
}
_.extend(LoginUserScreen.prototype, AbstractScreen.prototype);
LoginUserScreen.prototype.onShow = function ()
{
require('App/User').setWindowTitle('');
};
module.exports = LoginUserScreen;
}());

175
dev/Screen/User/MailBox.js Normal file
View file

@ -0,0 +1,175 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Utils = require('Common/Utils'),
Events = require('Common/Events'),
Translator = require('Common/Translator'),
Cache = require('Common/Cache'),
AppStore = require('Stores/User/App'),
AccountStore = require('Stores/User/Account'),
SettingsStore = require('Stores/User/Settings'),
FolderStore = require('Stores/User/Folder'),
MessageStore = require('Stores/User/Message'),
AbstractScreen = require('Knoin/AbstractScreen')
;
/**
* @constructor
* @extends AbstractScreen
*/
function MailBoxUserScreen()
{
AbstractScreen.call(this, 'mailbox', [
require('View/User/MailBox/SystemDropDown'),
require('View/User/MailBox/FolderList'),
require('View/User/MailBox/MessageList'),
require('View/User/MailBox/MessageView')
]);
this.oLastRoute = {};
}
_.extend(MailBoxUserScreen.prototype, AbstractScreen.prototype);
/**
* @type {Object}
*/
MailBoxUserScreen.prototype.oLastRoute = {};
MailBoxUserScreen.prototype.updateWindowTitle = function ()
{
var
sEmail = AccountStore.email(),
nFoldersInboxUnreadCount = FolderStore.foldersInboxUnreadCount()
;
require('App/User').setWindowTitle(('' === sEmail ? '' : '' +
(0 < nFoldersInboxUnreadCount ? '(' + nFoldersInboxUnreadCount + ') ' : ' ') +
sEmail + ' - ') + Translator.i18n('TITLES/MAILBOX'));
};
MailBoxUserScreen.prototype.onShow = function ()
{
this.updateWindowTitle();
AppStore.focusedState(Enums.Focused.None);
AppStore.focusedState(Enums.Focused.MessageList);
};
/**
* @param {string} sFolderHash
* @param {number} iPage
* @param {string} sSearch
* @param {boolean=} bPreview = false
*/
MailBoxUserScreen.prototype.onRoute = function (sFolderHash, iPage, sSearch)
{
var
sFolderFullNameRaw = Cache.getFolderFullNameRaw(sFolderHash),
oFolder = Cache.getFolderFromCacheList(sFolderFullNameRaw)
;
if (oFolder)
{
FolderStore.currentFolder(oFolder);
MessageStore.messageListPage(iPage);
MessageStore.messageListSearch(sSearch);
require('App/User').reloadMessageList();
}
};
MailBoxUserScreen.prototype.onStart = function ()
{
FolderStore.folderList.subscribe(Utils.windowResizeCallback);
MessageStore.messageList.subscribe(Utils.windowResizeCallback);
MessageStore.message.subscribe(Utils.windowResizeCallback);
_.delay(function () {
SettingsStore.layout.valueHasMutated();
}, 50);
Events.sub('mailbox.inbox-unread-count', _.bind(function (iCount) {
FolderStore.foldersInboxUnreadCount(iCount);
var sEmail = AccountStore.email();
_.each(AccountStore.accounts(), function (oItem) {
if (oItem && sEmail === oItem.email)
{
oItem.count(iCount);
}
});
this.updateWindowTitle();
}, this));
};
MailBoxUserScreen.prototype.onBuild = function ()
{
if (!Globals.bMobileDevice)
{
_.defer(function () {
require('App/User').initHorizontalLayoutResizer(Enums.ClientSideKeyName.MessageListSize);
});
}
};
/**
* @return {Array}
*/
MailBoxUserScreen.prototype.routes = function ()
{
var
sInboxFolderName = Cache.getFolderInboxName(),
fNormS = function (oRequest, oVals) {
oVals[0] = Utils.pString(oVals[0]);
oVals[1] = Utils.pInt(oVals[1]);
oVals[1] = 0 >= oVals[1] ? 1 : oVals[1];
oVals[2] = Utils.pString(oVals[2]);
if ('' === oRequest)
{
oVals[0] = sInboxFolderName;
oVals[1] = 1;
}
return [decodeURI(oVals[0]), oVals[1], decodeURI(oVals[2])];
},
fNormD = function (oRequest, oVals) {
oVals[0] = Utils.pString(oVals[0]);
oVals[1] = Utils.pString(oVals[1]);
if ('' === oRequest)
{
oVals[0] = sInboxFolderName;
}
return [decodeURI(oVals[0]), 1, decodeURI(oVals[1])];
}
;
return [
[/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)\/(.+)\/?$/, {'normalize_': fNormS}],
[/^([a-zA-Z0-9]+)\/p([1-9][0-9]*)$/, {'normalize_': fNormS}],
[/^([a-zA-Z0-9]+)\/(.+)\/?$/, {'normalize_': fNormD}],
[/^([^\/]*)$/, {'normalize_': fNormS}]
];
};
module.exports = MailBoxUserScreen;
}());

132
dev/Screen/User/Settings.js Normal file
View file

@ -0,0 +1,132 @@
(function () {
'use strict';
var
_ = require('_'),
Enums = require('Common/Enums'),
Globals = require('Common/Globals'),
Translator = require('Common/Translator'),
Plugins = require('Common/Plugins'),
AppStore = require('Stores/User/App'),
AccountStore = require('Stores/User/Account'),
Settings = require('Storage/Settings'),
kn = require('Knoin/Knoin'),
AbstractSettingsScreen = require('Screen/AbstractSettings')
;
/**
* @constructor
* @extends AbstractSettingsScreen
*/
function SettingsUserScreen()
{
AbstractSettingsScreen.call(this, [
require('View/User/Settings/SystemDropDown'),
require('View/User/Settings/Menu'),
require('View/User/Settings/Pane')
]);
Translator.initOnStartOrLangChange(function () {
this.sSettingsTitle = Translator.i18n('TITLES/SETTINGS');
}, this, function () {
this.setSettingsTitle();
});
}
_.extend(SettingsUserScreen.prototype, AbstractSettingsScreen.prototype);
/**
* @param {Function=} fCallback
*/
SettingsUserScreen.prototype.setupSettings = function (fCallback)
{
kn.addSettingsViewModel(require('Settings/User/General'),
'SettingsGeneral', 'SETTINGS_LABELS/LABEL_GENERAL_NAME', 'general', true);
if (AppStore.contactsIsAllowed())
{
kn.addSettingsViewModel(require('Settings/User/Contacts'),
'SettingsContacts', 'SETTINGS_LABELS/LABEL_CONTACTS_NAME', 'contacts');
}
kn.addSettingsViewModel(require('Settings/User/Accounts'), 'SettingsAccounts',
Settings.capa(Enums.Capa.AdditionalAccounts) ?
'SETTINGS_LABELS/LABEL_ACCOUNTS_NAME' : 'SETTINGS_LABELS/LABEL_IDENTITIES_NAME', 'accounts');
if (Settings.capa(Enums.Capa.Sieve))
{
kn.addSettingsViewModel(require('Settings/User/Filters'),
'SettingsFilters', 'SETTINGS_LABELS/LABEL_FILTERS_NAME', 'filters');
}
if (Settings.capa(Enums.Capa.AutoLogout) || Settings.capa(Enums.Capa.TwoFactor))
{
kn.addSettingsViewModel(require('Settings/User/Security'),
'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
}
if (AccountStore.isRootAccount() &&
(Settings.settingsGet('AllowGoogleSocial') && Settings.settingsGet('AllowGoogleSocialAuth')) ||
Settings.settingsGet('AllowFacebookSocial') ||
Settings.settingsGet('AllowTwitterSocial'))
{
kn.addSettingsViewModel(require('Settings/User/Social'),
'SettingsSocial', 'SETTINGS_LABELS/LABEL_SOCIAL_NAME', 'social');
}
if (Settings.settingsGet('ChangePasswordIsAllowed'))
{
kn.addSettingsViewModel(require('Settings/User/ChangePassword'),
'SettingsChangePassword', 'SETTINGS_LABELS/LABEL_CHANGE_PASSWORD_NAME', 'change-password');
}
if (Settings.capa(Enums.Capa.Templates))
{
kn.addSettingsViewModel(require('Settings/User/Templates'),
'SettingsTemplates', 'SETTINGS_LABELS/LABEL_TEMPLATES_NAME', 'templates');
}
kn.addSettingsViewModel(require('Settings/User/Folders'),
'SettingsFolders', 'SETTINGS_LABELS/LABEL_FOLDERS_NAME', 'folders');
if (Settings.capa(Enums.Capa.Themes))
{
kn.addSettingsViewModel(require('Settings/User/Themes'),
'SettingsThemes', 'SETTINGS_LABELS/LABEL_THEMES_NAME', 'themes');
}
if (Settings.capa(Enums.Capa.OpenPGP))
{
kn.addSettingsViewModel(require('Settings/User/OpenPgp'),
'SettingsOpenPGP', 'SETTINGS_LABELS/LABEL_OPEN_PGP_NAME', 'openpgp');
}
Plugins.runSettingsViewModelHooks(false);
if (fCallback)
{
fCallback();
}
};
SettingsUserScreen.prototype.onShow = function ()
{
this.setSettingsTitle();
Globals.keyScope(Enums.KeyState.Settings);
};
SettingsUserScreen.prototype.setSettingsTitle = function ()
{
require('App/User').setWindowTitle(this.sSettingsTitle);
};
module.exports = SettingsUserScreen;
}());

View file

@ -4,31 +4,39 @@
'use strict';
var
ko = require('ko')
ko = require('ko'),
Translator = require('Common/Translator'),
Settings = require('Storage/Settings'),
CoreStore = require('Stores/Admin/Core')
;
/**
* @constructor
*/
function AboutAdminSetting()
function AboutAdminSettings()
{
var
Settings = require('Storage/Settings'),
Data = require('Storage/Admin/Data')
;
this.version = ko.observable(Settings.settingsGet('Version'));
this.access = ko.observable(!!Settings.settingsGet('CoreAccess'));
this.errorDesc = ko.observable('');
this.coreReal = Data.coreReal;
this.coreUpdatable = Data.coreUpdatable;
this.coreAccess = Data.coreAccess;
this.coreChecking = Data.coreChecking;
this.coreUpdating = Data.coreUpdating;
this.coreRemoteVersion = Data.coreRemoteVersion;
this.coreRemoteRelease = Data.coreRemoteRelease;
this.coreVersionCompare = Data.coreVersionCompare;
this.coreReal = CoreStore.coreReal;
this.coreChannel = CoreStore.coreChannel;
this.coreType = CoreStore.coreType;
this.coreUpdatable = CoreStore.coreUpdatable;
this.coreAccess = CoreStore.coreAccess;
this.coreChecking = CoreStore.coreChecking;
this.coreUpdating = CoreStore.coreUpdating;
this.coreWarning = CoreStore.coreWarning;
this.coreVersion = CoreStore.coreVersion;
this.coreRemoteVersion = CoreStore.coreRemoteVersion;
this.coreRemoteRelease = CoreStore.coreRemoteRelease;
this.coreVersionCompare = CoreStore.coreVersionCompare;
this.coreRemoteVersionHtmlDesc = ko.computed(function () {
return Translator.i18n('TAB_ABOUT/HTML_NEW_VERSION', {'VERSION': this.coreRemoteVersion()});
}, this);
this.statusType = ko.computed(function () {
@ -67,7 +75,7 @@
}, this);
}
AboutAdminSetting.prototype.onBuild = function ()
AboutAdminSettings.prototype.onBuild = function ()
{
if (this.access())
{
@ -75,7 +83,7 @@
}
};
AboutAdminSetting.prototype.updateCoreData = function ()
AboutAdminSettings.prototype.updateCoreData = function ()
{
if (!this.coreUpdating())
{
@ -83,6 +91,6 @@
}
};
module.exports = AboutAdminSetting;
module.exports = AboutAdminSettings;
}());

View file

@ -7,85 +7,168 @@
_ = require('_'),
ko = require('ko'),
Utils = require('Common/Utils')
Utils = require('Common/Utils'),
Translator = require('Common/Translator')
;
/**
* @constructor
*/
function BrandingAdminSetting()
function BrandingAdminSettings()
{
var
Enums = require('Common/Enums'),
Settings = require('Storage/Settings')
Settings = require('Storage/Settings'),
AppStore = require('Stores/Admin/App')
;
this.capa = AppStore.prem;
this.title = ko.observable(Settings.settingsGet('Title'));
this.title.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.loadingDesc = ko.observable(Settings.settingsGet('LoadingDescription'));
this.loadingDesc.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.loginLogo = ko.observable(Settings.settingsGet('LoginLogo'));
this.loginLogo = ko.observable(Settings.settingsGet('LoginLogo') || '');
this.loginLogo.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.loginBackground = ko.observable(Settings.settingsGet('LoginBackground') || '');
this.loginBackground.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.userLogo = ko.observable(Settings.settingsGet('UserLogo') || '');
this.userLogo.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.loginDescription = ko.observable(Settings.settingsGet('LoginDescription'));
this.loginDescription.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.loginCss = ko.observable(Settings.settingsGet('LoginCss'));
this.loginCss.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.userCss = ko.observable(Settings.settingsGet('UserCss'));
this.userCss.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.welcomePageUrl = ko.observable(Settings.settingsGet('WelcomePageUrl'));
this.welcomePageUrl.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.welcomePageDisplay = ko.observable(Settings.settingsGet('WelcomePageDisplay'));
this.welcomePageDisplay.trigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.welcomePageDisplay.options = ko.computed(function () {
Translator.trigger();
return [
{'optValue': 'none', 'optText': Translator.i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_NONE')},
{'optValue': 'once', 'optText': Translator.i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ONCE')},
{'optValue': 'always', 'optText': Translator.i18n('TAB_BRANDING/OPTION_WELCOME_PAGE_DISPLAY_ALWAYS')}
];
});
this.loginPowered = ko.observable(!!Settings.settingsGet('LoginPowered'));
}
BrandingAdminSetting.prototype.onBuild = function ()
BrandingAdminSettings.prototype.onBuild = function ()
{
var
self = this,
Remote = require('Storage/Admin/Remote')
Remote = require('Remote/Admin/Ajax')
;
_.delay(function () {
if (this.capa())
{
_.delay(function () {
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.title.trigger, self),
f2 = Utils.settingsSaveHelperSimpleFunction(self.loadingDesc.trigger, self),
f3 = Utils.settingsSaveHelperSimpleFunction(self.loginLogo.trigger, self),
f4 = Utils.settingsSaveHelperSimpleFunction(self.loginDescription.trigger, self),
f5 = Utils.settingsSaveHelperSimpleFunction(self.loginCss.trigger, self)
;
var
f3 = Utils.settingsSaveHelperSimpleFunction(self.loginLogo.trigger, self),
f4 = Utils.settingsSaveHelperSimpleFunction(self.loginDescription.trigger, self),
f5 = Utils.settingsSaveHelperSimpleFunction(self.loginCss.trigger, self),
f6 = Utils.settingsSaveHelperSimpleFunction(self.userLogo.trigger, self),
f7 = Utils.settingsSaveHelperSimpleFunction(self.loginBackground.trigger, self),
f8 = Utils.settingsSaveHelperSimpleFunction(self.userCss.trigger, self),
f9 = Utils.settingsSaveHelperSimpleFunction(self.welcomePageUrl.trigger, self),
f10 = Utils.settingsSaveHelperSimpleFunction(self.welcomePageDisplay.trigger, self)
;
self.title.subscribe(function (sValue) {
Remote.saveAdminConfig(f1, {
'Title': Utils.trim(sValue)
self.loginLogo.subscribe(function (sValue) {
Remote.saveAdminConfig(f3, {
'LoginLogo': Utils.trim(sValue)
});
});
});
self.loadingDesc.subscribe(function (sValue) {
Remote.saveAdminConfig(f2, {
'LoadingDescription': Utils.trim(sValue)
self.loginBackground.subscribe(function (sValue) {
Remote.saveAdminConfig(f7, {
'LoginBackground': Utils.trim(sValue)
});
});
});
self.loginLogo.subscribe(function (sValue) {
Remote.saveAdminConfig(f3, {
'LoginLogo': Utils.trim(sValue)
self.userLogo.subscribe(function (sValue) {
Remote.saveAdminConfig(f6, {
'UserLogo': Utils.trim(sValue)
});
});
});
self.loginDescription.subscribe(function (sValue) {
Remote.saveAdminConfig(f4, {
'LoginDescription': Utils.trim(sValue)
self.loginDescription.subscribe(function (sValue) {
Remote.saveAdminConfig(f4, {
'LoginDescription': Utils.trim(sValue)
});
});
});
self.loginCss.subscribe(function (sValue) {
Remote.saveAdminConfig(f5, {
'LoginCss': Utils.trim(sValue)
self.loginCss.subscribe(function (sValue) {
Remote.saveAdminConfig(f5, {
'LoginCss': Utils.trim(sValue)
});
});
});
}, 50);
self.userCss.subscribe(function (sValue) {
Remote.saveAdminConfig(f8, {
'UserCss': Utils.trim(sValue)
});
});
self.welcomePageUrl.subscribe(function (sValue) {
Remote.saveAdminConfig(f9, {
'WelcomePageUrl': Utils.trim(sValue)
});
});
self.welcomePageDisplay.subscribe(function (sValue) {
Remote.saveAdminConfig(f10, {
'WelcomePageDisplay': Utils.trim(sValue)
});
});
self.loginPowered.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'LoginPowered': bValue ? '1' : '0'
});
});
}, 50);
}
else
{
_.delay(function () {
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.title.trigger, self),
f2 = Utils.settingsSaveHelperSimpleFunction(self.loadingDesc.trigger, self)
;
self.title.subscribe(function (sValue) {
Remote.saveAdminConfig(f1, {
'Title': Utils.trim(sValue)
});
});
self.loadingDesc.subscribe(function (sValue) {
Remote.saveAdminConfig(f2, {
'LoadingDescription': Utils.trim(sValue)
});
});
}, 50);
}
};
module.exports = BrandingAdminSetting;
module.exports = BrandingAdminSettings;
}());

View file

@ -10,16 +10,18 @@
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Translator = require('Common/Translator'),
Settings = require('Storage/Settings')
;
/**
* @constructor
*/
function ContactsAdminSetting()
function ContactsAdminSettings()
{
var
Remote = require('Storage/Admin/Remote')
Remote = require('Remote/Admin/Ajax')
;
this.defautOptionsAfterRender = Utils.defautOptionsAfterRender;
@ -68,7 +70,7 @@
var bDisabled = -1 === Utils.inArray(sValue, aSupportedTypes);
return {
'id': sValue,
'name': getTypeName(sValue) + (bDisabled ? ' (not supported)' : ''),
'name': getTypeName(sValue) + (bDisabled ? ' (' + Translator.i18n('HINTS/NOT_SUPPORTED') + ')' : ''),
'disabled': bDisabled
};
});
@ -96,7 +98,7 @@
this.contactsType.valueHasMutated();
}
}
});
}).extend({'notify': 'always'});
this.contactsType.subscribe(function () {
this.testContactsSuccess(false);
@ -141,7 +143,7 @@
this.onTestContactsResponse = _.bind(this.onTestContactsResponse, this);
}
ContactsAdminSetting.prototype.onTestContactsResponse = function (sResult, oData)
ContactsAdminSettings.prototype.onTestContactsResponse = function (sResult, oData)
{
this.testContactsSuccess(false);
this.testContactsError(false);
@ -167,18 +169,18 @@
this.testing(false);
};
ContactsAdminSetting.prototype.onShow = function ()
ContactsAdminSettings.prototype.onShow = function ()
{
this.testContactsSuccess(false);
this.testContactsError(false);
this.testContactsErrorMessage('');
};
ContactsAdminSetting.prototype.onBuild = function ()
ContactsAdminSettings.prototype.onBuild = function ()
{
var
self = this,
Remote = require('Storage/Admin/Remote')
Remote = require('Remote/Admin/Ajax')
;
_.delay(function () {
@ -237,6 +239,6 @@
}, 50);
};
module.exports = ContactsAdminSetting;
module.exports = ContactsAdminSettings;
}());

View file

@ -4,75 +4,47 @@
'use strict';
var
window = require('window'),
_ = require('_'),
ko = require('ko'),
Enums = require('Common/Enums'),
PopupsDomainViewModel = require('View/Popup/Domain'),
Data = require('Storage/Admin/Data'),
Remote = require('Storage/Admin/Remote')
DomainStore = require('Stores/Admin/Domain'),
Remote = require('Remote/Admin/Ajax')
;
/**
* @constructor
*/
function DomainsAdminSetting()
function DomainsAdminSettings()
{
this.domains = Data.domains;
this.domainsLoading = Data.domainsLoading;
this.iDomainForDeletionTimeout = 0;
this.domains = DomainStore.domains;
this.visibility = ko.computed(function () {
return Data.domainsLoading() ? 'visible' : 'hidden';
return this.domains.loading() ? 'visible' : 'hidden';
}, this);
this.domainForDeletion = ko.observable(null).extend({'toggleSubscribe': [this,
function (oPrev) {
if (oPrev)
{
oPrev.deleteAccess(false);
}
}, function (oNext) {
if (oNext)
{
oNext.deleteAccess(true);
this.startDomainForDeletionTimeout();
}
}
]});
this.domainForDeletion = ko.observable(null).deleteAccessHelper();
}
DomainsAdminSetting.prototype.startDomainForDeletionTimeout = function ()
DomainsAdminSettings.prototype.createDomain = function ()
{
var self = this;
window.clearInterval(this.iDomainForDeletionTimeout);
this.iDomainForDeletionTimeout = window.setTimeout(function () {
self.domainForDeletion(null);
}, 1000 * 3);
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Domain'));
};
DomainsAdminSetting.prototype.createDomain = function ()
{
require('Knoin/Knoin').showScreenPopup(PopupsDomainViewModel);
};
DomainsAdminSetting.prototype.deleteDomain = function (oDomain)
DomainsAdminSettings.prototype.deleteDomain = function (oDomain)
{
this.domains.remove(oDomain);
Remote.domainDelete(_.bind(this.onDomainListChangeRequest, this), oDomain.name);
};
DomainsAdminSetting.prototype.disableDomain = function (oDomain)
DomainsAdminSettings.prototype.disableDomain = function (oDomain)
{
oDomain.disabled(!oDomain.disabled());
Remote.domainDisable(_.bind(this.onDomainListChangeRequest, this), oDomain.name, oDomain.disabled());
};
DomainsAdminSetting.prototype.onBuild = function (oDom)
DomainsAdminSettings.prototype.onBuild = function (oDom)
{
var self = this;
oDom
@ -88,19 +60,19 @@
require('App/Admin').reloadDomainList();
};
DomainsAdminSetting.prototype.onDomainLoadRequest = function (sResult, oData)
DomainsAdminSettings.prototype.onDomainLoadRequest = function (sResult, oData)
{
if (Enums.StorageResultType.Success === sResult && oData && oData.Result)
{
require('Knoin/Knoin').showScreenPopup(PopupsDomainViewModel, [oData.Result]);
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Domain'), [oData.Result]);
}
};
DomainsAdminSetting.prototype.onDomainListChangeRequest = function ()
DomainsAdminSettings.prototype.onDomainListChangeRequest = function ()
{
require('App/Admin').reloadDomainList();
};
module.exports = DomainsAdminSetting;
module.exports = DomainsAdminSettings;
}());

View file

@ -9,63 +9,75 @@
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
LinkBuilder = require('Common/LinkBuilder'),
Links = require('Common/Links'),
Translator = require('Common/Translator'),
Settings = require('Storage/Settings'),
Data = require('Storage/Admin/Data')
ThemeStore = require('Stores/Theme'),
LanguageStore = require('Stores/Language'),
AppAdminStore = require('Stores/Admin/App'),
CapaAdminStore = require('Stores/Admin/Capa'),
Settings = require('Storage/Settings')
;
/**
* @constructor
*/
function GeneralAdminSetting()
function GeneralAdminSettings()
{
this.mainLanguage = Data.mainLanguage;
this.mainTheme = Data.mainTheme;
this.language = LanguageStore.language;
this.languages = LanguageStore.languages;
this.languageAdmin = LanguageStore.languageAdmin;
this.languagesAdmin = LanguageStore.languagesAdmin;
this.language = Data.language;
this.theme = Data.theme;
this.theme = ThemeStore.theme;
this.themes = ThemeStore.themes;
this.allowLanguagesOnSettings = Data.allowLanguagesOnSettings;
this.capaThemes = Data.capaThemes;
this.capaGravatar = Data.capaGravatar;
this.capaAdditionalAccounts = Data.capaAdditionalAccounts;
this.capaAdditionalIdentities = Data.capaAdditionalIdentities;
this.capaThemes = CapaAdminStore.themes;
this.capaUserBackground = CapaAdminStore.userBackground;
this.capaGravatar = CapaAdminStore.gravatar;
this.capaAdditionalAccounts = CapaAdminStore.additionalAccounts;
this.capaAttachmentThumbnails = CapaAdminStore.attachmentThumbnails;
this.capaTemplates = CapaAdminStore.templates;
this.allowLanguagesOnSettings = AppAdminStore.allowLanguagesOnSettings;
this.weakPassword = AppAdminStore.weakPassword;
this.mainAttachmentLimit = ko.observable(Utils.pInt(Settings.settingsGet('AttachmentLimit')) / (1024 * 1024)).extend({'posInterer': 25});
this.uploadData = Settings.settingsGet('PhpUploadSizes');
this.uploadDataDesc = this.uploadData && (this.uploadData['upload_max_filesize'] || this.uploadData['post_max_size']) ?
[
this.uploadData['upload_max_filesize'] ? 'upload_max_filesize = ' + this.uploadData['upload_max_filesize'] + '; ' : '',
this.uploadData['post_max_size'] ? 'post_max_size = ' + this.uploadData['post_max_size'] : ''
].join('')
: '';
this.uploadDataDesc = this.uploadData && (this.uploadData['upload_max_filesize'] || this.uploadData['post_max_size']) ? [
this.uploadData['upload_max_filesize'] ? 'upload_max_filesize = ' + this.uploadData['upload_max_filesize'] + '; ' : '',
this.uploadData['post_max_size'] ? 'post_max_size = ' + this.uploadData['post_max_size'] : ''
].join('') : '';
this.themesOptions = ko.computed(function () {
return _.map(Data.themes(), function (sTheme) {
return _.map(this.themes(), function (sTheme) {
return {
'optValue': sTheme,
'optText': Utils.convertThemeName(sTheme)
};
});
});
this.mainLanguageFullName = ko.computed(function () {
return Utils.convertLangName(this.mainLanguage());
}, this);
this.weakPassword = !!Settings.settingsGet('WeakPassword');
this.languageFullName = ko.computed(function () {
return Utils.convertLangName(this.language());
}, this);
this.languageAdminFullName = ko.computed(function () {
return Utils.convertLangName(this.languageAdmin());
}, this);
this.attachmentLimitTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.languageTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
this.languageAdminTrigger = ko.observable(Enums.SaveSettingsStep.Idle).extend({'throttle': 100});
this.themeTrigger = ko.observable(Enums.SaveSettingsStep.Idle);
}
GeneralAdminSetting.prototype.onBuild = function ()
GeneralAdminSettings.prototype.onBuild = function ()
{
var
self = this,
Remote = require('Storage/Admin/Remote')
Remote = require('Remote/Admin/Ajax')
;
_.delay(function () {
@ -73,7 +85,15 @@
var
f1 = Utils.settingsSaveHelperSimpleFunction(self.attachmentLimitTrigger, self),
f2 = Utils.settingsSaveHelperSimpleFunction(self.languageTrigger, self),
f3 = Utils.settingsSaveHelperSimpleFunction(self.themeTrigger, self)
f3 = Utils.settingsSaveHelperSimpleFunction(self.themeTrigger, self),
fReloadLanguageHelper = function (iSaveSettingsStep) {
return function() {
self.languageAdminTrigger(iSaveSettingsStep);
_.delay(function () {
self.languageAdminTrigger(Enums.SaveSettingsStep.Idle);
}, 1000);
};
}
;
self.mainAttachmentLimit.subscribe(function (sValue) {
@ -88,7 +108,23 @@
});
});
self.languageAdmin.subscribe(function (sValue) {
self.languageAdminTrigger(Enums.SaveSettingsStep.Animate);
Translator.reload(true, sValue,
fReloadLanguageHelper(Enums.SaveSettingsStep.TrueResult),
fReloadLanguageHelper(Enums.SaveSettingsStep.FalseResult));
Remote.saveAdminConfig(null, {
'LanguageAdmin': Utils.trim(sValue)
});
});
self.theme.subscribe(function (sValue) {
Utils.changeTheme(sValue, self.themeTrigger);
Remote.saveAdminConfig(f3, {
'Theme': Utils.trim(sValue)
});
@ -100,9 +136,9 @@
});
});
self.capaAdditionalIdentities.subscribe(function (bValue) {
self.capaTemplates.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'CapaAdditionalIdentities': bValue ? '1' : '0'
'CapaTemplates': bValue ? '1' : '0'
});
});
@ -112,12 +148,24 @@
});
});
self.capaAttachmentThumbnails.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'CapaAttachmentThumbnails': bValue ? '1' : '0'
});
});
self.capaThemes.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'CapaThemes': bValue ? '1' : '0'
});
});
self.capaUserBackground.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'CapaUserBackground': bValue ? '1' : '0'
});
});
self.allowLanguagesOnSettings.subscribe(function (bValue) {
Remote.saveAdminConfig(null, {
'AllowLanguagesOnSettings': bValue ? '1' : '0'
@ -127,19 +175,28 @@
}, 50);
};
GeneralAdminSetting.prototype.selectLanguage = function ()
GeneralAdminSettings.prototype.selectLanguage = function ()
{
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Languages'));
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Languages'), [
this.language, this.languages(), LanguageStore.userLanguage()
]);
};
GeneralAdminSettings.prototype.selectLanguageAdmin = function ()
{
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Languages'), [
this.languageAdmin, this.languagesAdmin(), LanguageStore.userLanguageAdmin()
]);
};
/**
* @return {string}
*/
GeneralAdminSetting.prototype.phpInfoLink = function ()
GeneralAdminSettings.prototype.phpInfoLink = function ()
{
return LinkBuilder.phpInfo();
return Links.phpInfo();
};
module.exports = GeneralAdminSetting;
module.exports = GeneralAdminSettings;
}());

View file

@ -5,23 +5,22 @@
var
ko = require('ko'),
moment = require('moment'),
Settings = require('Storage/Settings'),
Data = require('Storage/Admin/Data')
LicenseStore = require('Stores/Admin/License')
;
/**
* @constructor
*/
function LicensingAdminSetting()
function LicensingAdminSettings()
{
this.licensing = Data.licensing;
this.licensingProcess = Data.licensingProcess;
this.licenseValid = Data.licenseValid;
this.licenseExpired = Data.licenseExpired;
this.licenseError = Data.licenseError;
this.licenseTrigger = Data.licenseTrigger;
this.licensing = LicenseStore.licensing;
this.licensingProcess = LicenseStore.licensingProcess;
this.licenseValid = LicenseStore.licenseValid;
this.licenseExpired = LicenseStore.licenseExpired;
this.licenseError = LicenseStore.licenseError;
this.licenseTrigger = LicenseStore.licenseTrigger;
this.adminDomain = ko.observable('');
this.subscriptionEnabled = ko.observable(!!Settings.settingsGet('SubscriptionEnabled'));
@ -34,7 +33,7 @@
}, this);
}
LicensingAdminSetting.prototype.onBuild = function ()
LicensingAdminSettings.prototype.onBuild = function ()
{
if (this.subscriptionEnabled())
{
@ -42,29 +41,44 @@
}
};
LicensingAdminSetting.prototype.onShow = function ()
LicensingAdminSettings.prototype.onShow = function ()
{
this.adminDomain(Settings.settingsGet('AdminDomain'));
};
LicensingAdminSetting.prototype.showActivationForm = function ()
LicensingAdminSettings.prototype.showActivationForm = function ()
{
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Activate'));
};
/**
* @returns {string}
*/
LicensingAdminSetting.prototype.licenseExpiredMomentValue = function ()
LicensingAdminSettings.prototype.showTrialForm = function ()
{
var
iTime = this.licenseExpired(),
oDate = moment.unix(iTime)
;
return iTime && 1898625600 === iTime ? 'Never' : (oDate.format('LL') + ' (' + oDate.from(moment()) + ')');
require('Knoin/Knoin').showScreenPopup(require('View/Popup/Activate'), [true]);
};
module.exports = LicensingAdminSetting;
/**
* @return {boolean}
*/
LicensingAdminSettings.prototype.licenseIsUnlim = function ()
{
return 1898625600 === this.licenseExpired() || 1898625700 === this.licenseExpired();
};
/**
* @return {string}
*/
LicensingAdminSettings.prototype.licenseExpiredMomentValue = function ()
{
var
moment = require('moment'),
iTime = this.licenseExpired(),
oM = moment.unix(iTime)
;
return this.licenseIsUnlim() ? 'Never' :
(iTime && (oM.format('LL') + ' (' + oM.from(moment()) + ')'));
};
module.exports = LicensingAdminSettings;
}());

Some files were not shown because too many files have changed in this diff Show more