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 '';
|
||||||
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
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
44
dev/External/ko.js
vendored
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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']);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,6 @@ html.cssanimations {
|
||||||
.e-spinner .bounce2 {
|
.e-spinner .bounce2 {
|
||||||
animation-delay: -0.16s;
|
animation-delay: -0.16s;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes bouncedelay {
|
@keyframes bouncedelay {
|
||||||
|
|
|
||||||
|
|
@ -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',
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
@ -557,7 +568,7 @@ END;
|
||||||
*/
|
*/
|
||||||
public static function IsUtf8($sValue)
|
public static function IsUtf8($sValue)
|
||||||
{
|
{
|
||||||
return (bool) ( \function_exists('mb_check_encoding') ?
|
return (bool) (\function_exists('mb_check_encoding') ?
|
||||||
\mb_check_encoding($sValue, 'UTF-8') : \preg_match('//u', $sValue));
|
\mb_check_encoding($sValue, 'UTF-8') : \preg_match('//u', $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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@ class Config
|
||||||
*/
|
*/
|
||||||
public static $LargeThreadLimit = 50;
|
public static $LargeThreadLimit = 50;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public static $MessageAllHeaders = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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),
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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,8 +1081,10 @@ 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 ('.
|
||||||
(0 < \strlen($sCustomSearch) ? ' OR (prop_type = '.PropertyType::PHONE.' AND prop_value_custom <> \'\' AND prop_value_custom LIKE :search_custom_phone)' : '').
|
'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';
|
') GROUP BY id_contact, id_prop';
|
||||||
|
|
||||||
$aParams = array(
|
$aParams = array(
|
||||||
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 () {
|
||||||
|
|
|
||||||
|
|
@ -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
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',
|
'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',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue