mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
A lot small fixes
This commit is contained in:
parent
4457cdbc23
commit
09334159c2
38 changed files with 1496 additions and 239 deletions
|
|
@ -10,3 +10,12 @@ function __get_custom_data_full_path()
|
|||
return '';
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
window = require('window'),
|
||||
_ = require('_'),
|
||||
ko = require('ko'),
|
||||
SimplePace = require('SimplePace'),
|
||||
progressJs = require('progressJs'),
|
||||
|
||||
Enums = require('Common/Enums'),
|
||||
Utils = require('Common/Utils'),
|
||||
|
|
@ -280,9 +280,9 @@
|
|||
}
|
||||
}
|
||||
|
||||
if (SimplePace)
|
||||
if (progressJs)
|
||||
{
|
||||
SimplePace.set(100);
|
||||
progressJs().end();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
window = require('window'),
|
||||
_ = require('_'),
|
||||
$ = require('$'),
|
||||
SimplePace = require('SimplePace'),
|
||||
progressJs = require('progressJs'),
|
||||
Tinycon = require('Tinycon'),
|
||||
|
||||
Enums = require('Common/Enums'),
|
||||
|
|
@ -255,6 +255,7 @@
|
|||
{
|
||||
var
|
||||
self = this,
|
||||
sTrashFolder = FolderStore.trashFolder(),
|
||||
sSpamFolder = FolderStore.spamFolder()
|
||||
;
|
||||
|
||||
|
|
@ -262,11 +263,12 @@
|
|||
|
||||
var
|
||||
bSpam = sSpamFolder === oItem['To'],
|
||||
bTrash = sTrashFolder === oItem['To'],
|
||||
bHam = !bSpam && sSpamFolder === oItem['From'] && Cache.getFolderInboxName() === oItem['To']
|
||||
;
|
||||
|
||||
Remote.messagesMove(self.moveOrDeleteResponseHelper, oItem['From'], oItem['To'], oItem['Uid'],
|
||||
bSpam ? 'SPAM' : (bHam ? 'HAM' : ''));
|
||||
bSpam ? 'SPAM' : (bHam ? 'HAM' : ''), bSpam || bTrash);
|
||||
});
|
||||
|
||||
this.oMoveCache = {};
|
||||
|
|
@ -1305,9 +1307,9 @@
|
|||
{
|
||||
kn.hideLoading();
|
||||
|
||||
if (SimplePace)
|
||||
if (progressJs)
|
||||
{
|
||||
SimplePace.set(100);
|
||||
progressJs().end();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1332,10 +1334,9 @@
|
|||
bTwitter = Settings.settingsGet('AllowTwitterSocial')
|
||||
;
|
||||
|
||||
if (SimplePace)
|
||||
if (progressJs)
|
||||
{
|
||||
SimplePace.set(70);
|
||||
SimplePace.sleep();
|
||||
progressJs().set(70);
|
||||
}
|
||||
|
||||
Globals.leftPanelDisabled.subscribe(function (bValue) {
|
||||
|
|
|
|||
44
dev/External/ko.js
vendored
44
dev/External/ko.js
vendored
|
|
@ -811,7 +811,7 @@
|
|||
'parseOnBlur': true,
|
||||
'allowDragAndDrop': true,
|
||||
'focusCallback': fFocusCallback,
|
||||
'inputDelimiters': [',', ';'],
|
||||
'inputDelimiters': [',', ';', '\n'],
|
||||
'autoCompleteSource': fAutoCompleteSource,
|
||||
// 'elementHook': function (oEl, oItem) {
|
||||
// if (oEl && oItem)
|
||||
|
|
@ -821,23 +821,53 @@
|
|||
// }
|
||||
// },
|
||||
'parseHook': function (aInput) {
|
||||
return _.map(aInput, function (sInputValue) {
|
||||
|
||||
var aResult = [];
|
||||
|
||||
_.each(aInput, function (sInputValue) {
|
||||
|
||||
var
|
||||
aM = null,
|
||||
aValues = [],
|
||||
sValue = Utils.trim(sInputValue),
|
||||
oEmail = null
|
||||
;
|
||||
|
||||
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.mailsoParse(sValue);
|
||||
return [oEmail.toLine(false), oEmail];
|
||||
oEmail.mailsoParse(sV);
|
||||
|
||||
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) {
|
||||
$oEl.data('EmailsTagsValue', oEvent.target.value);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,49 @@
|
|||
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}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -727,13 +727,15 @@
|
|||
* @param {string} sToFolder
|
||||
* @param {Array} aUids
|
||||
* @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', {
|
||||
'FromFolder': sFolder,
|
||||
'ToFolder': sToFolder,
|
||||
'Uids': aUids.join(','),
|
||||
'MarkAsRead': bMarkAsRead ? '1' : '0',
|
||||
'Learning': sLearning || ''
|
||||
}, null, '', ['MessageList']);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -328,6 +328,8 @@
|
|||
self = this,
|
||||
iUnseenCount = 0,
|
||||
oMessage = null,
|
||||
sTrashFolder = FolderStore.trashFolder(),
|
||||
sSpamFolder = FolderStore.spamFolder(),
|
||||
aMessageList = this.messageList(),
|
||||
oFromFolder = Cache.getFolderFromCacheList(sFromFolderFullNameRaw),
|
||||
oToFolder = '' === sToFolderFullNameRaw ? null : Cache.getFolderFromCacheList(sToFolderFullNameRaw || ''),
|
||||
|
|
@ -359,6 +361,11 @@
|
|||
|
||||
if (oToFolder)
|
||||
{
|
||||
if (sTrashFolder === oToFolder.fullNameRaw || sSpamFolder === oToFolder.fullNameRaw)
|
||||
{
|
||||
iUnseenCount = 0;
|
||||
}
|
||||
|
||||
oToFolder.messageCountAll(oToFolder.messageCountAll() + aUidForRemove.length);
|
||||
if (0 < iUnseenCount)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -239,7 +239,6 @@ html.cssanimations {
|
|||
.e-spinner .bounce2 {
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@keyframes bouncedelay {
|
||||
|
|
|
|||
|
|
@ -110,7 +110,8 @@ cfg.paths.css = {
|
|||
'vendors/fontastic/styles.css',
|
||||
'vendors/jquery-nanoscroller/nanoscroller.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/opentip/opentip.css',
|
||||
'vendors/photoswipe/photoswipe.css',
|
||||
|
|
@ -127,7 +128,8 @@ cfg.paths.js = {
|
|||
src: [
|
||||
'vendors/json2.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'
|
||||
]
|
||||
},
|
||||
|
|
@ -153,7 +155,6 @@ cfg.paths.js = {
|
|||
libs: {
|
||||
name: 'libs.js',
|
||||
src: [
|
||||
'vendors/modernizr.js',
|
||||
'vendors/underscore/1.6.0/underscore-min.js',
|
||||
'vendors/jquery/jquery-1.11.2.min.js',
|
||||
'vendors/jquery-ui/js/jquery-ui-1.10.3.custom.min.js',
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "RainLoop",
|
||||
"title": "RainLoop Webmail",
|
||||
"version": "1.9.1",
|
||||
"release": "334",
|
||||
"release": "335",
|
||||
"description": "Simple, modern & fast web-based email client",
|
||||
"homepage": "http://rainloop.net",
|
||||
"main": "gulpfile.js",
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ class HtmlUtils
|
|||
{
|
||||
$aRemoveTags = array(
|
||||
'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)
|
||||
|
|
@ -755,7 +755,8 @@ class HtmlUtils
|
|||
|
||||
if ('' !== $sTagNameLower && \in_array($sTagNameLower, array('svg', 'head', 'link',
|
||||
'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))
|
||||
{
|
||||
|
|
@ -867,7 +868,8 @@ class HtmlUtils
|
|||
foreach (array(
|
||||
'id', 'class',
|
||||
'contenteditable', 'designmode', 'formaction',
|
||||
'data-bind', 'data-reactid', 'xmlns', 'srcset'
|
||||
'data-bind', 'data-reactid', 'xmlns', 'srcset',
|
||||
'data-x-skip-style'
|
||||
) as $sAttr)
|
||||
{
|
||||
@$oElement->removeAttribute($sAttr);
|
||||
|
|
@ -903,28 +905,51 @@ class HtmlUtils
|
|||
$sAlt = $oElement->hasAttribute('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')
|
||||
? \trim($oElement->getAttribute('height')) : '';
|
||||
|
||||
$sW = $oElement->hasAttribute('width')
|
||||
? \trim($oElement->getAttribute('width')) : '';
|
||||
// $sW = $oElement->hasAttribute('width')
|
||||
// ? \trim($oElement->getAttribute('width')) : '';
|
||||
|
||||
$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');
|
||||
if (('' === $sAlt && \in_array($sH, $aValues) && \in_array($sW, $aValues)) ||
|
||||
\preg_match('/(display:none|visibility:hidden)/i', \preg_replace('/[\s]+/', '', $sStyles)))
|
||||
$sSrcLower = \strtolower($sSrc);
|
||||
foreach ($aH as $sLine)
|
||||
{
|
||||
if (isset($oElement->parentNode))
|
||||
if (false !== \strpos($sSrcLower, $sLine))
|
||||
{
|
||||
@$oElement->parentNode->removeChild($oElement);
|
||||
continue;
|
||||
$bC = true;
|
||||
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'))
|
||||
|
|
@ -1002,12 +1027,14 @@ class HtmlUtils
|
|||
$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',
|
||||
\MailSo\Base\HtmlUtils::ClearStyle($oElement->getAttribute('style'), $oElement, $bHasExternals,
|
||||
$aFoundCIDs, $aContentLocationUrls, $aFoundedContentLocationUrls, $bDoNotReplaceExternalUrl, $fAdditionalExternalFilter));
|
||||
}
|
||||
|
||||
$oElement->removeAttribute('data-x-skip-style');
|
||||
}
|
||||
|
||||
$sResult = $oDom->saveHTML();
|
||||
|
|
@ -1023,7 +1050,7 @@ class HtmlUtils
|
|||
$sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>';
|
||||
|
||||
$sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
|
||||
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult);
|
||||
$sResult = \MailSo\Base\Utils::StripSpaces($sResult);
|
||||
|
||||
return \trim($sResult);
|
||||
}
|
||||
|
|
@ -1275,9 +1302,10 @@ class HtmlUtils
|
|||
*/
|
||||
public static function ConvertHtmlToPlain($sText)
|
||||
{
|
||||
$sText = trim(stripslashes($sText));
|
||||
$sText = preg_replace('/[\s]+/', ' ', $sText);
|
||||
$sText = preg_replace(array(
|
||||
$sText = \trim(\stripslashes($sText));
|
||||
$sText = \MailSo\Base\Utils::StripSpaces($sText);
|
||||
|
||||
$sText = \preg_replace(array(
|
||||
"/\r/",
|
||||
"/[\n\t]+/",
|
||||
'/<script[^>]*>.*?<\/script>/i',
|
||||
|
|
@ -1367,11 +1395,11 @@ class HtmlUtils
|
|||
''
|
||||
), $sText);
|
||||
|
||||
$sText = str_ireplace('<div>',"\n<div>", $sText);
|
||||
$sText = strip_tags($sText, '');
|
||||
$sText = preg_replace("/\n\\s+\n/", "\n", $sText);
|
||||
$sText = preg_replace("/[\n]{3,}/", "\n\n", $sText);
|
||||
$sText = \str_ireplace('<div>',"\n<div>", $sText);
|
||||
$sText = \strip_tags($sText, '');
|
||||
$sText = \preg_replace("/\n\\s+\n/", "\n", $sText);
|
||||
$sText = \preg_replace("/[\n]{3,}/", "\n\n", $sText);
|
||||
|
||||
return trim($sText);
|
||||
return \trim($sText);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -550,6 +550,17 @@ END;
|
|||
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
|
||||
*
|
||||
|
|
@ -1362,8 +1373,9 @@ END;
|
|||
*/
|
||||
public static function ClearFileName($sFileName)
|
||||
{
|
||||
return \MailSo\Base\Utils::ClearNullBite(\preg_replace('/[\s]+/u', ' ',
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName)));
|
||||
return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
|
||||
\MailSo\Base\Utils::StripSpaces(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sFileName))));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1373,8 +1385,8 @@ END;
|
|||
*/
|
||||
public static function ClearXss($sValue)
|
||||
{
|
||||
return \MailSo\Base\Utils::ClearNullBite(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue));
|
||||
return \MailSo\Base\Utils::Trim(\MailSo\Base\Utils::ClearNullBite(
|
||||
\str_replace(array('"', '/', '\\', '*', '?', '<', '>', '|', ':'), ' ', $sValue)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -56,6 +56,11 @@ class Config
|
|||
*/
|
||||
public static $LargeThreadLimit = 50;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
public static $MessageAllHeaders = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ abstract class Driver
|
|||
foreach ($mDesc as &$sLine)
|
||||
{
|
||||
$sLine = \strtr($sLine, array("\r" => '\r', "\n" => '\n'.$this->sNewLine));
|
||||
$sLine = \rtrim($mDesc);
|
||||
$sLine = \rtrim($sLine);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -178,34 +178,42 @@ class MailClient
|
|||
* @return string
|
||||
*/
|
||||
private function getEnvelopeOrHeadersRequestString()
|
||||
{
|
||||
if (\MailSo\Config::$MessageAllHeaders)
|
||||
{
|
||||
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(
|
||||
// \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);
|
||||
// return \MailSo\Imap\Enumerations\FetchType::ENVELOPE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1032,7 +1040,7 @@ class MailClient
|
|||
|
||||
$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));
|
||||
|
||||
$mMatch = array();
|
||||
|
|
@ -1079,7 +1087,7 @@ class MailClient
|
|||
$sSearch = \str_replace($sToken, '', $sSearch);
|
||||
}
|
||||
|
||||
$sSearch = \trim(\preg_replace('/[\s]+/', ' ', $sSearch));
|
||||
$sSearch = \MailSo\Base\Utils::StripSpaces($sSearch);
|
||||
}
|
||||
|
||||
foreach ($mMatch[1] as $iIndex => $sName)
|
||||
|
|
@ -1353,7 +1361,7 @@ class MailClient
|
|||
|
||||
if ('' !== \trim($sMainText))
|
||||
{
|
||||
$sMainText = \trim(\trim(preg_replace('/[\s]+/', ' ', $sMainText)), '"');
|
||||
$sMainText = \trim(\MailSo\Base\Utils::StripSpaces($sMainText), '"');
|
||||
if ($bIsGmail)
|
||||
{
|
||||
$sGmailRawSearch .= ' '.$sMainText;
|
||||
|
|
@ -1690,7 +1698,8 @@ class MailClient
|
|||
\MailSo\Imap\Enumerations\FetchType::INTERNALDATE,
|
||||
\MailSo\Imap\Enumerations\FetchType::FLAGS,
|
||||
\MailSo\Imap\Enumerations\FetchType::BODYSTRUCTURE,
|
||||
$bSimple ? $this->getEnvelopeOrHeadersRequestStringForSimpleList() :
|
||||
$bSimple ?
|
||||
$this->getEnvelopeOrHeadersRequestStringForSimpleList() :
|
||||
$this->getEnvelopeOrHeadersRequestString()
|
||||
), \MailSo\Base\Utils::PrepearFetchSequence($aRequestIndexOrUids), $bIndexAsUid);
|
||||
|
||||
|
|
|
|||
|
|
@ -620,8 +620,8 @@ class Message
|
|||
$this->oDeliveredTo = $oHeaders->GetAsEmailCollection(\MailSo\Mime\Enumerations\Header::DELIVERED_TO, $bCharsetAutoDetect);
|
||||
|
||||
$this->sInReplyTo = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::IN_REPLY_TO);
|
||||
$this->sReferences = \trim(\preg_replace('/[\s]+/', ' ',
|
||||
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES)));
|
||||
$this->sReferences = \MailSo\Base\Utils::StripSpaces(
|
||||
$oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::REFERENCES));
|
||||
|
||||
$sHeaderDate = $oHeaders->ValueByName(\MailSo\Mime\Enumerations\Header::DATE);
|
||||
$this->sHeaderDate = $sHeaderDate;
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ class Message
|
|||
public function SetReferences($sReferences)
|
||||
{
|
||||
$this->aHeadersValue[\MailSo\Mime\Enumerations\Header::REFERENCES] =
|
||||
\trim(\preg_replace('/[\s]+/', ' ', $sReferences));
|
||||
\MailSo\Base\Utils::StripSpaces($sReferences);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4127,7 +4127,7 @@ class Actions
|
|||
*/
|
||||
private function rainLoopRepo()
|
||||
{
|
||||
$sUrl = APP_REP_PATH;
|
||||
$sUrl = APP_REPOSITORY_PATH;
|
||||
if ('' !== $sUrl)
|
||||
{
|
||||
$sUrl = rtrim($sUrl, '\\/').'/';
|
||||
|
|
@ -7190,12 +7190,25 @@ class Actions
|
|||
$sFromFolder = $this->GetActionParam('FromFolder', '');
|
||||
$sToFolder = $this->GetActionParam('ToFolder', '');
|
||||
$aUids = \explode(',', (string) $this->GetActionParam('Uids', ''));
|
||||
$bMarkAsRead = '1' === (string) $this->GetActionParam('MarkAsRead', '0');
|
||||
|
||||
$aFilteredUids = \array_filter($aUids, function (&$mUid) {
|
||||
$mUid = (int) \trim($mUid);
|
||||
return 0 < $mUid;
|
||||
});
|
||||
|
||||
if ($bMarkAsRead)
|
||||
{
|
||||
try
|
||||
{
|
||||
$this->MailClient()->MessageSetSeen($sFromFolder, $aFilteredUids, true, true);
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
unset($oException);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$this->MailClient()->MessageMove($sFromFolder, $sToFolder, $aFilteredUids, true,
|
||||
|
|
@ -7259,7 +7272,7 @@ class Actions
|
|||
public function MainClearFileName($sFileName, $sContentType, $sMimeIndex, $iMaxLength = 250)
|
||||
{
|
||||
$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);
|
||||
|
||||
if (10 < $iMaxLength && $iMaxLength < \strlen($sClearedFileName) - \strlen($sExt))
|
||||
|
|
|
|||
|
|
@ -95,6 +95,9 @@ class Api
|
|||
\MailSo\Config::$MessageListPermanentFilter =
|
||||
\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 =
|
||||
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,11 @@ abstract class PdoAbstract
|
|||
*/
|
||||
protected $bExplain = false;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $bSqliteCollate = true;
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
|
|
@ -48,6 +53,18 @@ abstract class PdoAbstract
|
|||
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
|
||||
*
|
||||
|
|
@ -67,6 +84,7 @@ abstract class PdoAbstract
|
|||
|
||||
$sType = $sDsn = $sDbLogin = $sDbPassword = '';
|
||||
list($sType, $sDsn, $sDbLogin, $sDbPassword) = $this->getPdoAccessData();
|
||||
|
||||
if (!\in_array($sType, array('mysql', 'sqlite', 'pgsql')))
|
||||
{
|
||||
throw new \Exception('Unknown PDO SQL connection type');
|
||||
|
|
@ -82,15 +100,28 @@ abstract class PdoAbstract
|
|||
$oPdo = false;
|
||||
try
|
||||
{
|
||||
// $bCaseFunc = false;
|
||||
$oPdo = @new \PDO($sDsn, $sDbLogin, $sDbPassword);
|
||||
if ($oPdo)
|
||||
{
|
||||
$sPdoType = $oPdo->getAttribute(\PDO::ATTR_DRIVER_NAME);
|
||||
$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');
|
||||
}
|
||||
// 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)
|
||||
|
|
@ -156,10 +187,11 @@ abstract class PdoAbstract
|
|||
* @param string $sSql
|
||||
* @param array $aParams
|
||||
* @param bool $bMultiplyParams = false
|
||||
* @param bool $bLogParams = false
|
||||
*
|
||||
* @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)
|
||||
{
|
||||
|
|
@ -172,16 +204,27 @@ abstract class PdoAbstract
|
|||
$oStmt = $this->getPDO()->prepare($sSql);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aLogs = array();
|
||||
$aRootParams = $bMultiplyParams ? $aParams : array($aParams);
|
||||
foreach ($aRootParams as $aSubParams)
|
||||
{
|
||||
foreach ($aSubParams as $sName => $aValue)
|
||||
{
|
||||
if ($bLogParams)
|
||||
{
|
||||
$aLogs[$sName] = $aValue[0];
|
||||
}
|
||||
|
||||
$oStmt->bindValue($sName, $aValue[0], $aValue[1]);
|
||||
}
|
||||
|
||||
$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;
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ abstract class AbstractConfig
|
|||
*/
|
||||
private $sFile;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdditionalFile;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
|
@ -27,12 +32,19 @@ abstract class AbstractConfig
|
|||
/**
|
||||
* @param string $sFileName
|
||||
* @param string $sFileHeader = ''
|
||||
* @param string $sAdditionalFileName = ''
|
||||
*
|
||||
* @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->aData = $this->defaultValues();
|
||||
|
||||
|
|
@ -109,7 +121,7 @@ abstract class AbstractConfig
|
|||
*/
|
||||
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)
|
||||
{
|
||||
$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();
|
||||
|
||||
$iTime = \apc_fetch($sKey.'time');
|
||||
if ($iTime && $iMTime === (int) $iTime)
|
||||
$sTimeHash = \apc_fetch($sKey.'time');
|
||||
if ($sTimeHash && $sTimeHash === \md5($iMTime.'/'.$iATime))
|
||||
{
|
||||
$aFetchData = \apc_fetch($sKey.'data');
|
||||
if (\is_array($aFetchData))
|
||||
|
|
@ -148,11 +165,16 @@ abstract class AbstractConfig
|
|||
if ($this->bUseApcCache)
|
||||
{
|
||||
$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();
|
||||
|
||||
\apc_store($sKey.'time', $iMTime);
|
||||
\apc_store($sKey.'time', \md5($iMTime.'/'.$iATime));
|
||||
\apc_store($sKey.'data', $this->aData);
|
||||
|
||||
return true;
|
||||
|
|
@ -193,7 +215,7 @@ abstract class AbstractConfig
|
|||
}
|
||||
|
||||
$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)
|
||||
{
|
||||
|
|
@ -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();
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ class Application extends \RainLoop\Config\AbstractConfig
|
|||
{
|
||||
parent::__construct('application.ini',
|
||||
'; 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_date_filter' => array(0),
|
||||
'imap_message_list_permanent_filter' => array(''),
|
||||
'imap_message_all_headers' => array(false),
|
||||
'imap_large_thread_limit' => array(50),
|
||||
'imap_folder_list_limit' => array(200),
|
||||
'imap_show_login_alert' => array(true),
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
*/
|
||||
private function convertConfigMap($aMap)
|
||||
{
|
||||
if (0 < count($aMap))
|
||||
if (0 < \count($aMap))
|
||||
{
|
||||
$aResultMap = array();
|
||||
foreach ($aMap as /* @var $oProperty \RainLoop\Plugins\Property */ $oProperty)
|
||||
|
|
@ -33,12 +33,12 @@ class Plugin extends \RainLoop\Config\AbstractConfig
|
|||
if ($oProperty)
|
||||
{
|
||||
$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, '');
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($aResultMap))
|
||||
if (0 < \count($aResultMap))
|
||||
{
|
||||
return array(
|
||||
'plugin' => $aResultMap
|
||||
|
|
|
|||
|
|
@ -26,6 +26,11 @@ class Property
|
|||
*/
|
||||
public $Value;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public $ValueLower;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
|
|
@ -54,6 +59,7 @@ class Property
|
|||
$this->TypeStr = '';
|
||||
|
||||
$this->Value = '';
|
||||
$this->ValueLower = '';
|
||||
$this->ValueCustom = '';
|
||||
|
||||
$this->Frec = 0;
|
||||
|
|
@ -120,6 +126,7 @@ class Property
|
|||
$this->Value = \trim($this->Value);
|
||||
$this->ValueCustom = \trim($this->ValueCustom);
|
||||
$this->TypeStr = \trim($this->TypeStr);
|
||||
$this->ValueLower = '';
|
||||
|
||||
if (0 < \strlen($this->Value))
|
||||
{
|
||||
|
|
@ -131,16 +138,22 @@ class Property
|
|||
|
||||
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())
|
||||
{
|
||||
$sPhone = $this->Value;
|
||||
$sPhone = \trim($this->Value);
|
||||
$sPhone = \preg_replace('/^[+]+/', '', $sPhone);
|
||||
$sPhone = \preg_replace('/[^\d]/', '', $sPhone);
|
||||
$this->ValueCustom = $sPhone;
|
||||
$this->ValueCustom = \trim($sPhone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -957,6 +957,7 @@ class PdoAddressBook
|
|||
':prop_type' => array($oProp->Type, \PDO::PARAM_INT),
|
||||
':prop_type_str' => array($oProp->TypeStr, \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_frec' => array($iFreq, \PDO::PARAM_INT),
|
||||
);
|
||||
|
|
@ -965,9 +966,9 @@ class PdoAddressBook
|
|||
if (0 < \count($aParams))
|
||||
{
|
||||
$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 '.
|
||||
'(: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);
|
||||
}
|
||||
|
|
@ -1072,6 +1073,7 @@ class PdoAddressBook
|
|||
if (0 < \strlen($sSearch))
|
||||
{
|
||||
$sCustomSearch = $this->specialConvertSearchValueCustomPhone($sSearch);
|
||||
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch, '=');
|
||||
|
||||
$sSearchTypes = \implode(',', array(
|
||||
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 '.
|
||||
'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)' : '').
|
||||
') GROUP BY id_contact, id_prop';
|
||||
|
||||
|
|
@ -1088,12 +1092,17 @@ class PdoAddressBook
|
|||
':search' => array($this->specialConvertSearchValue($sSearch, '='), \PDO::PARAM_STR)
|
||||
);
|
||||
|
||||
if (0 < \strlen($sLowerSearch))
|
||||
{
|
||||
$aParams[':search_lower'] = array($sLowerSearch, \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
if (0 < \strlen($sCustomSearch))
|
||||
{
|
||||
$aParams[':search_custom_phone'] = array($sCustomSearch, \PDO::PARAM_STR);
|
||||
}
|
||||
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams);
|
||||
$oStmt = $this->prepareAndExecute($sSql, $aParams, false, true);
|
||||
if ($oStmt)
|
||||
{
|
||||
$aFetch = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
|
|
@ -1211,6 +1220,7 @@ class PdoAddressBook
|
|||
$oProperty->Type = (int) $aItem['prop_type'];
|
||||
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
|
||||
$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->Frec = isset($aItem['prop_frec']) ? (int) $aItem['prop_frec'] : 0;
|
||||
|
||||
|
|
@ -1320,6 +1330,7 @@ class PdoAddressBook
|
|||
$oProperty->Type = (int) $aItem['prop_type'];
|
||||
$oProperty->TypeStr = isset($aItem['prop_type_str']) ? (string) $aItem['prop_type_str'] : '';
|
||||
$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->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
|
||||
));
|
||||
|
||||
$sLowerSearch = $this->specialConvertSearchValueLower($sSearch);
|
||||
|
||||
$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(
|
||||
':id_user' => array($iUserID, \PDO::PARAM_INT),
|
||||
|
|
@ -1373,6 +1390,11 @@ class PdoAddressBook
|
|||
':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 .= ' LIMIT :limit';
|
||||
|
||||
|
|
@ -1547,7 +1569,7 @@ class PdoAddressBook
|
|||
{
|
||||
$oResult = \MailSo\Mime\Email::Parse(\trim($mItem));
|
||||
}
|
||||
catch (\Exception $oException) {}
|
||||
catch (\Exception $oException) { unset($oException); }
|
||||
return $oResult;
|
||||
}, $aEmails);
|
||||
|
||||
|
|
@ -1837,7 +1859,7 @@ SQLITEINITIAL;
|
|||
break;
|
||||
}
|
||||
|
||||
if (0 < strlen($sInitial))
|
||||
if (0 < \strlen($sInitial))
|
||||
{
|
||||
$aList = \explode(';', \trim($sInitial));
|
||||
foreach ($aList as $sV)
|
||||
|
|
@ -1869,17 +1891,26 @@ SQLITEINITIAL;
|
|||
{
|
||||
case 'mysql':
|
||||
$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;
|
||||
case 'pgsql':
|
||||
$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;
|
||||
case 'sqlite':
|
||||
$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;
|
||||
}
|
||||
|
|
@ -1934,6 +1965,24 @@ SQLITEINITIAL;
|
|||
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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
$sResult .= ' "'.$this->quote($sValue).'"';
|
||||
}
|
||||
|
||||
$sResult = \preg_replace('/[\s]+/u', ' ', $sResult);
|
||||
$sResult = \MailSo\Base\Utils::StripSpaces($sResult);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -358,8 +358,8 @@ class SieveStorage implements \RainLoop\Providers\Filters\FiltersInterface
|
|||
$sSubject = '';
|
||||
if (0 < \strlen($sValueSecond))
|
||||
{
|
||||
$sSubject = ':subject "'.$this->quote(
|
||||
\preg_replace('/[\s]+/u', ' ', $sValueSecond)).'" ';
|
||||
$sSubject = ':subject "'.
|
||||
$this->quote(\MailSo\Base\Utils::StripSpaces($sValueSecond)).'" ';
|
||||
}
|
||||
|
||||
if (0 < \strlen($sValueThird) && \is_numeric($sValueThird) && 1 < (int) $sValueThird)
|
||||
|
|
|
|||
|
|
@ -89,7 +89,10 @@
|
|||
|
||||
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
|
||||
.script(function () {
|
||||
|
|
@ -98,7 +101,9 @@
|
|||
];
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(20);
|
||||
|
||||
oProgress.set(20);
|
||||
|
||||
if (window.rainloopAppData['IncludeBackground']) {
|
||||
$('#rl-bg').attr('style', 'background-image: none !important;').backstretch(
|
||||
window.rainloopAppData['IncludeBackground'].replace('{{USER}}',
|
||||
|
|
@ -114,20 +119,20 @@
|
|||
];
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(10);
|
||||
oProgress.set(30);
|
||||
})
|
||||
.script(function () {
|
||||
return {'src': '{{BaseAppMainScriptLink}}', 'type': 'text/javascript', 'charset': 'utf-8'};
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(20);
|
||||
oProgress.set(50);
|
||||
})
|
||||
.script(function () {
|
||||
return window.rainloopAppData['PluginsLink'] ?
|
||||
{'src': window.rainloopAppData['PluginsLink'], 'type': 'text/javascript', 'charset': 'utf-8'} : null;
|
||||
})
|
||||
.wait(function () {
|
||||
__simplePace(5);
|
||||
oProgress.set(55);
|
||||
__runBoot(false);
|
||||
})
|
||||
.script(function () {
|
||||
|
|
|
|||
|
|
@ -22,16 +22,6 @@ Options -Indexes
|
|||
|
||||
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'))
|
||||
{
|
||||
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_DUMMY', '********');
|
||||
define('APP_GOOGLE_ACCESS_TOKEN_PREFIX', ':GAT:');
|
||||
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_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_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));
|
||||
|
||||
$sSalt = @file_get_contents(APP_DATA_FOLDER_PATH.'SALT.php');
|
||||
|
|
|
|||
20
vendors/progress.js/LICENSE
vendored
Normal file
20
vendors/progress.js/LICENSE
vendored
Normal 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
65
vendors/progress.js/README.md
vendored
Normal 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.
|
||||
11
vendors/progress.js/minified/progress.min.js
vendored
Normal file
11
vendors/progress.js/minified/progress.min.js
vendored
Normal 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});
|
||||
1
vendors/progress.js/minified/progressjs.min.css
vendored
Normal file
1
vendors/progress.js/minified/progressjs.min.css
vendored
Normal 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}
|
||||
62
vendors/progress.js/minified/progressjs.rainloop.css
vendored
Normal file
62
vendors/progress.js/minified/progressjs.rainloop.css
vendored
Normal 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
17
vendors/progress.js/package.json
vendored
Normal 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
574
vendors/progress.js/src/progress.js
vendored
Normal 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
181
vendors/progress.js/src/progressjs.css
vendored
Normal 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;
|
||||
}
|
||||
|
|
@ -29,7 +29,7 @@ module.exports = {
|
|||
'JSON': 'window.JSON',
|
||||
'JSEncrypt': 'window.JSEncrypt',
|
||||
'$LAB': 'window.$LAB',
|
||||
'SimplePace': 'window.SimplePace',
|
||||
'progressJs': 'window.progressJs',
|
||||
'PhotoSwipe': 'window.PhotoSwipe',
|
||||
'PhotoSwipeUI_Default': 'window.PhotoSwipeUI_Default',
|
||||
'queue': 'window.queue',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue