Added "Custom Theme Configuration" (background)

This commit is contained in:
RainLoop Team
2014-11-08 00:21:10 +04:00
parent 0587d66d45
commit ef81865ef2
45 changed files with 1151 additions and 73654 deletions

View File

@@ -99,6 +99,14 @@
}, {}, 60 * 60 * 1000);
if (Settings.settingsGet('UserBackgroundHash'))
{
_.delay(function () {
$('#rl-bg').backstretch(Links.publicLink(Settings.settingsGet('UserBackgroundHash')), {
'fade': Globals.bAnimationSupported ? 1000 : 0
});
}, 3000);
}
this.socialUsers = _.bind(this.socialUsers, this);
}

View File

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

View File

@@ -15,6 +15,15 @@
'Unload': 'unload'
};
/**
* @enum {number}
*/
Enums.SpoolerType = {
'Delay': 0,
'MessageList': 1,
'Move': 2
};
/**
* @enum {number}
*/

View File

@@ -152,6 +152,15 @@
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} sInboxFolderName = 'INBOX'
* @return {string}

View File

@@ -1031,6 +1031,8 @@
oData.theme = ko.observable('');
oData.themes = ko.observableArray([]);
oData.themeBackgroundName = ko.observable('');
oData.themeBackgroundHash = ko.observable('');
oData.mainTheme = ko.computed({
'read': oData.theme,
@@ -2074,7 +2076,7 @@
Utils.__themeTimer = 0;
Utils.__themeAjax = null;
Utils.changeTheme = function (sValue, themeTrigger)
Utils.changeTheme = function (sValue, sHash, themeTrigger, Links)
{
var
oThemeLink = $('#rlThemeLink'),
@@ -2091,6 +2093,7 @@
{
sUrl = sUrl.toString().replace(/\/-\/[^\/]+\/\-\//, '/-/' + sValue + '/-/');
sUrl = sUrl.toString().replace(/\/Css\/[^\/]+\/User\//, '/Css/0/User/');
sUrl = sUrl.toString().replace(/\/Hash\/[^\/]+\//, '/Hash/-/');
if ('Json/' !== sUrl.substring(sUrl.length - 5, sUrl.length))
{
@@ -2122,7 +2125,7 @@
if (oThemeStyle && oThemeStyle[0])
{
oThemeStyle.attr('data-href', sUrl).attr('data-theme', aData[0]);
if (oThemeStyle && oThemeStyle[0] && oThemeStyle[0].styleSheet && !Utils.isUnd(oThemeStyle[0].styleSheet.cssText))
if (oThemeStyle[0].styleSheet && !Utils.isUnd(oThemeStyle[0].styleSheet.cssText))
{
oThemeStyle[0].styleSheet.cssText = aData[1];
}
@@ -2132,6 +2135,26 @@
}
}
if (Links)
{
var $oBg = $('#rl-bg');
if (!sHash)
{
if ($oBg.data('backstretch'))
{
$oBg.backstretch('destroy').attr('style', '');
}
}
else
{
$oBg.backstretch(Links.publicLink(sHash), {
'fade': Globals.bAnimationSupported ? 1000 : 0,
'centeredX': true,
'centeredY': true
});
}
}
themeTrigger(Enums.SaveSettingsStep.TrueResult);
}

View File

@@ -89,7 +89,7 @@
self.theme.subscribe(function (sValue) {
Utils.changeTheme(sValue, self.themeTrigger);
Utils.changeTheme(sValue, '', self.themeTrigger);
Remote.saveAdminConfig(f3, {
'Theme': Utils.trim(sValue)

View File

@@ -7,6 +7,8 @@
_ = require('_'),
ko = require('ko'),
Jua = require('Jua'),
Enums = require('Common/Enums'),
Utils = require('Common/Utils'),
Links = require('Common/Links'),
@@ -20,11 +22,18 @@
*/
function ThemesUserSettings()
{
var self = this;
this.mainTheme = Data.mainTheme;
this.themesObjects = ko.observableArray([]);
this.background = {};
this.background.name = Data.themeBackgroundName;
this.background.hash = Data.themeBackgroundHash;
this.background.uploaderButton = ko.observable(null);
this.background.loading = ko.observable(false);
this.background.error = ko.observable('');
this.capaUserBackground = Data.capaUserBackground;
this.themeTrigger = ko.observable(Enums.SaveSettingsStep.Idle).extend({'throttle': 100});
this.iTimer = 0;
@@ -36,13 +45,17 @@
oTheme.selected(sValue === oTheme.name);
});
Utils.changeTheme(sValue, self.themeTrigger);
Utils.changeTheme(sValue, this.background.hash(), this.themeTrigger, Links);
Remote.saveSettings(null, {
'Theme': sValue
});
}, this);
this.background.hash.subscribe(function (sValue) {
Utils.changeTheme(Data.theme(), sValue, this.themeTrigger, Links);
}, this);
}
ThemesUserSettings.prototype.onBuild = function ()
@@ -56,6 +69,93 @@
'themePreviewSrc': Links.themePreviewLink(sTheme)
};
}));
this.initUploader();
};
ThemesUserSettings.prototype.onShow = function ()
{
this.background.error('');
};
ThemesUserSettings.prototype.clearBackground = function ()
{
if (this.capaUserBackground())
{
var self = this;
Remote.clearUserBackground(function () {
self.background.name('');
self.background.hash('');
});
}
};
ThemesUserSettings.prototype.initUploader = function ()
{
if (this.background.uploaderButton() && this.capaUserBackground())
{
var
oJua = new Jua({
'action': Links.uploadBackground(),
'name': 'uploader',
'queueSize': 1,
'multipleSizeLimit': 1,
'disableDragAndDrop': true,
'disableMultiple': true,
'clickElement': this.background.uploaderButton()
})
;
oJua
.on('onStart', _.bind(function () {
this.background.loading(true);
this.background.error('');
return true;
}, this))
.on('onComplete', _.bind(function (sId, bResult, oData) {
this.background.loading(false);
if (bResult && sId && oData && oData.Result && oData.Result.Name && oData.Result.Hash)
{
this.background.name(oData.Result.Name);
this.background.hash(oData.Result.Hash);
}
else
{
this.background.name('');
this.background.hash('');
var sError = '';
if (oData.ErrorCode)
{
switch (oData.ErrorCode)
{
case Enums.UploadErrorCode.FileIsTooBig:
sError = Utils.i18n('SETTINGS_THEMES/ERROR_FILE_IS_TOO_BIG');
break;
case Enums.UploadErrorCode.FileType:
sError = Utils.i18n('SETTINGS_THEMES/ERROR_FILE_TYPE_ERROR');
break;
}
}
if (!sError && oData.ErrorMessage)
{
sError = oData.ErrorMessage;
}
this.background.error(sError || Utils.i18n('SETTINGS_THEMES/ERROR_UNKNOWN'));
}
return true;
}, this))
;
}
};
module.exports = ThemesUserSettings;

View File

@@ -39,6 +39,8 @@
this.mainLanguage(Settings.settingsGet('Language'));
this.mainTheme(Settings.settingsGet('Theme'));
this.themeBackgroundName(Settings.settingsGet('UserBackgroundName'));
this.themeBackgroundHash(Settings.settingsGet('UserBackgroundHash'));
this.capaAdditionalAccounts(Settings.capa(Enums.Capa.AdditionalAccounts));
this.capaAdditionalIdentities(Settings.capa(Enums.Capa.AdditionalIdentities));

View File

@@ -240,7 +240,7 @@
Plugins.runHook('ajax-default-request', [sAction, oParameters, sGetAdd]);
this.ajaxRequest(fCallback, oParameters,
return this.ajaxRequest(fCallback, oParameters,
Utils.isUnd(iTimeout) ? Consts.Defaults.DefaultAjaxTimeout : Utils.pInt(iTimeout), sGetAdd, aAbortActions);
};

View File

@@ -244,7 +244,7 @@
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([
sFolderFullNameRaw,
@@ -260,7 +260,7 @@
}
else
{
this.defaultRequest(fCallback, 'MessageList', {
return this.defaultRequest(fCallback, 'MessageList', {
'Folder': sFolderFullNameRaw,
'Offset': iOffset,
'Limit': iLimit,
@@ -716,6 +716,9 @@
/**
* @param {?Function} fCallback
* @param {string} sRequestUid
* @param {string} sUid
* @param {Array} aProperties
*/
RemoteUserStorage.prototype.contactSave = function (fCallback, sRequestUid, sUid, aProperties)
{
@@ -750,6 +753,14 @@
}, null, '', ['Suggestions']);
};
/**
* @param {?Function} fCallback
*/
RemoteUserStorage.prototype.clearUserBackground = function (fCallback)
{
this.defaultRequest(fCallback, 'ClearUserBackground');
};
/**
* @param {?Function} fCallback
*/

View File

@@ -0,0 +1,20 @@
(function () {
'use strict';
var
queue = require('queue')
;
/**
* @constructor
*/
function Spooler()
{
this.queue = queue(1);
}
module.exports = new Spooler();
}());

View File

@@ -111,7 +111,7 @@ cfg.paths.js = {
'vendors/json2.min.js',
'vendors/labjs/LAB.min.js',
'vendors/simple-pace/simple-pace-1.0.min.js',
'vendors/rl/rl-1.2.min.js'
'vendors/rl/rl-1.3.min.js'
]
},
openpgp: {
@@ -148,6 +148,8 @@ cfg.paths.js = {
'vendors/jquery-nanoscroller/jquery.nanoscroller-0.7.min.js',
'vendors/jquery-wakeup/jquery.wakeup.min.js',
'vendors/jquery-letterfx/jquery-letterfx.min.js',
'vendors/jquery-backstretch/jquery.backstretch.min.js',
'vendors/queue/queue.min.js',
'vendors/inputosaurus/inputosaurus.min.js',
'vendors/moment/min/moment.min.js ',
'vendors/routes/signals.min.js',
@@ -367,8 +369,8 @@ regOtherMinTask('other:inputosaurus', 'vendors/inputosaurus/', 'inputosaurus.js'
regOtherMinTask('other:pace', 'vendors/simple-pace/', 'simple-pace.js', 'simple-pace-1.0.min.js',
'/*! RainLoop Simple Pace v1.0 (c) 2014 RainLoop Team; Licensed under MIT */\n');
regOtherMinTask('other:rl', 'vendors/rl/', 'rl.js', 'rl-1.2.min.js',
'/*! RainLoop Index Helper v1.2 (c) 2014 RainLoop Team; Licensed under MIT */\n');
regOtherMinTask('other:rl', 'vendors/rl/', 'rl.js', 'rl-1.3.min.js',
'/*! RainLoop Index Helper v1.3 (c) 2014 RainLoop Team; Licensed under MIT */\n');
gulp.task('package-inc-release', function() {
fs.writeFileSync('package.json',

View File

@@ -9,7 +9,8 @@ if (!defined('APP_VERSION'))
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/index.php'))
{
return include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/index.php';
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/index.php';
exit(0);
}
else
{

View File

@@ -2,7 +2,7 @@
"name": "RainLoop",
"title": "RainLoop Webmail",
"version": "1.6.11",
"release": "191",
"release": "192",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "gulpfile.js",

View File

@@ -68,5 +68,3 @@ else if (\function_exists('RainLoopSplAutoloadRegisterFunction'))
{
\spl_autoload_unregister('RainLoopSplAutoloadRegisterFunction');
}
return '';

View File

@@ -1051,8 +1051,6 @@ class Actions
'Plugins' => array()
);
// $aResult['MaterialDesign'] = false;
if ($aResult['UseRsaEncryption'] &&
\file_exists(APP_PRIVATE_DATA.'rsa/public') && \file_exists(APP_PRIVATE_DATA.'rsa/private'))
{
@@ -1075,7 +1073,6 @@ class Actions
$aResult['AuthAccountHash'] = $sAuthAccountHash;
}
if ($this->PremType())
{
$aResult['Title'] = $oConfig->Get('webmail', 'title', '');
@@ -1304,6 +1301,8 @@ class Actions
$aResult['EnableTwoFactor'] = false;
$aResult['ParentEmail'] = '';
$aResult['InterfaceAnimation'] = \RainLoop\Enumerations\InterfaceAnimation::NORMAL;
$aResult['UserBackgroundName'] = '';
$aResult['UserBackgroundHash'] = '';
if (!$bAdmin && $oSettings instanceof \RainLoop\Settings)
{
@@ -1334,6 +1333,12 @@ class Actions
$aResult['UseCheckboxesInList'] = (bool) $oSettings->GetConf('UseCheckboxesInList', $aResult['UseCheckboxesInList']);
$aResult['InterfaceAnimation'] = (string) $oSettings->GetConf('InterfaceAnimation', $aResult['InterfaceAnimation']);
if ($oConfig->Get('webmail', 'allow_user_background', false))
{
$aResult['UserBackgroundName'] = (string) $oSettings->GetConf('UserBackgroundName', $aResult['UserBackgroundName']);
$aResult['UserBackgroundHash'] = (string) $oSettings->GetConf('UserBackgroundHash', $aResult['UserBackgroundHash']);
}
$aResult['DefaultIdentityID'] = $oSettings->GetConf('DefaultIdentityID', $oAccount ? $oAccount->Email() : $aResult['DefaultIdentityID']);
$aResult['DisplayName'] = $oSettings->GetConf('DisplayName', $aResult['DisplayName']);
$aResult['ReplyTo'] = $oSettings->GetConf('ReplyTo', $aResult['ReplyTo']);
@@ -1356,10 +1361,11 @@ class Actions
$aResult['AllowTwitterSocial'] = false;
}
$sStaticCache = \md5(APP_VERSION.$this->Plugins()->Hash());
$sStaticCache = \md5(APP_VERSION.$this->Plugins()->Hash().$aResult['UserBackgroundHash']);
$sTheme = $this->ValidateTheme($sTheme);
$sNewThemeLink = './?/Css/0/'.($bAdmin ? 'Admin' : 'User').'/-/'.$sTheme.'/-/'.$sStaticCache.'/';
$sNewThemeLink = './?/Css/0/'.($bAdmin ? 'Admin' : 'User').'/-/'.$sTheme.'/-/'.$sStaticCache.'/Hash/'.
(empty($aResult['UserBackgroundHash']) ? '-' : $aResult['UserBackgroundHash']).'/';
$bUserLanguage = false;
if (!$bAdmin && !$aResult['Auth'] && !empty($_COOKIE['rllang']) &&
@@ -4507,7 +4513,7 @@ class Actions
*/
public function DoMessageList()
{
// sleep(5);
// sleep(2);
// throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantGetMessageList);
$sFolder = '';
@@ -6300,6 +6306,32 @@ class Actions
return $this->DefaultResponse(__FUNCTION__, $aResponse);
}
/**
* @return array
*/
public function DoClearUserBackground()
{
$oAccount = $this->getAccountFromToken();
$oSettings = $this->SettingsProvider()->Load($oAccount);
if ($oAccount && $oSettings)
{
$sHash = $oSettings->GetConf('UserBackgroundHash', '');
if (!empty($sHash))
{
$this->StorageProvider()->Clear(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
\RainLoop\KeyPathHelper::PublicFile($sHash)
);
}
$oSettings->SetConf('UserBackgroundName', '');
$oSettings->SetConf('UserBackgroundHash', '');
}
return $this->DefaultResponse(__FUNCTION__, $oAccount && $oSettings ? $this->SettingsProvider()->Save($oAccount, $oSettings) : false);
}
/**
* @return array
*/
@@ -6307,45 +6339,88 @@ class Actions
{
$oAccount = $this->getAccountFromToken();
$bResponse = false;
$sName = '';
$sHash = '';
$aFile = $this->GetActionParam('File', null);
$iError = $this->GetActionParam('Error', \RainLoop\Enumerations\UploadError::UNKNOWN);
if ($oAccount && UPLOAD_ERR_OK === $iError && \is_array($aFile))
{
$sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']);
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name']))
$sMimeType = \strtolower(\MailSo\Base\Utils::MimeContentType($aFile['name']));
if (\in_array($sMimeType, array('image/png', 'image/jpg', 'image/jpeg')))
{
$iError = \RainLoop\Enumerations\UploadError::ON_SAVING;
$sSavedName = 'upload-post-'.\md5($aFile['name'].$aFile['tmp_name']);
if (!$this->FilesProvider()->MoveUploadedFile($oAccount, $sSavedName, $aFile['tmp_name']))
{
$iError = \RainLoop\Enumerations\UploadError::ON_SAVING;
}
else
{
$rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
if (@\is_resource($rData))
{
$sData = @\stream_get_contents($rData);
if (!empty($sData) && 0 < \strlen($sData))
{
$iLimit = 3;
while (true)
{
$iLimit--;
if (0 > $iLimit)
{
$sHash = '';
break;
}
$sHash = \sha1($sSavedName.\microtime(true).\rand(10000, 99999));
if (!$this->StorageProvider()->Get(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
\RainLoop\KeyPathHelper::PublicFile($sHash), null))
{
break;
}
}
if (!empty($sHash))
{
if ($this->StorageProvider()->Put(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
\RainLoop\KeyPathHelper::PublicFile($sHash),
'data:'.$sMimeType.':'.$sData
))
{
$sName = $aFile['name'];
$oSettings = $this->SettingsProvider()->Load($oAccount);
if ($oSettings)
{
$oSettings->SetConf('UserBackgroundName', $sName);
$oSettings->SetConf('UserBackgroundHash', $sHash);
$this->SettingsProvider()->Save($oAccount, $oSettings);
}
}
}
}
unset($sData);
}
if (@\is_resource($rData))
{
@\fclose($rData);
}
unset($rData);
}
$this->FilesProvider()->Clear($oAccount, $sSavedName);
}
else
{
$rData = $this->FilesProvider()->GetFile($oAccount, $sSavedName);
if (@\is_resource($rData))
{
$sData = @\stream_get_contents($rData);
if (!empty($sData) && 0 < \strlen($sData))
{
$bResponse = $this->StorageProvider()->Put($oAccount,
\RainLoop\Providers\Storage\Enumerations\StorageType::USER,
\RainLoop\KeyPathHelper::UserBackground($oAccount->Email()),
\base64_encode($sData)
);
}
unset($sData);
}
if (@\is_resource($rData))
{
@\fclose($rData);
}
unset($rData);
$iError = \RainLoop\Enumerations\UploadError::FILE_TYPE;
}
$this->FilesProvider()->Clear($oAccount, $sSavedName);
}
if (UPLOAD_ERR_OK !== $iError)
@@ -6359,7 +6434,10 @@ class Actions
}
}
return $this->DefaultResponse(__FUNCTION__, $bResponse);
return $this->DefaultResponse(__FUNCTION__, !empty($sName) && !empty($sHash) ? array(
'Name' => $sName,
'Hash' => $sHash
) : false);
}
/**
@@ -6819,6 +6897,44 @@ class Actions
return $this->rawSmart(false);
}
/**
* @return bool
*/
public function RawPublic()
{
$sRawKey = (string) $this->GetActionParam('RawKey', '');
$this->verifyCacheByKey($sRawKey);
$sHash = $sRawKey;
$sData = '';
if (!empty($sHash))
{
$sData = $this->StorageProvider()->Get(null,
\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY,
\RainLoop\KeyPathHelper::PublicFile($sHash)
);
}
$aMatch = array();
if (!empty($sData) && 0 === \strpos($sData, 'data:') &&
\preg_match('/^data:([^:]+):/', $sData, $aMatch) && !empty($aMatch[1]))
{
$sContentType = \trim($aMatch[1]);
if (\in_array($sContentType, array('image/png', 'image/jpg', 'image/jpeg')))
{
$this->cacheByKey($sRawKey);
@\header('Content-Type: '.$sContentType);
echo \preg_replace('/^data:[^:]+:/', '', $sData);
unset($sData);
return true;
}
}
return false;
}
/**
* @param string $sFileName
*

View File

@@ -25,13 +25,13 @@ class KeyPathHelper
}
/**
* @param string $sEmail
* @param string $sHash
*
* @return string
*/
static public function UserBackground($sEmail)
static public function PublicFile($sHash)
{
return '/UserBackground/Base64/'.$sEmail.'/Data/';
return '/Public/Files/'.sha1($sHash).'/Data/';
}
/**

View File

@@ -264,10 +264,11 @@ class ServiceActions
/**
* @param string $sAction
* @param int $iSizeLimit = 0
*
* @return string
*/
private function privateUpload($sAction)
private function privateUpload($sAction, $iSizeLimit = 0)
{
$oConfig = $this->Config();
@@ -278,7 +279,7 @@ class ServiceActions
$aFile = null;
$sInputName = 'uploader';
$iError = \RainLoop\Enumerations\UploadError::UNKNOWN;
$iSizeLimit = ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0)) * 1024 * 1024;
$iSizeLimit = (0 < $iSizeLimit ? $iSizeLimit : ((int) $oConfig->Get('webmail', 'attachment_size_limit', 0))) * 1024 * 1024;
$iError = UPLOAD_ERR_OK;
$_FILES = isset($_FILES) ? $_FILES : null;
@@ -364,7 +365,7 @@ class ServiceActions
*/
public function ServiceUploadContacts()
{
return $this->privateUpload('UploadContacts');
return $this->privateUpload('UploadContacts', 5);
}
/**
@@ -372,7 +373,7 @@ class ServiceActions
*/
public function ServiceUploadBackground()
{
return $this->privateUpload('UploadBackground');
return $this->privateUpload('UploadBackground', 1);
}
/**
@@ -410,6 +411,8 @@ class ServiceActions
{
$this->oHttp->StatusHeader(404);
}
return '';
}
/**
@@ -616,7 +619,8 @@ class ServiceActions
$sResult = '';
$bAdmin = !empty($this->aPaths[2]) && 'Admin' === $this->aPaths[2];
$bJson = !empty($this->aPaths[7]) && 'Json' === $this->aPaths[7];
$bJson = !empty($this->aPaths[9]) && 'Json' === $this->aPaths[9];
$sHash = !empty($this->aPaths[8]) && 5 < \strlen($this->aPaths[8]) ? $this->aPaths[8] : '';
if ($bJson)
{
@@ -648,7 +652,7 @@ class ServiceActions
$sCacheFileName = '';
if ($bCacheEnabled)
{
$sCacheFileName = \RainLoop\KeyPathHelper::CssCache($sTheme, $this->oActions->Plugins()->Hash());
$sCacheFileName = \RainLoop\KeyPathHelper::CssCache($sTheme, $this->oActions->Plugins()->Hash(), $sHash);
$sResult = $this->Cacher()->Get($sCacheFileName);
}
@@ -687,6 +691,15 @@ class ServiceActions
$sResult = $oLess->compile(\implode("\n", $aResult));
if (!empty($sHash))
{
$sResult .= "\n".'.thm-body {'.
'background-image:none;'.
'background-image: url("./?/Raw/0/Public/'.$sHash.'/") !important;'.
'-moz-background-size:cover;-webkit-background-size:cover;background-size:cover;'.
'}';
}
if ($bCacheEnabled)
{
if (0 < \strlen($sCacheFileName))

View File

@@ -65,13 +65,13 @@
value: capaThemes
}
}"></div>
<!-- <div data-bind="component: {
<div data-bind="component: {
name: 'Checkbox',
params: {
label: 'Allow background selection on settings screen',
value: capaUserBackground
}
}"></div>-->
}"></div>
</div>
</div>
<div class="control-group">

View File

@@ -4,9 +4,9 @@
<span class="i18n" data-i18n-text="SETTINGS_IDENTITY/LEGEND_IDENTITY"></span>
</div>
<div class="control-group g-ui-user-select-none">
<label class="control-label">
<span class="i18n" data-i18n-text="SETTINGS_IDENTITY/LABEL_DISPLAY_NAME"></span>
</label>
<label class="control-label">
<span class="i18n" data-i18n-text="SETTINGS_IDENTITY/LABEL_DISPLAY_NAME"></span>
</label>
<div class="controls">
<div data-bind="component: {
name: 'Input',

View File

@@ -15,4 +15,30 @@
<img class="e-image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-bind="attr: { 'src': themePreviewSrc }" />
</div>
</div>
<br />
<br />
<div class="form-horizontal" data-bind="visible: capaUserBackground">
<div class="legend">
<span class="i18n" data-i18n-text="SETTINGS_THEMES/LEGEND_THEMES_CUSTOM"></span>
</div>
<div class="control-group g-ui-user-select-none">
<div class="row" data-bind="visible: '' !== background.error()" style="margin-left: 0; margin-bottom: 10px;">
<div class="alert alert-error span6" data-bind="text: background.error" style="margin-left: 0"></div>
</div>
<div class="row" data-bind="visible: '' !== background.name()" style="margin-left: 0">
<a class="btn" data-bind="visible: '' !== background.name(), click: clearBackground">
<i class="icon-remove"></i>
</a>
&nbsp;&nbsp;&nbsp;
<b data-bind="text: background.name"></b>
</div>
<div class="row" data-bind="visible: '' === background.name()" style="margin-left: 0">
<a class="btn" data-bind="initDom: background.uploaderButton">
<i data-bind="css: {'icon-image': !background.loading(), 'icon-spinner animated': background.loading()}"></i>
&nbsp;&nbsp;
<span class="i18n" data-i18n-text="SETTINGS_THEMES/BUTTON_UPLOAD_BACKGROUND_IMAGE"></span>
</a>
</div>
</div>
</div>
</div>

View File

@@ -2,28 +2,20 @@
if (defined('APP_VERSION'))
{
@ini_set('register_globals', 0);
@ini_set('zend.ze1_compatibility_mode', 0);
@ini_set('magic_quotes_gpc', 0);
@ini_set('magic_quotes_runtime', 0);
if (!defined('APP_START'))
{
define('APP_START', microtime(true));
@ini_set('suhosin.session.encrypt', 0);
@ini_set('suhosin.get.max_name_length', 2014);
@ini_set('suhosin.get.max_value_length', 2014);
@ini_set('register_globals', 0);
@ini_set('zend.ze1_compatibility_mode', 0);
@ini_set('magic_quotes_gpc', 0);
@ini_set('magic_quotes_runtime', 0);
define('APP_DEFAULT_DENY_ALL_HTACCESS', 'Deny from all
define('APP_DEFAULT_DENY_ALL_HTACCESS', 'Deny from all
<IfModule mod_autoindex.c>
Options -Indexes
</ifModule>');
if (isset($_ENV['RAINLOOP_INCLUDE_AS_VERSION']) && $_ENV['RAINLOOP_INCLUDE_AS_VERSION'])
{
$_ENV['RAINLOOP_INCLUDE_AS_VERSION'] = false;
return APP_VERSION;
}
else if (!defined('APP_START'))
{
define('APP_START', microtime(true));
define('APP_START_TIME', time());
define('APP_REQUEST_RND', md5(APP_START.rand(10000, 99999).APP_START));
define('APP_VERSION_ROOT_PATH', APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/');
@@ -196,7 +188,5 @@ Options -Indexes
unset($sSite, $sSalt, $sData, $sInstalled, $sPrivateDataFolderInternalName);
}
return include APP_VERSION_ROOT_PATH.'app/handle.php';
include APP_VERSION_ROOT_PATH.'app/handle.php';
}
return '';

View File

@@ -1,3 +0,0 @@
<?php
include '../rainloop/v/0.0.0/app/libraries/MailSo/MailSo.php';

View File

@@ -1,6 +0,0 @@
<?xml version="1.0"?>
<phpunit
colors="true"
stopOnFailure="true"
syntaxCheck="true">
</phpunit>

View File

@@ -1,232 +0,0 @@
MIME-Version: 1.0
Message-ID: <45a92f7.0e89f233c32fbd2b9d191d4cb28775c9@domain.com>
From: from@domain.com
To: test@domain.com
Subject: TEST HTML MESSAGE WITH ATTACHMENT
Date: Thu, 6 May 2010 07:26:37 -0700 (PDT)
Content-Type: multipart/mixed;
boundary="--=_NextPart_11de424d3d872ac110be4ecfffc45411"
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: Quoted-Printable
<html><body>TEST HTML MESSAGE WITH ATTACHMENT</body></html>
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: image/gif;
name="av-7.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="av-7.gif"
R0lGODdhMgAyAOfXAAAAADMAAGYAAJkAAMwAAP8AAAAzADMzAGYzAJkzAMwzAP8zAABmADNmAGZm
AJlmAMxmAP9mAACZADOZAGaZAJmZAMyZAP+ZAADMADPMAGbMAJnMAMzMAP/MAAD/ADP/AGb/AJn/
AMz/AP//AAAAMzMAM2YAM5kAM8wAM/8AMwAzMzMzM2YzM5kzM8wzM/8zMwBmMzNmM2ZmM5lmM8xm
M/9mMwCZMzOZM2aZM5mZM8yZM/+ZMwDMMzPMM2bMM5nMM8zMM//MMwD/MzP/M2b/M5n/M8z/M///
MwAAZjMAZmYAZpkAZswAZv8AZgAzZjMzZmYzZpkzZswzZv8zZgBmZjNmZmZmZplmZsxmZv9mZgCZ
ZjOZZmaZZpmZZsyZZv+ZZgDMZjPMZmbMZpnMZszMZv/MZgD/ZjP/Zmb/Zpn/Zsz/Zv//ZgAAmTMA
mWYAmZkAmcwAmf8AmQAzmTMzmWYzmZkzmcwzmf8zmQBmmTNmmWZmmZlmmcxmmf9mmQCZmTOZmWaZ
mZmZmcyZmf+ZmQDMmTPMmWbMmZnMmczMmf/MmQD/mTP/mWb/mZn/mcz/mf//mQAAzDMAzGYAzJkA
zMwAzP8AzAAzzDMzzGYzzJkzzMwzzP8zzABmzDNmzGZmzJlmzMxmzP9mzACZzDOZzGaZzJmZzMyZ
zP+ZzADMzDPMzGbMzJnMzMzMzP/MzAD/zDP/zGb/zJn/zMz/zP//zAAA/zMA/2YA/5kA/8wA//8A
/wAz/zMz/2Yz/5kz/8wz//8z/wBm/zNm/2Zm/5lm/8xm//9m/wCZ/zOZ/2aZ/5mZ/8yZ//+Z/wDM
/zPM/2bM/5nM/8zM///M/wD//zP//2b//5n//8z//////////wAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEA
AAAh+QQFCADYACwAAAAAMgAyAAAI/gCvCRxIsKDBgwgTKlzIsKHDhxAjSpxIsaLFixgzaswYiNVG
ioFWAAg0kOTHhitYsQJwjZVIKycXBoJ5jeXMa1ZMxjyYUyDLkddS7kTYM2RIn0MRCl0xk+TRpARV
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
IUMkPQhhTMlNSFBCRa12oEceJajhThKpZFNAADs=
----=_NextPart_11de424d3d872ac110be4ecfffc45411--

View File

@@ -1,16 +0,0 @@
MIME-Version: 1.0
From: test@domain.com
To: test@domain.com
Subject: TEST MESSAGE
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 8bit
Date: Wed, 28 Apr 2010 02:04:20 -0700
Message-ID: <16800462619664130307453@TEST-TEST>
TEST
.
. MESSGAE
BODY

View File

@@ -1,18 +0,0 @@
Envelope-to: webmail@test.com
Delivery-date: Tue, 15 Jun 2010 22:48:56 -0700
Received: from [84.51.195.105] (helo=local)
by mail.test.com with esmtpa (Exim 4.71)
(envelope-from <sss@test.com>)
id 1OOlUe-0002EQ-IJ
for webmail@test.com; Tue, 15 Jun 2010 22:48:56 -0700
Date: Wed, 16 Jun 2010 09:48:42 +0400
From: sss <sss@test.com>
X-Mailer: The Bat! (v4.0.24) Professional
Reply-To: sss <sss@test.com>
X-Priority: 3 (Normal)
Message-ID: <708372127.20100616094842@test.com>
To: webmail@test.com
Subject: =?iso-8859-5?B?v+DY4eLj39DvIA==?= =?iso-8859-5?B?2iDg0NHe4tUg4Q==?= =?iso-8859-5?B?3iDh2+PW0d7ZIA==?= =?iso-8859-5?B?V2luZG93cyBMaQ==?= =?iso-8859-5?B?dmUgSG90bWFpbA==?=
MIME-Version: 1.0
Content-Type: text/plain; charset=windows-1251
Content-Transfer-Encoding: 8bit

View File

@@ -1,55 +0,0 @@
MIME-Version: 1.0
Message-ID: <45a92f7.0e89f233c32fbd2b9d191d4cb28775c9@domain.com>
From: from@domain.com
To: test@domain.com
Subject: TEST HTML MESSAGE WITH ATTACHMENT
Date: Thu, 6 May 2010 07:26:37 -0700 (PDT)
Content-Type: multipart/mixed;
boundary="--=_NextPart_11de424d3d872ac110be4ecfffc45411"
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: text/html;
charset="utf-8"
Content-Transfer-Encoding: Quoted-Printable
<html><body>TEST HTML MESSAGE WITH ATTACHMENT</body></html>
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: image/gif;
name="av-7.gif"
Content-Transfer-Encoding: base64
Content-Disposition: attachment;
filename="av-7.gif"
R0lGODdhMgAyAOfXAAAAADMAAGYAAJkAAMwAAP8AAAAzADMzAGYzAJkzAMwzAP8zAABmADNmAGZm
AJlmAMxmAP9mAACZADOZAGaZAJmZAMyZAP+ZAADMADPMAGbMAJnMAMzMAP/MAAD/ADP/AGb/AJn/
AMz/AP//AAAAMzMAM2YAM5kAM8wAM/8AMwAzMzMzM2YzM5kzM8wzM/8zMwBmMzNmM2ZmM5lmM8xm
JkGbFiixJtrNgEcjNIo0ocmUcmc33Viyo9qSKnOzrTmx89CTGmUv5zm4NUiyPD02ZkVZtEvGnmVU
whaJcCZdn0/NYpzsPHxQkF/lPk0PNepOtFeFduwKVqPd2QZdB2BDOZk3oEObHeiQTAqG5l2DBHEH
IUMkPQhhTMlNSFBCRa12oEceJajhThKpZFNAADs=
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: image/gif;
Content-Transfer-Encoding: base64
R0lGODdhMgAyAOfXAAAAADMAAGYAAJkAAMwAAP8AAAAzADMzAGYzAJkzAMwzAP8zAABmADNmAGZm
AJlmAMxmAP9mAACZADOZAGaZAJmZAMyZAP+ZAADMADPMAGbMAJnMAMzMAP/MAAD/ADP/AGb/AJn/
AMz/AP//AAAAMzMAM2YAM5kAM8wAM/8AMwAzMzMzM2YzM5kzM8wzM/8zMwBmMzNmM2ZmM5lmM8xm
JkGbFiixJtrNgEcjNIo0ocmUcmc33Viyo9qSKnOzrTmx89CTGmUv5zm4NUiyPD02ZkVZtEvGnmVU
whaJcCZdn0/NYpzsPHxQkF/lPk0PNepOtFeFduwKVqPd2QZdB2BDOZk3oEObHeiQTAqG5l2DBHEH
IUMkPQhhTMlNSFBCRa12oEceJajhThKpZFNAADs=
----=_NextPart_11de424d3d872ac110be4ecfffc45411
Content-Type: image/png
Content-Transfer-Encoding: Quoted-Printable
Content-Disposition: attachment;
filename*0*=111; filename*1*=222.gif;
<html><body>TEST HTML MESSAGE WITH ATTACHMENT</body></html>
----=_NextPart_11de424d3d872ac110be4ecfffc45411--

View File

@@ -1,54 +0,0 @@
From: alex <alex@local>
To: alex <alex@LOCAL>
Date: Thu, 22 Nov 2013 09:42:17 +0100
Subject:
-------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5----...
Thread-Topic:
-------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5---------1---------2---------3---------4---------5----...
Message-ID: <50ADE569.2000807@local>
Accept-Language: de-DE
Content-Language: de-DE
X-MS-Has-Attach:
X-MS-TNEF-Correlator:
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:16.0) Gecko/20121026
Thunderbird/16.0.2
Content-Type: multipart/alternative;
boundary="_000_50ADE5692000807omninetlocal_"
MIME-Version: 1.0
--_000_50ADE5692000807omninetlocal_
Content-Type: text/plain; charset="iso-8859-15"
Content-Transfer-Encoding: quoted-printable
Test
-------1---------2---------3---------4---------5---------1---------2-------=
--3---------4---------5---------1---------2---------3---------4---------5--=
-------1---------2---------3---------4---------5---------1---------2-------=
--3---------4---------5---------1---------2---------3---------4---------5--
--_000_50ADE5692000807omninetlocal_
Content-Type: text/html; charset="iso-8859-15"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DISO-8=
859-15">
</head>
<body bgcolor=3D"#FFFFFF" text=3D"#000000">
Test<br>
<meta http-equiv=3D"Content-Type" content=3D"text/html;
charset=3DISO-8859-15">
<span>-------1---------2---------3---------4---------5---------1-------=
--2---------3---------4---------5---------1---------2---------3---------4--=
-------5---------1---------2---------3---------4---------5---------1-------=
--2---------3---------4---------5---------1---------2---------3---------4--=
-------5--</span>
<title>HTML</title>
<meta http-equiv=3D"Content-Type" content=3D"text/html;
charset=3DISO-8859-15">
<title>HTML</title>
</body>
</html>
--_000_50ADE5692000807omninetlocal_--

View File

@@ -1,96 +0,0 @@
<?php
namespace MailSoTests;
class LinkFinderText extends \PHPUnit_Framework_TestCase
{
/**
* @var \MailSo\Base\LinkFinder
*/
protected $object;
protected function setUp()
{
$this->object = \MailSo\Base\LinkFinder::NewInstance();
}
protected function tearDown()
{
$this->object = null;
}
public function testNewInstance()
{
$this->assertTrue($this->object instanceof \MailSo\Base\LinkFinder);
}
public function testClear()
{
$this->object->Text('111');
$this->assertEquals('111', $this->object->CompileText());
$this->object->Clear();
$this->assertEquals('', $this->object->CompileText());
}
public function testText()
{
$this->object->Text('222');
$this->assertEquals('222', $this->object->CompileText());
}
public function testLinkWrapper()
{
$this->object
->Text('333 http://domain.com 333')
->LinkWrapper(function ($sLink) {
return '!'.$sLink.'!';
})
;
$this->assertEquals('333 !http://domain.com! 333', $this->object->CompileText());
}
public function testMailWrapper()
{
$this->object
->Text('444 user@domain.com 444')
->MailWrapper(function ($sMail) {
return '!'.$sMail.'!';
})
;
$this->assertEquals('444 !user@domain.com! 444', $this->object->CompileText());
}
public function testUseDefaultWrappers()
{
$this->object
->Text('555 http://domain.com user@domain.com 555')
->UseDefaultWrappers()
;
$this->assertEquals('555 <a href="http://domain.com">http://domain.com</a> <a href="mailto:user@domain.com">user@domain.com</a> 555',
$this->object->CompileText());
$this->object->UseDefaultWrappers(true);
$this->assertEquals('555 <a target="_blank" href="http://domain.com">http://domain.com</a> <a target="_blank" href="mailto:user@domain.com">user@domain.com</a> 555',
$this->object->CompileText());
}
public function testCompileText()
{
$this->object
->Text('777 http://domain.com user@domain.com <> 777')
->LinkWrapper(function ($sLink) {
return '~'.$sLink.'~';
})
->MailWrapper(function ($sMail) {
return '~'.$sMail.'~';
})
;
$this->assertEquals('777 ~http://domain.com~ ~user@domain.com~ &lt;&gt; 777', $this->object->CompileText(true));
$this->assertEquals('777 ~http://domain.com~ ~user@domain.com~ <> 777', $this->object->CompileText(false));
}
}

View File

@@ -1,85 +0,0 @@
<?php
namespace MailSoTests;
class ImapClientTest extends \PHPUnit_Framework_TestCase
{
const CRLF = "\r\n";
public function testNamespace()
{
$rConnect = \MailSo\Base\StreamWrappers\Test::CreateStream(
'* NAMESPACE (("" "/")) NIL NIL'.self::CRLF.
'TAG1 OK Success'.self::CRLF
);
$oImapClient = \MailSo\Imap\ImapClient::NewInstance()->TestSetValues($rConnect, array('NAMESPACE'));
$oResult = $oImapClient->GetNamespace();
$this->assertTrue($oResult instanceof \MailSo\Imap\NamespaceResult);
}
public function testQuota()
{
$rConnect = \MailSo\Base\StreamWrappers\Test::CreateStream(
'* QUOTAROOT "INBOX" ""'.self::CRLF.
'* QUOTA "" (STORAGE 55163 10511217)'.self::CRLF.
'TAG1 OK Success'.self::CRLF
);
$oImapClient = \MailSo\Imap\ImapClient::NewInstance()->TestSetValues($rConnect, array('QUOTA'));
$aResult = $oImapClient->Quota();
$this->assertTrue(is_array($aResult));
$this->assertEquals(4, count($aResult));
$this->assertEquals(55163, $aResult[0]);
$this->assertEquals(10511217, $aResult[1]);
}
public function testFolderList()
{
$rConnect = \MailSo\Base\StreamWrappers\Test::CreateStream(
'* LIST (\Noselect) "/" 0'.self::CRLF.
'* LIST (\UnMarked) "/" 0/1'.self::CRLF.
'* LIST (\Noselect) "/" 1'.self::CRLF.
'* LIST (\Noselect) "/" 1/2'.self::CRLF.
'* LIST (\UnMarked) "/" 1/2/3'.self::CRLF.
'* LIST (\UnMarked \Inbox) "/" INBOX'.self::CRLF.
'* LIST (\UnMarked) "/" "INBOX/XXX XXX"'.self::CRLF.
'* LIST (\UnMarked) "/" &-BT,MAQBDoEM'.self::CRLF.
'* LIST (\UnMarked) "NIL" NILDelimiteFolder'.self::CRLF.
'* LIST (\UnMarked) "" EmptyDelimiteFolder'.self::CRLF.
'TAG1 OK Success'.self::CRLF
);
$oImapClient = \MailSo\Imap\ImapClient::NewInstance()->TestSetValues($rConnect);
$aResult = $oImapClient->FolderList();
$this->assertTrue(is_array($aResult) && 0 < count($aResult));
$this->assertTrue($aResult[0] instanceof \MailSo\Imap\Folder);
$this->assertEquals('0', $aResult[0]->FullNameRaw());
$this->assertEquals('0', $aResult[0]->NameRaw());
$this->assertEquals('0/1', $aResult[1]->FullNameRaw());
$this->assertEquals('1', $aResult[1]->NameRaw());
$this->assertEquals('1', $aResult[2]->FullNameRaw());
$this->assertEquals('1/2', $aResult[3]->FullNameRaw());
$this->assertEquals('1/2/3', $aResult[4]->FullNameRaw());
$this->assertEquals('3', $aResult[4]->NameRaw());
$this->assertEquals('INBOX', $aResult[5]->FullNameRaw());
$this->assertEquals('INBOX/XXX XXX', $aResult[6]->FullNameRaw());
$this->assertEquals('XXX XXX', $aResult[6]->NameRaw());
$this->assertEquals('&-BT,MAQBDoEM', $aResult[7]->FullNameRaw());
$this->assertTrue($aResult[5] instanceof \MailSo\Imap\Folder);
$this->assertEquals('/', $aResult[5]->Delimiter());
$this->assertEquals(2, count($aResult[5]->FlagsLowerCase()));
$this->assertTrue(in_array('\inbox', $aResult[5]->FlagsLowerCase()));
$this->assertTrue($aResult[8] instanceof \MailSo\Imap\Folder);
$this->assertEquals('.', $aResult[8]->Delimiter());
$this->assertTrue($aResult[9] instanceof \MailSo\Imap\Folder);
$this->assertEquals('.', $aResult[8]->Delimiter());
}
}

View File

@@ -1,18 +0,0 @@
<?php
namespace MailSoTests;
class EmailCollectionTest extends \PHPUnit_Framework_TestCase
{
public function testNewInstance()
{
$oMails = \MailSo\Mime\EmailCollection::NewInstance('admin@example.com');
$this->assertEquals(1, $oMails->Count());
}
public function testNewInstance1()
{
$oMails = \MailSo\Mime\EmailCollection::NewInstance('User Name <username@domain.com>, User D\'Name <username@domain.com>, "User Name" <username@domain.com>');
$this->assertEquals(3, $oMails->Count());
}
}

View File

@@ -1,131 +0,0 @@
<?php
namespace MailSoTests;
class EmailTest extends \PHPUnit_Framework_TestCase
{
public function testNewInstance()
{
$oEmail = \MailSo\Mime\Email::NewInstance('admin@example.com', 'Administrator', 'Remark');
$this->assertEquals('admin@example.com', $oEmail->GetEmail());
$this->assertEquals('Administrator', $oEmail->GetDisplayName());
$this->assertEquals('Remark', $oEmail->GetRemark());
$this->assertEquals('admin', $oEmail->GetAccountName());
$this->assertEquals('example.com', $oEmail->GetDomain());
$this->assertEquals('"Administrator" <admin@example.com> (Remark)', $oEmail->ToString());
$this->assertEquals(array('Administrator', 'admin@example.com', 'Remark'), $oEmail->ToArray());
}
public function testNewInstance1()
{
$oEmail = \MailSo\Mime\Email::NewInstance('admin@example.com');
$this->assertEquals('admin@example.com', $oEmail->GetEmail());
$this->assertEquals('', $oEmail->GetDisplayName());
$this->assertEquals('', $oEmail->GetRemark());
$this->assertEquals('admin@example.com', $oEmail->ToString());
$this->assertEquals(array('', 'admin@example.com', ''), $oEmail->ToArray());
}
public function testNewInstance2()
{
$oEmail = \MailSo\Mime\Email::NewInstance('admin@example.com', 'Administrator');
$this->assertEquals('admin@example.com', $oEmail->GetEmail());
$this->assertEquals('Administrator', $oEmail->GetDisplayName());
$this->assertEquals('', $oEmail->GetRemark());
$this->assertEquals('"Administrator" <admin@example.com>', $oEmail->ToString());
$this->assertEquals(array('Administrator', 'admin@example.com', ''), $oEmail->ToArray());
}
public function testNewInstance3()
{
$oEmail = \MailSo\Mime\Email::NewInstance('admin@example.com', '', 'Remark');
$this->assertEquals('admin@example.com', $oEmail->GetEmail());
$this->assertEquals('', $oEmail->GetDisplayName());
$this->assertEquals('Remark', $oEmail->GetRemark());
$this->assertEquals('<admin@example.com> (Remark)', $oEmail->ToString());
$this->assertEquals(array('', 'admin@example.com', 'Remark'), $oEmail->ToArray());
}
/**
* @expectedException \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function testNewInstance4()
{
\MailSo\Mime\Email::NewInstance('');
}
public function testParse1()
{
$oEmail = \MailSo\Mime\Email::Parse('help@example.com');
$this->assertEquals('help@example.com', $oEmail->GetEmail());
$oEmail = \MailSo\Mime\Email::Parse('<help@example.com>');
$this->assertEquals('help@example.com', $oEmail->GetEmail());
}
public function testParse2()
{
$oEmail = \MailSo\Mime\Email::Parse('"Тест" <help@example.com> (Ремарка)');
$this->assertEquals('"Тест" <help@example.com> (Ремарка)', $oEmail->ToString());
$this->assertEquals('"=?utf-8?B?0KLQtdGB0YI=?=" <help@example.com> (=?utf-8?B?0KDQtdC80LDRgNC60LA=?=)', $oEmail->ToString(true));
}
/**
* @expectedException \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function testParse5()
{
\MailSo\Mime\Email::Parse('');
}
/**
* @expectedException \MailSo\Base\Exceptions\InvalidArgumentException
*/
public function testParse6()
{
\MailSo\Mime\Email::Parse('example.com');
}
public function testParsePuny1()
{
$oMail = \MailSo\Mime\Email::Parse('help@xn--d1acufc.xn--p1ai');
$this->assertEquals('help@xn--d1acufc.xn--p1ai', $oMail->ToString());
$this->assertEquals('help@домен.рф', $oMail->ToString(false, true));
}
public function testParsePuny2()
{
$oMail = \MailSo\Mime\Email::Parse('help@домен.рф');
$this->assertEquals('help@xn--d1acufc.xn--p1ai', $oMail->ToString());
$this->assertEquals('help@домен.рф', $oMail->ToString(false, true));
}
public static function providerForParse()
{
return array(
array('test <help@example.com>',
array('test', 'help@example.com', '')),
array('test<help@example.com>',
array('test', 'help@example.com', '')),
array('test< help@example.com >',
array('test', 'help@example.com', '')),
array('<help@example.com> (Remark)',
array('', 'help@example.com', 'Remark')),
array('"New \" Admin" <help@example.com> (Rem)',
array('New " Admin', 'help@example.com', 'Rem')),
array('"Тест" <help@example.com> (Ремарка)',
array('Тест', 'help@example.com', 'Ремарка')),
array('Microsoft Outlook<MicrosoftExchange329e71ec88ae4615bbc36ab6ce41109e@PPTH.PRIVATE>',
array('Microsoft Outlook', 'microsoftexchange329e71ec88ae4615bbc36ab6ce41109e@ppth.private', '')),
);
}
/**
* @dataProvider providerForParse
*/
public function testParseWithProvider($sValue, $aResult)
{
$oMail = \MailSo\Mime\Email::Parse($sValue);
$this->assertEquals($aResult, $oMail->ToArray());
}
}

22
vendors/jquery-backstretch/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,22 @@
Copyright (c) 2012 Scott Robbin
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

136
vendors/jquery-backstretch/README.md vendored Normal file
View File

@@ -0,0 +1,136 @@
# Backstretch
Backstretch is a simple jQuery plugin that allows you to add a dynamically-resized, slideshow-capable background image to any page or element. The image will stretch to fit the page/element, and will automatically resize as the window/element size changes.
## Demo
There are a couple of examples included with this package, or feel free to check it out live [on the project page itself](http://srobbin.com/jquery-plugins/backstretch/).
## Setup
Include the jQuery library (version 1.7 or newer) and Backstretch plugin files in your webpage (preferably at the bottom of the page, before the closing BODY tag):
```html
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="jquery.backstretch.min.js"></script>
<script>
// To attach Backstrech as the body's background
$.backstretch("path/to/image.jpg");
// You may also attach Backstretch to a block-level element
$(".foo").backstretch("path/to/image.jpg");
// Or, to start a slideshow, just pass in an array of images
$(".foo").backstretch([
"path/to/image.jpg",
"path/to/image2.jpg",
"path/to/image3.jpg"
], {duration: 4000});
</script>
```
## Options
| Name | Description | Type | Default |
|------|-------------|------|---------|
| `centeredX` | The ratio of the width/height of the image doesn't always jive with the width/height of the window. This parameter controls whether or not we center the image on the X axis to account for the discrepancy. | Boolean | true |
| `centeredY` | This parameter controls whether or not we center the image on the Y axis to account for the aforementioned discrepancy. | Boolean | true |
| `fade` | This is the speed at which the image will fade in. Integers in milliseconds are accepted, as well as standard jQuery speed strings (slow, normal, fast). | Integer or String | 0 |
| `duration` | The amount of time in between slides, when using Backstretch as a slideshow, expressed as the number of milliseconds. | Integer | 5000 |
## Slideshow API
Once you've instantiated a Backstretch slideshow, there are many actions that you can perform it:
```javascript
// Start a slideshow
$('.foo').backstretch([
'path/to/image.jpg',
'path/to/image2.jpg',
'path/to/image3.jpg'
]);
// Pause the slideshow
$('.foo').backstretch("pause");
// Advance to the next slide
$('.foo').backstretch("next");
```
| Method | Description |
|------|-------------|
| `.backstretch("show", n)` | Jump to the slide at a given index, where n is the number of the image that you'd like to display. Slide number starts at 0. |
| `.backstretch("prev")` | Display the previous image in a slideshow. |
| `.backstretch("next")` | Advance to the next image in a slideshow. |
| `.backstretch("pause")` | Pause the slideshow. |
| `.backstretch("resume")` | Resume a paused slideshow. |
| `.backstretch("destroy", preserveBackground)` | Destroy the Backstretch instance. Optionally, you can pass in a Boolean parameter, preserveBackground, to determine whether or not you'd like to keep the current image stretched as the background image. |
| `.backstretch("resize")` | This method is called automatically when the container (window or block-level element) is resized, however you can always call this manually if needed. |
## Public Variables
Sometimes, you'll want to access Backstretch's images after you've instantiated the plugin. For example, perhaps you'd like to be able add more images to a slideshow. Doing so is easy. You can access the images array as follows:
```javascript
$('.foo').backstretch([
'path/to/image.jpg',
'path/to/image2.jpg',
'path/to/image3.jpg'
]);
// Access the instance
var instance = $('.foo').data('backstretch');
// Then, you can manipulate the images array directly
instance.images.push('path/to/image4.jpg')
```
Additionally, the current index of a slideshow is available through the instance as well:
```javascript
$("body").data("backstretch").index;
```
## Events
### backstretch.before
Backstretch will fire a "backstretch.before" event before a new image loads, triggering a function that is passed the event, Backstretch instance, and index of the image that will be displayed. If you listen for that event, you can, for example, coordinate other changes to coincide with your slideshow.
```javascript
$(window).on("backstretch.before", function (e, instance, index) {
// If we wanted to stop the slideshow after it reached the end
if (index === instance.images.length - 1) {
instance.pause();
};
});
```
### backstretch.after
Backstretch will also fire a "backstretch.after" event after the new images has completed loading.
```javascript
$(window).on("backstretch.after", function (e, instance, index) {
// Do something
});
```
## Changelog
### Version 2.0
* Now accepts an array of images to create a slideshow
* Can attach Backstretch to any block-level element, not just the body
* Deprecated "speed" option in favor of "fade" for fadeIn timing
* Added "duration" option, and Slideshow API
### Version 1.2
* You can now called backstretch twice, and it will replace the existing image.
### Version 1.1
* Added 'centeredX' and 'centeredY' options.
* Removed 'hideUntilReady' option. It looks pretty bad if you don't hide the image until it's fully loaded.
* Fixed IE img onload bug.
* Now supports iPhone/iPad orientation changes.

View File

@@ -0,0 +1,377 @@
/*! Backstretch - v2.0.4 - 2013-06-19
* http://srobbin.com/jquery-plugins/backstretch/
* Copyright (c) 2013 Scott Robbin; Licensed MIT */
;(function ($, window, undefined) {
'use strict';
/* PLUGIN DEFINITION
* ========================= */
$.fn.backstretch = function (images, options) {
// We need at least one image or method name
if (images === undefined || images.length === 0) {
$.error("No images were supplied for Backstretch");
}
/*
* Scroll the page one pixel to get the right window height on iOS
* Pretty harmless for everyone else
*/
if ($(window).scrollTop() === 0 ) {
window.scrollTo(0, 0);
}
return this.each(function () {
var $this = $(this)
, obj = $this.data('backstretch');
// Do we already have an instance attached to this element?
if (obj) {
// Is this a method they're trying to execute?
if (typeof images == 'string' && typeof obj[images] == 'function') {
// Call the method
obj[images](options);
// No need to do anything further
return;
}
// Merge the old options with the new
options = $.extend(obj.options, options);
// Remove the old instance
obj.destroy(true);
}
obj = new Backstretch(this, images, options);
$this.data('backstretch', obj);
});
};
// If no element is supplied, we'll attach to body
$.backstretch = function (images, options) {
// Return the instance
return $('body')
.backstretch(images, options)
.data('backstretch');
};
// Custom selector
$.expr[':'].backstretch = function(elem) {
return $(elem).data('backstretch') !== undefined;
};
/* DEFAULTS
* ========================= */
$.fn.backstretch.defaults = {
centeredX: true // Should we center the image on the X axis?
, centeredY: true // Should we center the image on the Y axis?
, duration: 5000 // Amount of time in between slides (if slideshow)
, fade: 0 // Speed of fade transition between slides
};
/* STYLES
*
* Baked-in styles that we'll apply to our elements.
* In an effort to keep the plugin simple, these are not exposed as options.
* That said, anyone can override these in their own stylesheet.
* ========================= */
var styles = {
wrap: {
left: 0
, top: 0
, overflow: 'hidden'
, margin: 0
, padding: 0
, height: '100%'
, width: '100%'
, zIndex: -999999
}
, img: {
position: 'absolute'
, display: 'none'
, margin: 0
, padding: 0
, border: 'none'
, width: 'auto'
, height: 'auto'
, maxHeight: 'none'
, maxWidth: 'none'
, zIndex: -999999
}
};
/* CLASS DEFINITION
* ========================= */
var Backstretch = function (container, images, options) {
this.options = $.extend({}, $.fn.backstretch.defaults, options || {});
/* In its simplest form, we allow Backstretch to be called on an image path.
* e.g. $.backstretch('/path/to/image.jpg')
* So, we need to turn this back into an array.
*/
this.images = $.isArray(images) ? images : [images];
// Preload images
$.each(this.images, function () {
$('<img />')[0].src = this;
});
// Convenience reference to know if the container is body.
this.isBody = container === document.body;
/* We're keeping track of a few different elements
*
* Container: the element that Backstretch was called on.
* Wrap: a DIV that we place the image into, so we can hide the overflow.
* Root: Convenience reference to help calculate the correct height.
*/
this.$container = $(container);
this.$root = this.isBody ? supportsFixedPosition ? $(window) : $(document) : this.$container;
// Don't create a new wrap if one already exists (from a previous instance of Backstretch)
var $existing = this.$container.children(".backstretch").first();
this.$wrap = $existing.length ? $existing : $('<div class="backstretch"></div>').css(styles.wrap).appendTo(this.$container);
// Non-body elements need some style adjustments
if (!this.isBody) {
// If the container is statically positioned, we need to make it relative,
// and if no zIndex is defined, we should set it to zero.
var position = this.$container.css('position')
, zIndex = this.$container.css('zIndex');
this.$container.css({
position: position === 'static' ? 'relative' : position
, zIndex: zIndex === 'auto' ? 0 : zIndex
, background: 'none'
});
// Needs a higher z-index
this.$wrap.css({zIndex: -999998});
}
// Fixed or absolute positioning?
this.$wrap.css({
position: this.isBody && supportsFixedPosition ? 'fixed' : 'absolute'
});
// Set the first image
this.index = 0;
this.show(this.index);
// Listen for resize
$(window).on('resize.backstretch', $.proxy(this.resize, this))
.on('orientationchange.backstretch', $.proxy(function () {
// Need to do this in order to get the right window height
if (this.isBody && window.pageYOffset === 0) {
window.scrollTo(0, 1);
this.resize();
}
}, this));
};
/* PUBLIC METHODS
* ========================= */
Backstretch.prototype = {
resize: function () {
try {
var bgCSS = {left: 0, top: 0}
, rootWidth = this.isBody ? this.$root.width() : this.$root.innerWidth()
, bgWidth = rootWidth
, rootHeight = this.isBody ? ( window.innerHeight ? window.innerHeight : this.$root.height() ) : this.$root.innerHeight()
, bgHeight = bgWidth / this.$img.data('ratio')
, bgOffset;
// Make adjustments based on image ratio
if (bgHeight >= rootHeight) {
bgOffset = (bgHeight - rootHeight) / 2;
if(this.options.centeredY) {
bgCSS.top = '-' + bgOffset + 'px';
}
} else {
bgHeight = rootHeight;
bgWidth = bgHeight * this.$img.data('ratio');
bgOffset = (bgWidth - rootWidth) / 2;
if(this.options.centeredX) {
bgCSS.left = '-' + bgOffset + 'px';
}
}
this.$wrap.css({width: rootWidth, height: rootHeight})
.find('img:not(.deleteable)').css({width: bgWidth, height: bgHeight}).css(bgCSS);
} catch(err) {
// IE7 seems to trigger resize before the image is loaded.
// This try/catch block is a hack to let it fail gracefully.
}
return this;
}
// Show the slide at a certain position
, show: function (newIndex) {
// Validate index
if (Math.abs(newIndex) > this.images.length - 1) {
return;
}
// Vars
var self = this
, oldImage = self.$wrap.find('img').addClass('deleteable')
, evtOptions = { relatedTarget: self.$container[0] };
// Trigger the "before" event
self.$container.trigger($.Event('backstretch.before', evtOptions), [self, newIndex]);
// Set the new index
this.index = newIndex;
// Pause the slideshow
clearInterval(self.interval);
// New image
self.$img = $('<img />')
.css(styles.img)
.bind('load', function (e) {
var imgWidth = this.width || $(e.target).width()
, imgHeight = this.height || $(e.target).height();
// Save the ratio
$(this).data('ratio', imgWidth / imgHeight);
// Show the image, then delete the old one
// "speed" option has been deprecated, but we want backwards compatibilty
$(this).fadeIn(self.options.speed || self.options.fade, function () {
oldImage.remove();
// Resume the slideshow
if (!self.paused) {
self.cycle();
}
// Trigger the "after" and "show" events
// "show" is being deprecated
$(['after', 'show']).each(function () {
self.$container.trigger($.Event('backstretch.' + this, evtOptions), [self, newIndex]);
});
});
// Resize
self.resize();
})
.appendTo(self.$wrap);
// Hack for IE img onload event
self.$img.attr('src', self.images[newIndex]);
return self;
}
, next: function () {
// Next slide
return this.show(this.index < this.images.length - 1 ? this.index + 1 : 0);
}
, prev: function () {
// Previous slide
return this.show(this.index === 0 ? this.images.length - 1 : this.index - 1);
}
, pause: function () {
// Pause the slideshow
this.paused = true;
return this;
}
, resume: function () {
// Resume the slideshow
this.paused = false;
this.next();
return this;
}
, cycle: function () {
// Start/resume the slideshow
if(this.images.length > 1) {
// Clear the interval, just in case
clearInterval(this.interval);
this.interval = setInterval($.proxy(function () {
// Check for paused slideshow
if (!this.paused) {
this.next();
}
}, this), this.options.duration);
}
return this;
}
, destroy: function (preserveBackground) {
// Stop the resize events
$(window).off('resize.backstretch orientationchange.backstretch');
// Clear the interval
clearInterval(this.interval);
// Remove Backstretch
if(!preserveBackground) {
this.$wrap.remove();
}
this.$container.removeData('backstretch');
}
};
/* SUPPORTS FIXED POSITION?
*
* Based on code from jQuery Mobile 1.1.0
* http://jquerymobile.com/
*
* In a nutshell, we need to figure out if fixed positioning is supported.
* Unfortunately, this is very difficult to do on iOS, and usually involves
* injecting content, scrolling the page, etc.. It's ugly.
* jQuery Mobile uses this workaround. It's not ideal, but works.
*
* Modified to detect IE6
* ========================= */
var supportsFixedPosition = (function () {
var ua = navigator.userAgent
, platform = navigator.platform
// Rendering engine is Webkit, and capture major version
, wkmatch = ua.match( /AppleWebKit\/([0-9]+)/ )
, wkversion = !!wkmatch && wkmatch[ 1 ]
, ffmatch = ua.match( /Fennec\/([0-9]+)/ )
, ffversion = !!ffmatch && ffmatch[ 1 ]
, operammobilematch = ua.match( /Opera Mobi\/([0-9]+)/ )
, omversion = !!operammobilematch && operammobilematch[ 1 ]
, iematch = ua.match( /MSIE ([0-9]+)/ )
, ieversion = !!iematch && iematch[ 1 ];
return !(
// iOS 4.3 and older : Platform is iPhone/Pad/Touch and Webkit version is less than 534 (ios5)
((platform.indexOf( "iPhone" ) > -1 || platform.indexOf( "iPad" ) > -1 || platform.indexOf( "iPod" ) > -1 ) && wkversion && wkversion < 534) ||
// Opera Mini
(window.operamini && ({}).toString.call( window.operamini ) === "[object OperaMini]") ||
(operammobilematch && omversion < 7458) ||
//Android lte 2.1: Platform is Android and Webkit version is less than 533 (Android 2.2)
(ua.indexOf( "Android" ) > -1 && wkversion && wkversion < 533) ||
// Firefox Mobile before 6.0 -
(ffversion && ffversion < 6) ||
// WebOS less than 3
("palmGetResource" in window && wkversion && wkversion < 534) ||
// MeeGo
(ua.indexOf( "MeeGo" ) > -1 && ua.indexOf( "NokiaBrowser/8.5.0" ) > -1) ||
// IE6
(ieversion && ieversion <= 6)
);
}());
}(jQuery, window));

View File

@@ -0,0 +1,4 @@
/*! Backstretch - v2.0.4 - 2013-06-19
* http://srobbin.com/jquery-plugins/backstretch/
* Copyright (c) 2013 Scott Robbin; Licensed MIT */
(function(a,d,p){a.fn.backstretch=function(c,b){(c===p||0===c.length)&&a.error("No images were supplied for Backstretch");0===a(d).scrollTop()&&d.scrollTo(0,0);return this.each(function(){var d=a(this),g=d.data("backstretch");if(g){if("string"==typeof c&&"function"==typeof g[c]){g[c](b);return}b=a.extend(g.options,b);g.destroy(!0)}g=new q(this,c,b);d.data("backstretch",g)})};a.backstretch=function(c,b){return a("body").backstretch(c,b).data("backstretch")};a.expr[":"].backstretch=function(c){return a(c).data("backstretch")!==p};a.fn.backstretch.defaults={centeredX:!0,centeredY:!0,duration:5E3,fade:0};var r={left:0,top:0,overflow:"hidden",margin:0,padding:0,height:"100%",width:"100%",zIndex:-999999},s={position:"absolute",display:"none",margin:0,padding:0,border:"none",width:"auto",height:"auto",maxHeight:"none",maxWidth:"none",zIndex:-999999},q=function(c,b,e){this.options=a.extend({},a.fn.backstretch.defaults,e||{});this.images=a.isArray(b)?b:[b];a.each(this.images,function(){a("<img />")[0].src=this});this.isBody=c===document.body;this.$container=a(c);this.$root=this.isBody?l?a(d):a(document):this.$container;c=this.$container.children(".backstretch").first();this.$wrap=c.length?c:a('<div class="backstretch"></div>').css(r).appendTo(this.$container);this.isBody||(c=this.$container.css("position"),b=this.$container.css("zIndex"),this.$container.css({position:"static"===c?"relative":c,zIndex:"auto"===b?0:b,background:"none"}),this.$wrap.css({zIndex:-999998}));this.$wrap.css({position:this.isBody&&l?"fixed":"absolute"});this.index=0;this.show(this.index);a(d).on("resize.backstretch",a.proxy(this.resize,this)).on("orientationchange.backstretch",a.proxy(function(){this.isBody&&0===d.pageYOffset&&(d.scrollTo(0,1),this.resize())},this))};q.prototype={resize:function(){try{var a={left:0,top:0},b=this.isBody?this.$root.width():this.$root.innerWidth(),e=b,g=this.isBody?d.innerHeight?d.innerHeight:this.$root.height():this.$root.innerHeight(),j=e/this.$img.data("ratio"),f;j>=g?(f=(j-g)/2,this.options.centeredY&&(a.top="-"+f+"px")):(j=g,e=j*this.$img.data("ratio"),f=(e-b)/2,this.options.centeredX&&(a.left="-"+f+"px"));this.$wrap.css({width:b,height:g}).find("img:not(.deleteable)").css({width:e,height:j}).css(a)}catch(h){}return this},show:function(c){if(!(Math.abs(c)>this.images.length-1)){var b=this,e=b.$wrap.find("img").addClass("deleteable"),d={relatedTarget:b.$container[0]};b.$container.trigger(a.Event("backstretch.before",d),[b,c]);this.index=c;clearInterval(b.interval);b.$img=a("<img />").css(s).bind("load",function(f){var h=this.width||a(f.target).width();f=this.height||a(f.target).height();a(this).data("ratio",h/f);a(this).fadeIn(b.options.speed||b.options.fade,function(){e.remove();b.paused||b.cycle();a(["after","show"]).each(function(){b.$container.trigger(a.Event("backstretch."+this,d),[b,c])})});b.resize()}).appendTo(b.$wrap);b.$img.attr("src",b.images[c]);return b}},next:function(){return this.show(this.index<this.images.length-1?this.index+1:0)},prev:function(){return this.show(0===this.index?this.images.length-1:this.index-1)},pause:function(){this.paused=!0;return this},resume:function(){this.paused=!1;this.next();return this},cycle:function(){1<this.images.length&&(clearInterval(this.interval),this.interval=setInterval(a.proxy(function(){this.paused||this.next()},this),this.options.duration));return this},destroy:function(c){a(d).off("resize.backstretch orientationchange.backstretch");clearInterval(this.interval);c||this.$wrap.remove();this.$container.removeData("backstretch")}};var l,f=navigator.userAgent,m=navigator.platform,e=f.match(/AppleWebKit\/([0-9]+)/),e=!!e&&e[1],h=f.match(/Fennec\/([0-9]+)/),h=!!h&&h[1],n=f.match(/Opera Mobi\/([0-9]+)/),t=!!n&&n[1],k=f.match(/MSIE ([0-9]+)/),k=!!k&&k[1];l=!((-1<m.indexOf("iPhone")||-1<m.indexOf("iPad")||-1<m.indexOf("iPod"))&&e&&534>e||d.operamini&&"[object OperaMini]"==={}.toString.call(d.operamini)||n&&7458>t||-1<f.indexOf("Android")&&e&&533>e||h&&6>h||"palmGetResource"in d&&e&&534>e||-1<f.indexOf("MeeGo")&&-1<f.indexOf("NokiaBrowser/8.5.0")||k&&6>=k)})(jQuery,window);

72848
vendors/phpunit.phar vendored

File diff suppressed because one or more lines are too long

26
vendors/queue/LICENSE vendored Normal file
View File

@@ -0,0 +1,26 @@
Copyright (c) 2012, Michael Bostock
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* The name Michael Bostock may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

83
vendors/queue/README.md vendored Normal file
View File

@@ -0,0 +1,83 @@
# queue.js
**Queue.js** is yet another asynchronous helper library for JavaScript. Think of it as a minimalist version of [Async.js](https://github.com/caolan/async) that allows fine-tuning over parallelism. Or, think of it as a version of [TameJs](https://github.com/maxtaco/tamejs/) that does not use code generation.
For example, if you wanted to stat two files in parallel:
```js
queue()
.defer(fs.stat, __dirname + "/../Makefile")
.defer(fs.stat, __dirname + "/../package.json")
.await(function(error, file1, file2) { console.log(file1, file2); });
```
Or, if you wanted to run a bazillion asynchronous tasks (here represented as an array of closures) serially:
```js
var q = queue(1);
tasks.forEach(function(t) { q.defer(t); });
q.awaitAll(function(error, results) { console.log("all done!"); });
```
Queue.js can be run inside Node.js or in a browser.
## Installation
In a browser, you can use the official hosted copy on [d3js.org](http://d3js.org):
```html
<script src="http://d3js.org/queue.v1.min.js"></script>
```
Queue.js supports the asynchronous module definition (AMD) API. For example, if you use [RequireJS](http://requirejs.org/), you may load as follows:
```js
require.config({paths: {queue: "http://d3js.org/queue.v1.min"}});
require(["queue"], function(queue) {
console.log(queue.version);
});
```
In Node, use [NPM](http://npmjs.org) to install:
```bash
npm install queue-async
```
And then `require("queue-async")`. (The package name is [queue-async](https://npmjs.org/package/queue-async) because the name “queue” was already taken.)
## API Reference
### queue([parallelism])
Constructs a new queue with the specified *parallelism*. If *parallelism* is not specified, the queue has infinite parallelism. Otherwise, *parallelism* is a positive integer. For example, if *parallelism* is 1, then all tasks will be run in series. If *parallelism* is 3, then at most three tasks will be allowed to proceed concurrently; this is useful, for example, when loading resources in a web browser.
### queue.defer(task[, arguments…])
Adds the specified asynchronous *task* function to the queue, with any optional *arguments*. The *task* will be called with the specified optional arguments and an additional callback argument; the callback must then be invoked by the task when it has finished. The task must invoke the callback with two arguments: the error, if any, and the result of the task. For example:
```js
function simpleTask(callback) {
setTimeout(function() {
callback(null, {answer: 42});
}, 250);
}
```
If an error occurs, any tasks that were scheduled *but not yet started* will not run. For a serial queue (of *parallelism* 1), this means that a task will only run if all previous tasks succeed. For a queue with higher parallelism, only the first error that occurs is reported to the await callback, and tasks that were started before the error occurred will continue to run; note, however, that their results will not be reported to the await callback.
Tasks can only be deferred before the *await* callback is set. If a task is deferred after the await callback is set, the behavior of the queue is undefined.
### queue.await(callback)
### queue.awaitAll(callback)
Sets the *callback* to be invoked when all deferred tasks have finished.
The first argument to the *callback* is the first error that occurred, or null if no error occurred. If an error occurred, there are no additional arguments to the callback. Otherwise, the *await* callback is passed each result as an additional separate argument, while the *awaitAll* callback is passed a single array of results as the second argument.
If all tasks complete before the *await* or *awaitAll* callback is set, the callback will be invoked immediately. This method should only be called once, after any tasks have been deferred. If the await callback is set multiple times, or set before a task is deferred, the behavior of the queue is undefined.
## Callbacks
The callbacks follow the Node.js convention where the first argument is an optional error object and the second argument is the result of the task. Queue.js does not support asynchronous functions that return multiple results; however, you can homogenize such functions by wrapping them and converting multiple results into a single object or array.

80
vendors/queue/queue.js vendored Normal file
View File

@@ -0,0 +1,80 @@
(function() {
var slice = [].slice;
function queue(parallelism) {
var q,
tasks = [],
started = 0, // number of tasks that have been started (and perhaps finished)
active = 0, // number of tasks currently being executed (started but not finished)
remaining = 0, // number of tasks not yet finished
popping, // inside a synchronous task callback?
error = null,
await = noop,
all;
if (!parallelism) parallelism = Infinity;
function pop() {
while (popping = started < tasks.length && active < parallelism) {
var i = started++,
t = tasks[i],
a = slice.call(t, 1);
a.push(callback(i));
++active;
t[0].apply(null, a);
}
}
function callback(i) {
return function(e, r) {
--active;
if (error != null) return;
if (e != null) {
error = e; // ignore new tasks and squelch active callbacks
started = remaining = NaN; // stop queued tasks from starting
notify();
} else {
tasks[i] = r;
if (--remaining) popping || pop();
else notify();
}
};
}
function notify() {
if (error != null) await(error);
else if (all) await(error, tasks);
else await.apply(null, [error].concat(tasks));
}
return q = {
defer: function() {
if (!error) {
tasks.push(arguments);
++remaining;
pop();
}
return q;
},
await: function(f) {
await = f;
all = false;
if (!remaining) notify();
return q;
},
awaitAll: function(f) {
await = f;
all = true;
if (!remaining) notify();
return q;
}
};
}
function noop() {}
queue.version = "1.0.7";
if (typeof define === "function" && define.amd) define(function() { return queue; });
else if (typeof module === "object" && module.exports) module.exports = queue;
else this.queue = queue;
})();

1
vendors/queue/queue.min.js vendored Normal file
View File

@@ -0,0 +1 @@
!function(){function n(n){function e(){for(;i=a<c.length&&n>p;){var u=a++,e=c[u],o=t.call(e,1);o.push(l(u)),++p,e[0].apply(null,o)}}function l(n){return function(u,t){--p,null==s&&(null!=u?(s=u,a=d=0/0,o()):(c[n]=t,--d?i||e():o()))}}function o(){null!=s?m(s):f?m(s,c):m.apply(null,[s].concat(c))}var r,i,f,c=[],a=0,p=0,d=0,s=null,m=u;return n||(n=1/0),r={defer:function(){return s||(c.push(arguments),++d,e()),r},await:function(n){return m=n,f=!1,d||o(),r},awaitAll:function(n){return m=n,f=!0,d||o(),r}}}function u(){}var t=[].slice;n.version="1.0.7","function"==typeof define&&define.amd?define(function(){return n}):"object"==typeof module&&module.exports?module.exports=n:this.queue=n}();

View File

@@ -1,2 +1,2 @@
/*! RainLoop Index Helper v1.2 (c) 2014 RainLoop Team; Licensed under MIT */
!function(t,n,e){function s(){}s.prototype.s=t.sessionStorage,s.prototype.t=t.top||t,s.prototype.getHash=function(){var t=null;if(this.s)t=this.s.getItem("__rlA")||null;else if(this.t){var n=this.t.name&&e&&"{"===this.t.name.toString().substr(0,1)?e.parse(this.t.name.toString()):null;t=n?n.__rlA||null:null}return t},s.prototype.setHash=function(){var n=t.rainloopAppData,s=null;this.s?this.s.setItem("__rlA",n&&n.AuthAccountHash?n.AuthAccountHash:""):this.t&&e&&(s={},s.__rlA=n&&n.AuthAccountHash?n.AuthAccountHash:"",this.t.name=e.stringify(s))},s.prototype.clearHash=function(){this.s?this.s.setItem("__rlA",""):this.t&&(this.t.name="")},t._rlhh=new s,t.__rlah=function(){return t._rlhh?t._rlhh.getHash():null},t.__rlah_set=function(){t._rlhh&&t._rlhh.setHash()},t.__rlah_clear=function(){t._rlhh&&t._rlhh.clearHash()},t.__includeScr=function(t){n.write(unescape('%3Cscript data-cfasync="false" type="text/javascript" src="'+t+'"%3E%3C/script%3E'))},t.__showError=function(){var e=n.getElementById("rl-loading"),s=n.getElementById("rl-loading-error");e&&(e.style.display="none"),s&&(s.style.display="block"),t.SimplePace&&t.SimplePace.set(100)},t.__simplePace=function(n){t.SimplePace&&t.SimplePace.add(n)},t.__runBoot=function(n){t.__APP_BOOT&&!n?t.__APP_BOOT(function(t){t||__showError()}):__showError()}}(window,window.document,window.JSON);
/*! RainLoop Index Helper v1.3 (c) 2014 RainLoop Team; Licensed under MIT */
!function(t,n,e){function s(){}s.prototype.s=t.sessionStorage,s.prototype.t=t.top||t,s.prototype.getHash=function(){var t=null;if(this.s)t=this.s.getItem("__rlA")||null;else if(this.t){var n=this.t.name&&e&&"{"===this.t.name.toString().substr(0,1)?e.parse(this.t.name.toString()):null;t=n?n.__rlA||null:null}return t},s.prototype.setHash=function(){var n=t.rainloopAppData,s=null;this.s?this.s.setItem("__rlA",n&&n.AuthAccountHash?n.AuthAccountHash:""):this.t&&e&&(s={},s.__rlA=n&&n.AuthAccountHash?n.AuthAccountHash:"",this.t.name=e.stringify(s))},s.prototype.clearHash=function(){this.s?this.s.setItem("__rlA",""):this.t&&(this.t.name="")},t._rlhh=new s,t.__rlah=function(){return t._rlhh?t._rlhh.getHash():null},t.__rlah_set=function(){t._rlhh&&t._rlhh.setHash()},t.__rlah_clear=function(){t._rlhh&&t._rlhh.clearHash()},t.__includeScr=function(t){n.write(unescape('%3Cscript data-cfasync="false" type="text/javascript" src="'+t+'"%3E%3C/script%3E'))},t.__showError=function(){var e=n.getElementById("rl-loading"),s=n.getElementById("rl-loading-error");e&&(e.style.display="none"),s&&(s.style.display="block"),t.SimplePace&&t.SimplePace.set(100)},t.__simplePace=function(n){t.SimplePace&&t.SimplePace.add(n)},t.__runBoot=function(n){t.__APP_BOOT&&!n?t.__APP_BOOT(function(t){t||__showError()}):__showError()}}(window,window.document,window.JSON);

12
vendors/rl/rl.js vendored
View File

@@ -1,5 +1,5 @@
/*! RainLoop Index Helper v1.2 (c) 2013 RainLoop Team; Licensed under MIT */
(function (window, document, JSON) {
/*! RainLoop Index Helper v1.3 (c) 2014 RainLoop Team; Licensed under MIT */
(function (window, document, JSON, undefined) {
/**
* @constructor
@@ -7,7 +7,7 @@
function CRLTopDriver() {}
CRLTopDriver.prototype.s = window['sessionStorage'];
CRLTopDriver.prototype.t = window['top'] || window;
/**
@@ -51,7 +51,7 @@
window['__rlah'] = function () {
return window['_rlhh'] ? window['_rlhh']['getHash']() : null;
};
window['__rlah_set'] = function () {
if (window['_rlhh']) {
window['_rlhh']['setHash']();
@@ -68,7 +68,7 @@
window['__includeScr'] = function (sSrc) {
document.write(unescape('%3Csc' + 'ript data-cfasync="false" type="text/jav' + 'ascr' + 'ipt" sr' + 'c="' + sSrc + '"%3E%3C/' + 'scr' + 'ipt%3E'));
};
window['__showError'] = function () {
var oR = document.getElementById('rl-loading'),
oL = document.getElementById('rl-loading-error');
@@ -95,5 +95,5 @@
__showError();
}
};
}(window, window.document, window.JSON));

View File

@@ -29,6 +29,7 @@ module.exports = {
'JSEncrypt': 'window.JSEncrypt',
'$LAB': 'window.$LAB',
'SimplePace': 'window.SimplePace',
'queue': 'window.queue',
'moment': 'moment',
'ifvisible': 'ifvisible',
'crossroads': 'crossroads',