A lot small fixes

This commit is contained in:
RainLoop Team 2015-06-04 22:02:31 +04:00
parent 4457cdbc23
commit 09334159c2
38 changed files with 1496 additions and 239 deletions

View file

@ -10,3 +10,12 @@ function __get_custom_data_full_path()
return ''; return '';
return '/var/external-rainloop-data-folder/'; // custom data folder path return '/var/external-rainloop-data-folder/'; // custom data folder path
} }
/**
* @return string
*/
function __get_additional_configuration_name()
{
return '';
return defined('APP_SITE') && 0 < strlen(APP_SITE) ? APP_SITE.'.ini' : ''; // additional configuration file name
}

View file

@ -7,7 +7,7 @@
window = require('window'), window = require('window'),
_ = require('_'), _ = require('_'),
ko = require('ko'), ko = require('ko'),
SimplePace = require('SimplePace'), progressJs = require('progressJs'),
Enums = require('Common/Enums'), Enums = require('Common/Enums'),
Utils = require('Common/Utils'), Utils = require('Common/Utils'),
@ -280,9 +280,9 @@
} }
} }
if (SimplePace) if (progressJs)
{ {
SimplePace.set(100); progressJs().end();
} }
}; };

View file

@ -7,7 +7,7 @@
window = require('window'), window = require('window'),
_ = require('_'), _ = require('_'),
$ = require('$'), $ = require('$'),
SimplePace = require('SimplePace'), progressJs = require('progressJs'),
Tinycon = require('Tinycon'), Tinycon = require('Tinycon'),
Enums = require('Common/Enums'), Enums = require('Common/Enums'),
@ -255,6 +255,7 @@
{ {
var var
self = this, self = this,
sTrashFolder = FolderStore.trashFolder(),
sSpamFolder = FolderStore.spamFolder() sSpamFolder = FolderStore.spamFolder()
; ;
@ -262,11 +263,12 @@
var var
bSpam = sSpamFolder === oItem['To'], bSpam = sSpamFolder === oItem['To'],
bTrash = sTrashFolder === oItem['To'],
bHam = !bSpam && sSpamFolder === oItem['From'] && Cache.getFolderInboxName() === oItem['To'] bHam = !bSpam && sSpamFolder === oItem['From'] && Cache.getFolderInboxName() === oItem['To']
; ;
Remote.messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'], Remote.messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'],
bSpam ? 'SPAM' : (bHam ? 'HAM' : '')); bSpam ? 'SPAM' : (bHam ? 'HAM' : ''), bSpam || bTrash);
}); });
this.oMoveCache = {}; this.oMoveCache = {};
@ -1305,9 +1307,9 @@
{ {
kn.hideLoading(); kn.hideLoading();
if (SimplePace) if (progressJs)
{ {
SimplePace.set(100); progressJs().end();
} }
}; };
@ -1332,10 +1334,9 @@
bTwitter = Settings.settingsGet('AllowTwitterSocial') bTwitter = Settings.settingsGet('AllowTwitterSocial')
; ;
if (SimplePace) if (progressJs)
{ {
SimplePace.set(70); progressJs().set(70);
SimplePace.sleep();
} }
Globals.leftPanelDisabled.subscribe(function (bValue) { Globals.leftPanelDisabled.subscribe(function (bValue) {

44
dev/External/ko.js vendored
View file

@ -811,7 +811,7 @@
'parseOnBlur': true, 'parseOnBlur': true,
'allowDragAndDrop': true, 'allowDragAndDrop': true,
'focusCallback': fFocusCallback, 'focusCallback': fFocusCallback,
'inputDelimiters': [',', ';'], 'inputDelimiters': [',', ';', '\n'],
'autoCompleteSource': fAutoCompleteSource, 'autoCompleteSource': fAutoCompleteSource,
// 'elementHook': function (oEl, oItem) { // 'elementHook': function (oEl, oItem) {
// if (oEl && oItem) // if (oEl && oItem)
@ -821,23 +821,53 @@
// } // }
// }, // },
'parseHook': function (aInput) { 'parseHook': function (aInput) {
return _.map(aInput, function (sInputValue) {
var aResult = [];
_.each(aInput, function (sInputValue) {
var var
aM = null,
aValues = [],
sValue = Utils.trim(sInputValue), sValue = Utils.trim(sInputValue),
oEmail = null oEmail = null
; ;
if ('' !== sValue) if ('' !== sValue)
{ {
aM = sValue.match(/[@]/g);
if (aM && 0 < aM.length)
{
sValue = sValue.replace(/[\r\n]+/g, '; ').replace(/[\s]+/g, ' ');
aValues = EmailModel.splitHelper(sValue, ';');
_.each(aValues, function (sV) {
oEmail = new EmailModel(); oEmail = new EmailModel();
oEmail.mailsoParse(sValue); oEmail.mailsoParse(sV);
return [oEmail.toLine(false), oEmail];
if (oEmail.email)
{
aResult.push([oEmail.toLine(false), oEmail]);
}
else
{
aResult.push(['', null]);
} }
return [sValue, null];
}); });
}
else
{
aResult.push([sInputValue, null]);
}
}
else
{
aResult.push([sInputValue, null]);
}
});
return aResult;
}, },
'change': _.bind(function (oEvent) { 'change': _.bind(function (oEvent) {
$oEl.data('EmailsTagsValue', oEvent.target.value); $oEl.data('EmailsTagsValue', oEvent.target.value);

View file

@ -36,6 +36,49 @@
return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null; return oEmailModel.initByJson(oJsonEmail) ? oEmailModel : null;
}; };
/**
* @static
* @param {string} sLine
* @param {string=} sDelimiter = ';'
* @return {Array}
*/
EmailModel.splitHelper = function (sLine, sDelimiter)
{
sDelimiter = sDelimiter || ';';
sLine = sLine.replace(/[\r\n]+/g, '; ').replace(/[\s]+/g, ' ');
var
iIndex = 0,
iLen = sLine.length,
bAt = false,
sChar = '',
sResult = ''
;
for (; iIndex < iLen; iIndex++)
{
sChar = sLine.charAt(iIndex);
switch (sChar)
{
case '@':
bAt = true;
break;
case ' ':
if (bAt)
{
bAt = false;
sResult += sDelimiter;
}
break;
}
sResult += sChar;
}
return sResult.split(sDelimiter);
};
/** /**
* @type {string} * @type {string}
*/ */

View file

@ -727,13 +727,15 @@
* @param {string} sToFolder * @param {string} sToFolder
* @param {Array} aUids * @param {Array} aUids
* @param {string=} sLearning * @param {string=} sLearning
* @param {boolean=} bMarkAsRead
*/ */
RemoteUserAjax.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids, sLearning) RemoteUserAjax.prototype.messagesMove = function (fCallback, sFolder, sToFolder, aUids, sLearning, bMarkAsRead)
{ {
this.defaultRequest(fCallback, 'MessageMove', { this.defaultRequest(fCallback, 'MessageMove', {
'FromFolder': sFolder, 'FromFolder': sFolder,
'ToFolder': sToFolder, 'ToFolder': sToFolder,
'Uids': aUids.join(','), 'Uids': aUids.join(','),
'MarkAsRead': bMarkAsRead ? '1' : '0',
'Learning': sLearning || '' 'Learning': sLearning || ''
}, null, '', ['MessageList']); }, null, '', ['MessageList']);
}; };

View file

@ -328,6 +328,8 @@
self = this, self = this,
iUnseenCount = 0, iUnseenCount = 0,
oMessage = null, oMessage = null,
sTrashFolder = FolderStore.trashFolder(),
sSpamFolder = FolderStore.spamFolder(),
aMessageList = this.messageList(), aMessageList = this.messageList(),
oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw), oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''), oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
@ -359,6 +361,11 @@
if (oToFolder) if (oToFolder)
{ {
if (sTrashFolder === oToFolder.fullNameRaw || sSpamFolder === oToFolder.fullNameRaw)
{
iUnseenCount = 0;
}
oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length); oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
if (0 < iUnseenCount) if (0 < iUnseenCount)
{ {

View file

@ -239,7 +239,6 @@ html.cssanimations {
.e-spinner .bounce2 { .e-spinner .bounce2 {
animation-delay: -0.16s; animation-delay: -0.16s;
} }
} }
@keyframes bouncedelay { @keyframes bouncedelay {

View file

@ -110,7 +110,8 @@ cfg.paths.css = {
'vendors/fontastic/styles.css', 'vendors/fontastic/styles.css',
'vendors/jquery-nanoscroller/nanoscroller.css', 'vendors/jquery-nanoscroller/nanoscroller.css',
'vendors/jquery-letterfx/jquery-letterfx.min.css', 'vendors/jquery-letterfx/jquery-letterfx.min.css',
'vendors/simple-pace/styles.css', 'vendors/progress.js/minified/progressjs.min.css',
'vendors/progress.js/minified/progressjs.rainloop.css',
'vendors/inputosaurus/inputosaurus.css', 'vendors/inputosaurus/inputosaurus.css',
'vendors/opentip/opentip.css', 'vendors/opentip/opentip.css',
'vendors/photoswipe/photoswipe.css', 'vendors/photoswipe/photoswipe.css',
@ -127,7 +128,8 @@ cfg.paths.js = {
src: [ src: [
'vendors/json2.min.js', 'vendors/json2.min.js',
'vendors/labjs/LAB.min.js', 'vendors/labjs/LAB.min.js',
'vendors/simple-pace/simple-pace-1.0.min.js', 'vendors/modernizr.js',
'vendors/progress.js/minified/progress.min.js',
'vendors/rl/rl-1.5.min.js' 'vendors/rl/rl-1.5.min.js'
] ]
}, },
@ -153,7 +155,6 @@ cfg.paths.js = {
libs: { libs: {
name: 'libs.js', name: 'libs.js',
src: [ src: [
'vendors/modernizr.js',
'vendors/underscore/1.6.0/underscore-min.js', 'vendors/underscore/1.6.0/underscore-min.js',
'vendors/jquery/jquery-1.11.2.min.js', 'vendors/jquery/jquery-1.11.2.min.js',
'vendors/jquery-ui/js/jquery-ui-1.10.3.custom.min.js', 'vendors/jquery-ui/js/jquery-ui-1.10.3.custom.min.js',

View file

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

View file

@ -126,7 +126,7 @@ class HtmlUtils
{ {
$aRemoveTags = array( $aRemoveTags = array(
'link', 'base', 'meta', 'title', 'script', 'bgsound', 'keygen', 'source', 'link', 'base', 'meta', 'title', 'script', 'bgsound', 'keygen', 'source',
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio' 'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio', 'area', 'map'
); );
if ($bClearStyleAndHead) if ($bClearStyleAndHead)
@ -755,7 +755,8 @@ class HtmlUtils
if ('' !== $sTagNameLower && \in_array($sTagNameLower, array('svg', 'head', 'link', if ('' !== $sTagNameLower && \in_array($sTagNameLower, array('svg', 'head', 'link',
'base', 'meta', 'title', 'style', 'x-script', 'script', 'bgsound', 'keygen', 'source', 'base', 'meta', 'title', 'style', 'x-script', 'script', 'bgsound', 'keygen', 'source',
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio'))) 'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset',
'video', 'audio', 'area', 'map')))
{ {
if (isset($oElement->parentNode)) if (isset($oElement->parentNode))
{ {
@ -867,7 +868,8 @@ class HtmlUtils
foreach (array( foreach (array(
'id', 'class', 'id', 'class',
'contenteditable', 'designmode', 'formaction', 'contenteditable', 'designmode', 'formaction',
'data-bind', 'data-reactid', 'xmlns', 'srcset' 'data-bind', 'data-reactid', 'xmlns', 'srcset',
'data-x-skip-style'
) as $sAttr) ) as $sAttr)
{ {
@$oElement->removeAttribute($sAttr); @$oElement->removeAttribute($sAttr);
@ -903,28 +905,51 @@ class HtmlUtils
$sAlt = $oElement->hasAttribute('alt') $sAlt = $oElement->hasAttribute('alt')
? \trim($oElement->getAttribute('alt')) : ''; ? \trim($oElement->getAttribute('alt')) : '';
if ($oElement->hasAttribute('src') && '' === $sAlt)
{
$aH = array(
'email.microsoftemail.com/open',
'github.com/notifications/beacon/',
'mandrillapp.com/track/open',
'list-manage.com/track/open'
);
$sH = $oElement->hasAttribute('height') $sH = $oElement->hasAttribute('height')
? \trim($oElement->getAttribute('height')) : ''; ? \trim($oElement->getAttribute('height')) : '';
$sW = $oElement->hasAttribute('width') // $sW = $oElement->hasAttribute('width')
? \trim($oElement->getAttribute('width')) : ''; // ? \trim($oElement->getAttribute('width')) : '';
$sStyles = $oElement->hasAttribute('style') $sStyles = $oElement->hasAttribute('style')
? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : ''; ? \preg_replace('/[\s]+/', '', \trim(\trim(\trim($oElement->getAttribute('style')), ';'))) : '';
if ($oElement->hasAttribute('src')) $sSrc = \trim($oElement->getAttribute('src'));
$bC = \in_array($sH, array('1', '0', '1px', '0px')) ||
\preg_match('/(display:none|visibility:hidden|height:0|height:[01][a-z][a-z])/i', $sStyles);
if (!$bC)
{ {
$aValues = array('4', '3', '2', '1', '0', '4px', '3px', '2px', '1px', '0px'); $sSrcLower = \strtolower($sSrc);
if (('' === $sAlt && \in_array($sH, $aValues) && \in_array($sW, $aValues)) || foreach ($aH as $sLine)
\preg_match('/(display:none|visibility:hidden)/i', \preg_replace('/[\s]+/', '', $sStyles)))
{ {
if (isset($oElement->parentNode)) if (false !== \strpos($sSrcLower, $sLine))
{ {
@$oElement->parentNode->removeChild($oElement); $bC = true;
continue; break;
} }
} }
} }
if ($bC)
{
$oElement->setAttribute('style', 'display:none');
$oElement->setAttribute('data-x-skip-style', 'true');
$oElement->setAttribute('data-x-hidden-src', $sSrc);
$oElement->removeAttribute('src');
}
}
} }
if ($oElement->hasAttribute('src')) if ($oElement->hasAttribute('src'))
@ -1002,12 +1027,14 @@ class HtmlUtils
$oElement->setAttribute('style', (empty($sStyles) ? '' : $sStyles.'; ').\implode('; ', $aStyles)); $oElement->setAttribute('style', (empty($sStyles) ? '' : $sStyles.'; ').\implode('; ', $aStyles));
} }
if ($oElement->hasAttribute('style')) if ($oElement->hasAttribute('style') && !$oElement->hasAttribute('data-x-skip-style'))
{ {
$oElement->setAttribute('style', $oElement->setAttribute('style',
\MailSo\Base\HtmlUtils::ClearStyle($oElement->getAttribute('style'), $oElement, $bHasExternals, \MailSo\Base\HtmlUtils::ClearStyle($oElement->getAttribute('style'), $oElement, $bHasExternals,
$aFoundCIDs, $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $fAdditionalExternalFilter)); $aFoundCIDs, $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $fAdditionalExternalFilter));
} }
$oElement->removeAttribute('data-x-skip-style');
} }
$sResult = $oDom->saveHTML(); $sResult = $oDom->saveHTML();
@ -1023,7 +1050,7 @@ class HtmlUtils
$sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>'; $sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>';
$sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult); $sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult); $sResult = \MailSo\Base\Utils::StripSpaces($sResult);
return \trim($sResult); return \trim($sResult);
} }
@ -1275,9 +1302,10 @@ class HtmlUtils
*/ */
public static function ConvertHtmlToPlain($sText) public static function ConvertHtmlToPlain($sText)
{ {
$sText = trim(stripslashes($sText)); $sText = \trim(\stripslashes($sText));
$sText = preg_replace('/[\s]+/', ' ', $sText); $sText = \MailSo\Base\Utils::StripSpaces($sText);
$sText = preg_replace(array(
$sText = \preg_replace(array(
"/\r/", "/\r/",
"/[\n\t]+/", "/[\n\t]+/",
'/<script[^>]*>.*?<\/script>/i', '/<script[^>]*>.*?<\/script>/i',
@ -1367,11 +1395,11 @@ class HtmlUtils
'' ''
), $sText); ), $sText);
$sText = str_ireplace('<div>',"\n<div>", $sText); $sText = \str_ireplace('<div>',"\n<div>", $sText);
$sText = strip_tags($sText, ''); $sText = \strip_tags($sText, '');
$sText = preg_replace("/\n\\s+\n/", "\n", $sText); $sText = \preg_replace("/\n\\s+\n/", "\n", $sText);
$sText = preg_replace("/[\n]{3,}/", "\n\n", $sText); $sText = \preg_replace("/[\n]{3,}/", "\n\n", $sText);
return trim($sText); return \trim($sText);
} }
} }

View file

@ -550,6 +550,17 @@ END;
return \MailSo\Base\Utils::IsAscii($sValue) ? \strtoupper($sValue) : $sValue; return \MailSo\Base\Utils::IsAscii($sValue) ? \strtoupper($sValue) : $sValue;
} }
/**
* @param string $sValue
*
* @return string
*/
public static function StripSpaces($sValue)
{
return \MailSo\Base\Utils::Trim(
\preg_replace('/[\s]+/u', ' ', $sValue));
}
/** /**
* @param string $sValue * @param string $sValue
* *
@ -1362,8 +1373,9 @@ END;
*/ */
public static function ClearFileName($sFileName) public static function ClearFileName($sFileName)
{ {
return \MailSo\Base\Utils::ClearNullBite(\preg_replace('/[\s]+/u', ' ', return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))); \MailSo\Base\Utils::StripSpaces(
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))));
} }
/** /**
@ -1373,8 +1385,8 @@ END;
*/ */
public static function ClearXss($sValue) public static function ClearXss($sValue)
{ {
return \MailSo\Base\Utils::ClearNullBite( return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue)); \str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue)));
} }
/** /**

View file

@ -56,6 +56,11 @@ class Config
*/ */
public static $LargeThreadLimit = 50; public static $LargeThreadLimit = 50;
/**
* @var bool
*/
public static $MessageAllHeaders = false;
/** /**
* @var bool * @var bool
*/ */

View file

@ -267,7 +267,7 @@ abstract class Driver
foreach ($mDesc as &$sLine) foreach ($mDesc as &$sLine)
{ {
$sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine)); $sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine));
$sLine = \rtrim($mDesc); $sLine = \rtrim($sLine);
} }
} }
else else

View file

@ -178,34 +178,42 @@ class MailClient
* @return string * @return string
*/ */
private function getEnvelopeOrHeadersRequestString() private function getEnvelopeOrHeadersRequestString()
{
if (\MailSo\Config::$MessageAllHeaders)
{ {
return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK; return \MailSo\Imap\Enumerations\FetchType::BODY_HEADER_PEEK;
}
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE; return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array(
\MailSo\Mime\Enumerations\Header::RETURN_PATH,
\MailSo\Mime\Enumerations\Header::RECEIVED,
\MailSo\Mime\Enumerations\Header::MIME_VERSION,
\MailSo\Mime\Enumerations\Header::MESSAGE_ID,
\MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
\MailSo\Mime\Enumerations\Header::FROM_,
\MailSo\Mime\Enumerations\Header::TO_,
\MailSo\Mime\Enumerations\Header::CC,
\MailSo\Mime\Enumerations\Header::BCC,
\MailSo\Mime\Enumerations\Header::SENDER,
\MailSo\Mime\Enumerations\Header::REPLY_TO,
\MailSo\Mime\Enumerations\Header::DELIVERED_TO,
\MailSo\Mime\Enumerations\Header::IN_REPLY_TO,
\MailSo\Mime\Enumerations\Header::REFERENCES,
\MailSo\Mime\Enumerations\Header::DATE,
\MailSo\Mime\Enumerations\Header::SUBJECT,
\MailSo\Mime\Enumerations\Header::SENSITIVITY,
\MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY,
\MailSo\Mime\Enumerations\Header::IMPORTANCE,
\MailSo\Mime\Enumerations\Header::X_PRIORITY,
\MailSo\Mime\Enumerations\Header::X_DRAFT_INFO,
\MailSo\Mime\Enumerations\Header::RETURN_RECEIPT_TO,
\MailSo\Mime\Enumerations\Header::DISPOSITION_NOTIFICATION_TO,
\MailSo\Mime\Enumerations\Header::X_CONFIRM_READING_TO,
\MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
\MailSo\Mime\Enumerations\Header::X_DKIM_AUTHENTICATION_RESULTS,
), true);
// //
// return \MailSo\Imap\Enumerations\FetchType::BuildBodyCustomHeaderRequest(array( // return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
// \MailSo\Mime\Enumerations\Header::RETURN_PATH,
// \MailSo\Mime\Enumerations\Header::RECEIVED,
// \MailSo\Mime\Enumerations\Header::MIME_VERSION,
// \MailSo\Mime\Enumerations\Header::MESSAGE_ID,
// \MailSo\Mime\Enumerations\Header::FROM_,
// \MailSo\Mime\Enumerations\Header::TO_,
// \MailSo\Mime\Enumerations\Header::CC,
// \MailSo\Mime\Enumerations\Header::BCC,
// \MailSo\Mime\Enumerations\Header::SENDER,
// \MailSo\Mime\Enumerations\Header::REPLY_TO,
// \MailSo\Mime\Enumerations\Header::IN_REPLY_TO,
// \MailSo\Mime\Enumerations\Header::DATE,
// \MailSo\Mime\Enumerations\Header::SUBJECT,
// \MailSo\Mime\Enumerations\Header::X_MSMAIL_PRIORITY,
// \MailSo\Mime\Enumerations\Header::IMPORTANCE,
// \MailSo\Mime\Enumerations\Header::X_PRIORITY,
// \MailSo\Mime\Enumerations\Header::CONTENT_TYPE,
// \MailSo\Mime\Enumerations\Header::REFERENCES,
// \MailSo\Mime\Enumerations\Header::X_DRAFT_INFO,
// \MailSo\Mime\Enumerations\Header::RECEIVED_SPF,
// \MailSo\Mime\Enumerations\Header::AUTHENTICATION_RESULTS,
// ), true);
} }
/** /**
@ -1032,7 +1040,7 @@ class MailClient
$sReg = 'e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize'; $sReg = 'e?mail|from|to|subject|has|is|date|text|body|size|larger|bigger|smaller|maxsize|minsize';
$sSearch = \trim(\preg_replace('/[\s]+/', ' ', $sSearch)); $sSearch = \MailSo\Base\Utils::StripSpaces($sSearch);
$sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch)); $sSearch = \trim(\preg_replace('/('.$sReg.'): /i', '\\1:', $sSearch));
$mMatch = array(); $mMatch = array();
@ -1079,7 +1087,7 @@ class MailClient
$sSearch = \str_replace($sToken, '', $sSearch); $sSearch = \str_replace($sToken, '', $sSearch);
} }
$sSearch = \trim(\preg_replace('/[\s]+/', ' ', $sSearch)); $sSearch = \MailSo\Base\Utils::StripSpaces($sSearch);
} }
foreach ($mMatch[1] as $iIndex => $sName) foreach ($mMatch[1] as $iIndex => $sName)
@ -1353,7 +1361,7 @@ class MailClient
if ('' !== \trim($sMainText)) if ('' !== \trim($sMainText))
{ {
$sMainText = \trim(\trim(preg_replace('/[\s]+/', ' ', $sMainText)), '"'); $sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"');
if ($bIsGmail) if ($bIsGmail)
{ {
$sGmailRawSearch .= ' '.$sMainText; $sGmailRawSearch .= ' '.$sMainText;
@ -1690,7 +1698,8 @@ class MailClient
\MailSo\Imap\Enumerations\FetchType::INTERNALDATE, \MailSo\Imap\Enumerations\FetchType::INTERNALDATE,
\MailSo\Imap\Enumerations\FetchType::FLAGS, \MailSo\Imap\Enumerations\FetchType::FLAGS,
\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE, \MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE,
$bSimple ? $this->getEnvelopeOrHeadersRequestStringForSimpleList() : $bSimple ?
$this->getEnvelopeOrHeadersRequestStringForSimpleList() :
$this->getEnvelopeOrHeadersRequestString() $this->getEnvelopeOrHeadersRequestString()
), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid); ), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid);

View file

@ -620,8 +620,8 @@ class Message
$this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect); $this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
$this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO); $this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
$this->sReferences = \trim(\preg_replace('/[\s]+/', ' ', $this->sReferences = \MailSo\Base\Utils::StripSpaces(
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES))); $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
$sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE); $sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
$this->sHeaderDate = $sHeaderDate; $this->sHeaderDate = $sHeaderDate;

View file

@ -257,7 +257,7 @@ class Message
public function SetReferences($sReferences) public function SetReferences($sReferences)
{ {
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] = $this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] =
\trim(\preg_replace('/[\s]+/', ' ', $sReferences)); \MailSo\Base\Utils::StripSpaces($sReferences);
return $this; return $this;
} }

View file

@ -4127,7 +4127,7 @@ class Actions
*/ */
private function rainLoopRepo() private function rainLoopRepo()
{ {
$sUrl = APP_REP_PATH; $sUrl = APP_REPOSITORY_PATH;
if ('' !== $sUrl) if ('' !== $sUrl)
{ {
$sUrl = rtrim($sUrl, '\\/').'/'; $sUrl = rtrim($sUrl, '\\/').'/';
@ -7190,12 +7190,25 @@ class Actions
$sFromFolder = $this->GetActionParam('FromFolder', ''); $sFromFolder = $this->GetActionParam('FromFolder', '');
$sToFolder = $this->GetActionParam('ToFolder', ''); $sToFolder = $this->GetActionParam('ToFolder', '');
$aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); $aUids = \explode(',', (string) $this->GetActionParam('Uids', ''));
$bMarkAsRead = '1' === (string) $this->GetActionParam('MarkAsRead', '0');
$aFilteredUids = \array_filter($aUids, function (&$mUid) { $aFilteredUids = \array_filter($aUids, function (&$mUid) {
$mUid = (int) \trim($mUid); $mUid = (int) \trim($mUid);
return 0 < $mUid; return 0 < $mUid;
}); });
if ($bMarkAsRead)
{
try
{
$this->MailClient()->MessageSetSeen($sFromFolder, $aFilteredUids, true, true);
}
catch (\Exception $oException)
{
unset($oException);
}
}
try try
{ {
$this->MailClient()->MessageMove($sFromFolder, $sToFolder, $aFilteredUids, true, $this->MailClient()->MessageMove($sFromFolder, $sToFolder, $aFilteredUids, true,
@ -7259,7 +7272,7 @@ class Actions
public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250) public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250)
{ {
$sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex.'.').$sContentType) : $sFileName; $sFileName = 0 === \strlen($sFileName) ? \preg_replace('/[^a-zA-Z0-9]/', '.', (empty($sMimeIndex) ? '' : $sMimeIndex.'.').$sContentType) : $sFileName;
$sClearedFileName = \preg_replace('/[\s]+/', ' ', \preg_replace('/[\.]+/', '.', $sFileName)); $sClearedFileName = \MailSo\Base\Utils::StripSpaces(\preg_replace('/[\.]+/', '.', $sFileName));
$sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName); $sExt = \MailSo\Base\Utils::GetFileExtension($sClearedFileName);
if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt)) if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt))

View file

@ -95,6 +95,9 @@ class Api
\MailSo\Config::$MessageListPermanentFilter = \MailSo\Config::$MessageListPermanentFilter =
\trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')); \trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', ''));
\MailSo\Config::$MessageAllHeaders =
!!\RainLoop\Api::Config()->Get('labs', 'imap_message_all_headers', false);
\MailSo\Config::$LargeThreadLimit = \MailSo\Config::$LargeThreadLimit =
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50); (int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);

View file

@ -14,6 +14,11 @@ abstract class PdoAbstract
*/ */
protected $bExplain = false; protected $bExplain = false;
/**
* @var bool
*/
protected $bSqliteCollate = true;
/** /**
* @var \MailSo\Log\Logger * @var \MailSo\Log\Logger
*/ */
@ -48,6 +53,18 @@ abstract class PdoAbstract
return array('', '', '', ''); return array('', '', '', '');
} }
/**
* @param string $sStr1
* @param string $sStr2
*
* @return int
*/
public function sqliteNoCaseCollationHelper($sStr1, $sStr2)
{
$this->oLogger->WriteDump(array($sStr1, $sStr2));
return \strcmp(\mb_strtoupper($sStr1, 'UTF-8'), \mb_strtoupper($sStr2, 'UTF-8'));
}
/** /**
* @return \PDO * @return \PDO
* *
@ -67,6 +84,7 @@ abstract class PdoAbstract
$sType = $sDsn = $sDbLogin = $sDbPassword = ''; $sType = $sDsn = $sDbLogin = $sDbPassword = '';
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData(); list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
if (!\in_array($sType, array('mysql', 'sqlite', 'pgsql'))) if (!\in_array($sType, array('mysql', 'sqlite', 'pgsql')))
{ {
throw new \Exception('Unknown PDO SQL connection type'); throw new \Exception('Unknown PDO SQL connection type');
@ -82,15 +100,28 @@ abstract class PdoAbstract
$oPdo = false; $oPdo = false;
try try
{ {
// $bCaseFunc = false;
$oPdo = @new \PDO($sDsn, $sDbLogin, $sDbPassword); $oPdo = @new \PDO($sDsn, $sDbLogin, $sDbPassword);
if ($oPdo) if ($oPdo)
{ {
$sPdoType = $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); $oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
if ('mysql' === $sType && 'mysql' === $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME))
if ('mysql' === $sType && 'mysql' === $sPdoType)
{ {
$oPdo->exec('SET NAMES utf8 COLLATE utf8_general_ci'); $oPdo->exec('SET NAMES utf8 COLLATE utf8_general_ci');
// $oPdo->exec('SET NAMES utf8'); // $oPdo->exec('SET NAMES utf8');
} }
// else if ('sqlite' === $sType && 'sqlite' === $sPdoType && $this->bSqliteCollate)
// {
// if (\method_exists($oPdo, 'sqliteCreateCollation') && \MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtoupper'))
// {
// $oPdo->sqliteCreateCollation('SQLITE_NOCASE_UTF8', array($this, 'sqliteNoCaseCollationHelper'));
// $bCaseFunc = true;
// }
// }
//
// $this->oLogger->Write('PDO:'.$sPdoType.($bCaseFunc ? '/SQLITE_NOCASE_UTF8' : ''));
} }
} }
catch (\Exception $oException) catch (\Exception $oException)
@ -156,10 +187,11 @@ abstract class PdoAbstract
* @param string $sSql * @param string $sSql
* @param array $aParams * @param array $aParams
* @param bool $bMultiplyParams = false * @param bool $bMultiplyParams = false
* @param bool $bLogParams = false
* *
* @return \PDOStatement|null * @return \PDOStatement|null
*/ */
protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false) protected function prepareAndExecute($sSql, $aParams = array(), $bMultiplyParams = false, $bLogParams = false)
{ {
if ($this->bExplain && !$bMultiplyParams) if ($this->bExplain && !$bMultiplyParams)
{ {
@ -172,16 +204,27 @@ abstract class PdoAbstract
$oStmt = $this->getPDO()->prepare($sSql); $oStmt = $this->getPDO()->prepare($sSql);
if ($oStmt) if ($oStmt)
{ {
$aLogs = array();
$aRootParams = $bMultiplyParams ? $aParams : array($aParams); $aRootParams = $bMultiplyParams ? $aParams : array($aParams);
foreach ($aRootParams as $aSubParams) foreach ($aRootParams as $aSubParams)
{ {
foreach ($aSubParams as $sName => $aValue) foreach ($aSubParams as $sName => $aValue)
{ {
if ($bLogParams)
{
$aLogs[$sName] = $aValue[0];
}
$oStmt->bindValue($sName, $aValue[0], $aValue[1]); $oStmt->bindValue($sName, $aValue[0], $aValue[1]);
} }
$mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null; $mResult = $oStmt->execute() && !$bMultiplyParams ? $oStmt : null;
} }
if ($bLogParams && $aLogs)
{
$this->writeLog('Params: '.@\json_encode($aLogs, \defined('JSON_UNESCAPED_UNICODE') ? JSON_UNESCAPED_UNICODE : 0));
}
} }
return $mResult; return $mResult;

View file

@ -9,6 +9,11 @@ abstract class AbstractConfig
*/ */
private $sFile; private $sFile;
/**
* @var string
*/
private $sAdditionalFile;
/** /**
* @var array * @var array
*/ */
@ -27,12 +32,19 @@ abstract class AbstractConfig
/** /**
* @param string $sFileName * @param string $sFileName
* @param string $sFileHeader = '' * @param string $sFileHeader = ''
* @param string $sAdditionalFileName = ''
* *
* @return void * @return void
*/ */
public function __construct($sFileName, $sFileHeader = '') public function __construct($sFileName, $sFileHeader = '', $sAdditionalFileName = '')
{ {
$this->sFile = \APP_PRIVATE_DATA.'configs/'.$sFileName; $this->sFile = \APP_PRIVATE_DATA.'configs/'.\trim($sFileName);
$sAdditionalFileName = \trim($sAdditionalFileName);
$this->sAdditionalFile = \APP_PRIVATE_DATA.'configs/'.$sAdditionalFileName;
$this->sAdditionalFile = 0 < \strlen($sAdditionalFileName) &&
\file_exists($this->sAdditionalFile) ? $this->sAdditionalFile : '';
$this->sFileHeader = $sFileHeader; $this->sFileHeader = $sFileHeader;
$this->aData = $this->defaultValues(); $this->aData = $this->defaultValues();
@ -109,7 +121,7 @@ abstract class AbstractConfig
*/ */
private function cacheKey() private function cacheKey()
{ {
return 'config:'.\sha1($this->sFile).':'; return 'config:'.\sha1($this->sFile).':'.\sha1($this->sAdditionalFile).':';
} }
/** /**
@ -120,12 +132,17 @@ abstract class AbstractConfig
if ($this->bUseApcCache) if ($this->bUseApcCache)
{ {
$iMTime = @\filemtime($this->sFile); $iMTime = @\filemtime($this->sFile);
if (\is_int($iMTime) && 0 < $iMTime) $iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
if (0 < $iMTime)
{ {
$sKey = $this->cacheKey(); $sKey = $this->cacheKey();
$iTime = \apc_fetch($sKey.'time'); $sTimeHash = \apc_fetch($sKey.'time');
if ($iTime && $iMTime === (int) $iTime) if ($sTimeHash && $sTimeHash === \md5($iMTime.'/'.$iATime))
{ {
$aFetchData = \apc_fetch($sKey.'data'); $aFetchData = \apc_fetch($sKey.'data');
if (\is_array($aFetchData)) if (\is_array($aFetchData))
@ -148,11 +165,16 @@ abstract class AbstractConfig
if ($this->bUseApcCache) if ($this->bUseApcCache)
{ {
$iMTime = @\filemtime($this->sFile); $iMTime = @\filemtime($this->sFile);
if (\is_int($iMTime) && 0 < $iMTime) $iMTime = \is_int($iMTime) && 0 < $iMTime ? $iMTime : 0;
$iATime = $this->sAdditionalFile ? @\filemtime($this->sAdditionalFile) : 0;
$iATime = \is_int($iATime) && 0 < $iATime ? $iATime : 0;
if (0 < $iMTime)
{ {
$sKey = $this->cacheKey(); $sKey = $this->cacheKey();
\apc_store($sKey.'time', $iMTime); \apc_store($sKey.'time', \md5($iMTime.'/'.$iATime));
\apc_store($sKey.'data', $this->aData); \apc_store($sKey.'data', $this->aData);
return true; return true;
@ -193,7 +215,7 @@ abstract class AbstractConfig
} }
$aData = \RainLoop\Utils::CustomParseIniFile($this->sFile, true); $aData = \RainLoop\Utils::CustomParseIniFile($this->sFile, true);
if (\is_array($aData) && 0 < count($aData)) if (\is_array($aData) && 0 < \count($aData))
{ {
foreach ($aData as $sSectionKey => $aSectionValue) foreach ($aData as $sSectionKey => $aSectionValue)
{ {
@ -206,6 +228,28 @@ abstract class AbstractConfig
} }
} }
unset($aData);
if (\file_exists($this->sAdditionalFile) && \is_readable($this->sAdditionalFile))
{
$aSubData = \RainLoop\Utils::CustomParseIniFile($this->sAdditionalFile, true);
if (\is_array($aSubData) && 0 < \count($aSubData))
{
foreach ($aSubData as $sSectionKey => $aSectionValue)
{
if (\is_array($aSectionValue))
{
foreach ($aSectionValue as $sParamKey => $mParamValue)
{
$this->Set($sSectionKey, $sParamKey, $mParamValue);
}
}
}
}
unset($aSubData);
}
$this->storeDataToCache(); $this->storeDataToCache();
return true; return true;

View file

@ -11,7 +11,8 @@ class Application extends \RainLoop\Config\AbstractConfig
{ {
parent::__construct('application.ini', parent::__construct('application.ini',
'; RainLoop Webmail configuration file '; RainLoop Webmail configuration file
; Please don\'t add custom parameters here, those will be overwritten'); ; Please don\'t add custom parameters here, those will be overwritten',
defined('APP_ADDITIONAL_CONFIGURATION_NAME') ? APP_ADDITIONAL_CONFIGURATION_NAME : '');
} }
/** /**
@ -321,6 +322,7 @@ Enables caching in the system'),
'imap_message_list_count_limit_trigger' => array(0), 'imap_message_list_count_limit_trigger' => array(0),
'imap_message_list_date_filter' => array(0), 'imap_message_list_date_filter' => array(0),
'imap_message_list_permanent_filter' => array(''), 'imap_message_list_permanent_filter' => array(''),
'imap_message_all_headers' => array(false),
'imap_large_thread_limit' => array(50), 'imap_large_thread_limit' => array(50),
'imap_folder_list_limit' => array(200), 'imap_folder_list_limit' => array(200),
'imap_show_login_alert' => array(true), 'imap_show_login_alert' => array(true),

View file

@ -25,7 +25,7 @@ class Plugin extends \RainLoop\Config\AbstractConfig
*/ */
private function convertConfigMap($aMap) private function convertConfigMap($aMap)
{ {
if (0 < count($aMap)) if (0 < \count($aMap))
{ {
$aResultMap = array(); $aResultMap = array();
foreach ($aMap as /* @var $oProperty \RainLoop\Plugins\Property */ $oProperty) foreach ($aMap as /* @var $oProperty \RainLoop\Plugins\Property */ $oProperty)
@ -33,12 +33,12 @@ class Plugin extends \RainLoop\Config\AbstractConfig
if ($oProperty) if ($oProperty)
{ {
$mValue = $oProperty->DefaultValue(); $mValue = $oProperty->DefaultValue();
$sValue = is_array($mValue) && isset($mValue[0]) ? $mValue[0] : $mValue; $sValue = \is_array($mValue) && isset($mValue[0]) ? $mValue[0] : $mValue;
$aResultMap[$oProperty->Name()] = array($sValue, ''); $aResultMap[$oProperty->Name()] = array($sValue, '');
} }
} }
if (0 < count($aResultMap)) if (0 < \count($aResultMap))
{ {
return array( return array(
'plugin' => $aResultMap 'plugin' => $aResultMap

View file

@ -26,6 +26,11 @@ class Property
*/ */
public $Value; public $Value;
/**
* @var string
*/
public $ValueLower;
/** /**
* @var string * @var string
*/ */
@ -54,6 +59,7 @@ class Property
$this->TypeStr = ''; $this->TypeStr = '';
$this->Value = ''; $this->Value = '';
$this->ValueLower = '';
$this->ValueCustom = ''; $this->ValueCustom = '';
$this->Frec = 0; $this->Frec = 0;
@ -120,6 +126,7 @@ class Property
$this->Value = \trim($this->Value); $this->Value = \trim($this->Value);
$this->ValueCustom = \trim($this->ValueCustom); $this->ValueCustom = \trim($this->ValueCustom);
$this->TypeStr = \trim($this->TypeStr); $this->TypeStr = \trim($this->TypeStr);
$this->ValueLower = '';
if (0 < \strlen($this->Value)) if (0 < \strlen($this->Value))
{ {
@ -131,16 +138,22 @@ class Property
if ($this->IsName()) if ($this->IsName())
{ {
$this->Value = \preg_replace('/[\s]+/u', ' ', $this->Value); $this->Value = \MailSo\Base\Utils::StripSpaces($this->Value);
} }
// phones clear value for searching // lower value for searching
if (\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtolower'))
{
$this->ValueLower = (string) @\mb_strtolower($this->Value, 'UTF-8');
}
// phone value for searching
if ($this->IsPhone()) if ($this->IsPhone())
{ {
$sPhone = $this->Value; $sPhone = \trim($this->Value);
$sPhone = \preg_replace('/^[+]+/', '', $sPhone); $sPhone = \preg_replace('/^[+]+/', '', $sPhone);
$sPhone = \preg_replace('/[^\d]/', '', $sPhone); $sPhone = \preg_replace('/[^\d]/', '', $sPhone);
$this->ValueCustom = $sPhone; $this->ValueCustom = \trim($sPhone);
} }
} }
} }

View file

@ -957,6 +957,7 @@ class PdoAddressBook
':prop_type' => array($oProp->Type, \PDO::PARAM_INT), ':prop_type' => array($oProp->Type, \PDO::PARAM_INT),
':prop_type_str' => array($oProp->TypeStr, \PDO::PARAM_STR), ':prop_type_str' => array($oProp->TypeStr, \PDO::PARAM_STR),
':prop_value' => array($oProp->Value, \PDO::PARAM_STR), ':prop_value' => array($oProp->Value, \PDO::PARAM_STR),
':prop_value_lower' => array($oProp->ValueLower, \PDO::PARAM_STR),
':prop_value_custom' => array($oProp->ValueCustom, \PDO::PARAM_STR), ':prop_value_custom' => array($oProp->ValueCustom, \PDO::PARAM_STR),
':prop_frec' => array($iFreq, \PDO::PARAM_INT), ':prop_frec' => array($iFreq, \PDO::PARAM_INT),
); );
@ -965,9 +966,9 @@ class PdoAddressBook
if (0 < \count($aParams)) if (0 < \count($aParams))
{ {
$sSql = 'INSERT INTO rainloop_ab_properties '. $sSql = 'INSERT INTO rainloop_ab_properties '.
'( id_contact, id_user, prop_type, prop_type_str, prop_value, prop_value_custom, prop_frec)'. '( id_contact, id_user, prop_type, prop_type_str, prop_value, prop_value_lower, prop_value_custom, prop_frec)'.
' VALUES '. ' VALUES '.
'(:id_contact, :id_user, :prop_type, :prop_type_str, :prop_value, :prop_value_custom, :prop_frec)'; '(:id_contact, :id_user, :prop_type, :prop_type_str, :prop_value, :prop_value_lower, :prop_value_custom, :prop_frec)';
$this->prepareAndExecute($sSql, $aParams, true); $this->prepareAndExecute($sSql, $aParams, true);
} }
@ -1072,6 +1073,7 @@ class PdoAddressBook
if (0 < \strlen($sSearch)) if (0 < \strlen($sSearch))
{ {
$sCustomSearch = $this->specialConvertSearchValueCustomPhone($sSearch); $sCustomSearch = $this->specialConvertSearchValueCustomPhone($sSearch);
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch, '=');
$sSearchTypes = \implode(',', array( $sSearchTypes = \implode(',', array(
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME, PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME,
@ -1079,7 +1081,9 @@ class PdoAddressBook
)); ));
$sSql = 'SELECT id_user, id_prop, id_contact FROM rainloop_ab_properties '. $sSql = 'SELECT id_user, id_prop, id_contact FROM rainloop_ab_properties '.
'WHERE (id_user = :id_user) AND prop_type IN ('.$sSearchTypes.') AND (prop_value LIKE :search ESCAPE \'=\''. 'WHERE (id_user = :id_user) AND prop_type IN ('.$sSearchTypes.') AND ('.
'prop_value LIKE :search ESCAPE \'=\''.
(0 < \strlen($sLowerSearch) ? ' OR (prop_value_lower <> \'\' AND prop_value_lower LIKE :search_lower ESCAPE \'=\')' : '').
(0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : ''). (0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
') GROUP BY id_contact, id_prop'; ') GROUP BY id_contact, id_prop';
@ -1088,12 +1092,17 @@ class PdoAddressBook
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR) ':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
); );
if (0 < \strlen($sLowerSearch))
{
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
}
if (0 < \strlen($sCustomSearch)) if (0 < \strlen($sCustomSearch))
{ {
$aParams[':search_custom_phone'] = array($sCustomSearch, \PDO::PARAM_STR); $aParams[':search_custom_phone'] = array($sCustomSearch, \PDO::PARAM_STR);
} }
$oStmt = $this->prepareAndExecute($sSql, $aParams); $oStmt = $this->prepareAndExecute($sSql, $aParams, false, true);
if ($oStmt) if ($oStmt)
{ {
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC); $aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
@ -1211,6 +1220,7 @@ class PdoAddressBook
$oProperty->Type = (int) $aItem['prop_type']; $oProperty->Type = (int) $aItem['prop_type'];
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : ''; $oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
$oProperty->Value = (string) $aItem['prop_value']; $oProperty->Value = (string) $aItem['prop_value'];
$oProperty->ValueLower = isset($aItem['prop_value_lower']) ? (string) $aItem['prop_value_lower'] : '';
$oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : ''; $oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : '';
$oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0; $oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
@ -1320,6 +1330,7 @@ class PdoAddressBook
$oProperty->Type = (int) $aItem['prop_type']; $oProperty->Type = (int) $aItem['prop_type'];
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : ''; $oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
$oProperty->Value = (string) $aItem['prop_value']; $oProperty->Value = (string) $aItem['prop_value'];
$oProperty->ValueLower = isset($aItem['prop_value_lower']) ? (string) $aItem['prop_value_lower'] : '';
$oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : ''; $oProperty->ValueCustom = isset($aItem['prop_value_custom']) ? (string) $aItem['prop_value_custom'] : '';
$oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0; $oProperty->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
@ -1364,8 +1375,14 @@ class PdoAddressBook
PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME PropertyType::EMAIl, PropertyType::FIRST_NAME, PropertyType::LAST_NAME, PropertyType::NICK_NAME
)); ));
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch);
$sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_ab_properties '. $sSql = 'SELECT id_contact, id_prop, prop_type, prop_value FROM rainloop_ab_properties '.
'WHERE (id_user = :id_user) AND prop_type IN ('.$sTypes.') AND prop_value LIKE :search ESCAPE \'=\''; 'WHERE (id_user = :id_user) AND prop_type IN ('.$sTypes.') AND ('.
'prop_value LIKE :search ESCAPE \'=\''.
(0 < \strlen($sLowerSearch) ? ' OR (prop_value_lower <> \'\' AND prop_value_lower LIKE :search_lower ESCAPE \'=\')' : '').
')'
;
$aParams = array( $aParams = array(
':id_user' => array($iUserID, \PDO::PARAM_INT), ':id_user' => array($iUserID, \PDO::PARAM_INT),
@ -1373,6 +1390,11 @@ class PdoAddressBook
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR) ':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
); );
if (0 < \strlen($sLowerSearch))
{
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
}
$sSql .= ' ORDER BY prop_frec DESC'; $sSql .= ' ORDER BY prop_frec DESC';
$sSql .= ' LIMIT :limit'; $sSql .= ' LIMIT :limit';
@ -1547,7 +1569,7 @@ class PdoAddressBook
{ {
$oResult = \MailSo\Mime\Email::Parse(\trim($mItem)); $oResult = \MailSo\Mime\Email::Parse(\trim($mItem));
} }
catch (\Exception $oException) {} catch (\Exception $oException) { unset($oException); }
return $oResult; return $oResult;
}, $aEmails); }, $aEmails);
@ -1837,7 +1859,7 @@ SQLITEINITIAL;
break; break;
} }
if (0 < strlen($sInitial)) if (0 < \strlen($sInitial))
{ {
$aList = \explode(';', \trim($sInitial)); $aList = \explode(';', \trim($sInitial));
foreach ($aList as $sV) foreach ($aList as $sV)
@ -1869,17 +1891,26 @@ SQLITEINITIAL;
{ {
case 'mysql': case 'mysql':
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array( $mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
1 => $this->getInitialTablesArray($this->sDsnType) 1 => $this->getInitialTablesArray($this->sDsnType),
2 => array(
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower varchar(255) NOT NULL DEFAULT \'\' AFTER prop_value_custom;'
)
)); ));
break; break;
case 'pgsql': case 'pgsql':
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array( $mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
1 => $this->getInitialTablesArray($this->sDsnType) 1 => $this->getInitialTablesArray($this->sDsnType),
2 => array(
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower text NOT NULL DEFAULT \'\';'
)
)); ));
break; break;
case 'sqlite': case 'sqlite':
$mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array( $mCache = $this->dataBaseUpgrade($this->sDsnType.'-ab-version', array(
1 => $this->getInitialTablesArray($this->sDsnType) 1 => $this->getInitialTablesArray($this->sDsnType),
2 => array(
'ALTER TABLE rainloop_ab_properties ADD prop_value_lower text NOT NULL DEFAULT \'\';'
)
)); ));
break; break;
} }
@ -1934,6 +1965,24 @@ SQLITEINITIAL;
array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'), $sSearch).'%'; array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'), $sSearch).'%';
} }
/**
* @param string $sSearch
* @param string $sEscapeSign = '='
*
* @return string
*/
private function specialConvertSearchValueLower($sSearch, $sEscapeSign = '=')
{
if (!\MailSo\Base\Utils::FunctionExistsAndEnabled('mb_strtolower'))
{
return '';
}
return '%'.\str_replace(array($sEscapeSign, '_', '%'),
array($sEscapeSign.$sEscapeSign, $sEscapeSign.'_', $sEscapeSign.'%'),
(string) @\mb_strtolower($sSearch, 'UTF-8')).'%';
}
/** /**
* @param string $sSearch * @param string $sSearch
* *

View file

@ -242,7 +242,7 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
$sResult .= ' "'.$this->quote($sValue).'"'; $sResult .= ' "'.$this->quote($sValue).'"';
} }
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult); $sResult = \MailSo\Base\Utils::StripSpaces($sResult);
} }
} }
else else
@ -358,8 +358,8 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
$sSubject = ''; $sSubject = '';
if (0 < \strlen($sValueSecond)) if (0 < \strlen($sValueSecond))
{ {
$sSubject = ':subject "'.$this->quote( $sSubject = ':subject "'.
\preg_replace('/[\s]+/u', ' ', $sValueSecond)).'" '; $this->quote(\MailSo\Base\Utils::StripSpaces($sValueSecond)).'" ';
} }
if (0 < \strlen($sValueThird) && \is_numeric($sValueThird) && 1 < (int) $sValueThird) if (0 < \strlen($sValueThird) && \is_numeric($sValueThird) && 1 < (int) $sValueThird)

View file

@ -89,7 +89,10 @@
if (window.$LAB && window.rainloopAppData && window.rainloopAppData['TemplatesLink'] && window.rainloopAppData['LangLink']) if (window.$LAB && window.rainloopAppData && window.rainloopAppData['TemplatesLink'] && window.rainloopAppData['LangLink'])
{ {
__simplePace(10); var oProgress = progressJs();
oProgress.setOptions({'theme': 'rainloop'});
oProgress.start().set(5);
window.$LAB window.$LAB
.script(function () { .script(function () {
@ -98,7 +101,9 @@
]; ];
}) })
.wait(function () { .wait(function () {
__simplePace(20);
oProgress.set(20);
if (window.rainloopAppData['IncludeBackground']) { if (window.rainloopAppData['IncludeBackground']) {
$('#rl-bg').attr('style', 'background-image: none !important;').backstretch( $('#rl-bg').attr('style', 'background-image: none !important;').backstretch(
window.rainloopAppData['IncludeBackground'].replace('{{USER}}', window.rainloopAppData['IncludeBackground'].replace('{{USER}}',
@ -114,20 +119,20 @@
]; ];
}) })
.wait(function () { .wait(function () {
__simplePace(10); oProgress.set(30);
}) })
.script(function () { .script(function () {
return {'src': '{{BaseAppMainScriptLink}}', 'type': 'text/javascript', 'charset': 'utf-8'}; return {'src': '{{BaseAppMainScriptLink}}', 'type': 'text/javascript', 'charset': 'utf-8'};
}) })
.wait(function () { .wait(function () {
__simplePace(20); oProgress.set(50);
}) })
.script(function () { .script(function () {
return window.rainloopAppData['PluginsLink'] ? return window.rainloopAppData['PluginsLink'] ?
{'src': window.rainloopAppData['PluginsLink'], 'type': 'text/javascript', 'charset': 'utf-8'} : null; {'src': window.rainloopAppData['PluginsLink'], 'type': 'text/javascript', 'charset': 'utf-8'} : null;
}) })
.wait(function () { .wait(function () {
__simplePace(5); oProgress.set(55);
__runBoot(false); __runBoot(false);
}) })
.script(function () { .script(function () {

View file

@ -22,16 +22,6 @@ Options -Indexes
define('APP_USE_APC_CACHE', true); define('APP_USE_APC_CACHE', true);
$sCustomDataPath = '';
if (file_exists(APP_INDEX_ROOT_PATH.'include.php'))
{
include_once APP_INDEX_ROOT_PATH.'include.php';
}
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
define('APP_DATA_FOLDER_PATH', 0 === strlen($sCustomDataPath) ? APP_INDEX_ROOT_PATH.'data/' : $sCustomDataPath.'/');
unset($sCustomDataPath);
if (function_exists('date_default_timezone_set')) if (function_exists('date_default_timezone_set'))
{ {
date_default_timezone_set('UTC'); date_default_timezone_set('UTC');
@ -53,12 +43,30 @@ Options -Indexes
define('APP_MULTIPLY', 0 < strlen($sPrivateDataFolderInternalName) && APP_DEFAULT_PRIVATE_DATA_NAME !== APP_PRIVATE_DATA_NAME); define('APP_MULTIPLY', 0 < strlen($sPrivateDataFolderInternalName) && APP_DEFAULT_PRIVATE_DATA_NAME !== APP_PRIVATE_DATA_NAME);
define('APP_DUMMY', '********'); define('APP_DUMMY', '********');
define('APP_GOOGLE_ACCESS_TOKEN_PREFIX', ':GAT:');
define('APP_DEV_VERSION', '0.0.0'); define('APP_DEV_VERSION', '0.0.0');
define('APP_GOOGLE_ACCESS_TOKEN_PREFIX', ':GAT:');
define('APP_WEB_SITE', 'http://www.rainloop.net/');
define('APP_API_PATH', 'http://api.rainloop.net/'); define('APP_API_PATH', 'http://api.rainloop.net/');
define('APP_REP_PATH', 'http://repository.rainloop.net/v1/');
define('APP_REPO_CORE_FILE', 'http://repository.rainloop.net/v2/core.{{channel}}.json');
define('APP_STATUS_PATH', 'http://status.rainloop.net/'); define('APP_STATUS_PATH', 'http://status.rainloop.net/');
define('APP_REPOSITORY_PATH', 'http://repository.rainloop.net/v1/');
define('APP_REPO_CORE_FILE', 'http://repository.rainloop.net/v2/core.{{channel}}.json');
$sCustomDataPath = '';
$sCustomConfiguration = '';
if (file_exists(APP_INDEX_ROOT_PATH.'include.php'))
{
include_once APP_INDEX_ROOT_PATH.'include.php';
}
$sCustomDataPath = function_exists('__get_custom_data_full_path') ? rtrim(trim(__get_custom_data_full_path()), '\\/') : '';
define('APP_DATA_FOLDER_PATH', 0 === strlen($sCustomDataPath) ? APP_INDEX_ROOT_PATH.'data/' : $sCustomDataPath.'/');
unset($sCustomDataPath);
$sCustomConfiguration = function_exists('__get_additional_configuration_name') ? trim(__get_additional_configuration_name()) : '';
define('APP_ADDITIONAL_CONFIGURATION_NAME', $sCustomConfiguration);
unset($sCustomConfiguration);
define('APP_DATA_FOLDER_PATH_UNIX', str_replace('\\', '/', APP_DATA_FOLDER_PATH)); define('APP_DATA_FOLDER_PATH_UNIX', str_replace('\\', '/', APP_DATA_FOLDER_PATH));
$sSalt = @file_get_contents(APP_DATA_FOLDER_PATH.'SALT.php'); $sSalt = @file_get_contents(APP_DATA_FOLDER_PATH.'SALT.php');

20
vendors/progress.js/LICENSE vendored Normal file
View file

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Afshin Mehrabani (afshin.meh@gmail.com)
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.

65
vendors/progress.js/README.md vendored Normal file
View file

@ -0,0 +1,65 @@
# ProgressJS
> ProgressJs is a JavaScript and CSS3 library which helps developers create and manage progress bars for every object on the page.
## How To Use
1) Include `progress.js` and `progressjs.css` in the page (use the minified version from `minified` folder for production)
2) Execute the following JavaScript code in the page:
```javascript
//to set progress-bar for whole page
progressJs().start();
//or for specific element
progressJs("#targetElement").start();
```
Use other methods to increase, decrease or set an auto-increase function for your progress-bar. Furthermore, you can change the template using `setOption` method.
## API
Check the API and method usage with example here: https://github.com/usablica/progress.js/wiki/API
## Build
First, you should install `nodejs` and `npm`, then run this command: `npm install` to install all dependencies.
Now you can run this command to minify all the static resources:
make build
## Roadmap
- Add `example` folder and provide examples
- More browser compatibility + mobile/tablet device support
- Add more templates
## Release History
* **v0.1.0** - 2014-02-14
- First version
- Increase, decrease and auto-increase functions
- Ability to design and add templates
## Author
**Afshin Mehrabani**
- [Twitter](https://twitter.com/afshinmeh)
- [Github](https://github.com/afshinm)
- [Personal page](http://afshinm.name/)
## License
> Copyright (C) 2012 Afshin Mehrabani (afshin.meh@gmail.com)
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.

View file

@ -0,0 +1,11 @@
(function(l,e){"object"===typeof exports?e(exports):"function"===typeof define&&define.amd?define(["exports"],e):e(l)})(this,function(l){function e(a){this._targetElement="undefined"!=typeof a.length?a:[a];"undefined"===typeof window._progressjsId&&(window._progressjsId=1);"undefined"===typeof window._progressjsIntervals&&(window._progressjsIntervals={});this._options={theme:"blue",overlayMode:!1,considerTransition:!0}}function m(a,c){var d=this;100<=c&&(c=100);a.hasAttribute("data-progressjs")&&
setTimeout(function(){"undefined"!=typeof d._onProgressCallback&&d._onProgressCallback.call(d,a,c);var b=h(a);b.style.width=parseInt(c)+"%";var b=b.querySelector(".progressjs-percent"),g=parseInt(b.innerHTML.replace("%","")),e=parseInt(c),j=function(a,b,c){var d=Math.abs(b-c);3>d?k=30:20>d?k=20:intervanIn=1;0!=b-c&&(a.innerHTML=(f?++b:--b)+"%",setTimeout(function(){j(a,b,c)},k))},f=!0;g>e&&(f=!1);var k=10;j(b,g,e)},50)}function h(a){a=parseInt(a.getAttribute("data-progressjs"));return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="'+
a+'"] > .progressjs-inner')}function p(a){for(var c=0,d=this._targetElement.length;c<d;c++){var b=this._targetElement[c];if(b.hasAttribute("data-progressjs")){var g=h(b);(g=parseInt(g.style.width.replace("%","")))&&m.call(this,b,g+(a||1))}}}function q(){var a,c=document.createElement("fakeelement"),d={transition:"transitionend",OTransition:"oTransitionEnd",MozTransition:"transitionend",WebkitTransition:"webkitTransitionEnd"};for(a in d)if(void 0!==c.style[a])return d[a]}var n=function(a){if("object"===
typeof a)return new e(a);if("string"===typeof a){if(a=document.querySelectorAll(a))return new e(a);throw Error("There is no element with given selector.");}return new e(document.body)};n.version="0.1.0";n.fn=e.prototype={clone:function(){return new e(this)},setOption:function(a,c){this._options[a]=c;return this},setOptions:function(a){var c=this._options,d={},b;for(b in c)d[b]=c[b];for(b in a)d[b]=a[b];this._options=d;return this},start:function(){"undefined"!=typeof this._onBeforeStartCallback&&
this._onBeforeStartCallback.call(this);if(!document.querySelector(".progressjs-container")){var a=document.createElement("div");a.className="progressjs-container";document.body.appendChild(a)}for(var a=0,c=this._targetElement.length;a<c;a++){var d=this._targetElement[a];if(!d.hasAttribute("data-progressjs")){var b=d,g,e,j;"body"===b.tagName.toLowerCase()?(g=b.clientWidth,e=b.clientHeight):(g=b.offsetWidth,e=b.offsetHeight);for(var f=j=0;b&&!isNaN(b.offsetLeft)&&!isNaN(b.offsetTop);)j+=b.offsetLeft,
f+=b.offsetTop,b=b.offsetParent;b=f;d.setAttribute("data-progressjs",window._progressjsId);f=document.createElement("div");f.className="progressjs-progress progressjs-theme-"+this._options.theme;f.style.position="body"===d.tagName.toLowerCase()?"fixed":"absolute";f.setAttribute("data-progressjs",window._progressjsId);var k=document.createElement("div");k.className="progressjs-inner";var h=document.createElement("div");h.className="progressjs-percent";h.innerHTML="1%";k.appendChild(h);this._options.overlayMode&&
"body"===d.tagName.toLowerCase()?(f.style.left=0,f.style.right=0,f.style.top=0,f.style.bottom=0):(f.style.left=j+"px",f.style.top=b+"px",f.style.width=g+"px",this._options.overlayMode&&(f.style.height=e+"px"));f.appendChild(k);document.querySelector(".progressjs-container").appendChild(f);m(d,1);++window._progressjsId}}return this},set:function(a){for(var c=0,d=this._targetElement.length;c<d;c++)m.call(this,this._targetElement[c],a);return this},increase:function(a){p.call(this,a);return this},autoIncrease:function(a,
c){var d=this,b=parseInt(this._targetElement[0].getAttribute("data-progressjs"));"undefined"!=typeof window._progressjsIntervals[b]&&clearInterval(window._progressjsIntervals[b]);window._progressjsIntervals[b]=setInterval(function(){p.call(d,a)},c);return this},end:function(){a:{"undefined"!=typeof this._onBeforeEndCallback&&(!0===this._options.considerTransition?h(this._targetElement[0]).addEventListener(q(),this._onBeforeEndCallback,!1):this._onBeforeEndCallback.call(this));for(var a=parseInt(this._targetElement[0].getAttribute("data-progressjs")),
c=0,d=this._targetElement.length;c<d;c++){var b=this._targetElement[c],e=h(b);if(!e)break a;var l=1;100>parseInt(e.style.width.replace("%",""))&&(m.call(this,b,100),l=500);(function(a,b){setTimeout(function(){a.parentNode.className+=" progressjs-end";setTimeout(function(){a.parentNode.parentNode.removeChild(a.parentNode);b.removeAttribute("data-progressjs")},1E3)},l)})(e,b)}if(window._progressjsIntervals[a])try{clearInterval(window._progressjsIntervals[a]),window._progressjsIntervals[a]=null,delete window._progressjsIntervals[a]}catch(j){}}return this},
onbeforeend:function(a){if("function"===typeof a)this._onBeforeEndCallback=a;else throw Error("Provided callback for onbeforeend was not a function");return this},onbeforestart:function(a){if("function"===typeof a)this._onBeforeStartCallback=a;else throw Error("Provided callback for onbeforestart was not a function");return this},onprogress:function(a){if("function"===typeof a)this._onProgressCallback=a;else throw Error("Provided callback for onprogress was not a function");return this}};return l.progressJs=
n});

View file

@ -0,0 +1 @@
.progressjs-inner{width:0}.progressjs-progress{z-index:9999999}.progressjs-theme-blue .progressjs-inner{height:2px;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db}.progressjs-theme-blue.progressjs-end{-webkit-transition:opacity .2s ease-out;-moz-transition:opacity .2s ease-out;-o-transition:opacity .2s ease-out;transition:opacity .2s ease-out;opacity:0}.progressjs-theme-blue .progressjs-percent{display:none}.progressjs-theme-blueOverlay{background-color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}.progressjs-theme-blueOverlay .progressjs-inner{height:100%;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db}.progressjs-theme-blueOverlay.progressjs-end{opacity:0!important}.progressjs-theme-blueOverlay .progressjs-percent{display:none}.progressjs-theme-blueOverlay{background-color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}.progressjs-theme-blueOverlay .progressjs-inner{height:100%;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db}.progressjs-theme-blueOverlay.progressjs-end{opacity:0!important}.progressjs-theme-blueOverlay .progressjs-percent{display:none}.progressjs-theme-blueOverlayRadius{background-color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;border-radius:5px}.progressjs-theme-blueOverlayRadius .progressjs-inner{height:100%;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db;border-radius:5px}.progressjs-theme-blueOverlayRadius.progressjs-end{opacity:0!important}.progressjs-theme-blueOverlayRadius .progressjs-percent{display:none}.progressjs-theme-blueOverlayRadiusHalfOpacity{background-color:white;opacity:.5;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;border-radius:5px}.progressjs-theme-blueOverlayRadiusHalfOpacity .progressjs-inner{height:100%;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db;border-radius:5px}.progressjs-theme-blueOverlayRadiusHalfOpacity.progressjs-end{opacity:0!important}.progressjs-theme-blueOverlayRadiusHalfOpacity .progressjs-percent{display:none}.progressjs-theme-blueOverlayRadiusWithPercentBar{background-color:white;-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out;border-radius:5px}.progressjs-theme-blueOverlayRadiusWithPercentBar .progressjs-inner{height:100%;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;background-color:#3498db;border-radius:5px}.progressjs-theme-blueOverlayRadiusWithPercentBar.progressjs-end{opacity:0!important}.progressjs-theme-blueOverlayRadiusWithPercentBar .progressjs-percent{width:70px;text-align:center;height:40px;position:absolute;right:50%;margin-right:-35px;top:50%;margin-top:-20px;font-size:30px;opacity:.5}.progressjs-theme-blackRadiusInputs{height:10px;border-radius:10px;overflow:hidden}.progressjs-theme-blackRadiusInputs .progressjs-inner{height:2px;-webkit-transition:all 1s ease-out;-moz-transition:all 1s ease-out;-o-transition:all 1s ease-out;transition:all 1s ease-out;background-color:#34495e}.progressjs-theme-blackRadiusInputs.progressjs-end{-webkit-transition:opacity .2s ease-out;-moz-transition:opacity .2s ease-out;-o-transition:opacity .2s ease-out;transition:opacity .2s ease-out;opacity:0}.progressjs-theme-blackRadiusInputs .progressjs-percent{display:none}

View file

@ -0,0 +1,62 @@
.progressjs-theme-rainloop {
z-index: 2000;
}
.progressjs-theme-rainloop .progressjs-inner {
background-color: #939595;
position: relative;
z-index: 2000;
height: 3px;
overflow: hidden;
-webkit-transition: width .5s;
-moz-transition: width .5s;
-o-transition: width .5s;
transition: width .5s;
}
.progressjs-theme-rainloop .progressjs-percent {
position: absolute;
top: 0;
left: 0;
right: -32px;
bottom: 0;
background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.3)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.3)), color-stop(0.75, rgba(255, 255, 255, 0.3)), color-stop(0.75, transparent), to(transparent));
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.3) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.3) 50%, rgba(255, 255, 255, 0.3) 75%, transparent 75%, transparent);
-webkit-background-size: 32px 32px;
-moz-background-size: 32px 32px;
-o-background-size: 32px 32px;
background-size: 32px 32px;
-webkit-animation: simple-pace-stripe-animation 500ms linear infinite;
-moz-animation: simple-pace-stripe-animation 500ms linear infinite;
-ms-animation: simple-pace-stripe-animation 500ms linear infinite;
-o-animation: simple-pace-stripe-animation 500ms linear infinite;
animation: simple-pace-stripe-animation 500ms linear infinite;
}
@-webkit-keyframes simple-pace-stripe-animation {
0% { -webkit-transform: none; transform: none; }
100% { -webkit-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-moz-keyframes simple-pace-stripe-animation {
0% { -moz-transform: none; transform: none; }
100% { -moz-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-o-keyframes simple-pace-stripe-animation {
0% { -o-transform: none; transform: none; }
100% { -o-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@-ms-keyframes simple-pace-stripe-animation {
0% { -ms-transform: none; transform: none; }
100% { -ms-transform: translate(-32px, 0); transform: translate(-32px, 0); }
}
@keyframes simple-pace-stripe-animation {
0% { transform: none; transform: none; }
100% { transform: translate(-32px, 0); transform: translate(-32px, 0); }
}

17
vendors/progress.js/package.json vendored Normal file
View file

@ -0,0 +1,17 @@
{
"name": "Progress.js",
"description": "Themeable HTML5 progress bar library",
"version": "0.1.0",
"author": "Afshin Mehrabani <afshin.meh@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/usablica/progress.js"
},
"devDependencies": {
"node-minify": "*"
},
"engine": [
"node >=0.1.90"
],
"main": "src/progress.js"
}

574
vendors/progress.js/src/progress.js vendored Normal file
View file

@ -0,0 +1,574 @@
/**
* Progress.js v0.1.0
* https://github.com/usablica/progress.js
* MIT licensed
*
* Copyright (C) 2013 usabli.ca - Afshin Mehrabani (@afshinmeh)
*/
(function (root, factory) {
if (typeof exports === 'object') {
// CommonJS
factory(exports);
} else if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['exports'], factory);
} else {
// Browser globals
factory(root);
}
} (this, function (exports) {
//Default config/variables
var VERSION = '0.1.0';
/**
* ProgressJs main class
*
* @class ProgressJs
*/
function ProgressJs(obj) {
if (typeof obj.length != 'undefined') {
this._targetElement = obj;
} else {
this._targetElement = [obj];
}
if (typeof window._progressjsId === 'undefined')
window._progressjsId = 1;
if (typeof window._progressjsIntervals === 'undefined')
window._progressjsIntervals = {};
this._options = {
//progress bar theme
theme: 'blue',
//overlay mode makes an overlay layer in the target element
overlayMode: false,
//to consider CSS3 transitions in events
considerTransition: true
};
}
/**
* Start progress for specific element(s)
*
* @api private
* @method _createContainer
*/
function _startProgress() {
//call onBeforeStart callback
if (typeof this._onBeforeStartCallback != 'undefined') {
this._onBeforeStartCallback.call(this);
}
//create the container for progress bar
_createContainer.call(this);
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
_setProgress.call(this, this._targetElement[i]);
}
}
/**
* Set progress bar for specific element
*
* @api private
* @method _setProgress
* @param {Object} targetElement
*/
function _setProgress(targetElement) {
//if the target element already as `data-progressjs`, ignore the init
if (targetElement.hasAttribute("data-progressjs"))
return;
//get target element position
var targetElementOffset = _getOffset.call(this, targetElement);
targetElement.setAttribute("data-progressjs", window._progressjsId);
var progressElementContainer = document.createElement('div');
progressElementContainer.className = 'progressjs-progress progressjs-theme-' + this._options.theme;
//set the position percent elements, it depends on targetElement tag
if (targetElement.tagName.toLowerCase() === 'body') {
progressElementContainer.style.position = 'fixed';
} else {
progressElementContainer.style.position = 'absolute';
}
progressElementContainer.setAttribute("data-progressjs", window._progressjsId);
var progressElement = document.createElement("div");
progressElement.className = "progressjs-inner";
//create an element for current percent of progress bar
var progressPercentElement = document.createElement('div');
progressPercentElement.className = "progressjs-percent";
progressPercentElement.innerHTML = "1%";
progressElement.appendChild(progressPercentElement);
if (this._options.overlayMode && targetElement.tagName.toLowerCase() === 'body') {
//if we have `body` for target element and also overlay mode is enable, we should use a different
//position for progress bar container element
progressElementContainer.style.left = 0;
progressElementContainer.style.right = 0;
progressElementContainer.style.top = 0;
progressElementContainer.style.bottom = 0;
} else {
//set progress bar container size and offset
progressElementContainer.style.left = targetElementOffset.left + 'px';
progressElementContainer.style.top = targetElementOffset.top + 'px';
//if targetElement is body set to percent so it scales with browser resize
if (targetElement.nodeName == 'BODY') {
progressElementContainer.style.width = '100%';
} else {
progressElementContainer.style.width = targetElementOffset.width + 'px';
}
if (this._options.overlayMode) {
progressElementContainer.style.height = targetElementOffset.height + 'px';
}
}
progressElementContainer.appendChild(progressElement);
//append the element to container
var container = document.querySelector('.progressjs-container');
container.appendChild(progressElementContainer);
_setPercentFor(targetElement, 1);
//and increase the progressId
++window._progressjsId;
}
/**
* Set percent for all elements
*
* @api private
* @method _setPercent
* @param {Number} percent
*/
function _setPercent(percent) {
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
_setPercentFor.call(this, this._targetElement[i], percent);
}
}
/**
* Set percent for specific element
*
* @api private
* @method _setPercentFor
* @param {Object} targetElement
* @param {Number} percent
*/
function _setPercentFor(targetElement, percent) {
var self = this;
//prevent overflow!
if (percent >= 100)
percent = 100;
if (targetElement.hasAttribute("data-progressjs")) {
//setTimeout for better CSS3 animation applying in some cases
setTimeout(function() {
//call the onprogress callback
if (typeof self._onProgressCallback != 'undefined') {
self._onProgressCallback.call(self, targetElement, percent);
}
var percentElement = _getPercentElement(targetElement);
percentElement.style.width = parseInt(percent) + '%';
var percentElement = percentElement.querySelector(".progressjs-percent");
var existingPercent = parseInt(percentElement.innerHTML.replace('%', ''));
//start increase/decrease the percent element with animation
(function(percentElement, existingPercent, currentPercent) {
var increasement = true;
if (existingPercent > currentPercent) {
increasement = false;
}
var intervalIn = 10;
function changePercentTimer(percentElement, existingPercent, currentPercent) {
//calculate the distance between two percents
var distance = Math.abs(existingPercent - currentPercent);
if (distance < 3) {
intervalIn = 30;
} else if (distance < 20) {
intervalIn = 20;
} else {
intervanIn = 1;
}
if ((existingPercent - currentPercent) != 0) {
//set the percent
percentElement.innerHTML = (increasement ? (++existingPercent) : (--existingPercent)) + '%';
setTimeout(function() { changePercentTimer(percentElement, existingPercent, currentPercent); }, intervalIn);
}
}
changePercentTimer(percentElement, existingPercent, currentPercent);
})(percentElement, existingPercent, parseInt(percent));
}, 50);
}
}
/**
* Get the progress bar element
*
* @api private
* @method _getPercentElement
* @param {Object} targetElement
*/
function _getPercentElement(targetElement) {
var progressjsId = parseInt(targetElement.getAttribute('data-progressjs'));
return document.querySelector('.progressjs-container > .progressjs-progress[data-progressjs="' + progressjsId + '"] > .progressjs-inner');
}
/**
* Auto increase the progress bar every X milliseconds
*
* @api private
* @method _autoIncrease
* @param {Number} size
* @param {Number} millisecond
*/
function _autoIncrease(size, millisecond) {
var self = this;
var target = this._targetElement[0];
if(!target) return;
var progressjsId = parseInt(target.getAttribute('data-progressjs'));
if (typeof window._progressjsIntervals[progressjsId] != 'undefined') {
clearInterval(window._progressjsIntervals[progressjsId]);
}
window._progressjsIntervals[progressjsId] = setInterval(function() {
_increasePercent.call(self, size);
}, millisecond);
}
/**
* Increase the size of progress bar
*
* @api private
* @method _increasePercent
* @param {Number} size
*/
function _increasePercent(size) {
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
var currentElement = this._targetElement[i];
if (currentElement.hasAttribute('data-progressjs')) {
var percentElement = _getPercentElement(currentElement);
var existingPercent = parseInt(percentElement.style.width.replace('%', ''));
if (existingPercent) {
_setPercentFor.call(this, currentElement, existingPercent + (size || 1));
}
}
}
}
/**
* Close and remove progress bar
*
* @api private
* @method _end
*/
function _end() {
//call onBeforeEnd callback
if (typeof this._onBeforeEndCallback != 'undefined') {
if (this._options.considerTransition === true) {
//we can safety assume that all layers would be the same, so `this._targetElement[0]` is the same as `this._targetElement[1]`
_getPercentElement(this._targetElement[0]).addEventListener(whichTransitionEvent(), this._onBeforeEndCallback, false);
} else {
this._onBeforeEndCallback.call(this);
}
}
var target = this._targetElement[0];
if(!target) return;
var progressjsId = parseInt(target.getAttribute('data-progressjs'));
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
var currentElement = this._targetElement[i];
var percentElement = _getPercentElement(currentElement);
if (!percentElement)
return;
var existingPercent = parseInt(percentElement.style.width.replace('%', ''));
var timeoutSec = 1;
if (existingPercent < 100) {
_setPercentFor.call(this, currentElement, 100);
timeoutSec = 500;
}
//I believe I should handle this situation with eventListener and `transitionend` event but I'm not sure
//about compatibility with IEs. Should be fixed in further versions.
(function(percentElement, currentElement) {
setTimeout(function() {
percentElement.parentNode.className += " progressjs-end";
setTimeout(function() {
//remove the percent element from page
percentElement.parentNode.parentNode.removeChild(percentElement.parentNode);
//and remove the attribute
currentElement.removeAttribute("data-progressjs");
}, 1000);
}, timeoutSec);
})(percentElement, currentElement);
}
//clean the setInterval for autoIncrease function
if (window._progressjsIntervals[progressjsId]) {
//`delete` keyword has some problems in IE
try {
clearInterval(window._progressjsIntervals[progressjsId]);
window._progressjsIntervals[progressjsId] = null;
delete window._progressjsIntervals[progressjsId];
} catch(ex) { }
}
}
/**
* Remove progress bar without finishing
*
* @api private
* @method _kill
*/
function _kill() {
var target = this._targetElement[0];
if(!target) return;
var progressjsId = parseInt(target.getAttribute('data-progressjs'));
for (var i = 0, elmsLength = this._targetElement.length; i < elmsLength; i++) {
var currentElement = this._targetElement[i];
var percentElement = _getPercentElement(currentElement);
if (!percentElement)
return;
//I believe I should handle this situation with eventListener and `transitionend` event but I'm not sure
//about compatibility with IEs. Should be fixed in further versions.
(function(percentElement, currentElement) {
percentElement.parentNode.className += " progressjs-end";
setTimeout(function() {
//remove the percent element from page
percentElement.parentNode.parentNode.removeChild(percentElement.parentNode);
//and remove the attribute
currentElement.removeAttribute("data-progressjs");
}, 1000);
})(percentElement, currentElement);
}
//clean the setInterval for autoIncrease function
if (window._progressjsIntervals[progressjsId]) {
//`delete` keyword has some problems in IE
try {
clearInterval(window._progressjsIntervals[progressjsId]);
window._progressjsIntervals[progressjsId] = null;
delete window._progressjsIntervals[progressjsId];
} catch(ex) { }
}
}
/**
* Create the progress bar container
*
* @api private
* @method _createContainer
*/
function _createContainer() {
//first check if we have an container already, we don't need to create it again
if (!document.querySelector(".progressjs-container")) {
var containerElement = document.createElement("div");
containerElement.className = "progressjs-container";
document.body.appendChild(containerElement);
}
}
/**
* Get an element position on the page
* Thanks to `meouw`: http://stackoverflow.com/a/442474/375966
*
* @api private
* @method _getOffset
* @param {Object} element
* @returns Element's position info
*/
function _getOffset(element) {
var elementPosition = {};
if (element.tagName.toLowerCase() === 'body') {
//set width
elementPosition.width = element.clientWidth;
//set height
elementPosition.height = element.clientHeight;
} else {
//set width
elementPosition.width = element.offsetWidth;
//set height
elementPosition.height = element.offsetHeight;
}
//calculate element top and left
var _x = 0;
var _y = 0;
while (element && !isNaN(element.offsetLeft) && !isNaN(element.offsetTop)) {
_x += element.offsetLeft;
_y += element.offsetTop;
element = element.offsetParent;
}
//set top
elementPosition.top = _y;
//set left
elementPosition.left = _x;
return elementPosition;
}
/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* via: http://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically
*
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function _mergeOptions(obj1, obj2) {
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}
var progressJs = function (targetElm) {
if (typeof (targetElm) === 'object') {
//Ok, create a new instance
return new ProgressJs(targetElm);
} else if (typeof (targetElm) === 'string') {
//select the target element with query selector
var targetElement = document.querySelectorAll(targetElm);
if (targetElement) {
return new ProgressJs(targetElement);
} else {
throw new Error('There is no element with given selector.');
}
} else {
return new ProgressJs(document.body);
}
};
/**
* Get correct transition callback
* Thanks @webinista: http://stackoverflow.com/a/9090128/375966
*
* @returns transition name
*/
function whichTransitionEvent() {
var t;
var el = document.createElement('fakeelement');
var transitions = {
'transition': 'transitionend',
'OTransition': 'oTransitionEnd',
'MozTransition': 'transitionend',
'WebkitTransition': 'webkitTransitionEnd'
}
for (t in transitions) {
if (el.style[t] !== undefined) {
return transitions[t];
}
}
}
/**
* Current ProgressJs version
*
* @property version
* @type String
*/
progressJs.version = VERSION;
//Prototype
progressJs.fn = ProgressJs.prototype = {
clone: function () {
return new ProgressJs(this);
},
setOption: function(option, value) {
this._options[option] = value;
return this;
},
setOptions: function(options) {
this._options = _mergeOptions(this._options, options);
return this;
},
start: function() {
_startProgress.call(this);
return this;
},
set: function(percent) {
_setPercent.call(this, percent);
return this;
},
increase: function(size) {
_increasePercent.call(this, size);
return this;
},
autoIncrease: function(size, millisecond) {
_autoIncrease.call(this, size, millisecond);
return this;
},
end: function() {
_end.call(this);
return this;
},
kill: function() {
_kill.call(this);
return this;
},
onbeforeend: function(providedCallback) {
if (typeof (providedCallback) === 'function') {
this._onBeforeEndCallback = providedCallback;
} else {
throw new Error('Provided callback for onbeforeend was not a function');
}
return this;
},
onbeforestart: function(providedCallback) {
if (typeof (providedCallback) === 'function') {
this._onBeforeStartCallback = providedCallback;
} else {
throw new Error('Provided callback for onbeforestart was not a function');
}
return this;
},
onprogress: function(providedCallback) {
if (typeof (providedCallback) === 'function') {
this._onProgressCallback = providedCallback;
} else {
throw new Error('Provided callback for onprogress was not a function');
}
return this;
}
};
exports.progressJs = progressJs;
return progressJs;
}));

181
vendors/progress.js/src/progressjs.css vendored Normal file
View file

@ -0,0 +1,181 @@
.progressjs-inner {
width: 0;
}
.progressjs-progress {
z-index: 9999999;
}
/* blue theme, like iOS 7 progress bar */
.progressjs-theme-blue .progressjs-inner {
height: 2px;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
}
.progressjs-theme-blue.progressjs-end {
-webkit-transition: opacity 0.2s ease-out;
-moz-transition: opacity 0.2s ease-out;
-o-transition: opacity 0.2s ease-out;
transition: opacity 0.2s ease-out;
opacity: 0;
}
.progressjs-theme-blue .progressjs-percent {
display: none;
}
/* blue theme with overlay layer, no percent bar */
.progressjs-theme-blueOverlay {
background-color: white;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.progressjs-theme-blueOverlay .progressjs-inner {
height: 100%;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
}
.progressjs-theme-blueOverlay.progressjs-end {
opacity: 0 !important;
}
.progressjs-theme-blueOverlay .progressjs-percent {
display: none;
}
/* blue theme with overlay layer, no percent bar */
.progressjs-theme-blueOverlay {
background-color: white;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
}
.progressjs-theme-blueOverlay .progressjs-inner {
height: 100%;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
}
.progressjs-theme-blueOverlay.progressjs-end {
opacity: 0 !important;
}
.progressjs-theme-blueOverlay .progressjs-percent {
display: none;
}
/* Blue theme with border radius and overlay layer */
.progressjs-theme-blueOverlayRadius {
background-color: white;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadius .progressjs-inner {
height: 100%;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadius.progressjs-end {
opacity: 0 !important;
}
.progressjs-theme-blueOverlayRadius .progressjs-percent {
display: none;
}
/* Blue theme with border radius and overlay layer */
.progressjs-theme-blueOverlayRadiusHalfOpacity {
background-color: white;
opacity: 0.5;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadiusHalfOpacity .progressjs-inner {
height: 100%;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadiusHalfOpacity.progressjs-end {
opacity: 0 !important;
}
.progressjs-theme-blueOverlayRadiusHalfOpacity .progressjs-percent {
display: none;
}
/* Blue theme with border radius, overlay layer and percent bar */
.progressjs-theme-blueOverlayRadiusWithPercentBar {
background-color: white;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
transition: all 0.2s ease-out;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadiusWithPercentBar .progressjs-inner {
height: 100%;
-webkit-transition: all 0.3s ease-out;
-moz-transition: all 0.3s ease-out;
-o-transition: all 0.3s ease-out;
transition: all 0.3s ease-out;
background-color: #3498db;
border-radius: 5px;
}
.progressjs-theme-blueOverlayRadiusWithPercentBar.progressjs-end {
opacity: 0 !important;
}
.progressjs-theme-blueOverlayRadiusWithPercentBar .progressjs-percent {
width: 70px;
text-align: center;
height: 40px;
position: absolute;
right: 50%;
margin-right: -35px;
top: 50%;
margin-top: -20px;
font-size: 30px;
opacity: .5;
}
.progressjs-theme-blackRadiusInputs {
height: 10px;
border-radius: 10px;
overflow: hidden;
}
.progressjs-theme-blackRadiusInputs .progressjs-inner {
height: 2px;
-webkit-transition: all 1s ease-out;
-moz-transition: all 1s ease-out;
-o-transition: all 1s ease-out;
transition: all 1s ease-out;
background-color: #34495e;
}
.progressjs-theme-blackRadiusInputs.progressjs-end {
-webkit-transition: opacity 0.2s ease-out;
-moz-transition: opacity 0.2s ease-out;
-o-transition: opacity 0.2s ease-out;
transition: opacity 0.2s ease-out;
opacity: 0;
}
.progressjs-theme-blackRadiusInputs .progressjs-percent {
display: none;
}

View file

@ -29,7 +29,7 @@ module.exports = {
'JSON': 'window.JSON', 'JSON': 'window.JSON',
'JSEncrypt': 'window.JSEncrypt', 'JSEncrypt': 'window.JSEncrypt',
'$LAB': 'window.$LAB', '$LAB': 'window.$LAB',
'SimplePace': 'window.SimplePace', 'progressJs': 'window.progressJs',
'PhotoSwipe': 'window.PhotoSwipe', 'PhotoSwipe': 'window.PhotoSwipe',
'PhotoSwipeUI_Default': 'window.PhotoSwipeUI_Default', 'PhotoSwipeUI_Default': 'window.PhotoSwipeUI_Default',
'queue': 'window.queue', 'queue': 'window.queue',