improved render of complex HTML mails.

This commit is contained in:
RainLoop Team 2013-11-16 04:04:07 +04:00
parent 8b09b84e7c
commit ea4262e954
6 changed files with 102 additions and 23 deletions

3
.gitignore vendored
View file

@ -4,5 +4,6 @@
/node_modules
/build/dist
/build/tmp
/data/
/data/*.*
/data/**
!/data/VERSION

View file

@ -17,10 +17,12 @@ class HtmlUtils
/**
* @param string $sText
* @param string $sHtmlAttrs = ''
* @param string $sBodyAttrs = ''
*
* @return \DOMDocument | bool
* @return \DOMDocument|bool
*/
public static function GetDomFromText($sText)
public static function GetDomFromText($sText, $sHtmlAttrs = '', $sBodyAttrs = '')
{
static $bOnce = true;
if ($bOnce)
@ -37,7 +39,7 @@ class HtmlUtils
@$oDom->loadHTML(
'<'.'?xml version="1.0" encoding="utf-8"?'.'>'.
'<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>'.$sText.'</body></html>'
'<html '.$sHtmlAttrs.'><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body '.$sBodyAttrs.'>'.$sText.'</body></html>'
);
return $oDom;
@ -45,16 +47,29 @@ class HtmlUtils
/**
* @param string $sHtml
* @param bool $bSetupBody = false
* @param string $sHtmlAttrs = '
* @param string $sBodyAttrs = ''
*
* @return string
*/
public static function ClearBodyAndHtmlTag($sHtml, $bSetupBody = false)
public static function ClearBodyAndHtmlTag($sHtml, &$sHtmlAttrs = '', &$sBodyAttrs = '')
{
$sHtml = \preg_replace('/<body([^>]*)>/im', '<div'.($bSetupBody ? ' class="mailso-body" ' : '').'\\1>', $sHtml);
$sHtml = \preg_replace('/<\/body>/im', '</div>', $sHtml);
$sHtml = \preg_replace('/<html([^>]*)>/im', '<div\\1>', $sHtml);
$sHtml = \preg_replace('/<\/html>/im', '</div>', $sHtml);
$aMatch = array();
if (preg_match('/<html([^>]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
{
$sHtmlAttrs = $aMatch[1];
}
$aMatch = array();
if (preg_match('/<body([^>]+)>/im', $sHtml, $aMatch) && !empty($aMatch[1]))
{
$sBodyAttrs = $aMatch[1];
}
$sHtml = \preg_replace('/<body([^>]*)>/im', '', $sHtml);
$sHtml = \preg_replace('/<\/body>/im', '', $sHtml);
$sHtml = \preg_replace('/<html([^>]*)>/im', '', $sHtml);
$sHtml = \preg_replace('/<\/html>/im', '', $sHtml);
return $sHtml;
}
@ -265,10 +280,12 @@ class HtmlUtils
$sHtml = \MailSo\Base\HtmlUtils::ClearTags($sHtml);
$sHtml = \MailSo\Base\HtmlUtils::ClearOn($sHtml);
$sHtml = \MailSo\Base\HtmlUtils::ClearBodyAndHtmlTag($sHtml);
$sHtmlAttrs = $sBodyAttrs = '';
$sHtml = \MailSo\Base\HtmlUtils::ClearBodyAndHtmlTag($sHtml, $sHtmlAttrs, $sBodyAttrs);
// Dom Part
$oDom = \MailSo\Base\HtmlUtils::GetDomFromText($sHtml);
$oDom = \MailSo\Base\HtmlUtils::GetDomFromText($sHtml, $sHtmlAttrs, $sBodyAttrs);
unset($sHtml);
if ($oDom)
@ -278,6 +295,58 @@ class HtmlUtils
{
$sTagNameLower = \strtolower($oElement->tagName);
// convert body attributes to styles
if ('body' === $sTagNameLower)
{
$aMargins = array(
$oElement->hasAttribute('topmargin')
? \trim($oElement->getAttribute('topmargin')) : '',
$oElement->hasAttribute('leftmargin')
? \trim($oElement->getAttribute('leftmargin')) : '',
$oElement->hasAttribute('bottommargin')
? \trim($oElement->getAttribute('bottommargin')) : '',
$oElement->hasAttribute('rightmargin')
? \trim($oElement->getAttribute('rightmargin')) : '',
);
$sText = $oElement->hasAttribute('text') ? \trim($oElement->getAttribute('text')) : '';
$aStyles = array();
if (!empty($sText))
{
$aStyles[] = 'color: '.$sText;
$oElement->removeAttribute('text');
}
foreach ($aMargins as $iIndex => $sItem)
{
if ('' !== $sItem)
{
switch ($iIndex) {
case 0:
$aStyles[] = 'margin-top: '.((int) $sItem).'px';
$oElement->removeAttribute('topmargin');
break;
case 1:
$aStyles[] = 'margin-left: '.((int) $sItem).'px';
$oElement->removeAttribute('leftmargin');
break;
case 2:
$aStyles[] = 'margin-bottom: '.((int) $sItem).'px';
$oElement->removeAttribute('bottommargin');
break;
case 3:
$aStyles[] = 'margin-right: '.((int) $sItem).'px';
$oElement->removeAttribute('rightmargin');
break;
}
}
}
$sStyles = $oElement->hasAttribute('style') ? $oElement->getAttribute('style') : '';
$oElement->setAttribute('style', (empty($sStyles) ? '' : $sStyles.'; ').\implode('; ', $aStyles));
}
if ('iframe' === $sTagNameLower || 'frame' === $sTagNameLower)
{
$oElement->setAttribute('src', 'javascript:false');
@ -378,7 +447,11 @@ class HtmlUtils
unset($oDom);
$sResult = \MailSo\Base\HtmlUtils::ClearTags($sResult);
$sResult = \MailSo\Base\HtmlUtils::ClearBodyAndHtmlTag($sResult, true);
$sHtmlAttrs = $sBodyAttrs = '';
$sResult = \MailSo\Base\HtmlUtils::ClearBodyAndHtmlTag($sResult, $sHtmlAttrs, $sBodyAttrs);
$sResult = '<div data-x-div-type="body" '.$sBodyAttrs.'>'.$sResult.'</div>';
$sResult = '<div data-x-div-type="html" '.$sHtmlAttrs.'>'.$sResult.'</div>';
return \trim($sResult);
}
@ -478,6 +551,11 @@ class HtmlUtils
}
}
if ($oElement->hasAttribute('data-x-div-type'))
{
$oElement->removeAttribute('data-x-div-type');
}
if ($oElement->hasAttribute('data-x-style-url'))
{
$sAddStyles = $oElement->getAttribute('data-x-style-url');

View file

@ -7132,7 +7132,7 @@ html.rl-no-preview-pane .messageView.message-selected {
.messageView .b-content .messageItem .bodyText .b-text-part.rtl-text-part {
direction: rtl;
}
.messageView .b-content .messageItem .bodyText .b-text-part.html .mailso-body {
.messageView .b-content .messageItem .bodyText .b-text-part.html div[data-x-div-type=body] {
margin: 15px;
}
.messageView .b-content .messageItem .bodyText .b-text-part.plain {

File diff suppressed because one or more lines are too long

View file

@ -4831,7 +4831,7 @@ html.rl-no-preview-pane .messageView.message-selected {
.messageView .b-content .messageItem .bodyText .b-text-part.rtl-text-part {
direction: rtl;
}
.messageView .b-content .messageItem .bodyText .b-text-part.html .mailso-body {
.messageView .b-content .messageItem .bodyText .b-text-part.html div[data-x-div-type=body] {
margin: 15px;
}
.messageView .b-content .messageItem .bodyText .b-text-part.plain {

File diff suppressed because one or more lines are too long