Render invoice-editor <img> elements on their own line
Playwright Tests / test (push) Canceled after 0s
Playwright Tests / test (push) Canceled after 0s
<img> is a nominally inline HTML element, but TinyMCE content places images between paragraphs of text; without a forced line break before/after, an image could render packed against adjacent text in the PDF. Insert a line break ahead of the image (unless one is already there) and always after it. Also fixes the img handler's early-return path to still apply the inline size cap (MaxInlineImageWidth/Height) when only one of width/height was resized, matching the aspect-ratio-locked branch. Fuchs/wwwroot/web/tools.js: cosmetic gulp rebuild diff (leading blank line), no behavior change. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -122,7 +122,9 @@ namespace MigraDoc.Extensions.Html
|
|||||||
// else (including any remote URL the caller didn't fetch/vet) is silently dropped, same
|
// else (including any remote URL the caller didn't fetch/vet) is silently dropped, same
|
||||||
// as every other unsupported element. Size mirrors what the editor shows (the width/height
|
// as every other unsupported element. Size mirrors what the editor shows (the width/height
|
||||||
// TinyMCE writes onto the <img> from its resize handles), capped so a stray huge size from
|
// TinyMCE writes onto the <img> from its resize handles), capped so a stray huge size from
|
||||||
// hand-edited HTML can't blow out the invoice table layout.
|
// hand-edited HTML can't blow out the invoice table layout. Always rendered alone on its
|
||||||
|
// own line — surrounded by line breaks rather than left inline with adjacent text — even
|
||||||
|
// though <img> is nominally an inline HTML element.
|
||||||
_handlers["img"] = (n, p) =>
|
_handlers["img"] = (n, p) =>
|
||||||
{
|
{
|
||||||
string src = n.GetAttributeValue("src", "");
|
string src = n.GetAttributeValue("src", "");
|
||||||
@@ -130,6 +132,11 @@ namespace MigraDoc.Extensions.Html
|
|||||||
return p;
|
return p;
|
||||||
var para = GetPara(p);
|
var para = GetPara(p);
|
||||||
if (para == null) return p;
|
if (para == null) return p;
|
||||||
|
|
||||||
|
var existing = para.Elements.Cast<DocumentObject>().ToList();
|
||||||
|
bool lastIsLineBreak = existing.Count > 0 && existing[^1] is Character { SymbolName: SymbolName.LineBreak };
|
||||||
|
if (existing.Count > 0 && !lastIsLineBreak) para.AddLineBreak();
|
||||||
|
|
||||||
var img = para.AddImage(source);
|
var img = para.AddImage(source);
|
||||||
img.LockAspectRatio = true;
|
img.LockAspectRatio = true;
|
||||||
|
|
||||||
@@ -152,13 +159,17 @@ namespace MigraDoc.Extensions.Html
|
|||||||
img.Width = Unit.FromCentimeter(img.Width.Centimeter * scale);
|
img.Width = Unit.FromCentimeter(img.Width.Centimeter * scale);
|
||||||
img.Height = Unit.FromCentimeter(img.Height.Centimeter * scale);
|
img.Height = Unit.FromCentimeter(img.Height.Centimeter * scale);
|
||||||
}
|
}
|
||||||
return para;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (wPx is > 0) img.Width = PxToUnit(wPx.Value);
|
if (wPx is > 0) img.Width = PxToUnit(wPx.Value);
|
||||||
else if (hPx is > 0) img.Height = PxToUnit(hPx.Value);
|
else if (hPx is > 0) img.Height = PxToUnit(hPx.Value);
|
||||||
|
|
||||||
if (img.Width > MaxInlineImageWidth) { img.LockAspectRatio = true; img.Width = MaxInlineImageWidth; }
|
if (img.Width > MaxInlineImageWidth) { img.LockAspectRatio = true; img.Width = MaxInlineImageWidth; }
|
||||||
if (img.Height > MaxInlineImageHeight) { img.LockAspectRatio = true; img.Height = MaxInlineImageHeight; }
|
if (img.Height > MaxInlineImageHeight) { img.LockAspectRatio = true; img.Height = MaxInlineImageHeight; }
|
||||||
|
}
|
||||||
|
|
||||||
|
para.AddLineBreak();
|
||||||
return para;
|
return para;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user