This commit is contained in:
the-djmaze 2022-08-26 15:17:30 +02:00
parent 4692dde3d5
commit cad5fb6067
3 changed files with 60 additions and 96 deletions

View file

@ -241,7 +241,7 @@ export const
)) { )) {
skipStyle = true; skipStyle = true;
setAttribute('style', 'display:none'); setAttribute('style', 'display:none');
setAttribute('data-x-hidden-src', value); setAttribute('data-x-src-hidden', value);
} }
else if ((attachment = findLocationByCid(value))) else if ((attachment = findLocationByCid(value)))
{ {
@ -253,7 +253,9 @@ export const
} }
else if ('cid:' === value.slice(0, 4)) else if ('cid:' === value.slice(0, 4))
{ {
attachment = findAttachmentByCid(value.slice(4)); value = value.slice(4);
setAttribute('data-x-src-cid', value);
attachment = findAttachmentByCid(value);
if (attachment && attachment.download) { if (attachment && attachment.download) {
oElement.src = attachment.linkPreview(); oElement.src = attachment.linkPreview();
attachment.isInline(true); attachment.isInline(true);
@ -267,16 +269,16 @@ export const
} }
else if ('data:image/' === value.slice(0, 11)) else if ('data:image/' === value.slice(0, 11))
{ {
setAttribute('src', value); oElement.src = value;
} }
else else
{ {
setAttribute('data-x-broken-src', value); setAttribute('data-x-src-broken', value);
} }
} }
else else
{ {
setAttribute('data-x-broken-src', value); setAttribute('data-x-src-broken', value);
} }
} }

View file

@ -20,7 +20,7 @@ import { folderInformation, messagesDeleteHelper } from 'Common/Folders';
import { serverRequest } from 'Common/Links'; import { serverRequest } from 'Common/Links';
import { i18n, getNotification, getUploadErrorDescByCode, timestampToString } from 'Common/Translator'; import { i18n, getNotification, getUploadErrorDescByCode, timestampToString } from 'Common/Translator';
import { MessageFlagsCache, setFolderHash } from 'Common/Cache'; import { MessageFlagsCache, setFolderHash } from 'Common/Cache';
import { Settings, SettingsCapa, SettingsGet, elementById, addShortcut } from 'Common/Globals'; import { Settings, SettingsCapa, SettingsGet, elementById, addShortcut, createElement } from 'Common/Globals';
//import { exitFullscreen, isFullscreen, toggleFullscreen } from 'Common/Fullscreen'; //import { exitFullscreen, isFullscreen, toggleFullscreen } from 'Common/Fullscreen';
import { AppUserStore } from 'Stores/User/App'; import { AppUserStore } from 'Stores/User/App';
@ -50,9 +50,13 @@ import { ThemeStore } from 'Stores/Theme';
let alreadyFullscreen; let alreadyFullscreen;
*/ */
let oLastMessage;
const const
ScopeCompose = 'Compose', ScopeCompose = 'Compose',
tpl = createElement('template'),
base64_encode = text => btoa(unescape(encodeURIComponent(text))).match(/.{1,76}/g).join('\r\n'), base64_encode = text => btoa(unescape(encodeURIComponent(text))).match(/.{1,76}/g).join('\r\n'),
email = new EmailModel(), email = new EmailModel(),
@ -226,7 +230,6 @@ export class ComposePopupView extends AbstractViewPopup {
} }
}; };
this.oLastMessage = null;
this.oEditor = null; this.oEditor = null;
this.aDraftInfo = null; this.aDraftInfo = null;
this.sInReplyTo = ''; this.sInReplyTo = '';
@ -828,7 +831,7 @@ export class ComposePopupView extends AbstractViewPopup {
this.editor(editor => { this.editor(editor => {
let signature = identity.signature() || '', let signature = identity.signature() || '',
isHtml = ':HTML:' === signature.slice(0, 6), isHtml = ':HTML:' === signature.slice(0, 6),
fromLine = this.oLastMessage ? emailArrayToStringLineHelper(this.oLastMessage.from, true) : ''; fromLine = oLastMessage ? emailArrayToStringLineHelper(oLastMessage.from, true) : '';
if (fromLine) { if (fromLine) {
signature = signature.replace(/{{FROM-FULL}}/g, fromLine); signature = signature.replace(/{{FROM-FULL}}/g, fromLine);
if (!fromLine.includes(' ') && 0 < fromLine.indexOf('@')) { if (!fromLine.includes(' ') && 0 < fromLine.indexOf('@')) {
@ -909,24 +912,20 @@ export class ComposePopupView extends AbstractViewPopup {
sText = '', sText = '',
identity = null, identity = null,
aDraftInfo = null, aDraftInfo = null,
message = null; message = 1 === arrayLength(oMessageOrArray)
? oMessageOrArray[0]
: (isArray(oMessageOrArray) ? null : oMessageOrArray);
const excludeEmail = {}, const
// excludeEmail = new Set(),
excludeEmail = {},
mEmail = AccountUserStore.email(), mEmail = AccountUserStore.email(),
lineComposeType = sType || ComposeType.Empty; lineComposeType = sType || ComposeType.Empty;
if (oMessageOrArray) { oLastMessage = message;
message =
1 === arrayLength(oMessageOrArray)
? oMessageOrArray[0]
: isArray(oMessageOrArray)
? null
: oMessageOrArray;
}
this.oLastMessage = message; if (mEmail) {
// excludeEmail.add(mEmail);
if (null !== mEmail) {
excludeEmail[mEmail] = true; excludeEmail[mEmail] = true;
} }
@ -934,6 +933,7 @@ export class ComposePopupView extends AbstractViewPopup {
identity = findIdentityByMessage(lineComposeType, message); identity = findIdentityByMessage(lineComposeType, message);
if (identity) { if (identity) {
// excludeEmail.add(identity.email());
excludeEmail[identity.email()] = true; excludeEmail[identity.email()] = true;
} }
@ -1030,9 +1030,15 @@ export class ComposePopupView extends AbstractViewPopup {
// no default // no default
} }
sText = message.bodyAsHTML().replace(/<img[^>]+>/g, '').replace(/<a\s[^>]+><\/a>/g, '');
let encrypted; let encrypted;
// https://github.com/the-djmaze/snappymail/issues/491
tpl.innerHTML = message.bodyAsHTML();
tpl.content.querySelectorAll('img').forEach(img =>
img.dataset.xSrcCid || img.dataset.xSrc || img.replaceWith(img.alt || img.title)
);
sText = tpl.innerHTML.trim();
switch (lineComposeType) { switch (lineComposeType) {
case ComposeType.Reply: case ComposeType.Reply:
case ComposeType.ReplyAll: case ComposeType.ReplyAll:
@ -1068,6 +1074,7 @@ export class ComposePopupView extends AbstractViewPopup {
case ComposeType.ForwardAsAttachment: case ComposeType.ForwardAsAttachment:
sText = ''; sText = '';
break; break;
default: default:
encrypted = PgpUserStore.isEncrypted(sText); encrypted = PgpUserStore.isEncrypted(sText);
if (encrypted) { if (encrypted) {
@ -1131,7 +1138,8 @@ export class ComposePopupView extends AbstractViewPopup {
this.setFocusInPopup(); this.setFocusInPopup();
} }
const downloads = this.getAttachmentsDownloadsForUpload(); // item.CID item.isInline item.isLinked
const downloads = this.attachments.filter(item => item && !item.tempName()).map(item => item.id);
if (arrayLength(downloads)) { if (arrayLength(downloads)) {
Remote.request('MessageUploadAttachments', Remote.request('MessageUploadAttachments',
(iError, oData) => { (iError, oData) => {
@ -1402,35 +1410,22 @@ export class ComposePopupView extends AbstractViewPopup {
if (message) { if (message) {
if (ComposeType.ForwardAsAttachment === type) { if (ComposeType.ForwardAsAttachment === type) {
this.addMessageAsAttachment(message); this.addMessageAsAttachment(message);
} else { } else if ([
ComposeType.Reply, ComposeType.ReplyAll,
ComposeType.Forward, ComposeType.Draft, ComposeType.EditAsNew
].includes(type)) {
message.attachments.forEach(item => { message.attachments.forEach(item => {
let add = false; const attachment = new ComposeAttachmentModel(
switch (type) { item.download,
case ComposeType.Reply: item.fileName,
case ComposeType.ReplyAll: item.estimatedSize,
break; item.isInline(),
item.isLinked(),
case ComposeType.Forward: item.cid,
case ComposeType.Draft: item.contentLocation
case ComposeType.EditAsNew: );
add = true; attachment.fromMessage = true;
break; this.addAttachment(attachment);
// no default
}
if (add) {
const attachment = new ComposeAttachmentModel(
item.download,
item.fileName,
item.estimatedSize,
item.isInline(),
item.isLinked(),
item.cid,
item.contentLocation
);
attachment.fromMessage = true;
this.addAttachment(attachment);
}
}); });
} }
} }
@ -1504,15 +1499,6 @@ export class ComposePopupView extends AbstractViewPopup {
this.dropMailvelope(); this.dropMailvelope();
} }
/**
* @returns {Array}
*/
getAttachmentsDownloadsForUpload() {
return this.attachments.filter(item => item && !item.tempName()).map(
item => item.id
);
}
mailvelopeArea() { mailvelopeArea() {
if (!this.mailvelope) { if (!this.mailvelope) {
/** /**

View file

@ -107,6 +107,8 @@ abstract class HtmlUtils
$aRemove = array(); $aRemove = array();
$sIdRight = \md5(\microtime());
$aNodes = $oBody->getElementsByTagName('*'); $aNodes = $oBody->getElementsByTagName('*');
foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement) foreach ($aNodes as /* @var $oElement \DOMElement */ $oElement)
{ {
@ -114,56 +116,30 @@ abstract class HtmlUtils
if (\in_array($sTagNameLower, $aRemoveTags)) if (\in_array($sTagNameLower, $aRemoveTags))
{ {
$aRemove[] = @$oElement; $aRemove[] = $oElement;
continue; continue;
} }
if ($oElement->hasAttribute('data-x-src-cid')) // images
{ if ($oElement->hasAttribute('data-x-src-broken') || $oElement->hasAttribute('data-x-src-hidden')) {
$aRemove[] = $oElement;
continue;
}
if ($oElement->hasAttribute('data-x-src-cid')) {
$sCid = $oElement->getAttribute('data-x-src-cid'); $sCid = $oElement->getAttribute('data-x-src-cid');
$oElement->removeAttribute('data-x-src-cid'); $oElement->removeAttribute('data-x-src-cid');
if (!empty($sCid)) {
if (!empty($sCid))
{
$aFoundCids[] = $sCid; $aFoundCids[] = $sCid;
@$oElement->removeAttribute('src');
$oElement->setAttribute('src', 'cid:'.$sCid); $oElement->setAttribute('src', 'cid:'.$sCid);
} }
} }
if ($oElement->hasAttribute('data-x-src')) {
if ($oElement->hasAttribute('data-x-src-location'))
{
$sSrc = $oElement->getAttribute('data-x-src-location');
$oElement->removeAttribute('data-x-src-location');
if (!empty($sSrc))
{
$aFoundContentLocationUrls[] = $sSrc;
@$oElement->removeAttribute('src');
$oElement->setAttribute('src', $sSrc);
}
}
if ($oElement->hasAttribute('data-x-broken-src'))
{
$oElement->setAttribute('src', $oElement->getAttribute('data-x-broken-src'));
$oElement->removeAttribute('data-x-broken-src');
}
if ($oElement->hasAttribute('data-x-src'))
{
$oElement->setAttribute('src', $oElement->getAttribute('data-x-src')); $oElement->setAttribute('src', $oElement->getAttribute('data-x-src'));
$oElement->removeAttribute('data-x-src'); $oElement->removeAttribute('data-x-src');
} }
// style attribute images // style attribute images
$aCid = array(); $aCid = array();
if ($oElement->hasAttribute('data-x-style-cid')) {
$aCid = \json_decode($oElement->getAttribute('data-x-style-cid'), true);
$oElement->removeAttribute('data-x-style-cid');
}
if ($oElement->hasAttribute('data-x-style-url')) { if ($oElement->hasAttribute('data-x-style-url')) {
$aCid = \array_merge($aCid, \json_decode($oElement->getAttribute('data-x-style-url'), true)); $aCid = \array_merge($aCid, \json_decode($oElement->getAttribute('data-x-style-url'), true));
$oElement->removeAttribute('data-x-style-url'); $oElement->removeAttribute('data-x-style-url');
@ -205,7 +181,7 @@ abstract class HtmlUtils
$sSrc = $oElement->getAttribute('src'); $sSrc = $oElement->getAttribute('src');
if ('data:image/' === \strtolower(\substr($sSrc, 0, 11))) if ('data:image/' === \strtolower(\substr($sSrc, 0, 11)))
{ {
$sHash = \md5($sSrc); $sHash = \md5($sSrc) . '@' . $sIdRight;
$aFoundDataURL[$sHash] = $sSrc; $aFoundDataURL[$sHash] = $sSrc;
$oElement->setAttribute('src', 'cid:'.$sHash); $oElement->setAttribute('src', 'cid:'.$sHash);