diff --git a/dev/Common/Html.js b/dev/Common/Html.js
index 0e8029fbd..0be300ec9 100644
--- a/dev/Common/Html.js
+++ b/dev/Common/Html.js
@@ -360,7 +360,7 @@ export const
});
*/
- isMsg && [...tmpl.content.querySelectorAll('*')].forEach(oElement => {
+ [...tmpl.content.querySelectorAll('*')].forEach(oElement => {
const name = oElement.tagName,
oStyle = oElement.style;
@@ -485,71 +485,73 @@ export const
*/
let skipStyle = false;
- value = delAttribute('src');
- if (value) {
- if ('IMG' === name) {
- oElement.loading = 'lazy';
- let attachment;
- if (value.startsWith('cid:'))
- {
- value = value.slice(4);
- setAttribute('data-x-src-cid', value);
- attachment = findAttachmentByCid(value);
- if (attachment?.download) {
- oElement.src = attachment.linkPreview();
- oElement.title += ' ('+attachment.fileName+')';
- attachment.isInline(true);
- attachment.isLinked(true);
+ if (isMsg) {
+ value = isMsg && delAttribute('src');
+ if (value) {
+ if ('IMG' === name) {
+ oElement.loading = 'lazy';
+ let attachment;
+ if (value.startsWith('cid:'))
+ {
+ value = value.slice(4);
+ setAttribute('data-x-src-cid', value);
+ attachment = findAttachmentByCid(value);
+ if (attachment?.download) {
+ oElement.src = attachment.linkPreview();
+ oElement.title += ' ('+attachment.fileName+')';
+ attachment.isInline(true);
+ attachment.isLinked(true);
+ }
}
- }
- else if ((attachment = findLocationByCid(value)))
- {
- if (attachment.download) {
- oElement.src = attachment.linkPreview();
- attachment.isLinked(true);
+ else if ((attachment = findLocationByCid(value)))
+ {
+ if (attachment.download) {
+ oElement.src = attachment.linkPreview();
+ attachment.isLinked(true);
+ }
}
- }
- else if (detectHiddenImages
- && ((oStyle.maxHeight && 3 > pInt(oStyle.maxHeight)) // TODO: issue with 'in'
- || (oStyle.maxWidth && 3 > pInt(oStyle.maxWidth)) // TODO: issue with 'in'
- || (oStyle.width && 2 > pInt(oStyle.width))
- || [
- 'email.microsoftemail.com/open',
- 'github.com/notifications/beacon/',
- '/track/open', // mandrillapp.com list-manage.com
- 'google-analytics.com'
- ].filter(uri => value.toLowerCase().includes(uri)).length
- )) {
- skipStyle = true;
- oStyle.display = 'none';
-// setAttribute('style', 'display:none');
- setAttribute('data-x-src-hidden', value);
-// result.tracking = true;
- }
- else if (httpre.test(value))
- {
- let src = stripTracking(value);
- if (src != value) {
- result.tracking = true;
- setAttribute('data-x-src-tracking', value);
+ else if (detectHiddenImages
+ && ((oStyle.maxHeight && 3 > pInt(oStyle.maxHeight)) // TODO: issue with 'in'
+ || (oStyle.maxWidth && 3 > pInt(oStyle.maxWidth)) // TODO: issue with 'in'
+ || (oStyle.width && 2 > pInt(oStyle.width))
+ || [
+ 'email.microsoftemail.com/open',
+ 'github.com/notifications/beacon/',
+ '/track/open', // mandrillapp.com list-manage.com
+ 'google-analytics.com'
+ ].filter(uri => value.toLowerCase().includes(uri)).length
+ )) {
+ skipStyle = true;
+ oStyle.display = 'none';
+ // setAttribute('style', 'display:none');
+ setAttribute('data-x-src-hidden', value);
+ // result.tracking = true;
+ }
+ else if (httpre.test(value))
+ {
+ let src = stripTracking(value);
+ if (src != value) {
+ result.tracking = true;
+ setAttribute('data-x-src-tracking', value);
+ }
+ setAttribute('data-x-src', src);
+ result.hasExternals = true;
+ oElement.alt || (oElement.alt = src.replace(/^.+\/([^/?]+).*$/, '$1').slice(-20));
+ }
+ else if (value.startsWith('data:image/'))
+ {
+ oElement.src = value;
+ }
+ else
+ {
+ setAttribute('data-x-src-broken', value);
}
- setAttribute('data-x-src', src);
- result.hasExternals = true;
- oElement.alt || (oElement.alt = src.replace(/^.+\/([^/?]+).*$/, '$1').slice(-20));
- }
- else if (value.startsWith('data:image/'))
- {
- oElement.src = value;
}
else
{
setAttribute('data-x-src-broken', value);
}
}
- else
- {
- setAttribute('data-x-src-broken', value);
- }
}
if (hasAttribute('background')) {
diff --git a/dev/External/SquireUI.js b/dev/External/SquireUI.js
index fe07975d2..b1e50fcad 100644
--- a/dev/External/SquireUI.js
+++ b/dev/External/SquireUI.js
@@ -386,6 +386,44 @@ class SquireUI
changes.redo.input.disabled = !e.detail.canRedo;
});
+ squire.addEventListener('pasteImage', e => {
+ const items = e.detail.clipboardData.items;
+ let l = items.length;
+ while (l--) {
+ const item = items[l];
+ if (/^image\/(png|jpeg|webp)/.test(item.type)) {
+ let reader = new FileReader();
+ reader.onload = event => {
+ let img = createElement("img"),
+ canvas = createElement("canvas"),
+ ctx = canvas.getContext('2d');
+ img.onload = ()=>{
+ ctx.drawImage(img, 0, 0);
+ let width = img.width, height = img.height;
+ if (width > height) {
+ // Landscape
+ if (width > 1024) {
+ height = height * 1024 / width;
+ width = 1024;
+ }
+ } else if (height > 1024) {
+ // Portrait
+ width = width * 1024 / height;
+ height = 1024;
+ }
+ canvas.width = width;
+ canvas.height = height;
+ ctx.drawImage(img, 0, 0, width, height);
+ squire.insertHTML('
', true);
+ };
+ img.src = event.target.result;
+ }
+ reader.readAsDataURL(item.getAsFile());
+ break;
+ }
+ }
+ });
+
actions.font.fontSize.input.selectedIndex = actions.font.fontSize.defaultValueIndex;
// squire.addEventListener('focus', () => shortcuts.off());
diff --git a/vendors/squire2/dist/squire-raw.js b/vendors/squire2/dist/squire-raw.js
index 4367a29dd..d69f0abe5 100644
--- a/vendors/squire2/dist/squire-raw.js
+++ b/vendors/squire2/dist/squire-raw.js
@@ -58,7 +58,7 @@
var notWS = /[^ \t\r\n]/;
// source/node/Category.ts
- var inlineNodeNames = /^(?:#text|A(?:BBR|CRONYM)?|B(?:R|D[IO])?|C(?:ITE|ODE)|D(?:ATA|EL|FN)|EM|FONT|HR|I(?:FRAME|MG|NPUT|NS)?|KBD|Q|R(?:P|T|UBY)|S(?:AMP|MALL|PAN|TR(?:IKE|ONG)|U[BP])?|TIME|U|VAR|WBR)$/;
+ var inlineNodeNames = /^(?:#text|A(?:BBR|CRONYM)?|B(?:R|D[IO])?|C(?:ITE|ODE)|D(?:ATA|EL|FN)|EM|FONT|HR|I(?:MG|NS)?|KBD|Q|R(?:P|T|UBY)|S(?:AMP|MALL|PAN|TR(?:IKE|ONG)|U[BP])?|TIME|U|VAR|WBR)$/;
var leafNodeNames = /* @__PURE__ */ new Set(["BR", "HR", "IMG"]);
var UNKNOWN = 0;
var INLINE = 1;
@@ -198,7 +198,7 @@
// okay if data is 'undefined' here.
notWS.test(node.data)
);
- var isLineBreak = (br, isLBIfEmptyBlock) => {
+ var isLineBreak = (br) => {
let block = br.parentNode;
while (isInline(block)) {
block = block.parentNode;
@@ -209,7 +209,7 @@
notWSTextNode
);
walker.currentNode = br;
- return !!walker.nextNode() || isLBIfEmptyBlock && !walker.previousNode();
+ return !!walker.nextNode();
};
var removeZWS = (root, keepNode) => {
const walker = createTreeWalker(root, SHOW_TEXT);
@@ -267,7 +267,7 @@
textChild = prev;
}
startContainer = textChild;
- startOffset = textChild.data.length;
+ startOffset = textChild.length;
}
}
break;
@@ -279,7 +279,7 @@
while (!(endContainer instanceof Text)) {
const child = endContainer.childNodes[endOffset - 1];
if (!child || isLeaf(child)) {
- if (child && child.nodeName === "BR" && !isLineBreak(child, false)) {
+ if (child && child.nodeName === "BR" && !isLineBreak(child)) {
--endOffset;
continue;
}
@@ -323,7 +323,7 @@
if (endContainer === endMax || endContainer === root) {
break;
}
- if (endContainer.nodeType !== TEXT_NODE && endContainer.childNodes[endOffset] && endContainer.childNodes[endOffset].nodeName === "BR" && !isLineBreak(endContainer.childNodes[endOffset], false)) {
+ if (endContainer.nodeType !== TEXT_NODE && endContainer.childNodes[endOffset] && endContainer.childNodes[endOffset].nodeName === "BR" && !isLineBreak(endContainer.childNodes[endOffset])) {
++endOffset;
}
if (endOffset !== getLength(endContainer)) {
@@ -529,30 +529,23 @@
if (isInline(child) && !child.firstChild) {
node.removeChild(child);
}
- } else if (child instanceof Text && !child.data) {
+ } else if (child instanceof Text && !child.length) {
node.removeChild(child);
}
}
};
var cleanupBRs = (node) => {
- const brs = node.querySelectorAll("BR");
- const brBreaksLine = [];
+ const brs = node.querySelectorAll("BR:last-child");
let l = brs.length;
- for (let i = 0; i < l; ++i) {
- brBreaksLine[i] = isLineBreak(brs[i], false);
- }
while (l--) {
const br = brs[l];
- const parent = br.parentNode;
- if (parent) {
- if (!brBreaksLine[l]) {
- detach(br);
- }
+ if (!isLineBreak(br)) {
+ br.remove();
}
}
};
var escapeHTML = (text) => {
- return text.split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""");
+ return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
};
// source/node/MergeSplit.ts
@@ -980,7 +973,7 @@
const iterator = createTreeWalker(root, SHOW_ELEMENT_OR_TEXT);
let afterNode = startContainer;
let afterOffset = startOffset;
- if (!(afterNode instanceof Text) || afterOffset === afterNode.data.length) {
+ if (!(afterNode instanceof Text) || afterOffset === afterNode.length) {
afterNode = getAdjacentInlineNode(iterator, "nextNode", afterNode);
afterOffset = 0;
}
@@ -993,7 +986,7 @@
afterNode || (startContainer instanceof Text ? startContainer : startContainer.childNodes[startOffset] || startContainer)
);
if (beforeNode instanceof Text) {
- beforeOffset = beforeNode.data.length;
+ beforeOffset = beforeNode.length;
}
}
let node = null;
@@ -3171,7 +3164,7 @@
nodeAfterSplit = child;
break;
}
- while (child && child instanceof Text && !child.data) {
+ while (child && child instanceof Text && !child.length) {
next = child.nextSibling;
if (!next || next.nodeName === "BR") {
break;
@@ -3517,7 +3510,7 @@
const brBreaksLine = [];
let l = nodes.length;
for (let i = 0; i < l; ++i) {
- brBreaksLine[i] = isLineBreak(nodes[i], false);
+ brBreaksLine[i] = isLineBreak(nodes[i]);
}
while (l--) {
const br = nodes[l];