mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-01-06 14:58:19 +08:00
Resolve #491
This commit is contained in:
parent
4692dde3d5
commit
cad5fb6067
3 changed files with 60 additions and 96 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue