]*>/gmi, ' * ')
.replace(/<\/li>/gi, '\n')
.replace(/<\/td>/gi, '\n')
.replace(/<\/tr>/gi, '\n')
diff --git a/dev/Screen/User/MailBox.js b/dev/Screen/User/MailBox.js
index 8f79ed316..07a6da8c8 100644
--- a/dev/Screen/User/MailBox.js
+++ b/dev/Screen/User/MailBox.js
@@ -55,6 +55,11 @@
nFoldersInboxUnreadCount = FolderStore.foldersInboxUnreadCount()
;
+ if (Settings.settingsGet('Filtered'))
+ {
+ nFoldersInboxUnreadCount = 0;
+ }
+
require('App/User').setWindowTitle(('' === sEmail ? '' : '' +
(0 < nFoldersInboxUnreadCount ? '(' + nFoldersInboxUnreadCount + ') ' : ' ') +
sEmail + ' - ') + Translator.i18n('TITLES/MAILBOX'));
@@ -82,7 +87,6 @@
* @param {string} sFolderHash
* @param {number} iPage
* @param {string} sSearch
- * @param {boolean=} bPreview = false
*/
MailBoxUserScreen.prototype.onRoute = function (sFolderHash, iPage, sSearch)
{
diff --git a/dev/Settings/Admin/Social.js b/dev/Settings/Admin/Social.js
index ca2d2ad84..8a6890cc5 100644
--- a/dev/Settings/Admin/Social.js
+++ b/dev/Settings/Admin/Social.js
@@ -20,6 +20,7 @@
this.googleEnable = SocialStore.google.enabled;
this.googleEnableAuth = SocialStore.google.capa.auth;
+ this.googleEnableAuthFast = SocialStore.google.capa.authFast;
this.googleEnableDrive = SocialStore.google.capa.drive;
this.googleEnablePreview = SocialStore.google.capa.preview;
diff --git a/dev/Settings/User/Social.js b/dev/Settings/User/Social.js
index b5521a546..82bbe5d2f 100644
--- a/dev/Settings/User/Social.js
+++ b/dev/Settings/User/Social.js
@@ -15,6 +15,7 @@
this.googleEnable = SocialStore.google.enabled;
this.googleEnableAuth = SocialStore.google.capa.auth;
+ this.googleEnableAuthFast = SocialStore.google.capa.authFast;
this.googleEnableDrive = SocialStore.google.capa.drive;
this.googleEnablePreview = SocialStore.google.capa.preview;
diff --git a/dev/Stores/Social.js b/dev/Stores/Social.js
index 0e870ce5b..ffeb0f6f9 100644
--- a/dev/Stores/Social.js
+++ b/dev/Stores/Social.js
@@ -33,6 +33,7 @@
this.google.capa = {};
this.google.capa.auth = ko.observable(false);
+ this.google.capa.authFast = ko.observable(false);
this.google.capa.drive = ko.observable(false);
this.google.capa.preview = ko.observable(false);
@@ -88,6 +89,7 @@
this.google.apiKey(Settings.settingsGet('GoogleApiKey'));
this.google.capa.auth(!!Settings.settingsGet('AllowGoogleSocialAuth'));
+ this.google.capa.authFast(!!Settings.settingsGet('AllowGoogleSocialAuthFast'));
this.google.capa.drive(!!Settings.settingsGet('AllowGoogleSocialDrive'));
this.google.capa.preview(!!Settings.settingsGet('AllowGoogleSocialPreview'));
diff --git a/dev/Styles/Login.less b/dev/Styles/Login.less
index 504b1e4d2..8da8dab3d 100644
--- a/dev/Styles/Login.less
+++ b/dev/Styles/Login.less
@@ -25,6 +25,9 @@
max-width: 450px;
}
+ .wrapper-parent {
+ }
+
.loginForm {
background-color: #efefef;
text-align: left;
@@ -34,6 +37,18 @@
width: 303px;
}
+ .loginWelcomeForm {
+ display: none;
+ }
+
+ .welcome-on {
+ display: block;
+ }
+
+ .welcome-off {
+ display: none;
+ }
+
/* .control-label {
font-size: 16px;
line-height: 30px;
diff --git a/dev/Styles/MessageView.less b/dev/Styles/MessageView.less
index 24d392852..25f6dc3cc 100644
--- a/dev/Styles/MessageView.less
+++ b/dev/Styles/MessageView.less
@@ -331,6 +331,10 @@ html.rl-no-preview-pane {
}
}
+ .bodySubHeader {
+ z-index: 2;
+ }
+
.bodyText {
color: #000;
@@ -338,9 +342,11 @@ html.rl-no-preview-pane {
.b-text-part {
+ height: 100%;
+
div[data-x-div-type=html] {
height: 100%;
- div[data-x-div-type=html] {
+ div[data-x-div-type=body] {
height: 100%;
}
}
@@ -357,14 +363,10 @@ html.rl-no-preview-pane {
}
}
- table {
- border-collapse: separate;
- }
-
blockquote {
border-left: 2px solid #000;
- margin: 0;
padding: 0px 10px;
+ margin: 0;
}
.rl-bq-switcher.hidden-bq {
@@ -372,8 +374,10 @@ html.rl-no-preview-pane {
}
&.html {
+
div[data-x-div-type=body] {
- margin: 15px;
+ padding: 15px;
+ // margin: 15px;
}
pre {
diff --git a/dev/Styles/Ui.less b/dev/Styles/Ui.less
index 1ac9744da..09afa1136 100644
--- a/dev/Styles/Ui.less
+++ b/dev/Styles/Ui.less
@@ -33,6 +33,10 @@
min-height: 300px;
}
+.g-ui-100-proc-height {
+ height: 100%;
+}
+
.g-ui-absolute-reset {
position: absolute;
top: 0;
diff --git a/dev/Styles/_FontasticToBoot.less b/dev/Styles/_FontasticToBoot.less
index 70b25dae9..52d8db353 100644
--- a/dev/Styles/_FontasticToBoot.less
+++ b/dev/Styles/_FontasticToBoot.less
@@ -17,12 +17,19 @@
width: 17px;
}
+.iconsize50 {
+ line-height: 50px;
+ font-size: 50px;
+ width: 50px;
+ height: 50px;
+}
+
.iconsize24 {
line-height: 24px;
font-size: 24px;
}
-.iconsize24 {
+.iconsize20 {
line-height: 20px;
font-size: 20px;
}
diff --git a/dev/View/User/Login.js b/dev/View/User/Login.js
index f3359f4b5..db5dc2e79 100644
--- a/dev/View/User/Login.js
+++ b/dev/View/User/Login.js
@@ -36,6 +36,8 @@
{
AbstractView.call(this, 'Center', 'Login');
+ this.welcome = ko.observable(!!Settings.settingsGet('UseLoginWelcomePage'));
+
this.email = ko.observable('');
this.password = ko.observable('');
this.signMe = ko.observable(false);
@@ -294,11 +296,12 @@
});
this.googleLoginEnabled = ko.observable(false);
+ this.googleFastLoginEnabled = ko.observable(false);
this.googleCommand = Utils.createCommand(this, function () {
window.open(Links.socialGoogle(), 'Google',
- 'left=200,top=100,width=650,height=450,menubar=no,status=no,resizable=yes,scrollbars=yes');
+ 'left=200,top=100,width=650,height=500,menubar=no,status=no,resizable=yes,scrollbars=yes');
return true;
@@ -306,15 +309,15 @@
return !this.submitRequest() && this.googleLoginEnabled();
});
- this.googleXAuthCommand = Utils.createCommand(this, function () {
+ this.googleFastCommand = Utils.createCommand(this, function () {
window.open(Links.socialGoogle(true), 'Google',
- 'left=200,top=100,width=650,height=450,menubar=no,status=no,resizable=yes,scrollbars=yes');
+ 'left=200,top=100,width=650,height=500,menubar=no,status=no,resizable=yes,scrollbars=yes');
return true;
}, function () {
- return !this.submitRequest() && this.googleLoginEnabled();
+ return !this.submitRequest() && this.googleFastLoginEnabled();
});
this.twitterLoginEnabled = ko.observable(false);
@@ -347,6 +350,11 @@
kn.extendAsViewModel(['View/User/Login', 'View/App/Login', 'LoginViewModel'], LoginUserView);
_.extend(LoginUserView.prototype, AbstractView.prototype);
+ LoginUserView.prototype.displayMainForm = function ()
+ {
+ this.welcome(false);
+ };
+
LoginUserView.prototype.onShow = function ()
{
kn.routeOff();
@@ -404,6 +412,8 @@
this.twitterLoginEnabled(!!Settings.settingsGet('AllowTwitterSocial'));
this.googleLoginEnabled(!!Settings.settingsGet('AllowGoogleSocial') &&
!!Settings.settingsGet('AllowGoogleSocialAuth'));
+ this.googleFastLoginEnabled(!!Settings.settingsGet('AllowGoogleSocial') &&
+ !!Settings.settingsGet('AllowGoogleSocialAuthFast'));
switch (sSignMe)
{
@@ -433,7 +443,7 @@
this.email(AppStore.devEmail);
this.password(AppStore.devPassword);
- if (this.googleLoginEnabled())
+ if (this.googleLoginEnabled() || this.googleFastLoginEnabled())
{
window['rl_' + sJsHash + '_google_login_service'] = fSocial;
}
diff --git a/dev/View/User/MailBox/MessageView.js b/dev/View/User/MailBox/MessageView.js
index f7a3b1aa3..11a4017bc 100644
--- a/dev/View/User/MailBox/MessageView.js
+++ b/dev/View/User/MailBox/MessageView.js
@@ -24,8 +24,6 @@
Cache = require('Common/Cache'),
- EmailModel = require('Model/Email'),
-
SocialStore = require('Stores/Social'),
AppStore = require('Stores/User/App'),
SettingsStore = require('Stores/User/Settings'),
@@ -66,6 +64,8 @@
this.oHeaderDom = null;
this.oMessageScrollerDom = null;
+ this.bodyBackgroundColor = ko.observable('');
+
this.pswp = null;
this.allowComposer = !!Settings.capa(Enums.Capa.Composer);
@@ -353,6 +353,10 @@
}, this);
+ this.messageActiveDom.subscribe(function (oDom) {
+ this.bodyBackgroundColor(oDom ? this.detectDomBackgroundColor(oDom): '');
+ }, this);
+
this.message.subscribe(function (oMessage) {
this.messageActiveDom(null);
@@ -466,6 +470,59 @@
kn.extendAsViewModel(['View/User/MailBox/MessageView', 'View/App/MailBox/MessageView', 'MailBoxMessageViewViewModel'], MessageViewMailBoxUserView);
_.extend(MessageViewMailBoxUserView.prototype, AbstractView.prototype);
+ MessageViewMailBoxUserView.prototype.detectDomBackgroundColor = function (oDom)
+ {
+ var
+ iLimit = 5,
+ sResult = '',
+ aC = null,
+ fFindDom = function (oDom) {
+ var aC = oDom ? oDom.children() : null;
+ return (aC && 1 === aC.length && aC.is('table,div,center')) ? aC : null;
+ },
+ fFindColor = function (oDom) {
+ var sResult = '';
+ if (oDom)
+ {
+ sResult = oDom.css('background-color') || '';
+ if (!oDom.is('table'))
+ {
+ sResult = 'rgba(0, 0, 0, 0)' === sResult || 'transparent' === sResult ? '' : sResult;
+ }
+ }
+
+ return sResult;
+ }
+ ;
+
+ if (oDom && 1 === oDom.length)
+ {
+ aC = oDom;
+ while ('' === sResult)
+ {
+ iLimit--;
+ if (0 >= iLimit)
+ {
+ break;
+ }
+
+ aC = fFindDom(aC);
+ if (aC)
+ {
+ sResult = fFindColor(aC);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ sResult = 'rgba(0, 0, 0, 0)' === sResult || 'transparent' === sResult ? '' : sResult;
+ }
+
+ return sResult;
+ };
+
MessageViewMailBoxUserView.prototype.isPgpActionVisible = function ()
{
return Enums.SignedVerifyStatus.Success !== this.viewPgpSignedVerifyStatus();
@@ -552,27 +609,28 @@
* @todo
* @param {string} sEmail
*/
- MessageViewMailBoxUserView.prototype.displayMailToPopup = function (sMailToUrl)
- {
- sMailToUrl = sMailToUrl.replace(/\?.+$/, '');
-
- var
- sResult = '',
- aTo = [],
- fParseEmailLine = function (sLine) {
- return sLine ? _.compact(_.map([window.decodeURIComponent(sLine)], function (sItem) {
- var oEmailModel = new EmailModel();
- oEmailModel.mailsoParse(sItem);
- return '' !== oEmailModel.email ? oEmailModel : null;
- })) : null;
- }
- ;
-
- aTo = fParseEmailLine(sMailToUrl);
- sResult = aTo && aTo[0] ? aTo[0].email : '';
-
- window.console.log(sResult);
- };
+// MessageViewMailBoxUserView.prototype.displayMailToPopup = function (sMailToUrl)
+// {
+// sMailToUrl = sMailToUrl.replace(/\?.+$/, '');
+//
+// var
+// sResult = '',
+// aTo = [],
+// EmailModel = require('Model/Email'),
+// fParseEmailLine = function (sLine) {
+// return sLine ? _.compact(_.map([window.decodeURIComponent(sLine)], function (sItem) {
+// var oEmailModel = new EmailModel();
+// oEmailModel.mailsoParse(sItem);
+// return '' !== oEmailModel.email ? oEmailModel : null;
+// })) : null;
+// }
+// ;
+//
+// aTo = fParseEmailLine(sMailToUrl);
+// sResult = aTo && aTo[0] ? aTo[0].email : '';
+//
+// return sResult;
+// };
MessageViewMailBoxUserView.prototype.onBuild = function (oDom)
{
@@ -592,6 +650,7 @@
}
}, this);
+ this.showAttachmnetControls.subscribe(fCheckHeaderHeight);
this.fullScreenMode.subscribe(fCheckHeaderHeight);
this.showFullInfo.subscribe(fCheckHeaderHeight);
this.message.subscribe(fCheckHeaderHeight);
@@ -806,18 +865,6 @@
this.initShortcuts();
};
- MessageViewMailBoxUserView.prototype.selectSelectedThreadMessage = function ()
- {
- var self = this;
- _.delay(function () {
- var oLast = self.oDom ? $('.thread-list .e-item.thread-list-message.real-msg.selected a.e-link', self.oDom) : null;
- if (oLast && oLast[0])
- {
- oLast.focus();
- }
- }, 30);
- };
-
/**
* @return {boolean}
*/
@@ -1196,6 +1243,8 @@
{
oMessage.showExternalImages(true);
}
+
+ this.checkHeaderHeight();
};
/**
@@ -1217,6 +1266,8 @@
{
oMessage.verifyPgpSignedClearMessage();
}
+
+ this.checkHeaderHeight();
};
/**
@@ -1248,6 +1299,8 @@
require('App/User').reloadFlagsCurrentMessageListAndMessageFromCache();
}
+
+ this.checkHeaderHeight();
};
module.exports = MessageViewMailBoxUserView;
diff --git a/package.json b/package.json
index 0847967c6..cb36f1de7 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "RainLoop",
"title": "RainLoop Webmail",
"version": "1.9.1",
- "release": "333",
+ "release": "334",
"description": "Simple, modern & fast web-based email client",
"homepage": "http://rainloop.net",
"main": "gulpfile.js",
diff --git a/rainloop/v/0.0.0/app/handle.php b/rainloop/v/0.0.0/app/handle.php
index 1de59f78c..464a43e3d 100644
--- a/rainloop/v/0.0.0/app/handle.php
+++ b/rainloop/v/0.0.0/app/handle.php
@@ -59,7 +59,7 @@ if (!\defined('RAINLOOP_APP_LIBRARIES_PATH'))
if (\class_exists('RainLoop\Api'))
{
- if (!\class_exists('MailSo\Version'))
+ if (!\class_exists('MailSo\Version', false))
{
include APP_VERSION_ROOT_PATH.'app/libraries/MailSo/MailSo.php';
}
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
index 7adb7fd1f..96f9ac02d 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Base/HtmlUtils.php
@@ -35,23 +35,32 @@ class HtmlUtils
*/
public static function GetDomFromText($sText, $sHtmlAttrs = '', $sBodyAttrs = '')
{
- static $bOnce = true;
- if ($bOnce)
+ $bState = true;
+ if (\MailSo\Base\Utils::FunctionExistsAndEnabled('libxml_use_internal_errors'))
{
- $bOnce = false;
- if (\MailSo\Base\Utils::FunctionExistsAndEnabled('libxml_use_internal_errors'))
- {
- @\libxml_use_internal_errors(true);
- }
+ $bState = \libxml_use_internal_errors(true);
}
$oDom = new \DOMDocument('1.0', 'utf-8');
$oDom->encoding = 'UTF-8';
+ $oDom->strictErrorChecking = false;
$oDom->formatOutput = false;
@$oDom->loadHTML('<'.'?xml version="1.0" encoding="utf-8"?'.'>'.
' '.$sText.'');
+ @$oDom->normalizeDocument();
+
+ if (\MailSo\Base\Utils::FunctionExistsAndEnabled('libxml_use_internal_errors'))
+ {
+ @\libxml_clear_errors();
+ }
+
+ if (\MailSo\Base\Utils::FunctionExistsAndEnabled('libxml_use_internal_errors'))
+ {
+ \libxml_use_internal_errors($bState);
+ }
+
return $oDom;
}
@@ -65,13 +74,13 @@ class HtmlUtils
public static function ClearBodyAndHtmlTag($sHtml, &$sHtmlAttrs = '', &$sBodyAttrs = '')
{
$aMatch = array();
- if (preg_match('/]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
+ if (\preg_match('/]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
{
$sHtmlAttrs = $aMatch[1];
}
$aMatch = array();
- if (preg_match('/]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
+ if (\preg_match('/]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
{
$sBodyAttrs = $aMatch[1];
}
@@ -81,6 +90,29 @@ class HtmlUtils
$sHtml = \preg_replace('/]*)>/im', '', $sHtml);
$sHtml = \preg_replace('/<\/html>/im', '', $sHtml);
+ $sHtmlAttrs = \preg_replace('/xmlns:[a-z]="[^"]*"/im', '', $sHtmlAttrs);
+ $sHtmlAttrs = \preg_replace('/xmlns="[^"]*"/im', '', $sHtmlAttrs);
+ $sBodyAttrs = \preg_replace('/xmlns:[a-z]="[^"]*"/im', '', $sBodyAttrs);
+
+ return $sHtml;
+ }
+
+ /**
+ * @param string $sHtml
+ * @param bool $bClearEmpty = true
+ *
+ * @return string
+ */
+ public static function FixSchemas($sHtml, $bClearEmpty = true)
+ {
+ if ($bClearEmpty)
+ {
+ $sHtml = \str_replace(' ', '', $sHtml);
+ }
+
+ $sHtml = \str_replace('', '', $sHtml);
+ $sHtml = \str_replace(' ', '', $sHtml);
+
return $sHtml;
}
@@ -104,6 +136,7 @@ class HtmlUtils
}
$aToRemove = array(
+ '/]*><\/p>/i',
'/]*>/msi',
'/<\?xml [^>]*\?>/msi'
);
@@ -262,7 +295,7 @@ class HtmlUtils
// $mResult = false;
// $oCss = null;
//
-// if (!\class_exists('\\Sabberworm\\CSS\\Parser'))
+// if (!\class_exists('Sabberworm\CSS\Parser'))
// {
// return $mResult;
// }
@@ -637,15 +670,17 @@ class HtmlUtils
* @param bool $bDoNotReplaceExternalUrl = false
* @param bool $bFindLinksInHtml = false
* @param callback|null $fAdditionalExternalFilter = null
+ * @param callback|null $fAdditionalDomReader = null
*
* @return string
*/
public static function ClearHtml($sHtml, &$bHasExternals = false, &$aFoundCIDs = array(),
$aContentLocationUrls = array(), &$aFoundedContentLocationUrls = array(),
- $bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false, $fAdditionalExternalFilter = null)
+ $bDoNotReplaceExternalUrl = false, $bFindLinksInHtml = false,
+ $fAdditionalExternalFilter = null, $fAdditionalDomReader = false,
+ $bTryToDetectHiddenImages = false)
{
$sResult = '';
-// $aBodyStyles = array();
$sHtml = null === $sHtml ? '' : (string) $sHtml;
$sHtml = \trim($sHtml);
@@ -659,8 +694,15 @@ class HtmlUtils
$fAdditionalExternalFilter = null;
}
+ if ($fAdditionalDomReader && !\is_callable($fAdditionalDomReader))
+ {
+ $fAdditionalDomReader = null;
+ }
+
$bHasExternals = false;
+ $sHtml = \MailSo\Base\HtmlUtils::FixSchemas($sHtml);
+
$sHtml = \MailSo\Base\HtmlUtils::ClearTags($sHtml, false);
$sHtml = \MailSo\Base\HtmlUtils::ClearOn($sHtml);
@@ -673,11 +715,37 @@ class HtmlUtils
if ($oDom)
{
+ if ($fAdditionalDomReader)
+ {
+ $oResDom = \call_user_func($fAdditionalDomReader, $oDom);
+ if ($oResDom)
+ {
+ $oDom = $oResDom;
+ }
+
+ unset($oResDom);
+ }
+
if ($bFindLinksInHtml)
{
\MailSo\Base\HtmlUtils::FindLinksInDOM($oDom);
}
+ $oXpath = new \DOMXpath($oDom);
+ $oComments = $oXpath->query('//comment()');
+ if ($oComments)
+ {
+ foreach ($oComments as $oComment)
+ {
+ if (isset($oComment->parentNode))
+ {
+ @$oComment->parentNode->removeChild($oComment);
+ }
+ }
+ }
+
+ unset($oXpath, $oComments);
+
$aNodes = $oDom->getElementsByTagName('*');
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
{
@@ -685,19 +753,10 @@ class HtmlUtils
{
$sTagNameLower = \strtolower($oElement->tagName);
- if (\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',
'object', 'embed', 'applet', 'mocha', 'iframe', 'frame', 'frameset', 'video', 'audio')))
{
-// if ('style' === $sTagNameLower)
-// {
-// $sV = (string) $oElement->textContent;
-// if (!empty($sV))
-// {
-// $aBodyStyles[] = $sV;
-// }
-// }
-
if (isset($oElement->parentNode))
{
@$oElement->parentNode->removeChild($oElement);
@@ -706,6 +765,7 @@ class HtmlUtils
}
}
+ $sLinkColor = '';
$aNodes = $oDom->getElementsByTagName('*');
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
{
@@ -715,6 +775,7 @@ class HtmlUtils
if ('body' === $sTagNameLower)
{
$aAttrs = array(
+ 'link' => '',
'text' => '',
'topmargin' => '',
'leftmargin' => '',
@@ -746,6 +807,13 @@ class HtmlUtils
switch ($sIndex)
{
+ case 'link':
+ $sLinkColor = \trim($aItem[1]);
+ if (!\preg_match('/^#[abcdef0-9]{3,6}$/i', $sLinkColor))
+ {
+ $sLinkColor = '';
+ }
+ break;
case 'text':
$aStyles[] = 'color: '.$aItem[1];
break;
@@ -767,7 +835,7 @@ class HtmlUtils
if (0 < \count($aStyles))
{
- $sStyles = $oElement->hasAttribute('style') ? $oElement->getAttribute('style') : '';
+ $sStyles = $oElement->hasAttribute('style') ? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : '';
$oElement->setAttribute('style', (empty($sStyles) ? '' : $sStyles.'; ').\implode('; ', $aStyles));
}
}
@@ -777,6 +845,15 @@ class HtmlUtils
$oElement->setAttribute('src', 'javascript:false');
}
+ if ('a' === $sTagNameLower && !empty($sLinkColor))
+ {
+ $sStyles = $oElement->hasAttribute('style')
+ ? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : '';
+
+ $oElement->setAttribute('style',
+ 'color: '.$sLinkColor.\trim((empty($sStyles) ? '' : '; '.$sStyles)));
+ }
+
if (\in_array($sTagNameLower, array('a', 'form', 'area')))
{
$oElement->setAttribute('target', '_blank');
@@ -787,15 +864,10 @@ class HtmlUtils
$oElement->setAttribute('tabindex', '-1');
}
-// if ('blockquote' === $sTagNameLower)
-// {
-// $oElement->removeAttribute('style');
-// }
-
foreach (array(
'id', 'class',
'contenteditable', 'designmode', 'formaction',
- 'data-bind', 'xmlns', 'srcset'
+ 'data-bind', 'data-reactid', 'xmlns', 'srcset'
) as $sAttr)
{
@$oElement->removeAttribute($sAttr);
@@ -826,6 +898,35 @@ class HtmlUtils
}
}
+ if ($bTryToDetectHiddenImages && 'img' === $sTagNameLower)
+ {
+ $sAlt = $oElement->hasAttribute('alt')
+ ? \trim($oElement->getAttribute('alt')) : '';
+
+ $sH = $oElement->hasAttribute('height')
+ ? \trim($oElement->getAttribute('height')) : '';
+
+ $sW = $oElement->hasAttribute('width')
+ ? \trim($oElement->getAttribute('width')) : '';
+
+ $sStyles = $oElement->hasAttribute('style')
+ ? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : '';
+
+ if ($oElement->hasAttribute('src'))
+ {
+ $aValues = array('4', '3', '2', '1', '0', '4px', '3px', '2px', '1px', '0px');
+ if (('' === $sAlt && \in_array($sH, $aValues) && \in_array($sW, $aValues)) ||
+ \preg_match('/(display:none|visibility:hidden)/i', \preg_replace('/[\s]+/', '', $sStyles)))
+ {
+ if (isset($oElement->parentNode))
+ {
+ @$oElement->parentNode->removeChild($oElement);
+ continue;
+ }
+ }
+ }
+ }
+
if ($oElement->hasAttribute('src'))
{
$sSrc = \trim($oElement->getAttribute('src'));
@@ -884,7 +985,7 @@ class HtmlUtils
{
$aStyles = array();
$sStyles = $oElement->hasAttribute('style')
- ? $oElement->getAttribute('style') : '';
+ ? \trim(\trim(\trim($oElement->getAttribute('style')), ';')) : '';
if (!empty($sBackground))
{
@@ -922,6 +1023,7 @@ class HtmlUtils
$sResult = '
'.$sResult.'
';
$sResult = \str_replace(\MailSo\Base\HtmlUtils::$KOS, ':', $sResult);
+ $sResult = \preg_replace('/[\s]+/u', ' ', $sResult);
return \trim($sResult);
}
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Config.php b/rainloop/v/0.0.0/app/libraries/MailSo/Config.php
index b40fdf518..6975e6432 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Config.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Config.php
@@ -66,6 +66,11 @@ class Config
*/
public static $PreferStartTlsIfAutoDetect = true;
+ /**
+ * @var string
+ */
+ public static $BoundaryPrefix = '_Part_';
+
/**
* @var \MailSo\Log\Logger|null
*/
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
index e290b0a83..ffd9cb0eb 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MailClient.php
@@ -756,7 +756,8 @@ class MailClient
{
$iUnseenCount = 0; // unneccessery
return \md5('FolderHash/'.$sFolder.'-'.$iCount.'-'.$iUnseenCount.'-'.$sUidNext.'-'.
- $sHighestModSeq.'-'.$this->GenerateImapClientHash()
+ $sHighestModSeq.'-'.$this->GenerateImapClientHash().'-'.
+ \MailSo\Config::$MessageListPermanentFilter
);
}
@@ -1882,6 +1883,7 @@ class MailClient
$oMessageCollection->Limit = $iLimit;
$oMessageCollection->Search = $sSearch;
$oMessageCollection->ThreadUid = $sThreadUid;
+ $oMessageCollection->Filtered = '' !== \MailSo\Config::$MessageListPermanentFilter;
$aUids = array();
$mAllSortedUids = null;
@@ -1988,7 +1990,9 @@ class MailClient
if (0 < \strlen($sSearch) && \is_array($aUids))
{
- $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter, $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
+ $aSearchedUids = $this->GetUids($oCacher, $sSearch, $sFilter,
+ $oMessageCollection->FolderName, $oMessageCollection->FolderHash);
+
if (\is_array($aSearchedUids) && 0 < \count($aSearchedUids))
{
$aFlippedSearchedUids = \array_flip($aSearchedUids);
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php
index ec176924a..427a18cac 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mail/MessageCollection.php
@@ -73,9 +73,9 @@ class MessageCollection extends \MailSo\Base\Collection
public $NewMessages;
/**
- * @var array
+ * @var bool
*/
- public $LastCollapsedThreadUids;
+ public $Filtered;
/**
* @access protected
@@ -116,7 +116,7 @@ class MessageCollection extends \MailSo\Base\Collection
$this->ThreadUid = '';
$this->NewMessages = array();
- $this->LastCollapsedThreadUids = array();
+ $this->Filtered = false;
return $this;
}
diff --git a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Message.php b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Message.php
index 7bfaec046..106b3e6ae 100644
--- a/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Message.php
+++ b/rainloop/v/0.0.0/app/libraries/MailSo/Mime/Message.php
@@ -511,7 +511,8 @@ class Message
*/
private function generateNewBoundary()
{
- return '----=_Part_'.rand(100, 999).'_'.rand(100000000, 999999999).'.'.time();
+ return '--='.\MailSo\Config::$BoundaryPrefix.
+ \rand(100, 999).'_'.rand(100000000, 999999999).'.'.\time();
}
/**
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
index d60264ccc..ba4128cac 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Actions.php
@@ -411,16 +411,17 @@ class Actions
/**
* @param string $sLine
* @param \RainLoop\Model\Account $oAccount = null
+ * @param bool $bUrlEncode = false
*
* @return string
*/
- private function compileLogParams($sLine, $oAccount = null)
+ private function compileLogParams($sLine, $oAccount = null, $bUrlEncode = false)
{
if (false !== \strpos($sLine, '{date:'))
{
$iTimeOffset = (int) $this->Config()->Get('logs', 'time_offset', 0);
- $sLine = \preg_replace_callback('/\{date:([^}]+)\}/', function ($aMatch) use ($iTimeOffset) {
- return \MailSo\Log\Logger::DateHelper($aMatch[1], $iTimeOffset);
+ $sLine = \preg_replace_callback('/\{date:([^}]+)\}/', function ($aMatch) use ($iTimeOffset, $bUrlEncode) {
+ return \RainLoop\Utils::UrlEncode(\MailSo\Log\Logger::DateHelper($aMatch[1], $iTimeOffset), $bUrlEncode);
}, $sLine);
$sLine = \preg_replace('/\{date:([^}]*)\}/', 'date', $sLine);
@@ -436,37 +437,38 @@ class Actions
if ($oAccount)
{
- $sLine = \str_replace('{imap:login}', $oAccount->IncLogin(), $sLine);
- $sLine = \str_replace('{imap:host}', $oAccount->DomainIncHost(), $sLine);
- $sLine = \str_replace('{imap:port}', $oAccount->DomainIncPort(), $sLine);
+ $sLine = \str_replace('{imap:login}', \RainLoop\Utils::UrlEncode($oAccount->IncLogin(), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{imap:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncHost(), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{imap:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncPort(), $bUrlEncode), $sLine);
- $sLine = \str_replace('{smtp:login}', $oAccount->OutLogin(), $sLine);
- $sLine = \str_replace('{smtp:host}', $oAccount->DomainOutHost(), $sLine);
- $sLine = \str_replace('{smtp:port}', $oAccount->DomainOutPort(), $sLine);
+ $sLine = \str_replace('{smtp:login}', \RainLoop\Utils::UrlEncode($oAccount->OutLogin(), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{smtp:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutHost(), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{smtp:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutPort(), $bUrlEncode), $sLine);
}
$sLine = \preg_replace('/\{imap:([^}]*)\}/i', 'imap', $sLine);
- $sLine = \preg_replace('/\{smtp:([^}]*)\}/i', 'imap', $sLine);
+ $sLine = \preg_replace('/\{smtp:([^}]*)\}/i', 'smtp', $sLine);
}
if (false !== \strpos($sLine, '{request:'))
{
if (false !== \strpos($sLine, '{request:ip}'))
{
- $sLine = \str_replace('{request:ip}', $this->Http()->GetClientIp(
- $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $sLine);
+ $sLine = \str_replace('{request:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp(
+ $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine);
}
if (false !== \strpos($sLine, '{request:domain}'))
{
$sLine = \str_replace('{request:domain}',
- $this->Http()->GetHost(false, true, true), $sLine);
+ \RainLoop\Utils::UrlEncode($this->Http()->GetHost(false, true, true), $bUrlEncode), $sLine);
}
if (false !== \strpos($sLine, '{request:domain-clear}'))
{
$sLine = \str_replace('{request:domain-clear}',
- \MailSo\Base\Utils::GetClearDomainName($this->Http()->GetHost(false, true, true)), $sLine);
+ \RainLoop\Utils::UrlEncode(
+ \MailSo\Base\Utils::GetClearDomainName($this->Http()->GetHost(false, true, true)), $bUrlEncode), $sLine);
}
$sLine = \preg_replace('/\{request:([^}]*)\}/i', 'request', $sLine);
@@ -477,15 +479,16 @@ class Actions
if (false !== \strpos($sLine, '{user:uid}'))
{
$sLine = \str_replace('{user:uid}',
- \base_convert(\sprintf('%u', \crc32(\md5(\RainLoop\Utils::GetConnectionToken()))), 10, 32),
+ \RainLoop\Utils::UrlEncode(\base_convert(\sprintf('%u',
+ \crc32(\md5(\RainLoop\Utils::GetConnectionToken()))), 10, 32), $bUrlEncode),
$sLine
);
}
if (false !== \strpos($sLine, '{user:ip}'))
{
- $sLine = \str_replace('{user:ip}', $this->Http()->GetClientIp(
- $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $sLine);
+ $sLine = \str_replace('{user:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp(
+ $this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine);
}
if (\preg_match('/\{user:(email|login|domain)\}/i', $sLine))
@@ -499,13 +502,15 @@ class Actions
if ($oAccount)
{
$sEmail = $oAccount->Email();
- $sLine = \str_replace('{user:email}', $sEmail, $sLine);
- $sLine = \str_replace('{user:login}',
- \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $sLine);
- $sLine = \str_replace('{user:domain}',
- \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sLine);
- $sLine = \str_replace('{user:domain-clear}',
- \MailSo\Base\Utils::GetClearDomainName(\MailSo\Base\Utils::GetDomainFromEmail($sEmail)), $sLine);
+
+ $sLine = \str_replace('{user:email}', \RainLoop\Utils::UrlEncode($sEmail, $bUrlEncode), $sLine);
+ $sLine = \str_replace('{user:login}', \RainLoop\Utils::UrlEncode(
+ \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{user:domain}', \RainLoop\Utils::UrlEncode(
+ \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $bUrlEncode), $sLine);
+ $sLine = \str_replace('{user:domain-clear}', \RainLoop\Utils::UrlEncode(
+ \MailSo\Base\Utils::GetClearDomainName(
+ \MailSo\Base\Utils::GetDomainFromEmail($sEmail)), $bUrlEncode), $sLine);
}
}
@@ -997,6 +1002,18 @@ class Actions
if (!!$this->Config()->Get('logs', 'enable', false))
{
+ $sSessionFilter = (string) $this->Config()->Get('logs', 'session_filter', '');
+ if (!empty($sSessionFilter))
+ {
+ $aSessionParts = \explode(':', $sSessionFilter, 2);
+
+ if (empty($aSessionParts[0]) || empty($aSessionParts[1]) ||
+ (string) $aSessionParts[1] !== (string) \RainLoop\Utils::GetCookie($aSessionParts[0], ''))
+ {
+ return $this->oLogger;
+ }
+ }
+
$iTimeOffset = (int) $this->Config()->Get('logs', 'time_offset', 0);
$this->oLogger->SetShowSecter(!$this->Config()->Get('logs', 'hide_passwords', true));
@@ -1370,6 +1387,7 @@ class Actions
'LoginDefaultDomain' => $oConfig->Get('login', 'default_domain', ''),
'DetermineUserLanguage' => (bool) $oConfig->Get('login', 'determine_user_language', true),
'DetermineUserDomain' => (bool) $oConfig->Get('login', 'determine_user_domain', false),
+ 'UseLoginWelcomePage' => (bool) $oConfig->Get('login', 'welcome_page', false),
'ForgotPasswordLinkUrl' => \trim($oConfig->Get('login', 'forgot_password_link_url', '')),
'RegistrationLinkUrl' => \trim($oConfig->Get('login', 'registration_link_url', '')),
'ContactsIsAllowed' => false,
@@ -1382,6 +1400,7 @@ class Actions
'MaterialDesign' => (bool) $oConfig->Get('labs', 'use_material_design', true),
'FolderSpecLimit' => (int) $oConfig->Get('labs', 'folders_spec_limit', 50),
'StartupUrl' => \trim(\ltrim(\trim($oConfig->Get('labs', 'startup_url', '')), '#/')),
+ 'Filtered' => '' !== \trim(\RainLoop\Api::Config()->Get('labs', 'imap_message_list_permanent_filter', '')),
'Community' => true,
'PremType' => false,
'Admin' => array(),
@@ -1397,7 +1416,7 @@ class Actions
$aResult['AttachmentsActions'][] = 'zip';
}
- if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('\\OCP\\Files'))
+ if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('OCP\Files'))
{
$aResult['AttachmentsActions'][] = 'owncloud';
}
@@ -1523,7 +1542,15 @@ class Actions
$aResult['WelcomePageDisplay'] = '';
}
- $aResult['StartupUrl'] = $this->compileLogParams($aResult['StartupUrl'], $oAccount);
+ if (!empty($aResult['StartupUrl']))
+ {
+ $aResult['StartupUrl'] = $this->compileLogParams($aResult['StartupUrl'], $oAccount, true);
+ }
+
+ if (!empty($aResult['UserIframeMessage']))
+ {
+ $aResult['UserIframeMessage'] = $this->compileLogParams($aResult['UserIframeMessage'], $oAccount, true);
+ }
}
else
{
@@ -1543,6 +1570,7 @@ class Actions
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
+ $aResult['AllowGoogleSocialAuthFast'] = (bool) $oConfig->Get('social', 'google_enable_auth_fast', true);
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
$aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true);
@@ -1553,6 +1581,7 @@ class Actions
'' === \trim($oConfig->Get('social', 'google_client_id', '')) || '' === \trim($oConfig->Get('social', 'google_client_secret', '')))))
{
$aResult['AllowGoogleSocialAuth'] = false;
+ $aResult['AllowGoogleSocialAuthFast'] = false;
$aResult['AllowGoogleSocialDrive'] = false;
$aResult['GoogleClientID'] = '';
$aResult['GoogleApiKey'] = '';
@@ -1563,7 +1592,9 @@ class Actions
$aResult['AllowGoogleSocialPreview'] = false;
}
- if ($aResult['AllowGoogleSocial'] && !$aResult['AllowGoogleSocialAuth'] && !$aResult['AllowGoogleSocialDrive'] && !$aResult['AllowGoogleSocialPreview'])
+ if ($aResult['AllowGoogleSocial'] &&
+ !$aResult['AllowGoogleSocialAuth'] && !$aResult['AllowGoogleSocialAuthFast'] &&
+ !$aResult['AllowGoogleSocialDrive'] && !$aResult['AllowGoogleSocialPreview'])
{
$aResult['AllowGoogleSocial'] = false;
}
@@ -1639,6 +1670,7 @@ class Actions
$aResult['AllowGoogleSocial'] = (bool) $oConfig->Get('social', 'google_enable', false);
$aResult['AllowGoogleSocialAuth'] = (bool) $oConfig->Get('social', 'google_enable_auth', true);
+ $aResult['AllowGoogleSocialAuthFast'] = (bool) $oConfig->Get('social', 'google_enable_auth_fast', true);
$aResult['AllowGoogleSocialDrive'] = (bool) $oConfig->Get('social', 'google_enable_drive', true);
$aResult['AllowGoogleSocialPreview'] = (bool) $oConfig->Get('social', 'google_enable_preview', true);
@@ -2882,7 +2914,7 @@ class Actions
$mResult = false;
- if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('\\OCP\\Files'))
+ if (\RainLoop\Utils::IsOwnCloudLoggedIn() && \class_exists('OCP\Files'))
{
$sSaveFolder = $this->Config()->Get('labs', 'owncloud_save_folder', '');
if (empty($sSaveFolder))
@@ -3644,6 +3676,7 @@ class Actions
$this->setConfigFromParams($oConfig, 'GoogleEnable', 'social', 'google_enable', 'bool');
$this->setConfigFromParams($oConfig, 'GoogleEnableAuth', 'social', 'google_enable_auth', 'bool');
+ $this->setConfigFromParams($oConfig, 'GoogleEnableAuthFast', 'social', 'google_enable_auth_fast', 'bool');
$this->setConfigFromParams($oConfig, 'GoogleEnableDrive', 'social', 'google_enable_drive', 'bool');
$this->setConfigFromParams($oConfig, 'GoogleEnablePreview', 'social', 'google_enable_preview', 'bool');
$this->setConfigFromParams($oConfig, 'GoogleClientID', 'social', 'google_client_id', 'string');
@@ -4092,7 +4125,7 @@ class Actions
/**
* @return string
*/
- private function rainloopRepo()
+ private function rainLoopRepo()
{
$sUrl = APP_REP_PATH;
if ('' !== $sUrl)
@@ -4281,7 +4314,7 @@ class Actions
{
$bRainLoopUpdatable = $this->rainLoopUpdatable();
- $aResult = $this->getRepositoryDataByUrl($this->rainloopRepo(), $bReal);
+ $aResult = $this->getRepositoryDataByUrl($this->rainLoopRepo(), $bReal);
$aSub = array();
if (\is_array($aResult))
@@ -4555,7 +4588,7 @@ class Actions
$bResult = false;
if ('' !== $sRealFile)
{
- $sUrl = $this->rainloopRepo().$sRealFile;
+ $sUrl = $this->rainLoopRepo().$sRealFile;
$sTmp = $this->downloadRemotePackageByUrl($sUrl);
}
@@ -6424,7 +6457,12 @@ class Actions
*/
public function DoQuota()
{
- $this->initMailClientConnection();
+ $oAccount = $this->initMailClientConnection();
+
+ if (!$this->GetCapa(false, \RainLoop\Enumerations\Capa::QUOTA, $oAccount))
+ {
+ return $this->DefaultResponse(__FUNCTION__, array(0, 0, 0, 0));
+ }
try
{
@@ -7960,6 +7998,11 @@ class Actions
$aResult[] = \RainLoop\Enumerations\Capa::RELOAD;
}
+ if ($oConfig->Get('capa', 'quota', true))
+ {
+ $aResult[] = \RainLoop\Enumerations\Capa::QUOTA;
+ }
+
if ($oConfig->Get('capa', 'settings', true))
{
$aResult[] = \RainLoop\Enumerations\Capa::SETTINGS;
@@ -9453,6 +9496,24 @@ class Actions
$mResult['InReplyTo'] = $mResponse->InReplyTo();
$mResult['References'] = $mResponse->References();
+ $fAdditionalDomReader = null;
+ if (0 < \strlen($sHtml) && $this->Config()->Get('labs', 'emogrifier', false))
+ {
+ if (!\class_exists('Pelago\Emogrifier', false))
+ {
+ include_once APP_VERSION_ROOT_PATH.'app/libraries/emogrifier/Emogrifier.php';
+ }
+
+ if (\class_exists('Pelago\Emogrifier', false))
+ {
+ $fAdditionalDomReader = function ($oDom) {
+ $oEmogrifier = new \Pelago\Emogrifier();
+ $oEmogrifier->preserveEncoding = false;
+ return $oEmogrifier->emogrify($oDom);
+ };
+ }
+ }
+
$fAdditionalExternalFilter = null;
if (!!$this->Config()->Get('labs', 'use_local_proxy_for_external_images', false))
{
@@ -9465,9 +9526,13 @@ class Actions
};
}
+// $this->Logger()->Write('---');
+// $this->Logger()->Write($sHtml);
+
$mResult['Html'] = 0 === \strlen($sHtml) ? '' : \MailSo\Base\HtmlUtils::ClearHtml(
$sHtml, $bHasExternals, $mFoundedCIDs, $aContentLocationUrls, $mFoundedContentLocationUrls, false, false,
- $fAdditionalExternalFilter
+ $fAdditionalExternalFilter, $fAdditionalDomReader,
+ !!$this->Config()->Get('labs', 'try_to_detect_hidden_images', false)
);
$mResult['ExternalProxy'] = null !== $fAdditionalExternalFilter;
@@ -9669,6 +9734,7 @@ class Actions
'UidNext' => $mResponse->UidNext,
'ThreadUid' => $mResponse->ThreadUid,
'NewMessages' => $this->responseObject($mResponse->NewMessages),
+ 'Filtered' => $mResponse->Filtered,
'Offset' => $mResponse->Offset,
'Limit' => $mResponse->Limit,
'Search' => $mResponse->Search
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
index 7ac756b24..67ba60049 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Api.php
@@ -32,6 +32,7 @@ class Api
if ($bOne)
{
\RainLoop\Api::SetupDefaultMailSoConfig();
+
$bOne = \RainLoop\Api::RunResult();
}
}
@@ -97,6 +98,7 @@ class Api
\MailSo\Config::$LargeThreadLimit =
(int) \RainLoop\Api::Config()->Get('labs', 'imap_large_thread_limit', 50);
+ \MailSo\Config::$BoundaryPrefix = '_RainLoop_';
\MailSo\Config::$SystemLogger = \RainLoop\Api::Logger();
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
index 0edf2ea53..afda4c8f8 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Config/Application.php
@@ -142,6 +142,7 @@ class Application extends \RainLoop\Config\AbstractConfig
'composer' => array(true),
'contacts' => array(true),
'settings' => array(true),
+ 'quota' => array(true),
'help' => array(true),
'reload' => array(true),
'search' => array(true),
@@ -164,6 +165,8 @@ class Application extends \RainLoop\Config\AbstractConfig
'determine_user_language' => array(true, ''),
'determine_user_domain' => array(false, ''),
+ 'welcome_page' => array(false, ''),
+
'forgot_password_link_url' => array('', ''),
'registration_link_url' => array('', ''),
@@ -184,7 +187,7 @@ Values:
'defaults' => array(
'view_editor_type' => array('Html', 'Editor mode used by default (Plain, Html, HtmlForced or PlainForced)'),
- 'view_layout' => array(1, 'layout: 0 - no preview, 1 - side preview, 3 - bottom preview'),
+ 'view_layout' => array(1, 'layout: 0 - no preview, 1 - side preview, 2 - bottom preview'),
'view_use_checkboxes' => array(true),
'autologout' => array(30),
'show_images' => array(false),
@@ -205,6 +208,7 @@ Values:
Disabling this option is not recommended.'),
'time_offset' => array(0),
+ 'session_filter' => array(''),
'filename' => array('log-{date:Y-m-d}.txt',
'Log filename.
@@ -246,6 +250,7 @@ Examples:
'social' => array(
'google_enable' => array(false, 'Google'),
'google_enable_auth' => array(false),
+ 'google_enable_auth_fast' => array(false),
'google_enable_drive' => array(false),
'google_enable_preview' => array(false),
'google_client_id' => array(''),
@@ -298,6 +303,7 @@ Enables caching in the system'),
'allow_html_editor_source_button' => array(false),
'allow_html_editor_biti_buttons' => array(false),
'allow_ctrl_enter_on_compose' => array(false),
+ 'try_to_detect_hidden_images' => array(false),
'hide_dangerous_actions' => array(false),
'use_app_debug_js' => array(false),
'use_app_debug_css' => array(false),
@@ -340,6 +346,7 @@ Enables caching in the system'),
'fast_cache_memcache_expire' => array(43200),
'use_local_proxy_for_external_images' => array(false),
'startup_url' => array(''),
+ 'emogrifier' => array(true),
'dev_email' => array(''),
'dev_password' => array('')
),
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php
index d7602cdee..56912b5e2 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Enumerations/Capa.php
@@ -24,6 +24,7 @@ class Capa
const SEARCH = 'SEARCH';
const SEARCH_ADV = 'SEARCH_ADV';
const SETTINGS = 'SETTINGS';
+ const QUOTA = 'QUOTA';
const HELP = 'HELP';
const TEMPLATES = 'TEMPLATES';
const MESSAGE_ACTIONS = 'MESSAGE_ACTIONS';
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/AbstractPlugin.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/AbstractPlugin.php
index 67b147a12..5f4b8101d 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/AbstractPlugin.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/AbstractPlugin.php
@@ -304,6 +304,22 @@ abstract class AbstractPlugin
return $this;
}
+ /**
+ * @param string $sFile
+ * @param bool $bAdminScope = false
+ *
+ * @return self
+ */
+ protected function replaceTemplate($sFile, $bAdminScope = false)
+ {
+ if ($this->oPluginManager)
+ {
+ $this->oPluginManager->AddTemplate($this->sPath.'/'.$sFile, $bAdminScope);
+ }
+
+ return $this;
+ }
+
/**
* @param string $sActionName
* @param string $sFunctionName
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/Manager.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/Manager.php
index a4ecfb7ca..00d751723 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/Manager.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Plugins/Manager.php
@@ -230,7 +230,7 @@ class Manager
public function HaveJs($bAdminScope = false)
{
$bResult = false;
-
+
if ($this->bIsEnabled)
{
$bResult = $bAdminScope ? 0 < \count($this->aAdminJs) : 0 < \count($this->aJs);
@@ -274,27 +274,24 @@ class Manager
}
/**
+ * @param array $aList
* @param bool $bAdminScope = false
* @return string
*/
- public function CompileTemplate($bAdminScope = false)
+ public function CompileTemplate(&$aList, $bAdminScope = false)
{
- $sResult = '';
if ($this->bIsEnabled)
{
$aTemplates = $bAdminScope ? $this->aAdminTemplates : $this->aTemplates;
foreach ($aTemplates as $sFile)
{
- if (file_exists($sFile))
+ if (\file_exists($sFile))
{
- $sTemplateName = substr(basename($sFile), 0, -5);
- $sResult .= '';
+ $sTemplateName = \substr(\basename($sFile), 0, -5);
+ $aList[$sTemplateName] = $sFile;
}
}
}
-
- return $sResult;
}
/**
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/OwnCloudSuggestions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/OwnCloudSuggestions.php
index a32e9e965..33eae71bf 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/OwnCloudSuggestions.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Providers/Suggestions/OwnCloudSuggestions.php
@@ -25,7 +25,7 @@ class OwnCloudSuggestions implements \RainLoop\Providers\Suggestions\ISuggestion
try
{
if ('' === $sQuery || !$oAccount || !\RainLoop\Utils::IsOwnCloudLoggedIn() ||
- !\class_exists('\\OCP\\Contacts') || !\OCP\Contacts::isEnabled()
+ !\class_exists('OCP\Contacts') || !\OCP\Contacts::isEnabled()
)
{
return $aResult;
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php b/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
index 1f75a9bb2..19b2cb183 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/ServiceActions.php
@@ -1220,11 +1220,23 @@ class ServiceActions
*/
public function compileTemplates($bAdmin = false, $bJsOutput = true)
{
- $sHtml =
- \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/Components', $this->oActions, 'Component').
- \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/'.($bAdmin ? 'Admin' : 'User'), $this->oActions).
- \RainLoop\Utils::CompileTemplates(APP_VERSION_ROOT_PATH.'app/templates/Views/Common', $this->oActions).
- $this->oActions->Plugins()->CompileTemplate($bAdmin);
+ $aTemplates = array();
+
+ \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/Components', 'Component');
+ \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/'.($bAdmin ? 'Admin' : 'User'));
+ \RainLoop\Utils::CompileTemplates($aTemplates, APP_VERSION_ROOT_PATH.'app/templates/Views/Common');
+
+ $this->oActions->Plugins()->CompileTemplate($aTemplates, $bAdmin);
+
+ $sHtml = '';
+ foreach ($aTemplates as $sName => $sFile)
+ {
+ $sName = \preg_replace('/[^a-zA-Z0-9]/', '', $sName);
+ $sHtml .= '';
+ }
+
+ unset($aTemplates);
return $bJsOutput ? 'window.rainloopTEMPLATES='.\MailSo\Base\Utils::Php2js(array($sHtml), $this->Logger()).';' : $sHtml;
}
diff --git a/rainloop/v/0.0.0/app/libraries/RainLoop/Utils.php b/rainloop/v/0.0.0/app/libraries/RainLoop/Utils.php
index 2eebccc0c..594a2fc8e 100644
--- a/rainloop/v/0.0.0/app/libraries/RainLoop/Utils.php
+++ b/rainloop/v/0.0.0/app/libraries/RainLoop/Utils.php
@@ -48,7 +48,7 @@ class Utils
define('_phpseclib_', true);
}
- if (!\class_exists('Crypt_RSA'))
+ if (!\class_exists('Crypt_RSA', false))
{
include_once 'Crypt/RSA.php';
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
@@ -470,30 +470,22 @@ class Utils
}
/**
+ * @param array $aList
* @param string $sDirName
- * @param \RainLoop\Actions $oAction
* @param string $sNameSuffix = ''
- *
- * @return string
*/
- public static function CompileTemplates($sDirName, $oAction, $sNameSuffix = '')
+ public static function CompileTemplates(&$aList, $sDirName, $sNameSuffix = '')
{
- $sResult = '';
if (\file_exists($sDirName))
{
- $aList = \RainLoop\Utils::FolderFiles($sDirName, '.html');
+ $aFileList = \RainLoop\Utils::FolderFiles($sDirName, '.html');
- foreach ($aList as $sName)
+ foreach ($aFileList as $sName)
{
$sTemplateName = \substr($sName, 0, -5).$sNameSuffix;
- $sResult .= '';
+ $aList[$sTemplateName] = $sDirName.'/'.$sName;
}
-
- $sResult = \trim($sResult);
}
-
- return $sResult;
}
/**
@@ -539,14 +531,25 @@ class Utils
public static function IsOwnCloud()
{
return isset($_ENV['RAINLOOP_OWNCLOUD']) && $_ENV['RAINLOOP_OWNCLOUD'] &&
- \class_exists('\\OC');
+ \class_exists('OC');
}
/**
* @return bool
*/
public static function IsOwnCloudLoggedIn()
{
- return self::IsOwnCloud() && \class_exists('\\OCP\\User') && \OCP\User::isLoggedIn();
+ return self::IsOwnCloud() && \class_exists('OCP\User') && \OCP\User::isLoggedIn();
+ }
+
+ /**
+ * @param string $sV
+ * @param bool $bEncode = false
+ *
+ * @return string
+ */
+ public static function UrlEncode($sV, $bEncode = false)
+ {
+ return $bEncode ? \urlencode($sV) : $sV;
}
/**
@@ -557,7 +560,7 @@ class Utils
$sAppPath = '';
if (\RainLoop\Utils::IsOwnCloud())
{
- if (\class_exists('\\OC_App'))
+ if (\class_exists('OC_App'))
{
$sAppPath = \rtrim(\trim(\OC_App::getAppWebPath('rainloop')), '\\/').'/app/';
}
diff --git a/rainloop/v/0.0.0/app/libraries/emogrifier/CHANGELOG.TXT b/rainloop/v/0.0.0/app/libraries/emogrifier/CHANGELOG.TXT
new file mode 100644
index 000000000..55c062e72
--- /dev/null
+++ b/rainloop/v/0.0.0/app/libraries/emogrifier/CHANGELOG.TXT
@@ -0,0 +1,73 @@
+2012-05-01
+Made removal of invisible nodes operate in a case-insensitive manner... Thanks Juha P.!
+
+2012-02-07
+Fixed some recent code introductions to use class constants rather than global constants.
+Fixed some recent code introductions to make it cleaner to read.
+
+2012-01-31
+Fixed a bug that was introduced with the 2011-12-22 revision... Thanks Sagi L. and M. Bąkowski!
+Added extraction of
diff --git a/rainloop/v/0.0.0/app/templates/Themes/template.less b/rainloop/v/0.0.0/app/templates/Themes/template.less
index bd4b0bec8..570df86a5 100644
--- a/rainloop/v/0.0.0/app/templates/Themes/template.less
+++ b/rainloop/v/0.0.0/app/templates/Themes/template.less
@@ -59,12 +59,15 @@
}
.thm-login {
- color: @login-color !important;
border: @login-border !important;
.thm-rgba-background-color(@login-background-color, @login-rgba-background-color);
.thm-linear-gradient-mixin(@login-gradient-start, @login-gradient-end);
.thm-border-radius(@login-border-radius);
.thm-box-shadow(@login-box-shadow);
+}
+
+.thm-login-text {
+ color: @login-color !important;
.legend, .e-checkbox-icon, .g-ui-link, .social-button, .language-button {
color: @login-color !important;
diff --git a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminLogin.html b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminLogin.html
index 1dc30c7c2..ab0051716 100644
--- a/rainloop/v/0.0.0/app/templates/Views/Admin/AdminLogin.html
+++ b/rainloop/v/0.0.0/app/templates/Views/Admin/AdminLogin.html
@@ -5,7 +5,7 @@
×
-