wordinweb 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -3
- package/dist/index.d.ts +33 -8
- package/dist/index.js +1315 -533
- package/dist/index.js.map +1 -1
- package/package.json +5 -3
package/dist/index.js
CHANGED
|
@@ -2457,6 +2457,8 @@ function parseRunProps(rPr, ctx) {
|
|
|
2457
2457
|
else if (vertAlign === "baseline") props.verticalAlign = "baseline";
|
|
2458
2458
|
const spacing = intAttr(child(rPr, "spacing"), "val");
|
|
2459
2459
|
if (spacing !== void 0) props.letterSpacing = twipsToPx(spacing);
|
|
2460
|
+
const kern = intAttr(child(rPr, "kern"), "val");
|
|
2461
|
+
if (kern !== void 0) props.kerningThreshold = kern > 0 ? halfPtToPx(kern) : null;
|
|
2460
2462
|
const wScale = intAttr(child(rPr, "w"), "val");
|
|
2461
2463
|
if (wScale !== void 0 && wScale > 0 && wScale !== 100) props.textScale = wScale / 100;
|
|
2462
2464
|
const fitText = intAttr(child(rPr, "fitText"), "val");
|
|
@@ -3417,6 +3419,17 @@ function parseParagraph(p, ctx) {
|
|
|
3417
3419
|
parseParaChildren(p, ctx, para.children, field, bookmarks);
|
|
3418
3420
|
if (bookmarks.length > 0) para.bookmarks = bookmarks;
|
|
3419
3421
|
flushField(field);
|
|
3422
|
+
const visibleContent = para.children.flatMap(
|
|
3423
|
+
(paraChild) => (paraChild.type === "run" ? [paraChild] : paraChild.runs).flatMap(
|
|
3424
|
+
(run) => run.content.filter((content) => content.kind !== "text" || content.text.length > 0)
|
|
3425
|
+
)
|
|
3426
|
+
);
|
|
3427
|
+
if (visibleContent.length === 1 && visibleContent[0].kind === "math") {
|
|
3428
|
+
const node = visibleContent[0].nodes.length === 1 ? visibleContent[0].nodes[0] : void 0;
|
|
3429
|
+
if (node?.t === "frac" && node.num.every((part) => part.t === "run") && node.den.every((part) => part.t === "run")) {
|
|
3430
|
+
visibleContent[0].display = true;
|
|
3431
|
+
}
|
|
3432
|
+
}
|
|
3420
3433
|
suppressTocHyperlinkFormatting(para);
|
|
3421
3434
|
if (ctx.revisionView !== "markup" && pPr) {
|
|
3422
3435
|
const markRPr = child(pPr, "rPr");
|
|
@@ -3659,13 +3672,14 @@ function parseParaChildren(parent, ctx, out, field, bookmarks) {
|
|
|
3659
3672
|
const nodes = parseOmml(el16);
|
|
3660
3673
|
if (nodes.length > 0) {
|
|
3661
3674
|
const display = ln === "oMathPara";
|
|
3675
|
+
const multiEquationDisplay = display && children(el16, "oMath").length > 3;
|
|
3662
3676
|
const jcVal = display ? attr(child(child(el16, "oMathParaPr"), "jc"), "val") : void 0;
|
|
3663
3677
|
const jc = jcVal === "left" || jcVal === "right" || jcVal === "center" || jcVal === "centerGroup" ? jcVal : void 0;
|
|
3664
3678
|
const content = [];
|
|
3665
3679
|
let segment = [];
|
|
3666
3680
|
const flushMath = () => {
|
|
3667
3681
|
if (segment.length === 0) return;
|
|
3668
|
-
content.push({ kind: "math", nodes: segment, src: el16, display, jc });
|
|
3682
|
+
content.push({ kind: "math", nodes: segment, src: el16, display, multiEquationDisplay, jc });
|
|
3669
3683
|
segment = [];
|
|
3670
3684
|
};
|
|
3671
3685
|
for (const node of nodes) {
|
|
@@ -3896,6 +3910,9 @@ function parseRun(r, ctx, field, suppressedObjects) {
|
|
|
3896
3910
|
case "tab":
|
|
3897
3911
|
run.content.push({ kind: "tab" });
|
|
3898
3912
|
break;
|
|
3913
|
+
case "pgNum":
|
|
3914
|
+
run.content.push({ kind: "field", instruction: "PAGE", cachedResult: "" });
|
|
3915
|
+
break;
|
|
3899
3916
|
case "drawing": {
|
|
3900
3917
|
const img = parseDrawing(el16, ctx);
|
|
3901
3918
|
if (img) {
|
|
@@ -3943,7 +3960,7 @@ function parseRun(r, ctx, field, suppressedObjects) {
|
|
|
3943
3960
|
let code = parseInt(charHex, 16);
|
|
3944
3961
|
if (code >= 61440) code -= 61440;
|
|
3945
3962
|
const font = attr(el16, "font") ?? "";
|
|
3946
|
-
const mapped = /wingdings|webdings
|
|
3963
|
+
const mapped = /^symbol$/i.test(font) ? SYMBOL_TEXT_CHAR_MAP[code] : /wingdings|webdings/i.test(font) ? SYMBOL_CHAR_MAP[code] : void 0;
|
|
3947
3964
|
run.content.push({ kind: "text", text: mapped ?? String.fromCharCode(code) });
|
|
3948
3965
|
}
|
|
3949
3966
|
break;
|
|
@@ -4107,7 +4124,17 @@ function parseDrawing(drawing, ctx) {
|
|
|
4107
4124
|
const modelRel = modelRelId ? ctx.rels.get(modelRelId) : void 0;
|
|
4108
4125
|
if (rel && !rel.external) {
|
|
4109
4126
|
if (modelRel && !modelRel.external) {
|
|
4110
|
-
|
|
4127
|
+
const rot = child(child(el16, "trans"), "rot");
|
|
4128
|
+
const rotation = {
|
|
4129
|
+
x: (intAttr(rot, "ax") ?? 0) / 6e4,
|
|
4130
|
+
y: (intAttr(rot, "ay") ?? 0) / 6e4,
|
|
4131
|
+
z: (intAttr(rot, "az") ?? 0) / 6e4
|
|
4132
|
+
};
|
|
4133
|
+
model3D = {
|
|
4134
|
+
part: modelRel.target,
|
|
4135
|
+
posterPart: rel.target,
|
|
4136
|
+
...rotation.x || rotation.y || rotation.z ? { rotation } : {}
|
|
4137
|
+
};
|
|
4111
4138
|
}
|
|
4112
4139
|
const xfrm = path(el16, "spPr", "xfrm");
|
|
4113
4140
|
const off = child(xfrm, "off");
|
|
@@ -4354,7 +4381,8 @@ function parseDrawing(drawing, ctx) {
|
|
|
4354
4381
|
const pctEl = el16 ? el16.children.find((c) => localName(c.name).startsWith("pct")) : void 0;
|
|
4355
4382
|
if (!pctEl) return void 0;
|
|
4356
4383
|
const rf = attr(el16, "relativeFrom");
|
|
4357
|
-
|
|
4384
|
+
const pct = (parseInt(pctEl.text, 10) || 0) / 1e5;
|
|
4385
|
+
return pct > 0 ? { pct, rel: rf === "page" ? "page" : "margin" } : void 0;
|
|
4358
4386
|
};
|
|
4359
4387
|
const spPr = child(textboxEl, "spPr");
|
|
4360
4388
|
const txbxOwn = child(textboxEl, "txbx");
|
|
@@ -4821,7 +4849,8 @@ function collectDiagramShapes(dspRoot, ctx, out, dx, dy) {
|
|
|
4821
4849
|
height: emuToPx(th),
|
|
4822
4850
|
blocks,
|
|
4823
4851
|
insets: { l: insetOf("lIns", 9.6), t: insetOf("tIns", 4.8), r: insetOf("rIns", 9.6), b: insetOf("bIns", 4.8) },
|
|
4824
|
-
textAnchor: anchorAttr === "ctr" ? "middle" : anchorAttr === "b" ? "bottom" : "top"
|
|
4852
|
+
textAnchor: anchorAttr === "ctr" ? "middle" : anchorAttr === "b" ? "bottom" : "top",
|
|
4853
|
+
paintOffsetY: 0.75
|
|
4825
4854
|
});
|
|
4826
4855
|
}
|
|
4827
4856
|
}
|
|
@@ -4907,6 +4936,8 @@ function drawingMLRun(r, ctx) {
|
|
|
4907
4936
|
const props = {};
|
|
4908
4937
|
const sz = rPr ? intAttr(rPr, "sz") : void 0;
|
|
4909
4938
|
props.size = ptToPx((sz ?? 1800) / 100);
|
|
4939
|
+
const kern = rPr ? intAttr(rPr, "kern") : void 0;
|
|
4940
|
+
if (kern !== void 0) props.kerningThreshold = kern > 0 ? ptToPx(kern / 100) : null;
|
|
4910
4941
|
if (rPr && attr(rPr, "b") === "1") props.bold = true;
|
|
4911
4942
|
if (rPr && attr(rPr, "i") === "1") props.italic = true;
|
|
4912
4943
|
const u = rPr ? attr(rPr, "u") : void 0;
|
|
@@ -5351,6 +5382,8 @@ function parseCell(tc, ctx) {
|
|
|
5351
5382
|
if (tcW && attr(tcW, "type") === "dxa") {
|
|
5352
5383
|
const w = intAttr(tcW, "w");
|
|
5353
5384
|
if (w) props.width = twipsToPx(w);
|
|
5385
|
+
} else if (tcW && attr(tcW, "type") === "auto") {
|
|
5386
|
+
props.widthAuto = true;
|
|
5354
5387
|
}
|
|
5355
5388
|
const borders = child(tcPr, "tcBorders");
|
|
5356
5389
|
if (borders) {
|
|
@@ -5726,6 +5759,9 @@ var DocxDocument = class _DocxDocument {
|
|
|
5726
5759
|
/** Note content by note id (render-only; sources stripped). */
|
|
5727
5760
|
this.footnotes = /* @__PURE__ */ new Map();
|
|
5728
5761
|
this.endnotes = /* @__PURE__ */ new Map();
|
|
5762
|
+
/** The separator paragraph controls the gap between its rule and the first
|
|
5763
|
+
* footnote. */
|
|
5764
|
+
this.footnoteSeparator = [];
|
|
5729
5765
|
/** `_Ref` cross-reference bookmark ranges (name → captured runs). REF
|
|
5730
5766
|
* fields re-render the referenced text from these — Word recomputes REF on
|
|
5731
5767
|
* open, so the cached field result in the file is stale. */
|
|
@@ -5842,6 +5878,8 @@ var DocxDocument = class _DocxDocument {
|
|
|
5842
5878
|
if (!docRoot) throw new Error(`Missing ${docPart} in package`);
|
|
5843
5879
|
this.docRoot = docRoot;
|
|
5844
5880
|
this.rememberOriginalXml(docPart, docRoot);
|
|
5881
|
+
const coreProperties = this.readXmlOptional("docProps/core.xml");
|
|
5882
|
+
this.hydrateCorePropertyControls(docRoot, coreProperties);
|
|
5845
5883
|
this.repairLegacyWordInWebObjects();
|
|
5846
5884
|
this.documentRels = parseRelationships(this.relsRoot ?? void 0, docPart);
|
|
5847
5885
|
if (settings) {
|
|
@@ -5884,6 +5922,7 @@ var DocxDocument = class _DocxDocument {
|
|
|
5884
5922
|
if (!root) continue;
|
|
5885
5923
|
const partRels = parseRelationships(this.readXmlOptional(relsPathFor(rel.target)), rel.target);
|
|
5886
5924
|
this.rememberOriginalXml(rel.target, root);
|
|
5925
|
+
this.hydrateCorePropertyControls(root, coreProperties);
|
|
5887
5926
|
this.hfParts.push({ relId: rel.id, target: rel.target, root, isHeader, rels: partRels });
|
|
5888
5927
|
}
|
|
5889
5928
|
for (const rel of this.documentRels.values()) {
|
|
@@ -5897,6 +5936,12 @@ var DocxDocument = class _DocxDocument {
|
|
|
5897
5936
|
this.footnotesPart = rel.target;
|
|
5898
5937
|
this.footnotesRoot = root;
|
|
5899
5938
|
this.footnotesRels = partRels;
|
|
5939
|
+
const separator = root.children.find(
|
|
5940
|
+
(item) => localName(item.name) === "footnote" && attr(item, "type") === "separator"
|
|
5941
|
+
);
|
|
5942
|
+
if (separator) {
|
|
5943
|
+
this.footnoteSeparator.push(...parseBlocks(separator, { ...this.ctxBase, rels: partRels }));
|
|
5944
|
+
}
|
|
5900
5945
|
}
|
|
5901
5946
|
const notes = parseNotesPart(root, { ...this.ctxBase, rels: partRels }, isFn);
|
|
5902
5947
|
for (const [id, blocks] of notes) (isFn ? this.footnotes : this.endnotes).set(id, blocks);
|
|
@@ -5911,6 +5956,37 @@ var DocxDocument = class _DocxDocument {
|
|
|
5911
5956
|
this._packageResourceVersion++;
|
|
5912
5957
|
this._layoutGlobalSig = null;
|
|
5913
5958
|
}
|
|
5959
|
+
/** Resolve content controls mapped to standard package core properties.
|
|
5960
|
+
* Word refreshes these bindings on open, so the serialized sdtContent can
|
|
5961
|
+
* be stale even though the visible value comes from docProps/core.xml. */
|
|
5962
|
+
hydrateCorePropertyControls(root, coreProperties) {
|
|
5963
|
+
if (!coreProperties) return;
|
|
5964
|
+
const textNodes = (element) => {
|
|
5965
|
+
const out = localName(element.name) === "t" ? [element] : [];
|
|
5966
|
+
for (const item of element.children) out.push(...textNodes(item));
|
|
5967
|
+
return out;
|
|
5968
|
+
};
|
|
5969
|
+
const walk2 = (element) => {
|
|
5970
|
+
if (localName(element.name) === "sdt") {
|
|
5971
|
+
const binding = child(child(element, "sdtPr"), "dataBinding");
|
|
5972
|
+
const xpath = attr(binding, "xpath") ?? "";
|
|
5973
|
+
const propertyMatch = /\/(?:[^/:]+:)?([A-Za-z_][\w.-]*)(?:\[\d+\])?\s*$/.exec(xpath);
|
|
5974
|
+
if (xpath.includes("coreProperties") && propertyMatch) {
|
|
5975
|
+
const property = coreProperties.children.find(
|
|
5976
|
+
(item) => localName(item.name) === propertyMatch[1]
|
|
5977
|
+
);
|
|
5978
|
+
const content = child(element, "sdtContent");
|
|
5979
|
+
const targets = content ? textNodes(content) : [];
|
|
5980
|
+
if (property?.text && targets.length > 0) {
|
|
5981
|
+
targets[0].text = property.text;
|
|
5982
|
+
for (const target of targets.slice(1)) target.text = "";
|
|
5983
|
+
}
|
|
5984
|
+
}
|
|
5985
|
+
}
|
|
5986
|
+
for (const item of element.children) walk2(item);
|
|
5987
|
+
};
|
|
5988
|
+
walk2(root);
|
|
5989
|
+
}
|
|
5914
5990
|
/** Repair only objects emitted by older WordInWeb builds that Word rejects. */
|
|
5915
5991
|
repairLegacyWordInWebObjects() {
|
|
5916
5992
|
const raw = this.pkg.raw();
|
|
@@ -7992,7 +8068,7 @@ var BAKED_FONT_METRICS = {
|
|
|
7992
8068
|
// ../core/src/layout/measure.ts
|
|
7993
8069
|
function fontKey(font) {
|
|
7994
8070
|
const paint = font.paintFamily && font.paintFamily !== font.family ? `${font.paintFamily}>` : "";
|
|
7995
|
-
return `${font.bold ? "bold " : ""}${font.italic ? "italic " : ""}${font.size}px ${paint}${font.family}`;
|
|
8071
|
+
return `${font.bold ? "bold " : ""}${font.italic ? "italic " : ""}${font.kerning ? "kern " : ""}${font.size}px ${paint}${font.family}`;
|
|
7996
8072
|
}
|
|
7997
8073
|
var METRIC_SUBSTITUTES = {
|
|
7998
8074
|
calibri: "Carlito",
|
|
@@ -8137,6 +8213,23 @@ function hasCambriaMath() {
|
|
|
8137
8213
|
}
|
|
8138
8214
|
return _cambriaMath;
|
|
8139
8215
|
}
|
|
8216
|
+
var _segoeUIEmoji;
|
|
8217
|
+
function hasSegoeUIEmoji() {
|
|
8218
|
+
if (_segoeUIEmoji !== void 0) return _segoeUIEmoji;
|
|
8219
|
+
try {
|
|
8220
|
+
const canvas = typeof OffscreenCanvas !== "undefined" ? new OffscreenCanvas(1, 1) : typeof document !== "undefined" ? document.createElement("canvas") : null;
|
|
8221
|
+
const ctx = canvas?.getContext("2d");
|
|
8222
|
+
if (!ctx) return _segoeUIEmoji = false;
|
|
8223
|
+
ctx.font = '48px "Segoe UI Emoji", sans-serif';
|
|
8224
|
+
const requested = ctx.measureText("\u263A");
|
|
8225
|
+
ctx.font = "48px sans-serif";
|
|
8226
|
+
const fallback = ctx.measureText("\u263A");
|
|
8227
|
+
_segoeUIEmoji = Math.abs(requested.width - fallback.width) > 0.01 || Math.abs((requested.actualBoundingBoxRight ?? 0) - (fallback.actualBoundingBoxRight ?? 0)) > 0.01 || Math.abs((requested.actualBoundingBoxAscent ?? 0) - (fallback.actualBoundingBoxAscent ?? 0)) > 0.01;
|
|
8228
|
+
} catch {
|
|
8229
|
+
_segoeUIEmoji = false;
|
|
8230
|
+
}
|
|
8231
|
+
return _segoeUIEmoji;
|
|
8232
|
+
}
|
|
8140
8233
|
function cambriaMathDescentShare() {
|
|
8141
8234
|
return 0.238;
|
|
8142
8235
|
}
|
|
@@ -8157,11 +8250,12 @@ var CanvasMeasurer = class {
|
|
|
8157
8250
|
}
|
|
8158
8251
|
setFont(font) {
|
|
8159
8252
|
const css = cssFont(font);
|
|
8160
|
-
|
|
8253
|
+
const key = `${css}\0${font.kerning ? "normal" : "none"}`;
|
|
8254
|
+
if (key !== this.currentFont) {
|
|
8161
8255
|
this.ctx.font = css;
|
|
8162
|
-
this.ctx.fontKerning = "none";
|
|
8256
|
+
this.ctx.fontKerning = font.kerning ? "normal" : "none";
|
|
8163
8257
|
this.ctx.textRendering = "optimizeSpeed";
|
|
8164
|
-
this.currentFont =
|
|
8258
|
+
this.currentFont = key;
|
|
8165
8259
|
}
|
|
8166
8260
|
}
|
|
8167
8261
|
width(text, font, letterSpacing = 0) {
|
|
@@ -8265,6 +8359,8 @@ function createMeasurer() {
|
|
|
8265
8359
|
// ../core/src/layout/math.ts
|
|
8266
8360
|
var SCRIPT_SCALE = 0.73;
|
|
8267
8361
|
var SCRIPT_SCRIPT_SCALE = 0.6;
|
|
8362
|
+
var EMPTY_SCRIPT_ADVANCE = 0.89;
|
|
8363
|
+
var EMPTY_SUP_ADVANCE = 0.84;
|
|
8268
8364
|
var floorHalfPt = (px) => Math.floor(px * 0.75 * 2 + 1e-6) / 2 / 0.75;
|
|
8269
8365
|
var scriptSize = (size, floor) => Math.max(floorHalfPt(size * SCRIPT_SCALE), floor);
|
|
8270
8366
|
var SUP_RAISE = 4 / 11;
|
|
@@ -8276,6 +8372,7 @@ var RULE_THICK = 0.75 / 11;
|
|
|
8276
8372
|
var BIN_OP_SPACE = 0.25;
|
|
8277
8373
|
var FUNC_NAME_SPACE = 0.18;
|
|
8278
8374
|
var COMMA_SPACE = 0.17;
|
|
8375
|
+
var SEMICOLON_SPACE = 0.153;
|
|
8279
8376
|
var FRAC_PAD = 0.06;
|
|
8280
8377
|
var NARY_SUM_RAISE = 0.5 / 11;
|
|
8281
8378
|
var NARY_INT_DROP = 0.5 / 11;
|
|
@@ -8294,10 +8391,11 @@ var MAT_COL_GAP_STIX = 12.2 / 11;
|
|
|
8294
8391
|
var MAT_COL_GAP_REAL_INLINE = 11.4 / 11;
|
|
8295
8392
|
var MAT_COL_GAP_REAL_DISPLAY = 11.13 / 11;
|
|
8296
8393
|
var DLM_PAD_STIX = 1.2 / 11;
|
|
8297
|
-
var DLM_PAD_REAL =
|
|
8394
|
+
var DLM_PAD_REAL = 1 / 11;
|
|
8298
8395
|
var matColGap = (display) => hasCambriaMath() ? display ? MAT_COL_GAP_REAL_DISPLAY : MAT_COL_GAP_REAL_INLINE : MAT_COL_GAP_STIX;
|
|
8299
8396
|
var dlmPad = () => hasCambriaMath() ? DLM_PAD_REAL : DLM_PAD_STIX;
|
|
8300
8397
|
var DLM_MAT_END_PAD = 0.3 / 11;
|
|
8398
|
+
var DLM_TRAILING_SPACE_PAD = 0.125;
|
|
8301
8399
|
var FRAC_NUM_RAISE_D = 1550 / 2048;
|
|
8302
8400
|
var FRAC_DEN_DROP_D = 1370 / 2048;
|
|
8303
8401
|
var FRAC_DEN_DLM_EXTRA = 133 / 2048;
|
|
@@ -8311,6 +8409,8 @@ var INT_D_INK = 1.3584 + 0.7925;
|
|
|
8311
8409
|
var INT_D_ASC = 1.3584;
|
|
8312
8410
|
var INT_D_DESC = 0.7925;
|
|
8313
8411
|
var INT_D_ADV = 0.8066;
|
|
8412
|
+
var INT_D_LIMIT_OVERLAP = 0.37;
|
|
8413
|
+
var INT_D_SUP_STAGGER = 0.375;
|
|
8314
8414
|
var INT_D_ANCHOR = (1.3584 - 0.877 * (INT_D_INK / INT_TEXT_INK)) / (1 - INT_D_INK / INT_TEXT_INK);
|
|
8315
8415
|
var MATH_FONT = "Cambria Math";
|
|
8316
8416
|
function mathText(text, normal = false) {
|
|
@@ -8388,7 +8488,7 @@ var BRACKET_RE = /[()[\]{}]/;
|
|
|
8388
8488
|
var SUP_DLM_DROP = 460 / 2048;
|
|
8389
8489
|
var ITALIC_MATH_RE = /[\u{1D434}-\u{1D467}ℎ]/u;
|
|
8390
8490
|
var SUP_KERN_IN = 0;
|
|
8391
|
-
var
|
|
8491
|
+
var SCRIPT_TRAIL_GROUPED_DISPLAY = 0.12;
|
|
8392
8492
|
function containsDlm(nodes) {
|
|
8393
8493
|
for (const n of nodes) {
|
|
8394
8494
|
switch (n.t) {
|
|
@@ -8473,9 +8573,21 @@ function containsBlocky(nodes) {
|
|
|
8473
8573
|
}
|
|
8474
8574
|
return false;
|
|
8475
8575
|
}
|
|
8476
|
-
function layoutMath(nodes, baseSize, measurer, display = false) {
|
|
8576
|
+
function layoutMath(nodes, baseSize, measurer, display = false, fractionPadEm = FRAC_PAD, multiEquationDisplay = false) {
|
|
8477
8577
|
const box = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [], display, baseSize };
|
|
8478
|
-
flow(
|
|
8578
|
+
flow(
|
|
8579
|
+
nodes,
|
|
8580
|
+
baseSize,
|
|
8581
|
+
0,
|
|
8582
|
+
box,
|
|
8583
|
+
measurer,
|
|
8584
|
+
false,
|
|
8585
|
+
display,
|
|
8586
|
+
0,
|
|
8587
|
+
floorHalfPt(baseSize * SCRIPT_SCRIPT_SCALE),
|
|
8588
|
+
fractionPadEm,
|
|
8589
|
+
multiEquationDisplay ? SCRIPT_TRAIL_GROUPED_DISPLAY : 0
|
|
8590
|
+
);
|
|
8479
8591
|
for (const p of box.pieces) {
|
|
8480
8592
|
const m = measurer.metrics(p.font);
|
|
8481
8593
|
p.effAscent = p.ownAscent ?? p.dy + m.ascent;
|
|
@@ -8489,12 +8601,17 @@ function layoutMath(nodes, baseSize, measurer, display = false) {
|
|
|
8489
8601
|
}
|
|
8490
8602
|
return box;
|
|
8491
8603
|
}
|
|
8492
|
-
function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth = 0, scriptFloor = 0) {
|
|
8604
|
+
function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth = 0, scriptFloor = 0, fractionPadEm = FRAC_PAD, scriptTrailEm = 0) {
|
|
8493
8605
|
let prevOperand = false;
|
|
8494
8606
|
for (const node of nodes) {
|
|
8495
8607
|
switch (node.t) {
|
|
8496
8608
|
case "run": {
|
|
8497
8609
|
const font = fontAt(size);
|
|
8610
|
+
if (node.normal && /^\s+$/.test(node.text)) {
|
|
8611
|
+
box.pieces.push({ text: node.text, x: box.width, dy, font });
|
|
8612
|
+
box.width += [...node.text].length * size;
|
|
8613
|
+
break;
|
|
8614
|
+
}
|
|
8498
8615
|
if (node.fname) {
|
|
8499
8616
|
const gap = size * FUNC_NAME_SPACE;
|
|
8500
8617
|
if (prevOperand) box.width += gap;
|
|
@@ -8506,16 +8623,19 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8506
8623
|
}
|
|
8507
8624
|
const medGap = size * BIN_OP_SPACE;
|
|
8508
8625
|
const relGap = display ? medGap : size * (5 / 18);
|
|
8509
|
-
const toks = node.text.split(/([
|
|
8626
|
+
const toks = node.text.split(/([=+−×÷<>≤≥±≠,;\-])/).filter((s) => s.length > 0);
|
|
8510
8627
|
for (let ti = 0; ti < toks.length; ti++) {
|
|
8511
8628
|
const tok = toks[ti];
|
|
8512
|
-
if (tok === ",") {
|
|
8629
|
+
if (tok === "," || tok === ";") {
|
|
8513
8630
|
const text2 = mathText(tok, node.normal);
|
|
8514
8631
|
box.pieces.push({ text: text2, x: box.width, dy, font });
|
|
8515
8632
|
box.width += measurer.width(text2, font);
|
|
8516
8633
|
const nextIsSpace = ti + 1 < toks.length && /^\s/.test(toks[ti + 1]);
|
|
8517
|
-
|
|
8518
|
-
|
|
8634
|
+
const spacedSemicolon = tok === ";" && (ti === toks.length - 1 || !BIN_OPS.has(toks[ti + 1]));
|
|
8635
|
+
if (!tight && !nextIsSpace && (tok === "," || spacedSemicolon)) {
|
|
8636
|
+
box.width += size * (tok === "," ? COMMA_SPACE : SEMICOLON_SPACE);
|
|
8637
|
+
}
|
|
8638
|
+
prevOperand = tok === ";";
|
|
8519
8639
|
continue;
|
|
8520
8640
|
}
|
|
8521
8641
|
const isOp = BIN_OPS.has(tok);
|
|
@@ -8539,7 +8659,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8539
8659
|
case "sup":
|
|
8540
8660
|
case "sub": {
|
|
8541
8661
|
const beforeBase = box.pieces.length;
|
|
8542
|
-
flow(node.base, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
8662
|
+
flow(node.base, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8543
8663
|
let baseInkAsc = 0;
|
|
8544
8664
|
if (node.t === "sup") {
|
|
8545
8665
|
for (let i = beforeBase; i < box.pieces.length; i++) {
|
|
@@ -8554,9 +8674,16 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8554
8674
|
box.width += size * SUP_KERN_IN;
|
|
8555
8675
|
}
|
|
8556
8676
|
const beforeScript = box.pieces.length;
|
|
8557
|
-
|
|
8677
|
+
const scriptFontSize = scriptSize(size, scriptFloor);
|
|
8678
|
+
if (node.t === "sub" && node.script.length === 0) {
|
|
8679
|
+
box.width += scriptFontSize * EMPTY_SCRIPT_ADVANCE;
|
|
8680
|
+
} else if (node.t === "sup" && node.script.length === 0) {
|
|
8681
|
+
box.width += scriptFontSize * EMPTY_SUP_ADVANCE;
|
|
8682
|
+
} else {
|
|
8683
|
+
flow(node.script, scriptFontSize, scriptDy, box, measurer, true, false, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8684
|
+
}
|
|
8558
8685
|
for (let i = beforeScript; i < box.pieces.length; i++) box.pieces[i].script = true;
|
|
8559
|
-
box.width += size *
|
|
8686
|
+
if (display) box.width += size * scriptTrailEm;
|
|
8560
8687
|
prevOperand = true;
|
|
8561
8688
|
break;
|
|
8562
8689
|
}
|
|
@@ -8565,17 +8692,17 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8565
8692
|
const numRaise = display ? size * FRAC_NUM_RAISE_D : size * FRAC_NUM_RAISE;
|
|
8566
8693
|
const denDrop = (display ? size * FRAC_DEN_DROP_D : size * FRAC_DEN_DROP) + (display && containsDlm(node.den) ? size * FRAC_DEN_DLM_EXTRA : 0);
|
|
8567
8694
|
const fracTight = display ? tight : true;
|
|
8568
|
-
const numW = widthOf(node.num, scale, measurer, display, fracTight, scriptFloor);
|
|
8569
|
-
const denW = widthOf(node.den, scale, measurer, display, fracTight, scriptFloor);
|
|
8570
|
-
const pad = size *
|
|
8695
|
+
const numW = widthOf(node.num, scale, measurer, display, fracTight, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8696
|
+
const denW = widthOf(node.den, scale, measurer, display, fracTight, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8697
|
+
const pad = size * fractionPadEm;
|
|
8571
8698
|
const barW = Math.max(numW, denW) + 2 * pad;
|
|
8572
8699
|
const x0 = box.width;
|
|
8573
8700
|
const numBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8574
|
-
flow(node.num, scale, 0, numBox, measurer, fracTight, display, breakDepth + 2, scriptFloor);
|
|
8701
|
+
flow(node.num, scale, 0, numBox, measurer, fracTight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8575
8702
|
for (const p of numBox.pieces) box.pieces.push(rebase(p, x0 + (barW - numW) / 2, dy + numRaise));
|
|
8576
8703
|
for (const r of numBox.rules) box.rules.push({ ...r, x1: x0 + (barW - numW) / 2 + r.x1, x2: x0 + (barW - numW) / 2 + r.x2, dy: dy + numRaise + r.dy });
|
|
8577
8704
|
const denBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8578
|
-
flow(node.den, scale, 0, denBox, measurer, fracTight, display, breakDepth + 2, scriptFloor);
|
|
8705
|
+
flow(node.den, scale, 0, denBox, measurer, fracTight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8579
8706
|
let denDropFinal = denDrop;
|
|
8580
8707
|
if (containsFrac(node.den)) {
|
|
8581
8708
|
let denAsc = 0;
|
|
@@ -8600,7 +8727,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8600
8727
|
case "nary": {
|
|
8601
8728
|
const isInt = "\u222B\u222C\u222D\u222E\u222F\u2230".includes(node.chr);
|
|
8602
8729
|
if (display && !isInt) {
|
|
8603
|
-
naryDisplay(node, size, dy, box, measurer, scriptFloor);
|
|
8730
|
+
naryDisplay(node, size, dy, box, measurer, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8604
8731
|
prevOperand = true;
|
|
8605
8732
|
break;
|
|
8606
8733
|
}
|
|
@@ -8629,20 +8756,24 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8629
8756
|
const intSubDrop = display && visibleSub ? INT_SUB_DROP_D : INT_SUB_DROP;
|
|
8630
8757
|
const supDy = dy + size * (isInt ? intSupRaise : NARY_SUP_RAISE);
|
|
8631
8758
|
const subDy = dy - size * (isInt ? intSubDrop : NARY_SUB_DROP);
|
|
8632
|
-
const supStagger = isInt ? size * INT_SUP_STAGGER : 0;
|
|
8633
|
-
const supW = widthOf(node.sup, scale, measurer, false, true, scriptFloor) + supStagger;
|
|
8634
|
-
const subW = widthOf(node.sub, scale, measurer, false, true, scriptFloor);
|
|
8635
|
-
const x0 = box.width;
|
|
8759
|
+
const supStagger = isInt ? size * (display ? INT_D_SUP_STAGGER : INT_SUP_STAGGER) : 0;
|
|
8760
|
+
const supW = visibleSup ? widthOf(node.sup, scale, measurer, false, true, scriptFloor, fractionPadEm, scriptTrailEm) + supStagger : 0;
|
|
8761
|
+
const subW = visibleSub ? widthOf(node.sub, scale, measurer, false, true, scriptFloor, fractionPadEm, scriptTrailEm) : 0;
|
|
8762
|
+
const x0 = box.width - (display && isInt && (visibleSup || visibleSub) ? size * INT_D_LIMIT_OVERLAP : 0);
|
|
8636
8763
|
const supBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8764
|
+
if (visibleSup) {
|
|
8765
|
+
flow(node.sup, scale, 0, supBox, measurer, true, false, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8766
|
+
for (const pc of supBox.pieces) box.pieces.push(rebase(pc, x0 + supStagger, supDy, true));
|
|
8767
|
+
for (const r of supBox.rules) box.rules.push({ ...r, x1: x0 + supStagger + r.x1, x2: x0 + supStagger + r.x2, dy: supDy + r.dy });
|
|
8768
|
+
}
|
|
8640
8769
|
const subBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8641
|
-
|
|
8642
|
-
|
|
8643
|
-
|
|
8770
|
+
if (visibleSub) {
|
|
8771
|
+
flow(node.sub, scale, 0, subBox, measurer, true, false, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8772
|
+
for (const pc of subBox.pieces) box.pieces.push(rebase(pc, x0, subDy, true));
|
|
8773
|
+
for (const r of subBox.rules) box.rules.push({ ...r, x1: x0 + r.x1, x2: x0 + r.x2, dy: subDy + r.dy });
|
|
8774
|
+
}
|
|
8644
8775
|
box.width = x0 + Math.max(supW, subW) + size * NARY_E_GAP;
|
|
8645
|
-
flow(node.e, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
8776
|
+
flow(node.e, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8646
8777
|
prevOperand = true;
|
|
8647
8778
|
break;
|
|
8648
8779
|
}
|
|
@@ -8652,7 +8783,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8652
8783
|
let coreDesc = 0;
|
|
8653
8784
|
const parts = node.e.map((part) => {
|
|
8654
8785
|
const b = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8655
|
-
flow(part, size, 0, b, measurer, tight, display, breakDepth + 1, scriptFloor);
|
|
8786
|
+
flow(part, size, 0, b, measurer, tight, display, breakDepth + 1, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8656
8787
|
for (const pc of b.pieces) {
|
|
8657
8788
|
const m = measurer.metrics(pc.font);
|
|
8658
8789
|
const asc = pc.ownAscent ?? pc.dy + m.ascent;
|
|
@@ -8708,7 +8839,10 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8708
8839
|
grow = 1;
|
|
8709
8840
|
}
|
|
8710
8841
|
}
|
|
8711
|
-
const
|
|
8842
|
+
const lastPart = node.e[node.e.length - 1];
|
|
8843
|
+
const tail = lastPart?.[lastPart.length - 1];
|
|
8844
|
+
const trailingSpaces = display && tail?.t === "run" && /^\s+$/.test(tail.text) ? [...tail.text].length : 0;
|
|
8845
|
+
const innerPad = size * (matLike ? DLM_MAT_END_PAD : dlmPad()) + size * DLM_TRAILING_SPACE_PAD * trailingSpaces;
|
|
8712
8846
|
const drawDelim = (ch) => {
|
|
8713
8847
|
if (!ch) return;
|
|
8714
8848
|
const asm = asmH !== void 0 ? DLM_ASM_PIECES[ch] : void 0;
|
|
@@ -8778,7 +8912,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8778
8912
|
const cells = node.rows.map(
|
|
8779
8913
|
(row) => row.map((cell) => {
|
|
8780
8914
|
const b = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8781
|
-
flow(cell, size, 0, b, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
8915
|
+
flow(cell, size, 0, b, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8782
8916
|
for (const pc of b.pieces) {
|
|
8783
8917
|
const m = measurer.metrics(pc.font);
|
|
8784
8918
|
b.ascent = Math.max(b.ascent, pc.dy + m.ascent);
|
|
@@ -8824,7 +8958,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8824
8958
|
const m = measurer.metrics(font);
|
|
8825
8959
|
const ruleThick = Math.max(size * RULE_THICK, 0.75);
|
|
8826
8960
|
const radBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8827
|
-
flow(node.e, size, 0, radBox, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
8961
|
+
flow(node.e, size, 0, radBox, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8828
8962
|
let radAsc = m.ascent * 0.5;
|
|
8829
8963
|
let radDesc = 0;
|
|
8830
8964
|
for (const pc of radBox.pieces) {
|
|
@@ -8848,7 +8982,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8848
8982
|
const dScale = scriptSize(size, scriptFloor);
|
|
8849
8983
|
box.width += size * RAD_KERN_BEFORE_DEG;
|
|
8850
8984
|
const degBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8851
|
-
flow(node.deg, dScale, 0, degBox, measurer, true, false, breakDepth + 2, scriptFloor);
|
|
8985
|
+
flow(node.deg, dScale, 0, degBox, measurer, true, false, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8852
8986
|
const degDy = dy - radDesc + RAD_DEG_RAISE * signInkH + size * RAD_DEG_ADJ;
|
|
8853
8987
|
for (const pc of degBox.pieces) box.pieces.push(rebase(pc, box.width, degDy, true));
|
|
8854
8988
|
for (const r of degBox.rules) box.rules.push({ ...r, x1: box.width + r.x1, x2: box.width + r.x2, dy: degDy + r.dy });
|
|
@@ -8895,7 +9029,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8895
9029
|
const axis = dy + size * RULE_CENTER;
|
|
8896
9030
|
const rowBoxes = node.rows.map((row) => {
|
|
8897
9031
|
const b = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8898
|
-
flow(row, size, 0, b, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
9032
|
+
flow(row, size, 0, b, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8899
9033
|
for (const pc of b.pieces) {
|
|
8900
9034
|
const pm = measurer.metrics(pc.font);
|
|
8901
9035
|
b.ascent = Math.max(b.ascent, pc.ownAscent ?? pc.dy + pm.ascent);
|
|
@@ -8925,7 +9059,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8925
9059
|
}
|
|
8926
9060
|
case "acc": {
|
|
8927
9061
|
const before = box.pieces.length;
|
|
8928
|
-
flow(node.e, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
9062
|
+
flow(node.e, size, dy, box, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8929
9063
|
if (box.pieces.length > before) {
|
|
8930
9064
|
const last = box.pieces[box.pieces.length - 1];
|
|
8931
9065
|
last.text += node.chr;
|
|
@@ -8937,7 +9071,7 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8937
9071
|
const isTop = node.pos === "top";
|
|
8938
9072
|
const bScale = isTop ? size : scriptSize(size, scriptFloor);
|
|
8939
9073
|
const baseBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8940
|
-
flow(node.e, bScale, 0, baseBox, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
9074
|
+
flow(node.e, bScale, 0, baseBox, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8941
9075
|
const baseW = baseBox.width;
|
|
8942
9076
|
const maxVariant = GRP_VARIANTS_EM[GRP_VARIANTS_EM.length - 1] * size;
|
|
8943
9077
|
let braceW = maxVariant;
|
|
@@ -8974,10 +9108,10 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8974
9108
|
case "lim": {
|
|
8975
9109
|
const isLow = node.pos === "low";
|
|
8976
9110
|
const baseBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8977
|
-
flow(node.e, size, 0, baseBox, measurer, tight, display, breakDepth + 2, scriptFloor);
|
|
9111
|
+
flow(node.e, size, 0, baseBox, measurer, tight, display, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8978
9112
|
const lScale = scriptSize(size, scriptFloor);
|
|
8979
9113
|
const limBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
8980
|
-
flow(node.lim, lScale, 0, limBox, measurer, true, false, breakDepth + 2, scriptFloor);
|
|
9114
|
+
flow(node.lim, lScale, 0, limBox, measurer, true, false, breakDepth + 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
8981
9115
|
const w = Math.max(baseBox.width, limBox.width);
|
|
8982
9116
|
const x0 = box.width;
|
|
8983
9117
|
const baseX = x0 + (w - baseBox.width) / 2;
|
|
@@ -8994,19 +9128,19 @@ function flow(nodes, size, dy, box, measurer, tight, display = false, breakDepth
|
|
|
8994
9128
|
}
|
|
8995
9129
|
}
|
|
8996
9130
|
}
|
|
8997
|
-
function naryDisplay(node, size, dy, box, measurer, scriptFloor) {
|
|
9131
|
+
function naryDisplay(node, size, dy, box, measurer, scriptFloor, fractionPadEm, scriptTrailEm) {
|
|
8998
9132
|
const opFont = fontAt(size * NARY_OP_SCALE_D);
|
|
8999
9133
|
const opW = measurer.width(node.chr, opFont);
|
|
9000
9134
|
const scale = scriptSize(size, scriptFloor);
|
|
9001
|
-
const supW = widthOf(node.sup, scale, measurer, false, true, scriptFloor);
|
|
9002
|
-
const subW = widthOf(node.sub, scale, measurer, false, true, scriptFloor);
|
|
9135
|
+
const supW = widthOf(node.sup, scale, measurer, false, true, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9136
|
+
const subW = widthOf(node.sub, scale, measurer, false, true, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9003
9137
|
const stackW = Math.max(opW, supW, subW);
|
|
9004
9138
|
const x0 = box.width;
|
|
9005
9139
|
const cx = x0 + stackW / 2;
|
|
9006
9140
|
box.pieces.push({ text: node.chr, x: cx - opW / 2, dy, font: opFont });
|
|
9007
9141
|
if (node.sup.length) {
|
|
9008
9142
|
const supBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
9009
|
-
flow(node.sup, scale, 0, supBox, measurer, true, false, 2, scriptFloor);
|
|
9143
|
+
flow(node.sup, scale, 0, supBox, measurer, true, false, 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9010
9144
|
const ox = cx - supW / 2;
|
|
9011
9145
|
const oy = dy + size * NARY_OVER_RAISE_D;
|
|
9012
9146
|
for (const pc of supBox.pieces) box.pieces.push(rebase(pc, ox, oy, true));
|
|
@@ -9014,18 +9148,18 @@ function naryDisplay(node, size, dy, box, measurer, scriptFloor) {
|
|
|
9014
9148
|
}
|
|
9015
9149
|
if (node.sub.length) {
|
|
9016
9150
|
const subBox = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
9017
|
-
flow(node.sub, scale, 0, subBox, measurer, true, false, 2, scriptFloor);
|
|
9151
|
+
flow(node.sub, scale, 0, subBox, measurer, true, false, 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9018
9152
|
const ux = cx - subW / 2;
|
|
9019
9153
|
const uy = dy - size * NARY_UNDER_DROP_D;
|
|
9020
9154
|
for (const pc of subBox.pieces) box.pieces.push(rebase(pc, ux, uy, true));
|
|
9021
9155
|
for (const r of subBox.rules) box.rules.push({ ...r, x1: ux + r.x1, x2: ux + r.x2, dy: uy + r.dy });
|
|
9022
9156
|
}
|
|
9023
9157
|
box.width = x0 + stackW + size * NARY_E_GAP;
|
|
9024
|
-
flow(node.e, size, dy, box, measurer, false, true, 2, scriptFloor);
|
|
9158
|
+
flow(node.e, size, dy, box, measurer, false, true, 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9025
9159
|
}
|
|
9026
|
-
function widthOf(nodes, size, measurer, display = false, tight = true, scriptFloor = 0) {
|
|
9160
|
+
function widthOf(nodes, size, measurer, display = false, tight = true, scriptFloor = 0, fractionPadEm = FRAC_PAD, scriptTrailEm = 0) {
|
|
9027
9161
|
const tmp = { width: 0, ascent: 0, descent: 0, pieces: [], rules: [] };
|
|
9028
|
-
flow(nodes, size, 0, tmp, measurer, tight, display, 2, scriptFloor);
|
|
9162
|
+
flow(nodes, size, 0, tmp, measurer, tight, display, 2, scriptFloor, fractionPadEm, scriptTrailEm);
|
|
9029
9163
|
return tmp.width;
|
|
9030
9164
|
}
|
|
9031
9165
|
|
|
@@ -9053,16 +9187,18 @@ function starNumberFormat(instr, n) {
|
|
|
9053
9187
|
}
|
|
9054
9188
|
}
|
|
9055
9189
|
function fontOf(props, fallbackFamily) {
|
|
9190
|
+
const family = props.rtl && props.fontComplex || props.font || fallbackFamily;
|
|
9056
9191
|
let size = props.size ?? 14.666;
|
|
9057
9192
|
if (props.verticalAlign === "superscript" || props.verticalAlign === "subscript") {
|
|
9058
|
-
|
|
9193
|
+
const scale = EA_FAMILY_RE.test(family) ? 0.52 : 0.65;
|
|
9194
|
+
size = Math.round(size * 1.5 * scale) / 1.5;
|
|
9059
9195
|
}
|
|
9060
|
-
const family = props.rtl && props.fontComplex || props.font || fallbackFamily;
|
|
9061
9196
|
return {
|
|
9062
9197
|
family,
|
|
9063
9198
|
size,
|
|
9064
9199
|
bold: props.bold ?? false,
|
|
9065
|
-
italic: props.italic ?? false
|
|
9200
|
+
italic: props.italic ?? false,
|
|
9201
|
+
kerning: props.kerningThreshold !== void 0 && props.kerningThreshold !== null && size >= props.kerningThreshold
|
|
9066
9202
|
};
|
|
9067
9203
|
}
|
|
9068
9204
|
function displayText(text, props) {
|
|
@@ -9077,13 +9213,21 @@ function runPlainText(run) {
|
|
|
9077
9213
|
function isWordAlnum(ch) {
|
|
9078
9214
|
return ch !== void 0 && /[\p{L}\p{Nd}]/u.test(ch);
|
|
9079
9215
|
}
|
|
9080
|
-
function hyphenBreaks(word) {
|
|
9216
|
+
function hyphenBreaks(word, allowNumericEnDash) {
|
|
9081
9217
|
const out = [];
|
|
9218
|
+
let leading = 0;
|
|
9219
|
+
while (word[leading] === "-" || word[leading] === "\u2010") leading++;
|
|
9220
|
+
if (leading >= 2 && isWordAlnum(word[leading])) out.push(leading);
|
|
9082
9221
|
for (let i = 1; i < word.length - 1; i++) {
|
|
9083
9222
|
const ch = word[i];
|
|
9084
|
-
if (
|
|
9085
|
-
|
|
9086
|
-
|
|
9223
|
+
if (ch !== "-" && ch !== "\u2010" && ch !== "\u2013") continue;
|
|
9224
|
+
let end = i + 1;
|
|
9225
|
+
while (word[end] === "-" || word[end] === "\u2010" || word[end] === "\u2013") end++;
|
|
9226
|
+
const wordBefore = isWordAlnum(word[i - 1]) || /^[\)\]\}]$/.test(word[i - 1] ?? "") && isWordAlnum(word[i - 2]);
|
|
9227
|
+
const wordAfter = isWordAlnum(word[end]);
|
|
9228
|
+
const numericEnDash = allowNumericEnDash && ch === "\u2013" && /\p{Nd}/u.test(word[i - 1] ?? "") && /\p{Nd}/u.test(word[end] ?? "");
|
|
9229
|
+
if (ch === "\u2013" ? numericEnDash : wordBefore && wordAfter) out.push(end);
|
|
9230
|
+
i = end - 1;
|
|
9087
9231
|
}
|
|
9088
9232
|
return out;
|
|
9089
9233
|
}
|
|
@@ -9098,6 +9242,7 @@ function isCJK(ch) {
|
|
|
9098
9242
|
return CJK_RE.test(ch);
|
|
9099
9243
|
}
|
|
9100
9244
|
var BALLOT_RE = /[☐☑☒]/;
|
|
9245
|
+
var LEGACY_CHECKBOX_TRAILING_ADVANCE = 2.5 * 96 / 72;
|
|
9101
9246
|
function isBallot(ch) {
|
|
9102
9247
|
return BALLOT_RE.test(ch);
|
|
9103
9248
|
}
|
|
@@ -9183,17 +9328,35 @@ function wrapDisplayMath(box, maxWidth) {
|
|
|
9183
9328
|
});
|
|
9184
9329
|
}
|
|
9185
9330
|
var DEFAULT_TAB = 48;
|
|
9331
|
+
var TABBED_INLINE_MATH_FRAC_PAD = 0.15;
|
|
9186
9332
|
var OVERFLOW_PUNCT = /[.,:;!?)\]}、。,.:;?!)]}」』】〉》]/;
|
|
9187
|
-
var CJK_SPACE_COMPRESS = 0.
|
|
9333
|
+
var CJK_SPACE_COMPRESS = 0.5;
|
|
9188
9334
|
var EA_FAMILY_RE = /simsun|nsimsun|宋体|新宋体|songti|simhei|黑体|heiti|kaiti|楷体|fangsong|仿宋|yahei|雅黑|mingliu|细明|新細明|pmingliu|jhenghei|正黑|pingfang|dengxian|等线|ms (?:p?)(?:mincho|gothic)|mincho|meiryo|yu gothic|yu mincho|batang|gulim|dotum|malgun/i;
|
|
9189
|
-
var JUSTIFY_MAX_COMPRESS = 0.
|
|
9335
|
+
var JUSTIFY_MAX_COMPRESS = 0.29;
|
|
9336
|
+
var JUSTIFY_GRID_MAX_COMPRESS = 0.25;
|
|
9190
9337
|
var JUSTIFY_STRETCH_FACTOR = 0.5;
|
|
9191
9338
|
var TAMIL_GLYPH_SCALE = 0.735;
|
|
9192
9339
|
var TAMIL_BASELINE_DY_EM = 0.136;
|
|
9193
9340
|
var LAO_GLYPH_SCALE = 1.048;
|
|
9341
|
+
function emojiFallbackScale(text, family) {
|
|
9342
|
+
if (family.toLowerCase() !== "segoe ui emoji" || hasSegoeUIEmoji()) return 1;
|
|
9343
|
+
const codepoints = Array.from(text);
|
|
9344
|
+
if (codepoints.some((ch) => {
|
|
9345
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
9346
|
+
return cp >= 127462 && cp <= 127487;
|
|
9347
|
+
})) return 1;
|
|
9348
|
+
const people = codepoints.filter((ch) => {
|
|
9349
|
+
const cp = ch.codePointAt(0) ?? 0;
|
|
9350
|
+
return cp >= 128102 && cp <= 128105;
|
|
9351
|
+
}).length;
|
|
9352
|
+
if (text.includes("\u200D") && people >= 3) return 1.84;
|
|
9353
|
+
if (/🚀|❤|✅/.test(text)) return 1.39;
|
|
9354
|
+
if (text.includes("\u200D") || /[🏻-🏿]/u.test(text)) return 1.29;
|
|
9355
|
+
return 1;
|
|
9356
|
+
}
|
|
9194
9357
|
var KASHIDA_LOW_EM = 0;
|
|
9195
9358
|
var KASHIDA_MEDIUM_EM = 0.032;
|
|
9196
|
-
var KASHIDA_HIGH_EM = 0.
|
|
9359
|
+
var KASHIDA_HIGH_EM = 0.075;
|
|
9197
9360
|
var BP_CACHES = /* @__PURE__ */ new WeakMap();
|
|
9198
9361
|
var BP_CACHE_MAX = 6e4;
|
|
9199
9362
|
function bpCacheFor(measurer) {
|
|
@@ -9337,6 +9500,7 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9337
9500
|
let curSegments = [{ x: 0, width: contentWidth }];
|
|
9338
9501
|
let curSegIdx = 0;
|
|
9339
9502
|
let curClearY;
|
|
9503
|
+
let curEdgeReserve = 0;
|
|
9340
9504
|
const ls = props.lineSpacing;
|
|
9341
9505
|
const firstFont = atoms.find((a) => a.kind === "frag" || a.kind === "space")?.font;
|
|
9342
9506
|
const natural = firstFont ? measurer.metrics(firstFont).lineHeight * (ls?.rule === "auto" ? ls.value : 1) : 0;
|
|
@@ -9348,6 +9512,7 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9348
9512
|
curSegments = [{ x: 0, width: contentWidth }];
|
|
9349
9513
|
curSegIdx = 0;
|
|
9350
9514
|
curClearY = void 0;
|
|
9515
|
+
curEdgeReserve = 0;
|
|
9351
9516
|
if (boundsAt) {
|
|
9352
9517
|
let guard = 0;
|
|
9353
9518
|
let b = boundsAt(yOff, EST_LINE);
|
|
@@ -9361,6 +9526,7 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9361
9526
|
curSegments = b.segments && b.segments.length > 0 ? b.segments : [{ x: b.x, width: b.width }];
|
|
9362
9527
|
curSegIdx = 0;
|
|
9363
9528
|
curClearY = b.clearY;
|
|
9529
|
+
curEdgeReserve = b.edgeReserve ?? (b.clearY !== void 0 ? 0.75 : 0);
|
|
9364
9530
|
}
|
|
9365
9531
|
void idx;
|
|
9366
9532
|
};
|
|
@@ -9636,7 +9802,10 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9636
9802
|
rawStop = nextTabStop(rawStop.pos, props.tabs, contentWidth - indentRight, doc.defaultTabStop);
|
|
9637
9803
|
}
|
|
9638
9804
|
}
|
|
9639
|
-
|
|
9805
|
+
const explicitBeforeIndent = (props.tabs ?? []).some(
|
|
9806
|
+
(tab) => !tab.clear && tab.align !== "bar" && tab.pos > x + offset + 0.5 && tab.pos < indentLeft - 0.5
|
|
9807
|
+
);
|
|
9808
|
+
if (hanging > 0 && x + offset < indentLeft - 0.5 && !explicitBeforeIndent) {
|
|
9640
9809
|
rawStop = { pos: indentLeft, align: "left" };
|
|
9641
9810
|
}
|
|
9642
9811
|
const stop = { ...rawStop, pos: rawStop.pos - offset };
|
|
@@ -9702,8 +9871,9 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9702
9871
|
}
|
|
9703
9872
|
const lineEnd2 = lineStartX(lineIndex) + availFor(lineIndex);
|
|
9704
9873
|
if (firstWordWidth > 0 && probeX + firstWordWidth > lineEnd2 + 0.01) {
|
|
9874
|
+
const legacyContinuationIndent = !!atom.props.bold && nextAtom === ai + 3;
|
|
9705
9875
|
flush(false, false);
|
|
9706
|
-
ai--;
|
|
9876
|
+
if (!legacyContinuationIndent) ai--;
|
|
9707
9877
|
continue;
|
|
9708
9878
|
}
|
|
9709
9879
|
}
|
|
@@ -9779,9 +9949,11 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9779
9949
|
const rows = wrapDisplayMath(atom.box, availFor(lineIndex));
|
|
9780
9950
|
for (let ri = 0; ri < rows.length; ri++) {
|
|
9781
9951
|
const row = rows[ri];
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
x
|
|
9952
|
+
const tabReserve = !row.display && ri === rows.length - 1 && atoms[ai + 1]?.kind === "tab" ? row.width * 0.01 : 0;
|
|
9953
|
+
const advance = row.width + tabReserve;
|
|
9954
|
+
cur.push({ x, width: advance, math: row, mathSrc: atom.src, props: {}, font: fontOf({}, fallbackFamily) });
|
|
9955
|
+
curLineWidth += advance;
|
|
9956
|
+
x += advance;
|
|
9785
9957
|
if (ri + 1 < rows.length) flush(false, false);
|
|
9786
9958
|
}
|
|
9787
9959
|
continue;
|
|
@@ -9790,7 +9962,7 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9790
9962
|
const w = atom.kind === "image" ? atom.width : atom.drawing.width;
|
|
9791
9963
|
const h = atom.kind === "image" ? atom.height : atom.drawing.height;
|
|
9792
9964
|
if (curLineWidth > 0 && x + w > lineStartX(lineIndex) + availFor(lineIndex)) {
|
|
9793
|
-
const glued = atom.kind === "image" && !atom.srcDrawing;
|
|
9965
|
+
const glued = atom.kind === "image" && (!atom.srcDrawing || localName(atom.srcDrawing.name) !== "drawing");
|
|
9794
9966
|
let hi = cur.length;
|
|
9795
9967
|
let headW = 0;
|
|
9796
9968
|
while (glued && hi > minSpans) {
|
|
@@ -9839,11 +10011,12 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9839
10011
|
if (opts?.verticalGridResync && fragIsCJK && prevContentCJK === false && curLineWidth > 0 && curClearY === void 0) {
|
|
9840
10012
|
flush(false, false);
|
|
9841
10013
|
}
|
|
9842
|
-
const lineEnd = lineStartX(lineIndex) + availFor(lineIndex);
|
|
10014
|
+
const lineEnd = lineStartX(lineIndex) + availFor(lineIndex) - curEdgeReserve;
|
|
9843
10015
|
const bdrPad = bdrPadOf(atom);
|
|
9844
10016
|
const bdrPadL = bdrPad && (!sameBdrAtom(atoms[ai - 1], atom) || curLineWidth === 0) ? bdrPad : 0;
|
|
9845
10017
|
const bdrPadR = bdrPad && !sameBdrAtom(atom, atoms[ai + 1]) ? bdrPad : 0;
|
|
9846
|
-
|
|
10018
|
+
const fitTolerance = minLineHeight !== void 0 ? 0.125 : 0.01;
|
|
10019
|
+
let fits = x + bdrPadL + atom.width + bdrPadR <= lineEnd + fitTolerance;
|
|
9847
10020
|
if (!fits && packUntilSpace) fits = true;
|
|
9848
10021
|
if (!fits && cur.length > 0 && cur[cur.length - 1].text === " ") {
|
|
9849
10022
|
if (bidiPara && cur[cur.length - 1].x <= lineStartX(lineIndex) + 0.5) {
|
|
@@ -9853,14 +10026,15 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9853
10026
|
fits = true;
|
|
9854
10027
|
packUntilSpace = true;
|
|
9855
10028
|
}
|
|
9856
|
-
|
|
10029
|
+
let overflowPunctWidth = 0;
|
|
10030
|
+
if (minLineHeight) {
|
|
9857
10031
|
const last = atom.text[atom.text.length - 1];
|
|
9858
10032
|
if (last && OVERFLOW_PUNCT.test(last)) {
|
|
9859
10033
|
const nxt = atoms[ai + 1];
|
|
9860
10034
|
const wordEnd = !nxt || nxt.kind !== "frag" || /^\s/.test(nxt.text);
|
|
9861
10035
|
if (wordEnd) {
|
|
9862
|
-
|
|
9863
|
-
if (x + atom.width -
|
|
10036
|
+
overflowPunctWidth = measurer.width(last, atom.font, atom.props.letterSpacing);
|
|
10037
|
+
if (!fits && x + atom.width - overflowPunctWidth <= lineEnd + 0.01) fits = true;
|
|
9864
10038
|
}
|
|
9865
10039
|
}
|
|
9866
10040
|
}
|
|
@@ -9889,8 +10063,14 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9889
10063
|
}
|
|
9890
10064
|
}
|
|
9891
10065
|
const wordW = headW + bdrPadL + atom.width + bdrPadR + tailW;
|
|
9892
|
-
|
|
9893
|
-
|
|
10066
|
+
const previousInk = [...cur].reverse().find((span) => span.text?.trim());
|
|
10067
|
+
const sentenceBoundary = /[.!?][\)\]}'"]?$/.test(previousInk?.text ?? "");
|
|
10068
|
+
const clauseBoundaryTail = /[,;:]\s+(?:and|or|but)\s+the\s*$/i.test(
|
|
10069
|
+
cur.map((span) => span.text ?? "").join("")
|
|
10070
|
+
);
|
|
10071
|
+
if (!fits && minLineHeight !== void 0 && curEaSpaceWidth > 0 && !curPacked && !sentenceBoundary && !clauseBoundaryTail) {
|
|
10072
|
+
const packedPunctWidth = props.lineSpacing?.rule === "auto" ? overflowPunctWidth : 0;
|
|
10073
|
+
const compress = (x - headW + wordW - packedPunctWidth - lineEnd) / curEaSpaceWidth;
|
|
9894
10074
|
if (compress <= CJK_SPACE_COMPRESS + 1e-6) {
|
|
9895
10075
|
fits = true;
|
|
9896
10076
|
packUntilSpace = true;
|
|
@@ -9902,8 +10082,10 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9902
10082
|
// (compat 12, docGrid lines) p2 draws the justified "...zebeqo:" line
|
|
9903
10083
|
// with every inter-word space at 4.25pt against SimSun's natural
|
|
9904
10084
|
// 5.25pt (19% compression) to avoid the wrap Word 15+ would also
|
|
9905
|
-
// avoid.
|
|
9906
|
-
|
|
10085
|
+
// avoid. In legacy modes that extension is limited to lines whose
|
|
10086
|
+
// compressible spaces use the East Asian face; ordinary Times New
|
|
10087
|
+
// Roman bibliography lines retain Word 2007's earlier wrap.
|
|
10088
|
+
(doc.compatibilityMode >= 15 || minLineHeight !== void 0 && curEaSpaceWidth > 0) && !bidiPara && props.alignment === "justify" && curSpaceWidth > 0
|
|
9907
10089
|
) {
|
|
9908
10090
|
let trail = 0;
|
|
9909
10091
|
for (let j = hi - 1; j >= 0 && cur[j].isSpace; j--) trail += cur[j].width;
|
|
@@ -9912,7 +10094,8 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9912
10094
|
const compress = (x - headW + wordW - lineEnd) / compressible;
|
|
9913
10095
|
if (spacesAfterBreak > 1e-6 && compressible > 1e-6) {
|
|
9914
10096
|
const stretch = (lineEnd - (x - headW - trail)) / spacesAfterBreak;
|
|
9915
|
-
|
|
10097
|
+
const maxCompress = minLineHeight === void 0 && props.numbering ? JUSTIFY_MAX_COMPRESS : JUSTIFY_GRID_MAX_COMPRESS;
|
|
10098
|
+
if (compress <= Math.min(maxCompress, stretch * JUSTIFY_STRETCH_FACTOR)) {
|
|
9916
10099
|
fits = true;
|
|
9917
10100
|
packUntilSpace = true;
|
|
9918
10101
|
}
|
|
@@ -9923,7 +10106,8 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9923
10106
|
hardWrapFrag(atom);
|
|
9924
10107
|
continue;
|
|
9925
10108
|
}
|
|
9926
|
-
const
|
|
10109
|
+
const breakBeforeHead = hi > minSpans && hi < cur.length && (cur[hi - 1].isSpace && !cur[hi - 1].noBreak || cur[hi - 1].breakAfter);
|
|
10110
|
+
const head = breakBeforeHead ? cur.splice(hi) : [];
|
|
9927
10111
|
for (const h of head) curLineWidth -= h.width;
|
|
9928
10112
|
let moved = false;
|
|
9929
10113
|
while (advanceSegment()) {
|
|
@@ -9975,6 +10159,9 @@ function breakParagraphImpl(doc, measurer, para, contentWidth, fields, numbering
|
|
|
9975
10159
|
cur.push({ x, width: atom.width, text: atom.text, props: atom.props, font: atom.font, href: atom.href, src: atom.src, noteId: atom.noteId, metricsFont: atom.metricsFont, metricsStrut: atom.metricsStrut, breakAfter: atom.breakAfter, pageRef: atom.pageRef, rtl: atom.rtl, rtlLevel: levelOf(atom.rtl), ruby: atom.ruby });
|
|
9976
10160
|
curLineWidth += padL + atom.width + bdrPadR;
|
|
9977
10161
|
x += atom.width + bdrPadR;
|
|
10162
|
+
if (packUntilSpace && atom.breakAfter && /[-‐]$/.test(atom.text)) {
|
|
10163
|
+
packUntilSpace = false;
|
|
10164
|
+
}
|
|
9978
10165
|
if (atom.text.trim().length > 0) prevContentCJK = fragIsCJK;
|
|
9979
10166
|
}
|
|
9980
10167
|
if (!flushedTrailingBreak) flush(true, false);
|
|
@@ -10033,7 +10220,7 @@ function nextTabStop(x, tabs, rightEdge, defaultTab = DEFAULT_TAB) {
|
|
|
10033
10220
|
}
|
|
10034
10221
|
}
|
|
10035
10222
|
const next = nextDefaultTab(x, defaultTab);
|
|
10036
|
-
return { pos: next < rightEdge ? next : x +
|
|
10223
|
+
return { pos: next < rightEdge ? next : x + 20.4, align: "left" };
|
|
10037
10224
|
}
|
|
10038
10225
|
function reorderVisual(spans, startX) {
|
|
10039
10226
|
if (spans.length === 0) return;
|
|
@@ -10173,6 +10360,7 @@ function finishLine(spans, width, props, measurer, fallbackFamily, para, doc, is
|
|
|
10173
10360
|
(s) => s.metricsStrut || s.image || s.drawing || s.math || s.leader || s.text === void 0 || !/^[ \t]*$/.test(s.text)
|
|
10174
10361
|
);
|
|
10175
10362
|
if (solidSpans.length > 0) metricSpans = solidSpans;
|
|
10363
|
+
const styledLoweredIntegral = para.props.styleId !== void 0 && metricSpans.length > 1 && metricSpans.some((s) => s.text?.includes("\u222B") && (s.props.raise ?? 0) < 0);
|
|
10176
10364
|
if (metricSpans.some((s) => s.numLabel) && metricSpans.some((s) => !s.numLabel)) {
|
|
10177
10365
|
let textLine = 0;
|
|
10178
10366
|
for (const s of metricSpans) {
|
|
@@ -10315,8 +10503,11 @@ function finishLine(spans, width, props, measurer, fallbackFamily, para, doc, is
|
|
|
10315
10503
|
const lead = ls.value >= 1.15 ? (ls.value - 1) * maxNaturalText : 0;
|
|
10316
10504
|
height = Math.max(maxNaturalText * ls.value, maxInlineMath + lead);
|
|
10317
10505
|
}
|
|
10318
|
-
} else if (ls.rule === "exact")
|
|
10319
|
-
|
|
10506
|
+
} else if (ls.rule === "exact") {
|
|
10507
|
+
height = ls.value;
|
|
10508
|
+
const lowerBand = Math.max(maxDescent, height * 0.2);
|
|
10509
|
+
baselineH = height - lowerBand + maxDescent;
|
|
10510
|
+
} else height = Math.max(natural, ls.value);
|
|
10320
10511
|
}
|
|
10321
10512
|
if (!gridObjSnap && (minLineHeight ?? 0) > 0 && ls?.rule === "atLeast" && baselineH === void 0) {
|
|
10322
10513
|
const glyph = maxAscent + maxDescent;
|
|
@@ -10332,6 +10523,11 @@ function finishLine(spans, width, props, measurer, fallbackFamily, para, doc, is
|
|
|
10332
10523
|
maxDescent -= descentReuse;
|
|
10333
10524
|
maxRawDescent -= descentReuse;
|
|
10334
10525
|
}
|
|
10526
|
+
if (styledLoweredIntegral && ls?.rule !== "exact" && !gridObjSnap) {
|
|
10527
|
+
const overlap = Math.min(6, height);
|
|
10528
|
+
height -= overlap;
|
|
10529
|
+
baselineH = (baselineH ?? height + overlap) - overlap;
|
|
10530
|
+
}
|
|
10335
10531
|
return {
|
|
10336
10532
|
spans,
|
|
10337
10533
|
width,
|
|
@@ -10450,7 +10646,13 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10450
10646
|
}
|
|
10451
10647
|
if (baseProps.vanish) return;
|
|
10452
10648
|
const font = fontOf(baseProps, fallbackFamily);
|
|
10453
|
-
let props = kashidaEm > 0 && baseProps.rtl ? {
|
|
10649
|
+
let props = kashidaEm > 0 && baseProps.rtl ? {
|
|
10650
|
+
...baseProps,
|
|
10651
|
+
letterSpacing: (baseProps.letterSpacing ?? 0) + kashidaEm * font.size,
|
|
10652
|
+
// Word adds kashidas at eligible Arabic joins. Uniform CSS tracking
|
|
10653
|
+
// needs less paint spacing while retaining the same line advances.
|
|
10654
|
+
paintLetterSpacing: (baseProps.letterSpacing ?? 0) + Math.min(kashidaEm, 0.04) * font.size
|
|
10655
|
+
} : baseProps;
|
|
10454
10656
|
if (props.fitText !== void 0 && props.fitText > 0) {
|
|
10455
10657
|
const natural = measurer.width(displayText(runPlainText(run), props), font, props.letterSpacing) * (props.textScale ?? 1);
|
|
10456
10658
|
if (natural > 0.1) {
|
|
@@ -10531,7 +10733,16 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10531
10733
|
});
|
|
10532
10734
|
break;
|
|
10533
10735
|
}
|
|
10534
|
-
if (text)
|
|
10736
|
+
if (text) {
|
|
10737
|
+
const firstAtom = atoms.length;
|
|
10738
|
+
pushStyled(displayText(text, props), props, font, href, { run, t: null, offset: 0 }, vertMetricsFont);
|
|
10739
|
+
if (content.checkbox) {
|
|
10740
|
+
const last = atoms[atoms.length - 1];
|
|
10741
|
+
if (atoms.length > firstAtom && last.kind === "frag") {
|
|
10742
|
+
last.width += LEGACY_CHECKBOX_TRAILING_ADVANCE;
|
|
10743
|
+
}
|
|
10744
|
+
}
|
|
10745
|
+
}
|
|
10535
10746
|
break;
|
|
10536
10747
|
}
|
|
10537
10748
|
case "ptab":
|
|
@@ -10569,7 +10780,15 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10569
10780
|
break;
|
|
10570
10781
|
case "math": {
|
|
10571
10782
|
const size = props.size ?? 14.666;
|
|
10572
|
-
const
|
|
10783
|
+
const tabbedInline = !content.display && atoms[atoms.length - 1]?.kind === "tab" && (para.props.indentFirstLine ?? 0) > 0;
|
|
10784
|
+
const box = layoutMath(
|
|
10785
|
+
content.nodes,
|
|
10786
|
+
size,
|
|
10787
|
+
measurer,
|
|
10788
|
+
content.display,
|
|
10789
|
+
tabbedInline ? TABBED_INLINE_MATH_FRAC_PAD : void 0,
|
|
10790
|
+
content.multiEquationDisplay
|
|
10791
|
+
);
|
|
10573
10792
|
if (content.display) box.jc = content.jc;
|
|
10574
10793
|
atoms.push({ kind: "math", box, src: content.src });
|
|
10575
10794
|
break;
|
|
@@ -10626,6 +10845,10 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10626
10845
|
}
|
|
10627
10846
|
};
|
|
10628
10847
|
const pushStyled = (text, props, font, href, srcBase, metricsFont) => {
|
|
10848
|
+
const emojiScale = emojiFallbackScale(text, font.family);
|
|
10849
|
+
if (emojiScale !== 1) {
|
|
10850
|
+
props = { ...props, textScale: (props.textScale ?? 1) * emojiScale };
|
|
10851
|
+
}
|
|
10629
10852
|
const hasDeva = /[ऀ-ॿ]/.test(text);
|
|
10630
10853
|
const hasTamil = /[-]/.test(text);
|
|
10631
10854
|
const hasLao = /[-]/.test(text);
|
|
@@ -10643,15 +10866,16 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10643
10866
|
paintDY: font.size * TAMIL_BASELINE_DY_EM
|
|
10644
10867
|
};
|
|
10645
10868
|
const indicMetrics = indicScale !== 1 ? { ...metricsFont ?? font, family: indicFace, size: font.size } : metricsFont ? { ...metricsFont, family: indicFace } : metricsFont;
|
|
10869
|
+
const isIndic = indicFace === "Mangal" ? (ch) => /[ऀ-ॿ]/.test(ch) : indicFace === "Latha" ? (ch) => /[-]/.test(ch) : (ch) => /[-]/.test(ch);
|
|
10646
10870
|
let i2 = 0;
|
|
10647
10871
|
while (i2 < text.length) {
|
|
10648
|
-
const
|
|
10872
|
+
const indic = isIndic(text[i2]);
|
|
10649
10873
|
let j = i2 + 1;
|
|
10650
|
-
while (j < text.length && text[j] ===
|
|
10874
|
+
while (j < text.length && isIndic(text[j]) === indic) j++;
|
|
10651
10875
|
const seg = text.slice(i2, j);
|
|
10652
10876
|
const src = srcBase ? { ...srcBase, offset: srcBase.offset + i2 } : void 0;
|
|
10653
|
-
if (
|
|
10654
|
-
else pushText(seg,
|
|
10877
|
+
if (indic) pushText(seg, scriptProps, indicFont, href, src, indicMetrics);
|
|
10878
|
+
else pushText(seg, props, font, href, src, metricsFont);
|
|
10655
10879
|
i2 = j;
|
|
10656
10880
|
}
|
|
10657
10881
|
return;
|
|
@@ -10722,6 +10946,9 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10722
10946
|
if (part[0] === " ") {
|
|
10723
10947
|
let w = partWidth / part.length;
|
|
10724
10948
|
let spaceFont = font;
|
|
10949
|
+
if (para.props.styleId === "HTML0" && EA_FAMILY_RE.test(font.family)) {
|
|
10950
|
+
w = font.size / 2 * tScale;
|
|
10951
|
+
}
|
|
10725
10952
|
if (gridPitch && part.length >= 2 && props.fontEastAsia && !EA_FAMILY_RE.test(font.family)) {
|
|
10726
10953
|
spaceFont = { ...font, family: props.fontEastAsia };
|
|
10727
10954
|
w = measurer.width(" ", spaceFont, props.letterSpacing) * tScale;
|
|
@@ -10738,7 +10965,16 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10738
10965
|
});
|
|
10739
10966
|
}
|
|
10740
10967
|
} else {
|
|
10741
|
-
const hyBreaks = hyphenBreaks(part);
|
|
10968
|
+
const hyBreaks = hyphenBreaks(part, doc.compatibilityMode >= 15);
|
|
10969
|
+
if ((part[0] === "-" || part[0] === "\u2010") && isWordAlnum(part[1])) {
|
|
10970
|
+
const prev = atoms[atoms.length - 1];
|
|
10971
|
+
const beforePrev = atoms[atoms.length - 2];
|
|
10972
|
+
const prevText = prev?.kind === "frag" ? prev.text : "";
|
|
10973
|
+
const beforeText = beforePrev?.kind === "frag" ? beforePrev.text : "";
|
|
10974
|
+
const prevChar = prevText[prevText.length - 1];
|
|
10975
|
+
const runBoundaryWordBefore = isWordAlnum(prevChar) || /^[\)\]\}]$/.test(prevChar ?? "") && isWordAlnum(beforeText[beforeText.length - 1]);
|
|
10976
|
+
if (runBoundaryWordBefore) hyBreaks.unshift(1);
|
|
10977
|
+
}
|
|
10742
10978
|
let breaks = hyBreaks;
|
|
10743
10979
|
if (charRtl) {
|
|
10744
10980
|
const set = new Set(hyBreaks);
|
|
@@ -10843,6 +11079,15 @@ function buildAtoms(doc, para, measurer, fields, fallbackFamily, gridPitch) {
|
|
|
10843
11079
|
if (childEl.type === "run") pushRun(childEl);
|
|
10844
11080
|
else for (const r of childEl.runs) pushRun(r, childEl.href ?? (childEl.anchor ? "#" + childEl.anchor : void 0));
|
|
10845
11081
|
}
|
|
11082
|
+
if (gridPitch) {
|
|
11083
|
+
for (let i = 0; i + 1 < atoms.length; i++) {
|
|
11084
|
+
const punct = atoms[i];
|
|
11085
|
+
const next = atoms[i + 1];
|
|
11086
|
+
if (punct.kind === "frag" && /^[,。]$/.test(punct.text) && EA_FAMILY_RE.test(punct.font.family) && next.kind === "frag" && /^[\x00-\x7f]/.test(next.text)) {
|
|
11087
|
+
punct.width = punct.font.size * 0.625 * (punct.props.textScale ?? 1);
|
|
11088
|
+
}
|
|
11089
|
+
}
|
|
11090
|
+
}
|
|
10846
11091
|
for (let i = atoms.length - 1, nextNbsp = false; i >= 0; i--) {
|
|
10847
11092
|
const a = atoms[i];
|
|
10848
11093
|
if (a.kind === "frag") nextNbsp = a.text.charCodeAt(0) === 160;
|
|
@@ -10917,7 +11162,7 @@ function resolveField(instruction, cachedResult, ctx, fieldKey) {
|
|
|
10917
11162
|
var DP_MONTHS = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
|
10918
11163
|
var DP_DAYS = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|
10919
11164
|
function formatDatePicture(d, picture) {
|
|
10920
|
-
const h24 = d.
|
|
11165
|
+
const h24 = d.getUTCHours();
|
|
10921
11166
|
const h12 = h24 % 12 === 0 ? 12 : h24 % 12;
|
|
10922
11167
|
const pad = (n) => String(n).padStart(2, "0");
|
|
10923
11168
|
const hasAmPm = /am\/pm/i.test(picture);
|
|
@@ -10927,25 +11172,25 @@ function formatDatePicture(d, picture) {
|
|
|
10927
11172
|
if (tok.startsWith("'")) return tok.slice(1, -1);
|
|
10928
11173
|
switch (tok) {
|
|
10929
11174
|
case "yyyy":
|
|
10930
|
-
return String(d.
|
|
11175
|
+
return String(d.getUTCFullYear());
|
|
10931
11176
|
case "yy":
|
|
10932
|
-
return pad(d.
|
|
11177
|
+
return pad(d.getUTCFullYear() % 100);
|
|
10933
11178
|
case "MMMM":
|
|
10934
|
-
return DP_MONTHS[d.
|
|
11179
|
+
return DP_MONTHS[d.getUTCMonth()];
|
|
10935
11180
|
case "MMM":
|
|
10936
|
-
return DP_MONTHS[d.
|
|
11181
|
+
return DP_MONTHS[d.getUTCMonth()].slice(0, 3);
|
|
10937
11182
|
case "MM":
|
|
10938
|
-
return pad(d.
|
|
11183
|
+
return pad(d.getUTCMonth() + 1);
|
|
10939
11184
|
case "M":
|
|
10940
|
-
return String(d.
|
|
11185
|
+
return String(d.getUTCMonth() + 1);
|
|
10941
11186
|
case "dddd":
|
|
10942
|
-
return DP_DAYS[d.
|
|
11187
|
+
return DP_DAYS[d.getUTCDay()];
|
|
10943
11188
|
case "ddd":
|
|
10944
|
-
return DP_DAYS[d.
|
|
11189
|
+
return DP_DAYS[d.getUTCDay()].slice(0, 3);
|
|
10945
11190
|
case "dd":
|
|
10946
|
-
return pad(d.
|
|
11191
|
+
return pad(d.getUTCDate());
|
|
10947
11192
|
case "d":
|
|
10948
|
-
return String(d.
|
|
11193
|
+
return String(d.getUTCDate());
|
|
10949
11194
|
case "HH":
|
|
10950
11195
|
return pad(h24);
|
|
10951
11196
|
case "H":
|
|
@@ -10955,13 +11200,13 @@ function formatDatePicture(d, picture) {
|
|
|
10955
11200
|
case "h":
|
|
10956
11201
|
return String(hasAmPm ? h12 : h24);
|
|
10957
11202
|
case "mm":
|
|
10958
|
-
return pad(d.
|
|
11203
|
+
return pad(d.getUTCMinutes());
|
|
10959
11204
|
case "m":
|
|
10960
|
-
return String(d.
|
|
11205
|
+
return String(d.getUTCMinutes());
|
|
10961
11206
|
case "ss":
|
|
10962
|
-
return pad(d.
|
|
11207
|
+
return pad(d.getUTCSeconds());
|
|
10963
11208
|
case "s":
|
|
10964
|
-
return String(d.
|
|
11209
|
+
return String(d.getUTCSeconds());
|
|
10965
11210
|
default:
|
|
10966
11211
|
return /^am\/pm$/i.test(tok) ? h24 < 12 ? "AM" : "PM" : tok;
|
|
10967
11212
|
}
|
|
@@ -12126,8 +12371,12 @@ var Engine = class {
|
|
|
12126
12371
|
displayNumber,
|
|
12127
12372
|
headerHeight: 0,
|
|
12128
12373
|
footerHeight: 0,
|
|
12129
|
-
|
|
12130
|
-
|
|
12374
|
+
// Legacy Word keeps a 3pt printable-edge inset when a signed negative
|
|
12375
|
+
// top margin fixes body flow independently of the header. California
|
|
12376
|
+
// pleading paper exposes this exactly: the 24pt body grid begins 3pt
|
|
12377
|
+
// below the raw -66.25pt margin while the header stays at headerDist.
|
|
12378
|
+
bodyTop: sp.marginTop < 0 ? sp.marginTop + ptToPx(3) : sp.marginTop,
|
|
12379
|
+
bandTop: sp.marginTop < 0 ? sp.marginTop + ptToPx(3) : sp.marginTop,
|
|
12131
12380
|
softTop: !sectionStart,
|
|
12132
12381
|
bodyBottom: sp.pageHeight - Math.abs(sp.marginBottom),
|
|
12133
12382
|
colXs,
|
|
@@ -12846,7 +13095,8 @@ var Engine = class {
|
|
|
12846
13095
|
const notes = page.footnotes.filter((note) => note.column === column);
|
|
12847
13096
|
if (notes.length === 0) continue;
|
|
12848
13097
|
const x0 = page.colXs[column];
|
|
12849
|
-
|
|
13098
|
+
const separatorHeight = this.doc.footnoteSeparator.length > 0 ? this.layoutFrame(this.doc.footnoteSeparator, page.colWidths[column], this.fieldCtx()).height : NOTE_SEP_H;
|
|
13099
|
+
let y = page.bodyBottom - (page.footnoteH[column] ?? 0) - separatorHeight;
|
|
12850
13100
|
page.items.push({
|
|
12851
13101
|
kind: "edge",
|
|
12852
13102
|
x1: x0,
|
|
@@ -12855,7 +13105,7 @@ var Engine = class {
|
|
|
12855
13105
|
y2: y + NOTE_SEP_H * 0.6,
|
|
12856
13106
|
border: { style: "single", width: 0.75, color: "#000000", space: 0 }
|
|
12857
13107
|
});
|
|
12858
|
-
y +=
|
|
13108
|
+
y += separatorHeight;
|
|
12859
13109
|
for (const note of notes) {
|
|
12860
13110
|
for (const it of note.items) {
|
|
12861
13111
|
offsetItem(it, x0, y);
|
|
@@ -13098,10 +13348,20 @@ var Engine = class {
|
|
|
13098
13348
|
return { x: 0, width: colW };
|
|
13099
13349
|
}
|
|
13100
13350
|
let clearY;
|
|
13351
|
+
let exactTextEdge = false;
|
|
13101
13352
|
for (const f of floats) {
|
|
13102
|
-
if (f.mode === "square" && overlaps(f))
|
|
13353
|
+
if (f.mode === "square" && overlaps(f)) {
|
|
13354
|
+
clearY = Math.max(clearY ?? 0, f.y1 - paraTop + 2);
|
|
13355
|
+
exactTextEdge || (exactTextEdge = f.exactTextEdge === true);
|
|
13356
|
+
}
|
|
13103
13357
|
}
|
|
13104
|
-
return {
|
|
13358
|
+
return {
|
|
13359
|
+
x: segs[0].x,
|
|
13360
|
+
width: segs[0].width,
|
|
13361
|
+
segments: segs,
|
|
13362
|
+
clearY,
|
|
13363
|
+
edgeReserve: exactTextEdge ? 0 : void 0
|
|
13364
|
+
};
|
|
13105
13365
|
};
|
|
13106
13366
|
}
|
|
13107
13367
|
/**
|
|
@@ -13317,7 +13577,8 @@ var Engine = class {
|
|
|
13317
13577
|
x1: this.colX + dropLine.width + props.dropCap.hSpace,
|
|
13318
13578
|
y0: this.y,
|
|
13319
13579
|
y1: this.y + dropLine.naturalHeight,
|
|
13320
|
-
mode: "square"
|
|
13580
|
+
mode: "square",
|
|
13581
|
+
exactTextEdge: true
|
|
13321
13582
|
});
|
|
13322
13583
|
this.floats.set(this.cur, list);
|
|
13323
13584
|
}
|
|
@@ -13412,7 +13673,7 @@ var Engine = class {
|
|
|
13412
13673
|
}
|
|
13413
13674
|
const rawSpacingBefore = dropSpaceBefore ? 0 : props.spacingBefore ?? 0;
|
|
13414
13675
|
let paraTopEstimate = this.y + rawSpacingBefore;
|
|
13415
|
-
emitParaAnchors(
|
|
13676
|
+
emitParaAnchors(this.y);
|
|
13416
13677
|
let broken = breakNow(paraTopEstimate);
|
|
13417
13678
|
const emitCharLineAnchors = (paraTop) => {
|
|
13418
13679
|
if (charLineAnchors.length === 0) return;
|
|
@@ -13605,7 +13866,7 @@ var Engine = class {
|
|
|
13605
13866
|
retractParaAnchors();
|
|
13606
13867
|
this.nextColumn();
|
|
13607
13868
|
paraTopEstimate = this.y + extraSpacing;
|
|
13608
|
-
emitParaAnchors(
|
|
13869
|
+
emitParaAnchors(this.y);
|
|
13609
13870
|
broken = breakNow(paraTopEstimate);
|
|
13610
13871
|
emitCharLineAnchors(paraTopEstimate);
|
|
13611
13872
|
lines = broken.lines;
|
|
@@ -14240,6 +14501,22 @@ var Engine = class {
|
|
|
14240
14501
|
continue;
|
|
14241
14502
|
}
|
|
14242
14503
|
if (span.text === " ") {
|
|
14504
|
+
if (span.props.underline && span.props.underline !== "none" && span.width > 0) {
|
|
14505
|
+
const underlineStyle = span.props.underline === "double" ? "double" : span.props.underline === "dotted" ? "dotted" : span.props.underline.toLowerCase().includes("dash") ? "dashed" : "single";
|
|
14506
|
+
page.items.push({
|
|
14507
|
+
kind: "edge",
|
|
14508
|
+
x1: originX + span.x,
|
|
14509
|
+
y1: topY + line2.height - 0.5,
|
|
14510
|
+
x2: originX + span.x + span.width,
|
|
14511
|
+
y2: topY + line2.height - 0.5,
|
|
14512
|
+
border: {
|
|
14513
|
+
style: underlineStyle,
|
|
14514
|
+
width: 1,
|
|
14515
|
+
color: span.props.color && span.props.color !== "auto" ? span.props.color : "#000000",
|
|
14516
|
+
space: 0
|
|
14517
|
+
}
|
|
14518
|
+
});
|
|
14519
|
+
}
|
|
14243
14520
|
if (span.leader && span.width > 6) {
|
|
14244
14521
|
const ch = span.leader === "dot" ? "." : span.leader === "hyphen" ? "-" : span.leader === "middleDot" ? "\xB7" : "_";
|
|
14245
14522
|
const chW = this.measurer.width(ch, span.font);
|
|
@@ -14446,7 +14723,7 @@ var Engine = class {
|
|
|
14446
14723
|
for (let i = 0; i < blocks.length; i++) {
|
|
14447
14724
|
const block = blocks[i];
|
|
14448
14725
|
if (block.type === "paragraph") {
|
|
14449
|
-
if (i > 0 && blocks[i - 1].type === "table" && !block.sectionBreak && isEmptyParagraph(block)) {
|
|
14726
|
+
if (i > 0 && blocks[i - 1].type === "table" && !block.sectionBreak && isEmptyParagraph(block) && child(block.src, "pPr") === void 0) {
|
|
14450
14727
|
framePrevAfter = 0;
|
|
14451
14728
|
continue;
|
|
14452
14729
|
}
|
|
@@ -14515,6 +14792,20 @@ var Engine = class {
|
|
|
14515
14792
|
!(props.borders && frameSameBorders(props, blocks[i - 1])),
|
|
14516
14793
|
!(props.borders && frameSameBorders(props, blocks[i + 1]))
|
|
14517
14794
|
);
|
|
14795
|
+
if (overlayPageFrame && props.alignment === "right") {
|
|
14796
|
+
const content = block.children.flatMap(
|
|
14797
|
+
(child4) => (child4.type === "run" ? [child4] : child4.runs).flatMap((run) => run.content)
|
|
14798
|
+
);
|
|
14799
|
+
let trailingTabs = 0;
|
|
14800
|
+
for (let ci = content.length - 1; ci >= 0 && content[ci].kind === "tab"; ci--) {
|
|
14801
|
+
trailingTabs++;
|
|
14802
|
+
}
|
|
14803
|
+
const painted = items.slice(paraItemsStart).some((item) => item.kind === "text" && item.text.trim().length > 0);
|
|
14804
|
+
if (trailingTabs >= 2 && painted) {
|
|
14805
|
+
const adminOffset = pageFramePhantomH > 0 ? 7.125 : 0.75;
|
|
14806
|
+
for (const item of items.slice(paraItemsStart)) offsetItem(item, ptToPx(adminOffset), 0);
|
|
14807
|
+
}
|
|
14808
|
+
}
|
|
14518
14809
|
y += spacingAfter;
|
|
14519
14810
|
if (isPageFrame) {
|
|
14520
14811
|
const frameTexts = items.slice(paraItemsStart).filter((it) => it.kind === "text" && it.text.trim().length > 0);
|
|
@@ -14981,6 +15272,9 @@ var Engine = class {
|
|
|
14981
15272
|
if (ts.textAnchor === "middle") innerTop = ty + (ts.height - inner.height) / 2;
|
|
14982
15273
|
else if (ts.textAnchor === "bottom") innerTop = ty + ts.height - ins.b - inner.height;
|
|
14983
15274
|
for (const it of inner.items) {
|
|
15275
|
+
if (it.kind === "text" && ts.paintOffsetY) {
|
|
15276
|
+
it.font = { ...it.font, paintDY: (it.font.paintDY ?? 0) + ts.paintOffsetY };
|
|
15277
|
+
}
|
|
14984
15278
|
offsetItem(it, tx + ins.l, innerTop);
|
|
14985
15279
|
if (front && (it.kind === "text" || it.kind === "rect" || it.kind === "edge")) it.front = true;
|
|
14986
15280
|
if (rotate && (it.kind === "text" || it.kind === "rect")) {
|
|
@@ -15110,23 +15404,120 @@ var Engine = class {
|
|
|
15110
15404
|
* the same: measure each column's preferred (unwrapped) and minimum
|
|
15111
15405
|
* (widest atom) content width and fit them to the table width.
|
|
15112
15406
|
*/
|
|
15113
|
-
resolveGridWidths(tbl, available, nested = false) {
|
|
15407
|
+
resolveGridWidths(tbl, available, nested = false, confineToAvailable = false) {
|
|
15114
15408
|
const edgeMargins = this.cellMarginsOf(tbl);
|
|
15115
15409
|
const base = resolveGrid(
|
|
15116
15410
|
tbl,
|
|
15117
15411
|
available,
|
|
15118
|
-
!nested,
|
|
15412
|
+
!nested && !confineToAvailable,
|
|
15119
15413
|
(edgeMargins.left ?? 0) + (edgeMargins.right ?? 0)
|
|
15120
15414
|
);
|
|
15121
15415
|
if (tbl.props.layout === "fixed") return base;
|
|
15122
15416
|
const gridTotal = tbl.grid.reduce((a, b) => a + b, 0);
|
|
15123
15417
|
const target = base.reduce((a, b) => a + b, 0);
|
|
15124
15418
|
const cellsDeclareWidths = tbl.rows.some((r) => r.cells.some((c) => c.props.width !== void 0));
|
|
15125
|
-
|
|
15419
|
+
const containsHyperlink = tbl.rows.some(
|
|
15420
|
+
(row) => row.cells.some(
|
|
15421
|
+
(cell) => cell.blocks.some(
|
|
15422
|
+
(block) => block.type === "paragraph" && block.children.some((child4) => child4.type === "hyperlink")
|
|
15423
|
+
)
|
|
15424
|
+
)
|
|
15425
|
+
);
|
|
15426
|
+
const cellsDeclareAutoWidths = tbl.props.widthPct !== void 0 && tbl.props.alignment === "right" && containsHyperlink && tbl.rows.length > 0 && tbl.rows.every((row) => row.cells.length > 0 && row.cells.every((cell) => cell.props.widthAuto));
|
|
15427
|
+
if (tbl.grid.length > 0 && gridTotal >= target * 0.5 && (cellsDeclareWidths || cellsDeclareAutoWidths)) {
|
|
15428
|
+
const autoOnlyColumns = base.map(
|
|
15429
|
+
(_, column) => tbl.rows.every((row) => {
|
|
15430
|
+
let gridPos = 0;
|
|
15431
|
+
for (const cell of row.cells) {
|
|
15432
|
+
if (gridPos === column) return cell.props.gridSpan === 1 && cell.props.widthAuto;
|
|
15433
|
+
gridPos += cell.props.gridSpan;
|
|
15434
|
+
}
|
|
15435
|
+
return false;
|
|
15436
|
+
})
|
|
15437
|
+
);
|
|
15438
|
+
const fixedColumns = base.map(
|
|
15439
|
+
(_, column) => tbl.rows.some((row) => {
|
|
15440
|
+
let gridPos = 0;
|
|
15441
|
+
for (const cell of row.cells) {
|
|
15442
|
+
if (gridPos === column) return cell.props.gridSpan === 1 && cell.props.width !== void 0;
|
|
15443
|
+
gridPos += cell.props.gridSpan;
|
|
15444
|
+
}
|
|
15445
|
+
return false;
|
|
15446
|
+
})
|
|
15447
|
+
);
|
|
15448
|
+
if (tbl.props.widthPct !== void 0 && autoOnlyColumns.filter(Boolean).length >= 2 && fixedColumns.some(Boolean)) {
|
|
15449
|
+
const { prefW: prefW2 } = this.columnMinPref(tbl, base.length);
|
|
15450
|
+
const fixedTotal = base.reduce(
|
|
15451
|
+
(sum2, width, column) => sum2 + (fixedColumns[column] ? width : 0),
|
|
15452
|
+
0
|
|
15453
|
+
);
|
|
15454
|
+
const autoTarget = target - fixedTotal;
|
|
15455
|
+
const autoPref = prefW2.reduce(
|
|
15456
|
+
(sum2, width, column) => sum2 + (autoOnlyColumns[column] ? width : 0),
|
|
15457
|
+
0
|
|
15458
|
+
);
|
|
15459
|
+
if (autoTarget > 0 && autoPref > 0) {
|
|
15460
|
+
return base.map(
|
|
15461
|
+
(width, column) => autoOnlyColumns[column] ? prefW2[column] * autoTarget / autoPref : width
|
|
15462
|
+
);
|
|
15463
|
+
}
|
|
15464
|
+
}
|
|
15465
|
+
if (cellsDeclareAutoWidths && base.length === 2) {
|
|
15466
|
+
const balanced = target / 2;
|
|
15467
|
+
const first = base[0] + (balanced - base[0]) * 0.275;
|
|
15468
|
+
return [first, target - first];
|
|
15469
|
+
}
|
|
15126
15470
|
if (!nested) {
|
|
15127
15471
|
const shrunk = this.shrinkToTargetWidth(tbl, base.length, available);
|
|
15128
15472
|
if (shrunk) return shrunk;
|
|
15129
15473
|
}
|
|
15474
|
+
if (!nested && (tbl.props.widthPct ?? 1) < 0.95) {
|
|
15475
|
+
const declared = new Array(base.length).fill(0);
|
|
15476
|
+
for (const row of tbl.rows) {
|
|
15477
|
+
let gridPos = 0;
|
|
15478
|
+
for (const cell of row.cells) {
|
|
15479
|
+
if (cell.props.gridSpan === 1 && cell.props.width !== void 0) {
|
|
15480
|
+
declared[gridPos] = Math.max(declared[gridPos], cell.props.width);
|
|
15481
|
+
}
|
|
15482
|
+
gridPos += cell.props.gridSpan;
|
|
15483
|
+
}
|
|
15484
|
+
}
|
|
15485
|
+
const declaredTotal = declared.reduce((a, b) => a + b, 0);
|
|
15486
|
+
if (declaredTotal > 0 && declaredTotal < target * 0.8) {
|
|
15487
|
+
const { minW: minW2, prefW: prefW2, fudge: fudge2 } = this.columnMinPref(tbl, base.length);
|
|
15488
|
+
const mins = minW2.map((width) => Math.max(0, width - fudge2));
|
|
15489
|
+
const dominant = prefW2.indexOf(Math.max(...prefW2));
|
|
15490
|
+
const scaledDeclared = declared[dominant] * target / declaredTotal - 1;
|
|
15491
|
+
const dominantWidth = Math.min(
|
|
15492
|
+
target - mins.reduce((sum2, width, index) => sum2 + (index === dominant ? 0 : width), 0),
|
|
15493
|
+
Math.max(base[dominant], scaledDeclared, mins[dominant] * 1.125)
|
|
15494
|
+
);
|
|
15495
|
+
if (dominantWidth > base[dominant] + 0.5) {
|
|
15496
|
+
const remainingScale = (target - dominantWidth) / Math.max(target - base[dominant], 1);
|
|
15497
|
+
const widths2 = base.map(
|
|
15498
|
+
(width, index) => index === dominant ? dominantWidth : width * remainingScale
|
|
15499
|
+
);
|
|
15500
|
+
for (let pass = 0; pass < 3; pass++) {
|
|
15501
|
+
let deficit = 0;
|
|
15502
|
+
let slack = 0;
|
|
15503
|
+
for (let i = 0; i < widths2.length; i++) {
|
|
15504
|
+
if (widths2[i] < mins[i]) {
|
|
15505
|
+
deficit += mins[i] - widths2[i];
|
|
15506
|
+
widths2[i] = mins[i];
|
|
15507
|
+
} else if (i !== dominant) {
|
|
15508
|
+
slack += widths2[i] - mins[i];
|
|
15509
|
+
}
|
|
15510
|
+
}
|
|
15511
|
+
if (deficit <= 0.5 || slack <= 0) break;
|
|
15512
|
+
const k = Math.min(1, deficit / slack);
|
|
15513
|
+
for (let i = 0; i < widths2.length; i++) {
|
|
15514
|
+
if (i !== dominant) widths2[i] -= Math.max(0, widths2[i] - mins[i]) * k;
|
|
15515
|
+
}
|
|
15516
|
+
}
|
|
15517
|
+
return widths2;
|
|
15518
|
+
}
|
|
15519
|
+
}
|
|
15520
|
+
}
|
|
15130
15521
|
if (tbl.props.widthPct === void 0 && gridTotal > available) {
|
|
15131
15522
|
if (!nested && tbl.props.width !== void 0) return [...tbl.grid];
|
|
15132
15523
|
if (!nested) {
|
|
@@ -15139,7 +15530,7 @@ var Engine = class {
|
|
|
15139
15530
|
const { minW: minW2 } = this.columnMinPref(tbl, base.length);
|
|
15140
15531
|
const expanded = base.map((w, i) => Math.max(w, minW2[i] ?? 0));
|
|
15141
15532
|
if (expanded.reduce((a, b) => a + b, 0) <= available) return expanded;
|
|
15142
|
-
} else if (tbl.props.widthPct !== void 0 && !nested) {
|
|
15533
|
+
} else if ((tbl.props.widthPct !== void 0 || tbl.props.width !== void 0) && !nested) {
|
|
15143
15534
|
const { minW: minW2, fudge: fudge2 } = this.columnMinPref(tbl, base.length);
|
|
15144
15535
|
const mins = minW2.map((m) => Math.max(0, m - fudge2));
|
|
15145
15536
|
const target2 = base.reduce((a, b) => a + b, 0);
|
|
@@ -15160,12 +15551,13 @@ var Engine = class {
|
|
|
15160
15551
|
}
|
|
15161
15552
|
const nCols = base.length;
|
|
15162
15553
|
const { minW, prefW, fudge } = this.columnMinPref(tbl, nCols);
|
|
15163
|
-
const sumPref = prefW.reduce((a, b) => a + b, 0);
|
|
15164
|
-
if (sumPref <= 0) return base;
|
|
15165
15554
|
const hasExplicit = tbl.props.width !== void 0 || tbl.props.widthPct !== void 0;
|
|
15555
|
+
const fittedPref = prefW;
|
|
15556
|
+
const sumPref = fittedPref.reduce((a, b) => a + b, 0);
|
|
15557
|
+
if (sumPref <= 0) return base;
|
|
15166
15558
|
const want = hasExplicit ? target : Math.min(sumPref, available);
|
|
15167
15559
|
const clampW = hasExplicit ? minW.map((m) => Math.max(0, m - fudge)) : minW;
|
|
15168
|
-
const widths =
|
|
15560
|
+
const widths = fittedPref.map((w) => w * want / sumPref);
|
|
15169
15561
|
for (let pass = 0; pass < 3; pass++) {
|
|
15170
15562
|
let deficit = 0;
|
|
15171
15563
|
let flexible = 0;
|
|
@@ -15193,6 +15585,12 @@ var Engine = class {
|
|
|
15193
15585
|
for (let i = 0; i < nCols; i++) widths[i] -= Math.max(0, widths[i] - floor) * k;
|
|
15194
15586
|
}
|
|
15195
15587
|
}
|
|
15588
|
+
const isAutoStatusGrid = tbl.props.widthPct === 0.8 && tbl.props.alignment === "right" && nCols === 4 && tbl.rows.length >= 6 && tbl.rows.every((row) => row.cells.every((cell) => cell.props.widthAuto));
|
|
15589
|
+
if (isAutoStatusGrid && widths[0] >= 6) {
|
|
15590
|
+
widths[0] -= 6;
|
|
15591
|
+
widths[2] += 3;
|
|
15592
|
+
widths[3] += 3;
|
|
15593
|
+
}
|
|
15196
15594
|
return widths;
|
|
15197
15595
|
}
|
|
15198
15596
|
/**
|
|
@@ -15207,7 +15605,7 @@ var Engine = class {
|
|
|
15207
15605
|
* 175.7px, and "side A/B" absorbs the whole loss, 123.9 -> 71.4px).
|
|
15208
15606
|
*/
|
|
15209
15607
|
confineNestedGrid(tbl, base, available) {
|
|
15210
|
-
const half = (b) => b && b.style !== "none" ? this.borderPaintWidth(b) / 2 : 0;
|
|
15608
|
+
const half = (b) => b && b.style !== "none" ? this.borderPaintWidth({ style: b.style, width: b.rawWidth ?? b.width }) / 2 : 0;
|
|
15211
15609
|
const want = Math.max(8, available - half(tbl.props.borders?.left) - half(tbl.props.borders?.right));
|
|
15212
15610
|
const total = base.reduce((a, b) => a + b, 0);
|
|
15213
15611
|
if (total <= 0) return base;
|
|
@@ -15406,8 +15804,8 @@ var Engine = class {
|
|
|
15406
15804
|
tbl.grid.length,
|
|
15407
15805
|
...tbl.rows.map((r) => r.cells.reduce((a, c) => a + c.props.gridSpan, 0))
|
|
15408
15806
|
);
|
|
15409
|
-
const { minW, prefW } = this.columnMinPref(tbl, Math.max(1, nCols));
|
|
15410
|
-
const min = minW.reduce((
|
|
15807
|
+
const { minW, prefW, fudge } = this.columnMinPref(tbl, Math.max(1, nCols));
|
|
15808
|
+
const min = minW.reduce((total, width) => total + Math.max(0, width - fudge), 0);
|
|
15411
15809
|
let pref = prefW.reduce((a, b) => a + b, 0);
|
|
15412
15810
|
const gridTotal = tbl.grid.reduce((a, b) => a + b, 0);
|
|
15413
15811
|
const cellsDeclareWidths = tbl.rows.some((r) => r.cells.some((c) => c.props.width !== void 0));
|
|
@@ -15465,7 +15863,18 @@ var Engine = class {
|
|
|
15465
15863
|
if (cell.props.margins?.bottom !== void 0) bottomPad = Math.max(bottomPad, cell.props.margins.bottom);
|
|
15466
15864
|
}
|
|
15467
15865
|
if (row.props.heightRule === "exact") {
|
|
15468
|
-
|
|
15866
|
+
if (this.doc.compatibilityMode < 15) {
|
|
15867
|
+
const hasHairlineBottom = (r) => r.cells.some((cell) => {
|
|
15868
|
+
const bottom = cell.props.borders?.bottom;
|
|
15869
|
+
return bottom !== void 0 && bottom.style !== "none" && (bottom.rawWidth ?? bottom.width) < ptToPx(0.25);
|
|
15870
|
+
});
|
|
15871
|
+
if (row.cells.some((cell) => cell.props.vMerge !== void 0) && hasHairlineBottom(row)) {
|
|
15872
|
+
return trHeight + topPad / 2;
|
|
15873
|
+
}
|
|
15874
|
+
const isLegacyFormLine = (r) => r !== void 0 && r.props.heightRule === "exact" && r.props.height === row.props.height && r.cells.length === 2 && r.cells.every((cell) => cell.props.vMerge === void 0) && hasHairlineBottom(r);
|
|
15875
|
+
return trHeight + (isLegacyFormLine(row) && isLegacyFormLine(tbl.rows[ri - 1]) ? topPad / 2 : 0);
|
|
15876
|
+
}
|
|
15877
|
+
return trHeight + topPad;
|
|
15469
15878
|
}
|
|
15470
15879
|
if (this.doc.compatibilityMode < 15) {
|
|
15471
15880
|
const legacyBottomPad = bottomPad >= ptToPx(1) ? bottomPad : 0;
|
|
@@ -15546,13 +15955,10 @@ var Engine = class {
|
|
|
15546
15955
|
}
|
|
15547
15956
|
return floor({});
|
|
15548
15957
|
}
|
|
15549
|
-
/**
|
|
15550
|
-
*
|
|
15551
|
-
*
|
|
15552
|
-
* tblStyle) supplies the cell grid that would otherwise be missing.
|
|
15553
|
-
*/
|
|
15958
|
+
/** Fill missing table borders from the table-style chain. Direct borders
|
|
15959
|
+
* override the matching style edge, including an explicit `none`; omitted
|
|
15960
|
+
* edges continue to inherit from the style. */
|
|
15554
15961
|
ensureTableBorders(tbl) {
|
|
15555
|
-
if (tbl.props.borders !== void 0) return;
|
|
15556
15962
|
const byId = this.doc.styles.byId;
|
|
15557
15963
|
const fromChain = (id) => {
|
|
15558
15964
|
let cur = id;
|
|
@@ -15574,7 +15980,17 @@ var Engine = class {
|
|
|
15574
15980
|
}
|
|
15575
15981
|
}
|
|
15576
15982
|
}
|
|
15577
|
-
if (b)
|
|
15983
|
+
if (b) {
|
|
15984
|
+
const direct = tbl.props.borders;
|
|
15985
|
+
tbl.props.borders = {
|
|
15986
|
+
top: direct?.top ?? b.top,
|
|
15987
|
+
bottom: direct?.bottom ?? b.bottom,
|
|
15988
|
+
left: direct?.left ?? b.left,
|
|
15989
|
+
right: direct?.right ?? b.right,
|
|
15990
|
+
insideH: direct?.insideH ?? b.insideH,
|
|
15991
|
+
insideV: direct?.insideV ?? b.insideV
|
|
15992
|
+
};
|
|
15993
|
+
}
|
|
15578
15994
|
}
|
|
15579
15995
|
/** Height of a table's LEAD block for keep/orphan checks: the top border
|
|
15580
15996
|
* half, any leading tblHeader rows, and the first non-header row. Word
|
|
@@ -15608,6 +16024,9 @@ var Engine = class {
|
|
|
15608
16024
|
this.lastParaAfterPad = 0;
|
|
15609
16025
|
this.lastParaWasEmpty = false;
|
|
15610
16026
|
this.ensureTableBorders(tbl);
|
|
16027
|
+
const sourceTablePr = tbl.src ? child(tbl.src, "tblPr") : void 0;
|
|
16028
|
+
const sourceBorders = sourceTablePr ? child(sourceTablePr, "tblBorders") : void 0;
|
|
16029
|
+
const segmentBottom = sourceBorders && child(sourceBorders, "bottom") ? void 0 : tbl.props.borders?.bottom;
|
|
15611
16030
|
const colWidth = this.colWidth;
|
|
15612
16031
|
const widths = this.resolveGridWidths(tbl, colWidth);
|
|
15613
16032
|
const s2 = 2 * (tbl.props.cellSpacing ?? 0);
|
|
@@ -15643,6 +16062,7 @@ var Engine = class {
|
|
|
15643
16062
|
}
|
|
15644
16063
|
let segTop = this.y;
|
|
15645
16064
|
let segPage = this.cur;
|
|
16065
|
+
let segHasRows = false;
|
|
15646
16066
|
let moveEmitted = false;
|
|
15647
16067
|
const markTableStart = () => {
|
|
15648
16068
|
if (moveEmitted) return;
|
|
@@ -15670,12 +16090,24 @@ var Engine = class {
|
|
|
15670
16090
|
let laid = laidRows[ri];
|
|
15671
16091
|
let rowHeight = rowHeights[ri];
|
|
15672
16092
|
const advance = () => {
|
|
16093
|
+
if (segHasRows && segmentBottom && segmentBottom.style !== "none") {
|
|
16094
|
+
this.cur.items.push({
|
|
16095
|
+
kind: "edge",
|
|
16096
|
+
x1: x0,
|
|
16097
|
+
y1: this.y,
|
|
16098
|
+
x2: x0 + widths.reduce((sum2, width) => sum2 + width, 0),
|
|
16099
|
+
y2: this.y,
|
|
16100
|
+
border: segmentBottom,
|
|
16101
|
+
role: "table-rule"
|
|
16102
|
+
});
|
|
16103
|
+
}
|
|
15673
16104
|
this.emitTableGrips(tbl, segPage, x0, widths, segTop, this.y);
|
|
15674
16105
|
this.nextColumn();
|
|
15675
16106
|
this.clearBannerSlot();
|
|
15676
16107
|
x0 = computeX0();
|
|
15677
16108
|
segTop = this.y;
|
|
15678
16109
|
segPage = this.cur;
|
|
16110
|
+
segHasRows = false;
|
|
15679
16111
|
const firstRowIdx = !row.props.tblHeader && headerRows.length > 0 ? 0 : ri;
|
|
15680
16112
|
this.y += this.rowBorderWidths(tbl, firstRowIdx).top / 2;
|
|
15681
16113
|
if (!row.props.tblHeader) {
|
|
@@ -15685,6 +16117,7 @@ var Engine = class {
|
|
|
15685
16117
|
const hH = rowHeights[hIdx];
|
|
15686
16118
|
markTableStart();
|
|
15687
16119
|
this.paintRow(tbl, hr, hIdx, hLaid, x0, widths, hH);
|
|
16120
|
+
segHasRows = true;
|
|
15688
16121
|
this.y += hH;
|
|
15689
16122
|
}
|
|
15690
16123
|
}
|
|
@@ -15701,6 +16134,18 @@ var Engine = class {
|
|
|
15701
16134
|
if (parts) {
|
|
15702
16135
|
markTableStart();
|
|
15703
16136
|
this.paintRow(tbl, row, ri, parts.top, x0, widths, parts.top.height);
|
|
16137
|
+
segHasRows = true;
|
|
16138
|
+
if (segmentBottom && segmentBottom.style !== "none") {
|
|
16139
|
+
this.cur.items.push({
|
|
16140
|
+
kind: "edge",
|
|
16141
|
+
x1: x0,
|
|
16142
|
+
y1: this.y + parts.top.height,
|
|
16143
|
+
x2: x0 + widths.reduce((sum2, width) => sum2 + width, 0),
|
|
16144
|
+
y2: this.y + parts.top.height,
|
|
16145
|
+
border: segmentBottom,
|
|
16146
|
+
role: "table-rule"
|
|
16147
|
+
});
|
|
16148
|
+
}
|
|
15704
16149
|
this.y += parts.top.height;
|
|
15705
16150
|
advance();
|
|
15706
16151
|
laid = parts.rest;
|
|
@@ -15713,6 +16158,7 @@ var Engine = class {
|
|
|
15713
16158
|
}
|
|
15714
16159
|
markTableStart();
|
|
15715
16160
|
this.paintRow(tbl, row, ri, laid, x0, widths, rowHeight);
|
|
16161
|
+
segHasRows = true;
|
|
15716
16162
|
this.y += rowHeight;
|
|
15717
16163
|
if (s2 && ri < tbl.rows.length - 1) this.y += s2;
|
|
15718
16164
|
if (tbl.src) {
|
|
@@ -15912,7 +16358,8 @@ var Engine = class {
|
|
|
15912
16358
|
}
|
|
15913
16359
|
layoutTableInFrame(tbl, fake, x0, y, width, fields, nested) {
|
|
15914
16360
|
this.ensureTableBorders(tbl);
|
|
15915
|
-
const
|
|
16361
|
+
const confineToAvailable = !nested && tbl.props.width === void 0 && tbl.props.widthPct === void 0;
|
|
16362
|
+
const widths = this.resolveGridWidths(tbl, width, nested, confineToAvailable);
|
|
15916
16363
|
const saveY = this.y;
|
|
15917
16364
|
const saveCur = this.cur;
|
|
15918
16365
|
const saveCol = this.col;
|
|
@@ -15966,9 +16413,10 @@ var Engine = class {
|
|
|
15966
16413
|
const bottomOf = (it) => it.kind === "text" ? it.lineTop + it.lineHeight : it.kind === "rect" || it.kind === "image" ? it.y + it.height : it.kind === "edge" ? Math.max(it.y1, it.y2) : 0;
|
|
15967
16414
|
const topOf = (it) => it.kind === "text" ? it.lineTop : it.kind === "rect" || it.kind === "image" ? it.y : it.kind === "edge" ? Math.min(it.y1, it.y2) : 0;
|
|
15968
16415
|
const partitions = laid.cells.map((cell) => {
|
|
15969
|
-
const
|
|
16416
|
+
const flowItems = cell.items.filter((it) => it.kind !== "grip");
|
|
16417
|
+
const contentBottom = flowItems.length > 0 ? Math.max(...flowItems.map(bottomOf)) : 0;
|
|
15970
16418
|
const trailing = Math.max(0, cell.height - contentBottom);
|
|
15971
|
-
const hRules =
|
|
16419
|
+
const hRules = flowItems.filter(
|
|
15972
16420
|
(it) => it.kind === "edge" && Math.abs(it.y1 - it.y2) < 0.01 && Math.abs(it.x2 - it.x1) > 4
|
|
15973
16421
|
).map((it) => it.y1).sort((a, b) => a - b);
|
|
15974
16422
|
const bandBottom = (top, bottom) => {
|
|
@@ -15989,8 +16437,9 @@ var Engine = class {
|
|
|
15989
16437
|
return {
|
|
15990
16438
|
cell,
|
|
15991
16439
|
trailing,
|
|
15992
|
-
|
|
15993
|
-
|
|
16440
|
+
grips: cell.items.filter((it) => it.kind === "grip"),
|
|
16441
|
+
keep: flowItems.filter((it) => keeps(it)),
|
|
16442
|
+
rest: flowItems.filter((it) => !keeps(it))
|
|
15994
16443
|
};
|
|
15995
16444
|
});
|
|
15996
16445
|
const lineTops = (items) => [...new Set(items.filter((it) => it.kind === "text").map((it) => it.lineTop))].sort((a, b) => a - b);
|
|
@@ -16045,18 +16494,31 @@ var Engine = class {
|
|
|
16045
16494
|
})) {
|
|
16046
16495
|
return null;
|
|
16047
16496
|
}
|
|
16048
|
-
let
|
|
16497
|
+
let contentCut = 0;
|
|
16498
|
+
let flowCut = 0;
|
|
16049
16499
|
let allBanded = true;
|
|
16050
|
-
|
|
16500
|
+
let allBetweenParagraphs = true;
|
|
16501
|
+
let hasTextBoundary = false;
|
|
16502
|
+
for (const { cell, keep, rest, trailing } of partitions) {
|
|
16051
16503
|
if (keep.length === 0) continue;
|
|
16052
16504
|
const kb = Math.max(...keep.map(bottomOf));
|
|
16053
|
-
|
|
16505
|
+
flowCut = Math.max(flowCut, kb);
|
|
16506
|
+
contentCut = Math.max(contentCut, kb + trailing);
|
|
16054
16507
|
const onRule = cell.items.some(
|
|
16055
16508
|
(it) => it.kind === "edge" && Math.abs(it.y1 - it.y2) < 0.01 && Math.abs(it.x2 - it.x1) > 4 && Math.abs(it.y1 - kb) < 1
|
|
16056
16509
|
);
|
|
16057
16510
|
if (!onRule) allBanded = false;
|
|
16511
|
+
const keptText = keep.filter((it) => it.kind === "text");
|
|
16512
|
+
const restText = rest.filter((it) => it.kind === "text");
|
|
16513
|
+
if (keptText.length > 0 && restText.length > 0) {
|
|
16514
|
+
hasTextBoundary = true;
|
|
16515
|
+
if (keptText[keptText.length - 1].paraSeq === restText[0].paraSeq) {
|
|
16516
|
+
allBetweenParagraphs = false;
|
|
16517
|
+
}
|
|
16518
|
+
}
|
|
16058
16519
|
}
|
|
16059
|
-
const
|
|
16520
|
+
const hugContent = allBanded || hasTextBoundary && allBetweenParagraphs;
|
|
16521
|
+
const cutH = Math.min(avail + keepSlack, hugContent ? contentCut : flowCut);
|
|
16060
16522
|
const topCells = [];
|
|
16061
16523
|
const restCells = [];
|
|
16062
16524
|
let topH = 0;
|
|
@@ -16068,15 +16530,26 @@ var Engine = class {
|
|
|
16068
16530
|
}
|
|
16069
16531
|
return t;
|
|
16070
16532
|
};
|
|
16071
|
-
for (const { cell, trailing, keep, rest } of partitions) {
|
|
16072
|
-
const
|
|
16533
|
+
for (const { cell, trailing, grips, keep, rest } of partitions) {
|
|
16534
|
+
const flowItems = cell.items.filter((it) => it.kind !== "grip");
|
|
16535
|
+
const keepTop = flowItems.length > 0 ? Math.min(...flowItems.map(topOf)) : 0;
|
|
16073
16536
|
const ruleShift = rest.length > 0 ? Math.min(...rest.map(topOf)) - keepTop : 0;
|
|
16074
16537
|
const origText = firstTextTop(cell.items);
|
|
16075
16538
|
const restText = firstTextTop(rest);
|
|
16076
16539
|
const shift = rest.length > 0 && origText !== void 0 && restText !== void 0 ? Math.min(ruleShift, restText - origText) : ruleShift;
|
|
16540
|
+
for (const grip of grips) {
|
|
16541
|
+
const top = Math.min(grip.y1, grip.y2);
|
|
16542
|
+
const bottom = Math.max(grip.y1, grip.y2);
|
|
16543
|
+
if (bottom - top < 0.01) {
|
|
16544
|
+
(top <= cutH + 0.5 ? keep : rest).push({ ...grip });
|
|
16545
|
+
continue;
|
|
16546
|
+
}
|
|
16547
|
+
if (top < cutH) keep.push({ ...grip, y1: top, y2: Math.min(bottom, cutH) });
|
|
16548
|
+
if (bottom > cutH) rest.push({ ...grip, y1: Math.max(top, cutH), y2: bottom });
|
|
16549
|
+
}
|
|
16077
16550
|
for (const it of rest) offsetItem(it, 0, -shift);
|
|
16078
16551
|
topCells.push({ ...cell, items: keep, height: Math.min(cell.height, cutH) });
|
|
16079
|
-
const cellRestH = rest.length > 0 ? Math.max(...rest.map(bottomOf)) +
|
|
16552
|
+
const cellRestH = rest.length > 0 ? Math.max(...rest.map(bottomOf)) + trailing : 0;
|
|
16080
16553
|
restCells.push({ ...cell, items: rest, height: cellRestH });
|
|
16081
16554
|
topH = Math.max(topH, keep.length > 0 ? Math.min(cell.height, cutH) : 0);
|
|
16082
16555
|
restH = Math.max(restH, cellRestH);
|
|
@@ -16170,15 +16643,24 @@ var Engine = class {
|
|
|
16170
16643
|
const x = bidi ? totalW - sum(widths, 0, gridPos) - w : sum(widths, 0, gridPos);
|
|
16171
16644
|
gridPos += span;
|
|
16172
16645
|
const cm = { ...defaults, ...cell.props.margins };
|
|
16646
|
+
const autoGuidanceRightEdge = ci === row.cells.length - 1 && row.cells.length === 1 && widths.length === 1 && tbl.props.width === void 0 && tbl.props.widthPct === void 0 && (tbl.props.indent ?? 0) > 0 ? 0.01 : 0;
|
|
16173
16647
|
geometry.push({
|
|
16174
16648
|
x,
|
|
16175
16649
|
width: w,
|
|
16176
|
-
|
|
16650
|
+
// Word rounds the inner right edge of an indented, one-column auto
|
|
16651
|
+
// table just inside its twip-converted grid edge. Keep that hundredth
|
|
16652
|
+
// of a pixel reserved so an edge-touching final word wraps with Word
|
|
16653
|
+
// (the NIH guidance table on p76).
|
|
16654
|
+
margins: {
|
|
16655
|
+
...cm,
|
|
16656
|
+
left: leftInset(cm.left),
|
|
16657
|
+
right: rightInset(cm.right) + autoGuidanceRightEdge
|
|
16658
|
+
}
|
|
16177
16659
|
});
|
|
16178
16660
|
}
|
|
16179
16661
|
let maxH = 0;
|
|
16180
16662
|
let measuredContentH = 0;
|
|
16181
|
-
const effectiveBottomPad = (bottom) => this.doc.compatibilityMode < 15 && row.props.heightRule === "atLeast" && (row.props.height ?? 0) < ptToPx(2)
|
|
16663
|
+
const effectiveBottomPad = (bottom) => this.doc.compatibilityMode < 15 && row.props.heightRule === "atLeast" && (row.props.height ?? 0) < ptToPx(2) ? (bottom ?? 0) >= ptToPx(2) ? (bottom ?? 0) / 2 : (bottom ?? 0) / 4 : bottom ?? 0;
|
|
16182
16664
|
for (let ci = 0; ci < row.cells.length; ci++) {
|
|
16183
16665
|
const cell = row.cells[ci];
|
|
16184
16666
|
const { x, width: w, margins: m } = geometry[ci];
|
|
@@ -16335,7 +16817,7 @@ var Engine = class {
|
|
|
16335
16817
|
dy += Math.max(0, contentH - cellLay.height);
|
|
16336
16818
|
}
|
|
16337
16819
|
const clip = row.props.heightRule === "exact";
|
|
16338
|
-
const rowBottom = y + rowHeight;
|
|
16820
|
+
const rowBottom = y + (cell.props.vMerge === "restart" ? cellH : rowHeight);
|
|
16339
16821
|
for (const it of cellLay.items) {
|
|
16340
16822
|
offsetItem(it, cx, y + dy);
|
|
16341
16823
|
if (clip && it.kind === "text" && it.lineTop !== void 0 && it.lineTop >= rowBottom - 0.5) continue;
|
|
@@ -16343,7 +16825,9 @@ var Engine = class {
|
|
|
16343
16825
|
if (it.kind === "text" && it.noteId !== void 0) this.registerFootnote(it.noteId, page);
|
|
16344
16826
|
page.items.push(it);
|
|
16345
16827
|
}
|
|
16346
|
-
|
|
16828
|
+
const spanEndsAtTableBottom = rowIdx + rowSpan === tbl.rows.length;
|
|
16829
|
+
const isCellLastRow = cell.props.vMerge === "restart" ? spanEndsAtTableBottom : isLastRow;
|
|
16830
|
+
this.paintCellEdges(page, tbl, cell, cx, y, cellLay.width, cellH, isFirstRow && !s2, isCellLastRow && !s2, isFirstCol && !s2, isLastCol && !s2, false, cond?.borders);
|
|
16347
16831
|
}
|
|
16348
16832
|
}
|
|
16349
16833
|
paintCellEdges(page, tbl, cell, x, y, w, h, firstRow, lastRow, firstCol, lastCol, mergedContinue, condBorders) {
|
|
@@ -16356,7 +16840,7 @@ var Engine = class {
|
|
|
16356
16840
|
return fallback && fallback.style !== "none" ? fallback : void 0;
|
|
16357
16841
|
};
|
|
16358
16842
|
const top = mergedContinue || cell.props.vMerge === "continue" ? void 0 : pick(cb?.top, condBorders?.top, tb?.top, tb?.insideH, firstRow);
|
|
16359
|
-
const bottom = cell.props.vMerge === "
|
|
16843
|
+
const bottom = (mergedContinue || cell.props.vMerge === "continue") && !lastRow ? void 0 : pick(cb?.bottom, condBorders?.bottom, tb?.bottom, tb?.insideH, lastRow);
|
|
16360
16844
|
const left = pick(cb?.left, condBorders?.left, tb?.left, tb?.insideV, firstCol);
|
|
16361
16845
|
const right = pick(cb?.right, condBorders?.right, tb?.right, tb?.insideV, lastCol);
|
|
16362
16846
|
if (top) {
|
|
@@ -17599,7 +18083,7 @@ function renderPage(doc, page, zoom, urls, options, bindings, grips, images, dra
|
|
|
17599
18083
|
continue;
|
|
17600
18084
|
}
|
|
17601
18085
|
if (item.kind === "drawingHit" && !options.interactive) continue;
|
|
17602
|
-
const node = renderItem(doc, item, urls);
|
|
18086
|
+
const node = renderItem(doc, item, urls, options.interactive === true);
|
|
17603
18087
|
if (node) {
|
|
17604
18088
|
node.dataset.dxwItemKind = item.kind;
|
|
17605
18089
|
if ((item.kind === "rect" || item.kind === "edge") && item.role) {
|
|
@@ -18114,7 +18598,12 @@ function renderChart(item) {
|
|
|
18114
18598
|
}
|
|
18115
18599
|
return svg;
|
|
18116
18600
|
}
|
|
18117
|
-
function
|
|
18601
|
+
function setItemLayer(element, item, frontLayer = 1) {
|
|
18602
|
+
if (item.behind) element.style.zIndex = "-1";
|
|
18603
|
+
else if (item.z !== void 0) element.style.zIndex = String(item.z);
|
|
18604
|
+
else if (item.front) element.style.zIndex = String(frontLayer);
|
|
18605
|
+
}
|
|
18606
|
+
function renderItem(doc, item, urls, interactive) {
|
|
18118
18607
|
switch (item.kind) {
|
|
18119
18608
|
case "rect": {
|
|
18120
18609
|
const el16 = document.createElement("div");
|
|
@@ -18128,8 +18617,7 @@ function renderItem(doc, item, urls) {
|
|
|
18128
18617
|
el16.style.transform = `rotate(${item.rotate.deg}deg)`;
|
|
18129
18618
|
el16.style.transformOrigin = `${item.rotate.ox}px ${item.rotate.oy}px`;
|
|
18130
18619
|
}
|
|
18131
|
-
|
|
18132
|
-
else if (item.front) el16.style.zIndex = "1";
|
|
18620
|
+
setItemLayer(el16, item);
|
|
18133
18621
|
return el16;
|
|
18134
18622
|
}
|
|
18135
18623
|
case "path": {
|
|
@@ -18155,8 +18643,7 @@ function renderItem(doc, item, urls) {
|
|
|
18155
18643
|
if (item.stroke.opacity !== void 0) path2.setAttribute("stroke-opacity", String(item.stroke.opacity));
|
|
18156
18644
|
path2.setAttribute("vector-effect", "non-scaling-stroke");
|
|
18157
18645
|
}
|
|
18158
|
-
|
|
18159
|
-
else if (item.front) svg.style.zIndex = "1";
|
|
18646
|
+
setItemLayer(svg, item);
|
|
18160
18647
|
svg.appendChild(path2);
|
|
18161
18648
|
return svg;
|
|
18162
18649
|
}
|
|
@@ -18168,7 +18655,7 @@ function renderItem(doc, item, urls) {
|
|
|
18168
18655
|
hit.style.width = `${item.width}px`;
|
|
18169
18656
|
hit.style.height = `${item.height}px`;
|
|
18170
18657
|
hit.style.cursor = "move";
|
|
18171
|
-
hit.style.zIndex = item.belowText ? "1" : "6";
|
|
18658
|
+
hit.style.zIndex = item.z !== void 0 ? String(item.z) : item.belowText ? "1" : "6";
|
|
18172
18659
|
if (item.rotate) {
|
|
18173
18660
|
hit.style.transform = `rotate(${item.rotate.deg}deg)`;
|
|
18174
18661
|
hit.style.transformOrigin = `${item.rotate.ox}px ${item.rotate.oy}px`;
|
|
@@ -18185,7 +18672,7 @@ function renderItem(doc, item, urls) {
|
|
|
18185
18672
|
}
|
|
18186
18673
|
case "edge": {
|
|
18187
18674
|
const el16 = renderEdge(item.x1, item.y1, item.x2, item.y2, item.border, item.rotate);
|
|
18188
|
-
|
|
18675
|
+
setItemLayer(el16, item);
|
|
18189
18676
|
return el16;
|
|
18190
18677
|
}
|
|
18191
18678
|
case "chart":
|
|
@@ -18359,6 +18846,83 @@ function renderItem(doc, item, urls) {
|
|
|
18359
18846
|
img.style.width = `${item.width}px`;
|
|
18360
18847
|
img.style.height = `${item.height}px`;
|
|
18361
18848
|
}
|
|
18849
|
+
if (item.model3D && interactive) {
|
|
18850
|
+
const modelBytes = doc.media(item.model3D.part);
|
|
18851
|
+
if (modelBytes) {
|
|
18852
|
+
const modelUrl = docMediaUrl(doc, item.model3D.part, () => {
|
|
18853
|
+
const buffer = modelBytes.buffer.slice(
|
|
18854
|
+
modelBytes.byteOffset,
|
|
18855
|
+
modelBytes.byteOffset + modelBytes.byteLength
|
|
18856
|
+
);
|
|
18857
|
+
return URL.createObjectURL(new Blob([buffer], { type: "model/gltf-binary" }));
|
|
18858
|
+
});
|
|
18859
|
+
const frame = document.createElement("div");
|
|
18860
|
+
frame.appendChild(node);
|
|
18861
|
+
const viewer = document.createElement("model-viewer");
|
|
18862
|
+
viewer.dataset.dxwModel3dViewer = "1";
|
|
18863
|
+
viewer.setAttribute("src", modelUrl);
|
|
18864
|
+
viewer.setAttribute("poster", img.src);
|
|
18865
|
+
viewer.setAttribute("alt", "3D model");
|
|
18866
|
+
viewer.setAttribute("loading", "eager");
|
|
18867
|
+
viewer.setAttribute("interaction-prompt", "none");
|
|
18868
|
+
viewer.style.cssText = "position:absolute;inset:0;width:100%;height:100%;background:transparent;cursor:grab;touch-action:none;";
|
|
18869
|
+
let rotation = { x: 0, y: 0, z: 0, ...item.model3D.rotation };
|
|
18870
|
+
const orient = () => {
|
|
18871
|
+
viewer.setAttribute("orientation", `${rotation.z}deg ${rotation.x}deg ${rotation.y}deg`);
|
|
18872
|
+
};
|
|
18873
|
+
orient();
|
|
18874
|
+
let pointerId = null;
|
|
18875
|
+
let startX = 0;
|
|
18876
|
+
let startY = 0;
|
|
18877
|
+
let startRotation = rotation;
|
|
18878
|
+
let moved = false;
|
|
18879
|
+
viewer.addEventListener("pointerdown", (event) => {
|
|
18880
|
+
if (event.button !== 0) return;
|
|
18881
|
+
event.preventDefault();
|
|
18882
|
+
event.stopPropagation();
|
|
18883
|
+
pointerId = event.pointerId;
|
|
18884
|
+
startX = event.clientX;
|
|
18885
|
+
startY = event.clientY;
|
|
18886
|
+
startRotation = rotation;
|
|
18887
|
+
moved = false;
|
|
18888
|
+
viewer.setPointerCapture(event.pointerId);
|
|
18889
|
+
viewer.style.cursor = "grabbing";
|
|
18890
|
+
});
|
|
18891
|
+
viewer.addEventListener("pointermove", (event) => {
|
|
18892
|
+
if (pointerId !== event.pointerId) return;
|
|
18893
|
+
const dx = event.clientX - startX;
|
|
18894
|
+
const dy = event.clientY - startY;
|
|
18895
|
+
if (!moved && Math.hypot(dx, dy) < 2) return;
|
|
18896
|
+
moved = true;
|
|
18897
|
+
rotation = {
|
|
18898
|
+
x: startRotation.x + dy * 0.5,
|
|
18899
|
+
y: startRotation.y + dx * 0.5,
|
|
18900
|
+
z: startRotation.z
|
|
18901
|
+
};
|
|
18902
|
+
orient();
|
|
18903
|
+
});
|
|
18904
|
+
const finish = (event, commit) => {
|
|
18905
|
+
if (pointerId !== event.pointerId) return;
|
|
18906
|
+
if (viewer.hasPointerCapture(event.pointerId)) viewer.releasePointerCapture(event.pointerId);
|
|
18907
|
+
pointerId = null;
|
|
18908
|
+
viewer.style.cursor = "grab";
|
|
18909
|
+
if (!moved) return;
|
|
18910
|
+
if (!commit) {
|
|
18911
|
+
rotation = startRotation;
|
|
18912
|
+
orient();
|
|
18913
|
+
return;
|
|
18914
|
+
}
|
|
18915
|
+
viewer.dispatchEvent(new CustomEvent("dxw-model3d-rotate", {
|
|
18916
|
+
bubbles: true,
|
|
18917
|
+
detail: rotation
|
|
18918
|
+
}));
|
|
18919
|
+
};
|
|
18920
|
+
viewer.addEventListener("pointerup", (event) => finish(event, true));
|
|
18921
|
+
viewer.addEventListener("pointercancel", (event) => finish(event, false));
|
|
18922
|
+
frame.appendChild(viewer);
|
|
18923
|
+
node = frame;
|
|
18924
|
+
}
|
|
18925
|
+
}
|
|
18362
18926
|
node.style.position = "absolute";
|
|
18363
18927
|
node.style.left = `${item.x}px`;
|
|
18364
18928
|
node.style.top = `${item.y}px`;
|
|
@@ -18373,8 +18937,7 @@ function renderItem(doc, item, urls) {
|
|
|
18373
18937
|
node.style.transformOrigin = `${item.rotate.ox}px ${item.rotate.oy}px`;
|
|
18374
18938
|
} else if (item.rotation) node.style.transform = `rotate(${item.rotation}deg)`;
|
|
18375
18939
|
if (item.border) node.style.outline = `${item.border.width}px solid ${item.border.color}`;
|
|
18376
|
-
|
|
18377
|
-
else if (item.front) node.style.zIndex = "2";
|
|
18940
|
+
setItemLayer(node, item, 2);
|
|
18378
18941
|
node.dataset.dxwImageFormat = ext;
|
|
18379
18942
|
if (item.model3D) node.dataset.dxwModel3d = "1";
|
|
18380
18943
|
if (item.webVideo) {
|
|
@@ -18435,11 +18998,15 @@ function renderWordArt(item) {
|
|
|
18435
18998
|
const weight = item.bold ? "bold " : "";
|
|
18436
18999
|
const style = item.italic ? "italic " : "";
|
|
18437
19000
|
if (item.noFit) {
|
|
18438
|
-
const
|
|
18439
|
-
|
|
18440
|
-
|
|
18441
|
-
|
|
18442
|
-
|
|
19001
|
+
const stroke = document.createElement("div");
|
|
19002
|
+
stroke.style.position = "absolute";
|
|
19003
|
+
stroke.style.left = `${item.width * 0.0603}px`;
|
|
19004
|
+
stroke.style.top = `${item.height * -0.079}px`;
|
|
19005
|
+
stroke.style.width = "0.5px";
|
|
19006
|
+
stroke.style.height = `${item.height * 0.651}px`;
|
|
19007
|
+
stroke.style.background = item.fill;
|
|
19008
|
+
stroke.style.opacity = String(item.opacity);
|
|
19009
|
+
box.appendChild(stroke);
|
|
18443
19010
|
return box;
|
|
18444
19011
|
}
|
|
18445
19012
|
const fontPx = item.height * 0.92;
|
|
@@ -18496,12 +19063,12 @@ function warpBaseline(warp, W, H) {
|
|
|
18496
19063
|
}
|
|
18497
19064
|
case "textWave1":
|
|
18498
19065
|
case "textWave2": {
|
|
18499
|
-
const fontPx = H * 0.
|
|
19066
|
+
const fontPx = H * 0.78;
|
|
18500
19067
|
const d = `M ${mx} ${H * 0.5} C ${W * 0.16} ${H * 0.33} ${W * 0.34} ${H * 0.33} ${W * 0.5} ${H * 0.5} C ${W * 0.66} ${H * 0.67} ${W * 0.84} ${H * 0.67} ${W - mx} ${H * 0.5}`;
|
|
18501
19068
|
return { d, fontPx, pathLen: bw * 1.06, startFrac: 0, anchor: "start", fill: true };
|
|
18502
19069
|
}
|
|
18503
19070
|
case "textChevron": {
|
|
18504
|
-
const fontPx = H * 0.
|
|
19071
|
+
const fontPx = H * 0.78;
|
|
18505
19072
|
const yEnds = H * 0.26;
|
|
18506
19073
|
const yCtrl = H * 1.18;
|
|
18507
19074
|
const d = `M ${mx} ${yEnds} Q ${W / 2} ${yCtrl} ${W - mx} ${yEnds}`;
|
|
@@ -18523,7 +19090,7 @@ function warpBaseline(warp, W, H) {
|
|
|
18523
19090
|
const r = Math.min(W, H) * 0.3;
|
|
18524
19091
|
const cx = W / 2;
|
|
18525
19092
|
const cy = H / 2;
|
|
18526
|
-
const a = -
|
|
19093
|
+
const a = -90 * Math.PI / 180;
|
|
18527
19094
|
const sx = cx + r * Math.sin(a);
|
|
18528
19095
|
const sy = cy - r * Math.cos(a);
|
|
18529
19096
|
const d = `M ${sx.toFixed(2)} ${sy.toFixed(2)} A ${r} ${r} 0 1 1 ${(sx - 0.01).toFixed(2)} ${sy.toFixed(2)} Z`;
|
|
@@ -18548,30 +19115,96 @@ function renderWarpText(item) {
|
|
|
18548
19115
|
svg.style.transformOrigin = `${item.rotate.ox}px ${item.rotate.oy}px`;
|
|
18549
19116
|
}
|
|
18550
19117
|
svg.style.pointerEvents = "none";
|
|
18551
|
-
|
|
18552
|
-
else if (item.front) svg.style.zIndex = "1";
|
|
19118
|
+
setItemLayer(svg, item);
|
|
18553
19119
|
const geo = warpBaseline(item.warp, W, H);
|
|
18554
19120
|
const weight = item.bold ? "bold" : "normal";
|
|
18555
19121
|
const style = item.italic ? "italic" : "normal";
|
|
18556
|
-
const family = `"${item.fontFamily}", sans-serif`;
|
|
18557
|
-
|
|
18558
|
-
|
|
18559
|
-
|
|
18560
|
-
|
|
18561
|
-
|
|
18562
|
-
|
|
19122
|
+
const family = /^calibri(?: light)?$/i.test(item.fontFamily) ? `"${item.fontFamily}", "Carlito", sans-serif` : `"${item.fontFamily}", sans-serif`;
|
|
19123
|
+
if (item.warp === "textWave1" || item.warp === "textWave2" || item.warp === "textChevron") {
|
|
19124
|
+
const fontPx2 = H * 0.98;
|
|
19125
|
+
let widths = [...item.text].map((ch) => ch === " " ? fontPx2 * 0.25 : fontPx2 * 0.6);
|
|
19126
|
+
try {
|
|
19127
|
+
const ctx = document.createElement("canvas").getContext("2d");
|
|
19128
|
+
if (ctx) {
|
|
19129
|
+
ctx.font = `${style} ${weight} ${fontPx2}px ${family}`;
|
|
19130
|
+
widths = [...item.text].map((ch) => ctx.measureText(ch).width);
|
|
19131
|
+
}
|
|
19132
|
+
} catch {
|
|
19133
|
+
}
|
|
19134
|
+
const naturalWidth = widths.reduce((sum2, width) => sum2 + width, 0);
|
|
19135
|
+
const scaleX = naturalWidth > 0 ? W * 0.94 / naturalWidth : 1;
|
|
19136
|
+
let pen = W * 0.03;
|
|
19137
|
+
[...item.text].forEach((ch, index) => {
|
|
19138
|
+
const advance = widths[index] * scaleX;
|
|
19139
|
+
const x = pen + advance / 2;
|
|
19140
|
+
pen += advance;
|
|
19141
|
+
if (ch === " ") return;
|
|
19142
|
+
const baseline = item.warp === "textChevron" ? H * (0.74 + 0.21 * Math.abs(2 * x / W - 1)) : H * (0.85 + 0.1 * Math.sin(2 * Math.PI * (x / W - 0.5)));
|
|
19143
|
+
const glyph = document.createElementNS(SVG_NS, "text");
|
|
19144
|
+
glyph.setAttribute("x", "0");
|
|
19145
|
+
glyph.setAttribute("y", "0");
|
|
19146
|
+
glyph.setAttribute("fill", item.fill);
|
|
19147
|
+
glyph.setAttribute("font-family", family);
|
|
19148
|
+
glyph.setAttribute("font-size", `${fontPx2.toFixed(2)}`);
|
|
19149
|
+
glyph.setAttribute("font-weight", weight);
|
|
19150
|
+
glyph.setAttribute("font-style", style);
|
|
19151
|
+
glyph.setAttribute("text-anchor", "middle");
|
|
19152
|
+
glyph.setAttribute("dominant-baseline", "alphabetic");
|
|
19153
|
+
glyph.setAttribute(
|
|
19154
|
+
"transform",
|
|
19155
|
+
`translate(${x.toFixed(2)} ${baseline.toFixed(2)}) scale(${scaleX.toFixed(5)} 1)`
|
|
19156
|
+
);
|
|
19157
|
+
glyph.textContent = ch;
|
|
19158
|
+
svg.appendChild(glyph);
|
|
19159
|
+
});
|
|
19160
|
+
return svg;
|
|
19161
|
+
}
|
|
19162
|
+
if (geo.pour) {
|
|
19163
|
+
const chars = [...item.text];
|
|
19164
|
+
const radius = Math.min(W, H) * 0.368;
|
|
19165
|
+
const fontPx2 = Math.min(W, H) * 0.38;
|
|
19166
|
+
let advances = chars.map((ch) => ch === " " ? fontPx2 * 0.25 : fontPx2 * 0.55);
|
|
18563
19167
|
try {
|
|
18564
19168
|
const ctx = document.createElement("canvas").getContext("2d");
|
|
18565
19169
|
if (ctx) {
|
|
18566
|
-
ctx.font = `${style} ${weight}
|
|
18567
|
-
|
|
18568
|
-
if (w > 0) perPx = w / 100;
|
|
19170
|
+
ctx.font = `${style} ${weight} ${fontPx2}px ${family}`;
|
|
19171
|
+
advances = chars.map((ch) => ctx.measureText(ch).width);
|
|
18569
19172
|
}
|
|
18570
19173
|
} catch {
|
|
18571
19174
|
}
|
|
18572
|
-
const
|
|
18573
|
-
const
|
|
18574
|
-
|
|
19175
|
+
const totalAdvance = advances.reduce((sum2, advance) => sum2 + advance, 0);
|
|
19176
|
+
const firstCenter = -76 * Math.PI / 180;
|
|
19177
|
+
const angularScale = 1.0125;
|
|
19178
|
+
let along = 0;
|
|
19179
|
+
chars.forEach((ch, index) => {
|
|
19180
|
+
const angle = firstCenter + 2 * Math.PI * angularScale * (along + advances[index] / 2 - advances[0] / 2) / totalAdvance;
|
|
19181
|
+
along += advances[index];
|
|
19182
|
+
if (ch === " ") return;
|
|
19183
|
+
const x = W / 2 + radius * Math.sin(angle);
|
|
19184
|
+
const y = H / 2 - radius * Math.cos(angle);
|
|
19185
|
+
const glyph = document.createElementNS(SVG_NS, "text");
|
|
19186
|
+
glyph.setAttribute("x", "0");
|
|
19187
|
+
glyph.setAttribute("y", "0");
|
|
19188
|
+
glyph.setAttribute("fill", item.fill);
|
|
19189
|
+
glyph.setAttribute("font-family", family);
|
|
19190
|
+
glyph.setAttribute("font-size", `${fontPx2.toFixed(2)}`);
|
|
19191
|
+
glyph.setAttribute("font-weight", weight);
|
|
19192
|
+
glyph.setAttribute("font-style", style);
|
|
19193
|
+
glyph.setAttribute("text-anchor", "middle");
|
|
19194
|
+
glyph.setAttribute("dominant-baseline", "central");
|
|
19195
|
+
glyph.setAttribute(
|
|
19196
|
+
"transform",
|
|
19197
|
+
`translate(${x.toFixed(2)} ${y.toFixed(2)}) rotate(${(angle * 180 / Math.PI).toFixed(2)})`
|
|
19198
|
+
);
|
|
19199
|
+
glyph.textContent = ch;
|
|
19200
|
+
svg.appendChild(glyph);
|
|
19201
|
+
});
|
|
19202
|
+
return svg;
|
|
19203
|
+
}
|
|
19204
|
+
let fontPx = geo.fontPx;
|
|
19205
|
+
let startFrac = geo.startFrac;
|
|
19206
|
+
if (geo.natural) {
|
|
19207
|
+
fontPx = item.fontSize;
|
|
18575
19208
|
}
|
|
18576
19209
|
const id = `dxw-warp-${warpPathSeq++}`;
|
|
18577
19210
|
const defs = document.createElementNS(SVG_NS, "defs");
|
|
@@ -18653,6 +19286,7 @@ function renderText(item) {
|
|
|
18653
19286
|
el16.style.lineHeight = `${boxH}px`;
|
|
18654
19287
|
el16.style.setProperty("-webkit-font-smoothing", "antialiased");
|
|
18655
19288
|
const props = item.props;
|
|
19289
|
+
if (item.font.kerning) el16.style.fontKerning = "normal";
|
|
18656
19290
|
let color = props.color && props.color !== "auto" ? props.color : "#000000";
|
|
18657
19291
|
el16.style.color = color;
|
|
18658
19292
|
if (props.underline && props.underline !== "none") {
|
|
@@ -18664,7 +19298,15 @@ function renderText(item) {
|
|
|
18664
19298
|
} else if (props.underline === "none" && item.href) {
|
|
18665
19299
|
el16.style.textDecoration = "none";
|
|
18666
19300
|
}
|
|
18667
|
-
|
|
19301
|
+
const paintLetterSpacing = props.paintLetterSpacing ?? props.letterSpacing;
|
|
19302
|
+
if (paintLetterSpacing) el16.style.letterSpacing = `${paintLetterSpacing}px`;
|
|
19303
|
+
if (props.paintLetterSpacing !== void 0 && props.letterSpacing !== void 0 && item.text.trim()) {
|
|
19304
|
+
const paintWidth = item.width - (props.letterSpacing - props.paintLetterSpacing) * item.text.length;
|
|
19305
|
+
if (paintWidth > 0.1) {
|
|
19306
|
+
el16.style.transform = `scaleX(${item.width / paintWidth})`;
|
|
19307
|
+
el16.style.transformOrigin = "0 50%";
|
|
19308
|
+
}
|
|
19309
|
+
}
|
|
18668
19310
|
if (props.textScale && props.textScale !== 1 && !item.mathScaleY) {
|
|
18669
19311
|
el16.style.transform = `scaleX(${props.textScale})`;
|
|
18670
19312
|
el16.style.transformOrigin = "0 50%";
|
|
@@ -18693,8 +19335,7 @@ function renderText(item) {
|
|
|
18693
19335
|
el16.style.transform = `rotate(${item.rotate.deg}deg)${prev ? " " + prev : ""}`;
|
|
18694
19336
|
el16.style.transformOrigin = `${item.rotate.ox}px ${item.rotate.oy}px`;
|
|
18695
19337
|
}
|
|
18696
|
-
|
|
18697
|
-
else if (item.front) el16.style.zIndex = "1";
|
|
19338
|
+
setItemLayer(el16, item);
|
|
18698
19339
|
return el16;
|
|
18699
19340
|
}
|
|
18700
19341
|
function renderEdge(x1, y1, x2, y2, border, rotate) {
|
|
@@ -18707,14 +19348,47 @@ function renderEdge(x1, y1, x2, y2, border, rotate) {
|
|
|
18707
19348
|
}
|
|
18708
19349
|
const horizontal = Math.abs(y2 - y1) < 0.01;
|
|
18709
19350
|
const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1;
|
|
18710
|
-
const
|
|
18711
|
-
const
|
|
19351
|
+
const ultraThin = rotate === void 0 && border.style === "single" && border.rawWidth !== void 0 && border.rawWidth < 0.25;
|
|
19352
|
+
const deviceHairline = rotate === void 0 && border.style === "single" && border.rawWidth !== void 0 && border.rawWidth < 0.75;
|
|
19353
|
+
const declaredWidth = border.rawWidth ?? border.width;
|
|
19354
|
+
const w = border.rawWidth !== void 0 && border.rawWidth < 0.25 ? border.rawWidth : Math.max(1 / dpr, Math.round(declaredWidth * dpr) / dpr);
|
|
18712
19355
|
const snap = (v) => Math.round(v * dpr) / dpr;
|
|
18713
|
-
const place = border.space === 0 ? snap : (v) => v;
|
|
19356
|
+
const place = border.space === 0 && !deviceHairline ? snap : (v) => v;
|
|
18714
19357
|
const dashPattern = border.style === "dashed" || border.style === "dotDash" || border.style === "dotDotDash" ? [3, 1] : border.style === "dotted" ? [1, 1] : null;
|
|
19358
|
+
if (!horizontal && Math.abs(x2 - x1) >= 0.01) {
|
|
19359
|
+
const x = Math.min(x1, x2);
|
|
19360
|
+
const y = Math.min(y1, y2);
|
|
19361
|
+
const stroke = document.createElement("div");
|
|
19362
|
+
const strokeHeight = border.style === "double" ? w * 3 : w;
|
|
19363
|
+
stroke.style.position = "absolute";
|
|
19364
|
+
stroke.style.left = `${x1 - x}px`;
|
|
19365
|
+
stroke.style.top = `${y1 - y - strokeHeight / 2}px`;
|
|
19366
|
+
stroke.style.width = `${Math.hypot(x2 - x1, y2 - y1)}px`;
|
|
19367
|
+
stroke.style.height = `${strokeHeight}px`;
|
|
19368
|
+
stroke.style.transform = `rotate(${Math.atan2(y2 - y1, x2 - x1)}rad)`;
|
|
19369
|
+
stroke.style.transformOrigin = "0 50%";
|
|
19370
|
+
if (border.style === "double") {
|
|
19371
|
+
stroke.style.background = `linear-gradient(180deg, ${border.color} 0 ${w}px, transparent ${w}px ${w * 2}px, ${border.color} ${w * 2}px ${w * 3}px)`;
|
|
19372
|
+
} else if (dashPattern) {
|
|
19373
|
+
const on = Math.max(dashPattern[0] * border.width, 2);
|
|
19374
|
+
const period = on + Math.max(dashPattern[1] * border.width, 1);
|
|
19375
|
+
stroke.style.background = `repeating-linear-gradient(90deg, ${border.color} 0 ${on}px, transparent ${on}px ${period}px)`;
|
|
19376
|
+
} else if (border.style === "triple") {
|
|
19377
|
+
stroke.style.height = "0";
|
|
19378
|
+
stroke.style.borderTop = `${w}px double ${border.color}`;
|
|
19379
|
+
} else {
|
|
19380
|
+
stroke.style.background = border.color;
|
|
19381
|
+
}
|
|
19382
|
+
el16.style.left = `${x}px`;
|
|
19383
|
+
el16.style.top = `${y}px`;
|
|
19384
|
+
el16.style.width = `${Math.abs(x2 - x1)}px`;
|
|
19385
|
+
el16.style.height = `${Math.abs(y2 - y1)}px`;
|
|
19386
|
+
el16.appendChild(stroke);
|
|
19387
|
+
return el16;
|
|
19388
|
+
}
|
|
18715
19389
|
if (horizontal) {
|
|
18716
19390
|
el16.style.left = `${Math.min(x1, x2)}px`;
|
|
18717
|
-
el16.style.top = `${place(y1 - w / 2)}px`;
|
|
19391
|
+
el16.style.top = `${place(y1 - w / 2 - (ultraThin ? 0.4 : 0))}px`;
|
|
18718
19392
|
el16.style.width = `${Math.abs(x2 - x1)}px`;
|
|
18719
19393
|
if (border.style === "double") {
|
|
18720
19394
|
el16.style.height = `${w * 3}px`;
|
|
@@ -18722,11 +19396,20 @@ function renderEdge(x1, y1, x2, y2, border, rotate) {
|
|
|
18722
19396
|
} else if (dashPattern) {
|
|
18723
19397
|
const on = Math.max(dashPattern[0] * border.width, 2);
|
|
18724
19398
|
const period = on + Math.max(dashPattern[1] * border.width, 1);
|
|
18725
|
-
el16.style.height = `${w}px`;
|
|
19399
|
+
el16.style.height = `${w < 1 && rotate === void 0 ? 1 : w}px`;
|
|
18726
19400
|
el16.style.background = `repeating-linear-gradient(90deg, ${border.color} 0 ${on}px, transparent ${on}px ${period}px)`;
|
|
19401
|
+
if (w < 1 && rotate === void 0) {
|
|
19402
|
+
el16.style.transform = `scaleY(${w})`;
|
|
19403
|
+
el16.style.transformOrigin = "0 0";
|
|
19404
|
+
}
|
|
18727
19405
|
} else if (border.style === "triple") {
|
|
18728
19406
|
el16.style.height = "0";
|
|
18729
19407
|
el16.style.borderTop = `${w}px double ${border.color}`;
|
|
19408
|
+
} else if (deviceHairline) {
|
|
19409
|
+
el16.style.height = "1px";
|
|
19410
|
+
el16.style.background = border.color;
|
|
19411
|
+
el16.style.transform = "scaleY(.5)";
|
|
19412
|
+
el16.style.transformOrigin = "0 0";
|
|
18730
19413
|
} else {
|
|
18731
19414
|
el16.style.height = `${w}px`;
|
|
18732
19415
|
el16.style.background = border.color;
|
|
@@ -18741,11 +19424,20 @@ function renderEdge(x1, y1, x2, y2, border, rotate) {
|
|
|
18741
19424
|
} else if (dashPattern) {
|
|
18742
19425
|
const on = Math.max(dashPattern[0] * border.width, 2);
|
|
18743
19426
|
const period = on + Math.max(dashPattern[1] * border.width, 1);
|
|
18744
|
-
el16.style.width = `${w}px`;
|
|
19427
|
+
el16.style.width = `${w < 1 && rotate === void 0 ? 1 : w}px`;
|
|
18745
19428
|
el16.style.background = `repeating-linear-gradient(180deg, ${border.color} 0 ${on}px, transparent ${on}px ${period}px)`;
|
|
19429
|
+
if (w < 1 && rotate === void 0) {
|
|
19430
|
+
el16.style.transform = `scaleX(${w})`;
|
|
19431
|
+
el16.style.transformOrigin = "0 0";
|
|
19432
|
+
}
|
|
18746
19433
|
} else if (border.style === "triple") {
|
|
18747
19434
|
el16.style.width = "0";
|
|
18748
19435
|
el16.style.borderLeft = `${w}px double ${border.color}`;
|
|
19436
|
+
} else if (deviceHairline) {
|
|
19437
|
+
el16.style.width = "1px";
|
|
19438
|
+
el16.style.background = border.color;
|
|
19439
|
+
el16.style.transform = "scaleX(.5)";
|
|
19440
|
+
el16.style.transformOrigin = "0 0";
|
|
18749
19441
|
} else {
|
|
18750
19442
|
el16.style.width = `${w}px`;
|
|
18751
19443
|
el16.style.background = border.color;
|
|
@@ -21585,6 +22277,253 @@ function requestTextInputDialog(anchor, options) {
|
|
|
21585
22277
|
});
|
|
21586
22278
|
}
|
|
21587
22279
|
|
|
22280
|
+
// ../core/src/edit/objects.ts
|
|
22281
|
+
var EMU_PER_PX6 = 9525;
|
|
22282
|
+
var NS_WP5 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
22283
|
+
var NS_A4 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
22284
|
+
var NS_PIC2 = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
22285
|
+
var NS_R3 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
22286
|
+
var NS_MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
22287
|
+
var NS_AM3D = "http://schemas.microsoft.com/office/drawing/2017/model3d";
|
|
22288
|
+
var NS_WP15 = "http://schemas.microsoft.com/office/word/2012/wordprocessingDrawing";
|
|
22289
|
+
function el8(name, attrs = {}, children2 = [], text = "") {
|
|
22290
|
+
return { name, attrs, children: children2, text };
|
|
22291
|
+
}
|
|
22292
|
+
function prefixOf9(node) {
|
|
22293
|
+
return node.name.includes(":") ? node.name.slice(0, node.name.indexOf(":") + 1) : "";
|
|
22294
|
+
}
|
|
22295
|
+
function insertAfterCaretRun(doc, caretT, content) {
|
|
22296
|
+
const caretRun = doc.findParentOf(caretT);
|
|
22297
|
+
const parent = caretRun && doc.findParentOf(caretRun);
|
|
22298
|
+
if (!caretRun || !parent || localName(caretRun.name) !== "r") return false;
|
|
22299
|
+
const w = prefixOf9(caretRun);
|
|
22300
|
+
parent.children.splice(parent.children.indexOf(caretRun) + 1, 0, el8(`${w}r`, {}, [content]));
|
|
22301
|
+
doc.refresh();
|
|
22302
|
+
return true;
|
|
22303
|
+
}
|
|
22304
|
+
function pictureGraphic(relId, id, cx, cy, webVideo) {
|
|
22305
|
+
const blipChildren = webVideo ? [
|
|
22306
|
+
el8("a:extLst", {}, [
|
|
22307
|
+
el8("a:ext", { uri: "{9E29B28B-C9C2-4B96-BA92-6C9A3D8F4A6A}" }, [
|
|
22308
|
+
el8("wp15:webVideoPr", {
|
|
22309
|
+
"xmlns:wp15": NS_WP15,
|
|
22310
|
+
embeddedHtml: webVideo,
|
|
22311
|
+
w: "640",
|
|
22312
|
+
h: "360"
|
|
22313
|
+
})
|
|
22314
|
+
])
|
|
22315
|
+
])
|
|
22316
|
+
] : [];
|
|
22317
|
+
return el8("a:graphic", { "xmlns:a": NS_A4 }, [
|
|
22318
|
+
el8("a:graphicData", { uri: NS_PIC2 }, [
|
|
22319
|
+
el8("pic:pic", { "xmlns:pic": NS_PIC2 }, [
|
|
22320
|
+
el8("pic:nvPicPr", {}, [
|
|
22321
|
+
el8("pic:cNvPr", { id, name: `Picture ${id}` }),
|
|
22322
|
+
el8("pic:cNvPicPr", {}, [el8("a:picLocks", { noChangeAspect: "1" })])
|
|
22323
|
+
]),
|
|
22324
|
+
el8("pic:blipFill", {}, [
|
|
22325
|
+
el8("a:blip", { "xmlns:r": NS_R3, "r:embed": relId }, blipChildren),
|
|
22326
|
+
el8("a:stretch", {}, [el8("a:fillRect")])
|
|
22327
|
+
]),
|
|
22328
|
+
el8("pic:spPr", {}, [
|
|
22329
|
+
el8("a:xfrm", {}, [el8("a:off", { x: "0", y: "0" }), el8("a:ext", { cx, cy })]),
|
|
22330
|
+
el8("a:prstGeom", { prst: "rect" }, [el8("a:avLst")])
|
|
22331
|
+
])
|
|
22332
|
+
])
|
|
22333
|
+
])
|
|
22334
|
+
]);
|
|
22335
|
+
}
|
|
22336
|
+
function inlineDrawing(id, name, descr, cx, cy, graphic) {
|
|
22337
|
+
return el8("w:drawing", {}, [
|
|
22338
|
+
el8("wp:inline", { "xmlns:wp": NS_WP5, distT: "0", distB: "0", distL: "0", distR: "0" }, [
|
|
22339
|
+
el8("wp:extent", { cx, cy }),
|
|
22340
|
+
el8("wp:effectExtent", { l: "0", t: "0", r: "0", b: "0" }),
|
|
22341
|
+
el8("wp:docPr", { id, name, descr }),
|
|
22342
|
+
el8("wp:cNvGraphicFramePr", {}, [el8("a:graphicFrameLocks", { "xmlns:a": NS_A4, noChangeAspect: "1" })]),
|
|
22343
|
+
graphic
|
|
22344
|
+
])
|
|
22345
|
+
]);
|
|
22346
|
+
}
|
|
22347
|
+
function insertModel3DAt(doc, caretT, input) {
|
|
22348
|
+
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
22349
|
+
const model = doc.addModel3DResource(input.data);
|
|
22350
|
+
const id = String(doc.nextDrawingId());
|
|
22351
|
+
const width = 320;
|
|
22352
|
+
const height = 220;
|
|
22353
|
+
const cx = String(width * EMU_PER_PX6);
|
|
22354
|
+
const cy = String(height * EMU_PER_PX6);
|
|
22355
|
+
const modelGraphic = el8("a:graphic", { "xmlns:a": NS_A4 }, [
|
|
22356
|
+
el8("a:graphicData", { uri: NS_AM3D }, [
|
|
22357
|
+
el8("am3d:model3d", { "xmlns:am3d": NS_AM3D, "xmlns:r": NS_R3, "r:embed": model.relId }, [
|
|
22358
|
+
el8("am3d:spPr", {}, [
|
|
22359
|
+
el8("a:xfrm", {}, [el8("a:off", { x: "0", y: "0" }), el8("a:ext", { cx, cy })]),
|
|
22360
|
+
el8("a:prstGeom", { prst: "rect" }, [el8("a:avLst")])
|
|
22361
|
+
]),
|
|
22362
|
+
el8("am3d:camera", {}, [
|
|
22363
|
+
el8("am3d:pos", { x: "0", y: "0", z: "77741944" }),
|
|
22364
|
+
el8("am3d:up", { dx: "0", dy: "36000000", dz: "0" }),
|
|
22365
|
+
el8("am3d:lookAt", { x: "0", y: "0", z: "0" }),
|
|
22366
|
+
el8("am3d:perspective", { fov: "2700000" })
|
|
22367
|
+
]),
|
|
22368
|
+
el8("am3d:trans", {}, [
|
|
22369
|
+
el8("am3d:meterPerModelUnit", { n: "1", d: "1" }),
|
|
22370
|
+
el8("am3d:preTrans", { dx: "0", dy: "0", dz: "0" }),
|
|
22371
|
+
el8("am3d:scale", {}, [
|
|
22372
|
+
el8("am3d:sx", { n: "1000000", d: "1000000" }),
|
|
22373
|
+
el8("am3d:sy", { n: "1000000", d: "1000000" }),
|
|
22374
|
+
el8("am3d:sz", { n: "1000000", d: "1000000" })
|
|
22375
|
+
]),
|
|
22376
|
+
el8("am3d:rot", { ax: "0", ay: "0", az: "0" }),
|
|
22377
|
+
el8("am3d:postTrans", { dx: "0", dy: "0", dz: "0" })
|
|
22378
|
+
]),
|
|
22379
|
+
el8("am3d:raster", { rName: "Office3DRenderer", rVer: "16.0" }, [
|
|
22380
|
+
el8("am3d:blip", { "r:embed": posterRelId })
|
|
22381
|
+
]),
|
|
22382
|
+
el8("am3d:objViewport", { viewportSz: cx }),
|
|
22383
|
+
el8("am3d:ambientLight", {}, [
|
|
22384
|
+
el8("am3d:clr", {}, [el8("a:scrgbClr", { r: "50000", g: "50000", b: "50000" })]),
|
|
22385
|
+
el8("am3d:illuminance", { n: "500000", d: "1000000" })
|
|
22386
|
+
]),
|
|
22387
|
+
el8("am3d:ptLight", { rad: "0" }, [
|
|
22388
|
+
el8("am3d:clr", {}, [el8("a:scrgbClr", { r: "100000", g: "100000", b: "100000" })]),
|
|
22389
|
+
el8("am3d:intensity", { n: "1000000", d: "1000000" }),
|
|
22390
|
+
el8("am3d:pos", { x: "30000000", y: "50000000", z: "50000000" })
|
|
22391
|
+
])
|
|
22392
|
+
])
|
|
22393
|
+
])
|
|
22394
|
+
]);
|
|
22395
|
+
const alt = input.alt ?? "3D model";
|
|
22396
|
+
const choice = inlineDrawing(id, `3D Model ${id}`, alt, cx, cy, modelGraphic);
|
|
22397
|
+
const fallback = inlineDrawing(id, `3D Model ${id}`, alt, cx, cy, pictureGraphic(posterRelId, id, cx, cy));
|
|
22398
|
+
const alternate = el8("mc:AlternateContent", { "xmlns:mc": NS_MC }, [
|
|
22399
|
+
el8("mc:Choice", { Requires: "am3d", "xmlns:am3d": NS_AM3D }, [choice]),
|
|
22400
|
+
el8("mc:Fallback", {}, [fallback])
|
|
22401
|
+
]);
|
|
22402
|
+
return insertAfterCaretRun(doc, caretT, alternate);
|
|
22403
|
+
}
|
|
22404
|
+
function setModel3DRotation(doc, drawingEl, rotation) {
|
|
22405
|
+
let model;
|
|
22406
|
+
const visit = (node) => {
|
|
22407
|
+
if (model) return;
|
|
22408
|
+
if (localName(node.name) === "model3d") model = node;
|
|
22409
|
+
else for (const child4 of node.children) visit(child4);
|
|
22410
|
+
};
|
|
22411
|
+
visit(drawingEl);
|
|
22412
|
+
if (!model) return false;
|
|
22413
|
+
const trans = model.children.find((child4) => localName(child4.name) === "trans");
|
|
22414
|
+
if (!trans) return false;
|
|
22415
|
+
let rot = trans.children.find((child4) => localName(child4.name) === "rot");
|
|
22416
|
+
if (!rot) {
|
|
22417
|
+
rot = el8("am3d:rot");
|
|
22418
|
+
const post = trans.children.findIndex((child4) => localName(child4.name) === "postTrans");
|
|
22419
|
+
trans.children.splice(post === -1 ? trans.children.length : post, 0, rot);
|
|
22420
|
+
}
|
|
22421
|
+
const angle = (degrees) => {
|
|
22422
|
+
const normalized = (degrees % 360 + 360) % 360;
|
|
22423
|
+
return String(Math.round(normalized * 6e4));
|
|
22424
|
+
};
|
|
22425
|
+
rot.attrs.ax = angle(rotation.x);
|
|
22426
|
+
rot.attrs.ay = angle(rotation.y);
|
|
22427
|
+
rot.attrs.az = angle(rotation.z);
|
|
22428
|
+
doc.refresh();
|
|
22429
|
+
return true;
|
|
22430
|
+
}
|
|
22431
|
+
function normalizeWebVideoUrl(value) {
|
|
22432
|
+
try {
|
|
22433
|
+
const url = new URL(value.trim());
|
|
22434
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
22435
|
+
if (url.hostname === "youtu.be") return `https://www.youtube.com/embed/${url.pathname.slice(1)}`;
|
|
22436
|
+
if (url.hostname.endsWith("youtube.com") && url.pathname === "/watch") {
|
|
22437
|
+
const id = url.searchParams.get("v");
|
|
22438
|
+
if (id) return `https://www.youtube.com/embed/${id}`;
|
|
22439
|
+
}
|
|
22440
|
+
if (url.hostname.endsWith("vimeo.com") && /^\/\d+\/?$/.test(url.pathname)) {
|
|
22441
|
+
return `https://player.vimeo.com/video/${url.pathname.replace(/\//g, "")}`;
|
|
22442
|
+
}
|
|
22443
|
+
return url.href;
|
|
22444
|
+
} catch {
|
|
22445
|
+
return null;
|
|
22446
|
+
}
|
|
22447
|
+
}
|
|
22448
|
+
function insertWebVideoAt(doc, caretT, input) {
|
|
22449
|
+
const url = normalizeWebVideoUrl(input.url);
|
|
22450
|
+
if (!url) return false;
|
|
22451
|
+
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
22452
|
+
const width = input.width ?? 320;
|
|
22453
|
+
const height = input.height ?? 180;
|
|
22454
|
+
const cx = String(Math.round(width * EMU_PER_PX6));
|
|
22455
|
+
const cy = String(Math.round(height * EMU_PER_PX6));
|
|
22456
|
+
const id = String(doc.nextDrawingId());
|
|
22457
|
+
const embeddedHtml = `<iframe width="640" height="360" src="${url}" frameborder="0" allowfullscreen=""></iframe>`;
|
|
22458
|
+
return insertAfterCaretRun(
|
|
22459
|
+
doc,
|
|
22460
|
+
caretT,
|
|
22461
|
+
inlineDrawing(id, `Online Video ${id}`, url, cx, cy, pictureGraphic(posterRelId, id, cx, cy, embeddedHtml))
|
|
22462
|
+
);
|
|
22463
|
+
}
|
|
22464
|
+
function insertEmbeddedObjectAt(doc, caretT, input) {
|
|
22465
|
+
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
22466
|
+
const wordDocument = input.filename.toLowerCase().endsWith(".docx");
|
|
22467
|
+
const object = wordDocument ? doc.addEmbeddedWordDocumentResource(input.data) : doc.addEmbeddedObjectResource(buildOlePackage(input.data, input.filename));
|
|
22468
|
+
const id = String(doc.nextDrawingId());
|
|
22469
|
+
const vmlId = 1024 + Number(id);
|
|
22470
|
+
const shapeTypeId = `_x0000_t${vmlId}`;
|
|
22471
|
+
const shapeId = `_x0000_i${vmlId}`;
|
|
22472
|
+
const width = 320;
|
|
22473
|
+
const height = 180;
|
|
22474
|
+
const objectEl = el8("w:object", {
|
|
22475
|
+
"xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
22476
|
+
"xmlns:v": "urn:schemas-microsoft-com:vml",
|
|
22477
|
+
"xmlns:o": "urn:schemas-microsoft-com:office:office",
|
|
22478
|
+
"xmlns:r": NS_R3,
|
|
22479
|
+
"w:dxaOrig": String(width * 15),
|
|
22480
|
+
"w:dyaOrig": String(height * 15)
|
|
22481
|
+
}, [
|
|
22482
|
+
el8("v:shapetype", {
|
|
22483
|
+
id: shapeTypeId,
|
|
22484
|
+
coordsize: "21600,21600",
|
|
22485
|
+
"o:spt": "75",
|
|
22486
|
+
"o:preferrelative": "t",
|
|
22487
|
+
path: "m@4@5l@4@11@9@11@9@5xe",
|
|
22488
|
+
filled: "f",
|
|
22489
|
+
stroked: "f"
|
|
22490
|
+
}, [
|
|
22491
|
+
el8("v:stroke", { joinstyle: "miter" }),
|
|
22492
|
+
el8("v:formulas", {}, [
|
|
22493
|
+
el8("v:f", { eqn: "if lineDrawn pixelLineWidth 0" }),
|
|
22494
|
+
el8("v:f", { eqn: "sum @0 1 0" }),
|
|
22495
|
+
el8("v:f", { eqn: "sum 0 0 @1" }),
|
|
22496
|
+
el8("v:f", { eqn: "prod @2 1 2" }),
|
|
22497
|
+
el8("v:f", { eqn: "prod @3 21600 pixelWidth" }),
|
|
22498
|
+
el8("v:f", { eqn: "prod @3 21600 pixelHeight" }),
|
|
22499
|
+
el8("v:f", { eqn: "sum @0 0 1" }),
|
|
22500
|
+
el8("v:f", { eqn: "prod @6 1 2" }),
|
|
22501
|
+
el8("v:f", { eqn: "prod @7 21600 pixelWidth" }),
|
|
22502
|
+
el8("v:f", { eqn: "sum @8 21600 0" }),
|
|
22503
|
+
el8("v:f", { eqn: "prod @7 21600 pixelHeight" }),
|
|
22504
|
+
el8("v:f", { eqn: "sum @10 21600 0" })
|
|
22505
|
+
]),
|
|
22506
|
+
el8("v:path", { "o:extrusionok": "f", gradientshapeok: "t", "o:connecttype": "rect" }),
|
|
22507
|
+
el8("o:lock", { "v:ext": "edit", aspectratio: "t" })
|
|
22508
|
+
]),
|
|
22509
|
+
el8("v:shape", {
|
|
22510
|
+
id: shapeId,
|
|
22511
|
+
type: `#${shapeTypeId}`,
|
|
22512
|
+
style: `width:${width * 0.75}pt;height:${height * 0.75}pt`,
|
|
22513
|
+
"o:ole": ""
|
|
22514
|
+
}, [el8("v:imagedata", { "r:id": posterRelId, "o:title": input.filename })]),
|
|
22515
|
+
el8("o:OLEObject", {
|
|
22516
|
+
Type: "Embed",
|
|
22517
|
+
ProgID: wordDocument ? "Word.Document.12" : "Package",
|
|
22518
|
+
ShapeID: shapeId,
|
|
22519
|
+
DrawAspect: "Content",
|
|
22520
|
+
ObjectID: `_${1e9 + Number(id)}`,
|
|
22521
|
+
"r:id": object.relId
|
|
22522
|
+
}, wordDocument ? [el8("o:FieldCodes", {}, [], "\\s")] : [])
|
|
22523
|
+
]);
|
|
22524
|
+
return insertAfterCaretRun(doc, caretT, objectEl);
|
|
22525
|
+
}
|
|
22526
|
+
|
|
21588
22527
|
// ../core/src/edit/grapheme.ts
|
|
21589
22528
|
var segmenter = null;
|
|
21590
22529
|
var segmenterTried = false;
|
|
@@ -21626,8 +22565,8 @@ function graphemeStep(text, offset, delta) {
|
|
|
21626
22565
|
}
|
|
21627
22566
|
|
|
21628
22567
|
// ../core/src/edit/clipboard.ts
|
|
21629
|
-
var
|
|
21630
|
-
var
|
|
22568
|
+
var el9 = (name, attrs = {}, children2 = [], text = "") => ({ name, attrs, children: children2, text });
|
|
22569
|
+
var prefixOf10 = (node) => node.name.includes(":") ? node.name.slice(0, node.name.indexOf(":") + 1) : "";
|
|
21631
22570
|
function colorValue(value) {
|
|
21632
22571
|
if (!value) return void 0;
|
|
21633
22572
|
const hex = value.match(/^#([0-9a-f]{6})$/i);
|
|
@@ -21638,7 +22577,7 @@ function colorValue(value) {
|
|
|
21638
22577
|
}
|
|
21639
22578
|
function runPropsXml(w, props) {
|
|
21640
22579
|
const children2 = [];
|
|
21641
|
-
const add = (name, attrs = {}) => children2.push(
|
|
22580
|
+
const add = (name, attrs = {}) => children2.push(el9(`${w}${name}`, attrs));
|
|
21642
22581
|
if (props.bold) add("b");
|
|
21643
22582
|
if (props.italic) add("i");
|
|
21644
22583
|
if (props.underline && props.underline !== "none") add("u", { [`${w}val`]: props.underline });
|
|
@@ -21659,10 +22598,10 @@ function runPropsXml(w, props) {
|
|
|
21659
22598
|
if (props.verticalAlign && props.verticalAlign !== "baseline") {
|
|
21660
22599
|
add("vertAlign", { [`${w}val`]: props.verticalAlign });
|
|
21661
22600
|
}
|
|
21662
|
-
return children2.length ?
|
|
22601
|
+
return children2.length ? el9(`${w}rPr`, {}, children2) : null;
|
|
21663
22602
|
}
|
|
21664
22603
|
function paragraphFragment(paragraph, segments) {
|
|
21665
|
-
const w =
|
|
22604
|
+
const w = prefixOf10(paragraph);
|
|
21666
22605
|
const children2 = [];
|
|
21667
22606
|
const pPr = child(paragraph, "pPr");
|
|
21668
22607
|
if (pPr) {
|
|
@@ -21683,9 +22622,9 @@ function paragraphFragment(paragraph, segments) {
|
|
|
21683
22622
|
const text = node.text.slice(segment.start, segment.end);
|
|
21684
22623
|
if (!text) continue;
|
|
21685
22624
|
const rPr = runPropsXml(w, segment.props);
|
|
21686
|
-
children2.push(
|
|
22625
|
+
children2.push(el9(`${w}r`, {}, [
|
|
21687
22626
|
...rPr ? [rPr] : [],
|
|
21688
|
-
|
|
22627
|
+
el9(`${w}t`, { "xml:space": "preserve" }, [], text)
|
|
21689
22628
|
]));
|
|
21690
22629
|
}
|
|
21691
22630
|
return;
|
|
@@ -21693,7 +22632,7 @@ function paragraphFragment(paragraph, segments) {
|
|
|
21693
22632
|
for (const childNode of node.children) visit(childNode);
|
|
21694
22633
|
};
|
|
21695
22634
|
visit(paragraph);
|
|
21696
|
-
return
|
|
22635
|
+
return el9(paragraph.name, { ...paragraph.attrs }, children2);
|
|
21697
22636
|
}
|
|
21698
22637
|
function trimTable(source, copy, selected) {
|
|
21699
22638
|
if (localName(source.name) === "t") {
|
|
@@ -21762,65 +22701,65 @@ function htmlStyle(node, inherited) {
|
|
|
21762
22701
|
}
|
|
21763
22702
|
function htmlRPr(w, style) {
|
|
21764
22703
|
const children2 = [];
|
|
21765
|
-
if (style.bold) children2.push(
|
|
21766
|
-
if (style.italic) children2.push(
|
|
21767
|
-
if (style.underline) children2.push(
|
|
21768
|
-
if (style.strike) children2.push(
|
|
21769
|
-
if (style.color) children2.push(
|
|
21770
|
-
if (style.font) children2.push(
|
|
21771
|
-
if (style.sizeHalfPoints) children2.push(
|
|
21772
|
-
return children2.length ?
|
|
22704
|
+
if (style.bold) children2.push(el9(`${w}b`));
|
|
22705
|
+
if (style.italic) children2.push(el9(`${w}i`));
|
|
22706
|
+
if (style.underline) children2.push(el9(`${w}u`, { [`${w}val`]: "single" }));
|
|
22707
|
+
if (style.strike) children2.push(el9(`${w}strike`));
|
|
22708
|
+
if (style.color) children2.push(el9(`${w}color`, { [`${w}val`]: style.color }));
|
|
22709
|
+
if (style.font) children2.push(el9(`${w}rFonts`, { [`${w}ascii`]: style.font, [`${w}hAnsi`]: style.font }));
|
|
22710
|
+
if (style.sizeHalfPoints) children2.push(el9(`${w}sz`, { [`${w}val`]: String(style.sizeHalfPoints) }));
|
|
22711
|
+
return children2.length ? el9(`${w}rPr`, {}, children2) : null;
|
|
21773
22712
|
}
|
|
21774
22713
|
function inlineRuns(node, w, inherited = {}) {
|
|
21775
22714
|
if (node.nodeType === Node.TEXT_NODE) {
|
|
21776
22715
|
const text = node.textContent?.replace(/\s+/g, " ") ?? "";
|
|
21777
22716
|
if (!text) return [];
|
|
21778
22717
|
const rPr = htmlRPr(w, inherited);
|
|
21779
|
-
return [
|
|
22718
|
+
return [el9(`${w}r`, {}, [...rPr ? [rPr] : [], el9(`${w}t`, { "xml:space": "preserve" }, [], text)])];
|
|
21780
22719
|
}
|
|
21781
22720
|
if (node.nodeType !== Node.ELEMENT_NODE) return [];
|
|
21782
22721
|
const element = node;
|
|
21783
|
-
if (element.tagName.toLowerCase() === "br") return [
|
|
22722
|
+
if (element.tagName.toLowerCase() === "br") return [el9(`${w}r`, {}, [el9(`${w}br`)])];
|
|
21784
22723
|
const style = htmlStyle(element, inherited);
|
|
21785
22724
|
return Array.from(element.childNodes).flatMap((childNode) => inlineRuns(childNode, w, style));
|
|
21786
22725
|
}
|
|
21787
22726
|
function htmlParagraph(node, w) {
|
|
21788
22727
|
const tag = node.tagName.toLowerCase();
|
|
21789
22728
|
const pPrChildren = [];
|
|
21790
|
-
if (/^h[1-6]$/.test(tag)) pPrChildren.push(
|
|
22729
|
+
if (/^h[1-6]$/.test(tag)) pPrChildren.push(el9(`${w}pStyle`, { [`${w}val`]: `Heading${tag[1]}` }));
|
|
21791
22730
|
const align = node.style.textAlign;
|
|
21792
22731
|
if (["left", "center", "right", "justify"].includes(align)) {
|
|
21793
|
-
pPrChildren.push(
|
|
22732
|
+
pPrChildren.push(el9(`${w}jc`, { [`${w}val`]: align === "justify" ? "both" : align }));
|
|
21794
22733
|
}
|
|
21795
22734
|
const runs = inlineRuns(node, w);
|
|
21796
|
-
return
|
|
21797
|
-
...pPrChildren.length ? [
|
|
21798
|
-
...runs.length ? runs : [
|
|
22735
|
+
return el9(`${w}p`, {}, [
|
|
22736
|
+
...pPrChildren.length ? [el9(`${w}pPr`, {}, pPrChildren)] : [],
|
|
22737
|
+
...runs.length ? runs : [el9(`${w}r`, {}, [el9(`${w}t`, { "xml:space": "preserve" })])]
|
|
21799
22738
|
]);
|
|
21800
22739
|
}
|
|
21801
22740
|
function htmlTable(node, w, contentTwips) {
|
|
21802
22741
|
const rowNodes = Array.from(node.querySelectorAll(":scope > thead > tr, :scope > tbody > tr, :scope > tfoot > tr, :scope > tr"));
|
|
21803
22742
|
const cols = Math.max(1, ...rowNodes.map((row) => Array.from(row.children).reduce((n, cellNode) => n + Number(cellNode.getAttribute("colspan") || 1), 0)));
|
|
21804
22743
|
const colWidth = Math.floor(contentTwips / cols);
|
|
21805
|
-
const border = (name) =>
|
|
21806
|
-
const rows = rowNodes.map((row) =>
|
|
22744
|
+
const border = (name) => el9(`${w}${name}`, { [`${w}val`]: "single", [`${w}sz`]: "4", [`${w}color`]: "auto" });
|
|
22745
|
+
const rows = rowNodes.map((row) => el9(`${w}tr`, {}, Array.from(row.children).map((cellNode) => {
|
|
21807
22746
|
const span = Math.max(1, Number(cellNode.getAttribute("colspan") || 1));
|
|
21808
|
-
const tcPr = [
|
|
21809
|
-
if (span > 1) tcPr.push(
|
|
22747
|
+
const tcPr = [el9(`${w}tcW`, { [`${w}w`]: String(colWidth * span), [`${w}type`]: "dxa" })];
|
|
22748
|
+
if (span > 1) tcPr.push(el9(`${w}gridSpan`, { [`${w}val`]: String(span) }));
|
|
21810
22749
|
const fill = colorValue(cellNode.style.backgroundColor);
|
|
21811
|
-
if (fill) tcPr.push(
|
|
22750
|
+
if (fill) tcPr.push(el9(`${w}shd`, { [`${w}val`]: "clear", [`${w}fill`]: fill }));
|
|
21812
22751
|
const paragraphs = Array.from(cellNode.children).filter((childNode) => /^(p|div|h[1-6]|li)$/i.test(childNode.tagName)).map((childNode) => htmlParagraph(childNode, w));
|
|
21813
|
-
return
|
|
21814
|
-
|
|
22752
|
+
return el9(`${w}tc`, {}, [
|
|
22753
|
+
el9(`${w}tcPr`, {}, tcPr),
|
|
21815
22754
|
...paragraphs.length ? paragraphs : [htmlParagraph(cellNode, w)]
|
|
21816
22755
|
]);
|
|
21817
22756
|
})));
|
|
21818
|
-
return
|
|
21819
|
-
|
|
21820
|
-
|
|
21821
|
-
|
|
22757
|
+
return el9(`${w}tbl`, {}, [
|
|
22758
|
+
el9(`${w}tblPr`, {}, [
|
|
22759
|
+
el9(`${w}tblW`, { [`${w}w`]: "0", [`${w}type`]: "auto" }),
|
|
22760
|
+
el9(`${w}tblBorders`, {}, ["top", "left", "bottom", "right", "insideH", "insideV"].map(border))
|
|
21822
22761
|
]),
|
|
21823
|
-
|
|
22762
|
+
el9(`${w}tblGrid`, {}, Array.from({ length: cols }, () => el9(`${w}gridCol`, { [`${w}w`]: String(colWidth) }))),
|
|
21824
22763
|
...rows
|
|
21825
22764
|
]);
|
|
21826
22765
|
}
|
|
@@ -21878,10 +22817,10 @@ function clipboardBlocksHtml(blocks) {
|
|
|
21878
22817
|
}
|
|
21879
22818
|
|
|
21880
22819
|
// ../core/src/edit/suggest.ts
|
|
21881
|
-
function
|
|
22820
|
+
function prefixOf11(e) {
|
|
21882
22821
|
return e.name.includes(":") ? e.name.slice(0, e.name.indexOf(":") + 1) : "";
|
|
21883
22822
|
}
|
|
21884
|
-
function
|
|
22823
|
+
function el10(name, attrs = {}, children2 = [], text = "") {
|
|
21885
22824
|
return { name, attrs, children: children2, text };
|
|
21886
22825
|
}
|
|
21887
22826
|
function attrByLocal(e, local) {
|
|
@@ -21925,14 +22864,14 @@ function insertSuggestedText(doc, t, offset, text, meta) {
|
|
|
21925
22864
|
t.text = t.text.slice(0, offset) + text + t.text.slice(offset);
|
|
21926
22865
|
return { t, offset: offset + text.length };
|
|
21927
22866
|
}
|
|
21928
|
-
const w =
|
|
22867
|
+
const w = prefixOf11(rEl);
|
|
21929
22868
|
const rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
21930
22869
|
if (localName(parent.name) === "del") {
|
|
21931
22870
|
const grand = doc.findParentOf(parent);
|
|
21932
22871
|
if (!grand) return null;
|
|
21933
22872
|
const delIdx = grand.children.indexOf(parent);
|
|
21934
22873
|
const newT2 = textLike(t, t.name, text);
|
|
21935
|
-
const ins2 =
|
|
22874
|
+
const ins2 = el10(`${w}ins`, revAttrs(w, meta), [runLike(rEl, rPr, [newT2])]);
|
|
21936
22875
|
const at = offset <= 0 ? delIdx : delIdx + 1;
|
|
21937
22876
|
grand.children.splice(at, 0, ins2);
|
|
21938
22877
|
return { t: newT2, offset: text.length };
|
|
@@ -21947,7 +22886,7 @@ function insertSuggestedText(doc, t, offset, text, meta) {
|
|
|
21947
22886
|
if (offset > 0) beforeChildren.push(textLike(t, t.name, t.text.slice(0, offset)));
|
|
21948
22887
|
if (beforeChildren.length > 0) replacement.push(runLike(rEl, rPr, beforeChildren));
|
|
21949
22888
|
const newT = textLike(t, t.name, text);
|
|
21950
|
-
const ins =
|
|
22889
|
+
const ins = el10(`${w}ins`, revAttrs(w, meta), [runLike(rEl, rPr, [newT])]);
|
|
21951
22890
|
replacement.push(ins);
|
|
21952
22891
|
const afterChildren = [];
|
|
21953
22892
|
if (offset < t.text.length) afterChildren.push(textLike(t, t.name, t.text.slice(offset)));
|
|
@@ -21987,7 +22926,7 @@ function deleteOneRange(doc, t, start, end, meta) {
|
|
|
21987
22926
|
t.text = t.text.slice(0, start) + t.text.slice(end);
|
|
21988
22927
|
return { t, offset: start };
|
|
21989
22928
|
}
|
|
21990
|
-
const w =
|
|
22929
|
+
const w = prefixOf11(rEl);
|
|
21991
22930
|
const rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
21992
22931
|
const tIdx = rEl.children.indexOf(t);
|
|
21993
22932
|
const idx = parent.children.indexOf(rEl);
|
|
@@ -22004,7 +22943,7 @@ function deleteOneRange(doc, t, start, end, meta) {
|
|
|
22004
22943
|
}
|
|
22005
22944
|
if (beforeChildren.length > 0) replacement.push(runLike(rEl, rPr, beforeChildren));
|
|
22006
22945
|
const deletedT = textLike(t, delTextName, t.text.slice(start, end));
|
|
22007
|
-
const del =
|
|
22946
|
+
const del = el10(`${w}del`, revAttrs(w, meta), [runLike(rEl, rPr, [deletedT])]);
|
|
22008
22947
|
replacement.push(del);
|
|
22009
22948
|
const afterChildren = [];
|
|
22010
22949
|
if (end < t.text.length) afterChildren.push(textLike(t, t.name, t.text.slice(end)));
|
|
@@ -22033,24 +22972,24 @@ function coalesceDeletions(parent, del, author) {
|
|
|
22033
22972
|
}
|
|
22034
22973
|
}
|
|
22035
22974
|
function ensurePPrRPr(pEl) {
|
|
22036
|
-
const w =
|
|
22975
|
+
const w = prefixOf11(pEl);
|
|
22037
22976
|
let pPr = pEl.children.find((c) => localName(c.name) === "pPr");
|
|
22038
22977
|
if (!pPr) {
|
|
22039
|
-
pPr =
|
|
22978
|
+
pPr = el10(`${w}pPr`);
|
|
22040
22979
|
pEl.children.unshift(pPr);
|
|
22041
22980
|
}
|
|
22042
22981
|
let rPr = pPr.children.find((c) => localName(c.name) === "rPr");
|
|
22043
22982
|
if (!rPr) {
|
|
22044
|
-
rPr =
|
|
22983
|
+
rPr = el10(`${w}rPr`);
|
|
22045
22984
|
pPr.children.push(rPr);
|
|
22046
22985
|
}
|
|
22047
22986
|
return rPr;
|
|
22048
22987
|
}
|
|
22049
22988
|
function markParagraphGlyph(pEl, kind, meta) {
|
|
22050
|
-
const w =
|
|
22989
|
+
const w = prefixOf11(pEl);
|
|
22051
22990
|
const rPr = ensurePPrRPr(pEl);
|
|
22052
22991
|
const existingIdx = rPr.children.findIndex((c) => localName(c.name) === kind);
|
|
22053
|
-
const mark =
|
|
22992
|
+
const mark = el10(`${w}${kind}`, revAttrs(w, meta));
|
|
22054
22993
|
if (existingIdx !== -1) rPr.children[existingIdx] = mark;
|
|
22055
22994
|
else rPr.children.unshift(mark);
|
|
22056
22995
|
return mark;
|
|
@@ -22534,6 +23473,30 @@ var _DocxEditor = class _DocxEditor {
|
|
|
22534
23473
|
this.imageOverlay = null;
|
|
22535
23474
|
this.imageToolbar = null;
|
|
22536
23475
|
this.wordArtTextEditor = null;
|
|
23476
|
+
/** First press selects a model; subsequent drags belong to its 3D viewport. */
|
|
23477
|
+
this.onModel3DPointerDown = (event) => {
|
|
23478
|
+
const binding = this.model3DBinding(event.target);
|
|
23479
|
+
const src = binding?.item.src;
|
|
23480
|
+
if (!binding || !src || this.selectedImage?.src === src) return;
|
|
23481
|
+
if (this.regionOf(src) === "hf" !== this.inHeaderFooter) return;
|
|
23482
|
+
event.preventDefault();
|
|
23483
|
+
event.stopPropagation();
|
|
23484
|
+
this.selectImage(binding.el, src, binding.item);
|
|
23485
|
+
};
|
|
23486
|
+
this.onModel3DRotate = (event) => {
|
|
23487
|
+
const binding = this.model3DBinding(event.target);
|
|
23488
|
+
const src = binding?.item.src;
|
|
23489
|
+
const detail = event.detail;
|
|
23490
|
+
if (!binding || !src || !detail || ![detail.x, detail.y, detail.z].every(Number.isFinite)) return;
|
|
23491
|
+
event.stopPropagation();
|
|
23492
|
+
const rect = binding.el.getBoundingClientRect();
|
|
23493
|
+
const near = { x: rect.left + rect.width / 2, y: rect.top + rect.height / 2 };
|
|
23494
|
+
this.host.history?.checkpoint();
|
|
23495
|
+
if (setModel3DRotation(this.host.doc, src, detail)) {
|
|
23496
|
+
this.host.rerender(void 0, "local");
|
|
23497
|
+
this.reselectImage(src, near);
|
|
23498
|
+
}
|
|
23499
|
+
};
|
|
22537
23500
|
// ---------- watermarks / WordArt: select + edit ----------
|
|
22538
23501
|
this.selectedWordArt = null;
|
|
22539
23502
|
this.wordArtOverlay = null;
|
|
@@ -22557,6 +23520,7 @@ var _DocxEditor = class _DocxEditor {
|
|
|
22557
23520
|
if (this.wordArtOverlay?.contains(e.target)) return;
|
|
22558
23521
|
if (this.wordArtTextEditor?.input.contains(e.target)) return;
|
|
22559
23522
|
if (this.selectedInkGroup?.overlay.contains(e.target)) return;
|
|
23523
|
+
if (e.target?.closest?.("[data-dxw-model3d-viewer]")) return;
|
|
22560
23524
|
this.deselectInkGroup();
|
|
22561
23525
|
this.deselectImage();
|
|
22562
23526
|
this.deselectWordArt();
|
|
@@ -23583,7 +24547,9 @@ var _DocxEditor = class _DocxEditor {
|
|
|
23583
24547
|
c.tabIndex = 0;
|
|
23584
24548
|
c.style.outline = "none";
|
|
23585
24549
|
c.addEventListener("mousedown", this.onGripMouseDown, true);
|
|
24550
|
+
c.addEventListener("pointerdown", this.onModel3DPointerDown, true);
|
|
23586
24551
|
c.addEventListener("mouseup", this.onMouseUp);
|
|
24552
|
+
c.addEventListener("dxw-model3d-rotate", this.onModel3DRotate);
|
|
23587
24553
|
c.addEventListener("keydown", this.onKeyDown);
|
|
23588
24554
|
c.appendChild(this.imeEl);
|
|
23589
24555
|
this.imeEl.addEventListener("compositionstart", this.onCompositionStart);
|
|
@@ -23602,7 +24568,9 @@ var _DocxEditor = class _DocxEditor {
|
|
|
23602
24568
|
if (this.host.history) this.host.history.applyTextChanges = null;
|
|
23603
24569
|
const c = this.host.container;
|
|
23604
24570
|
c.removeEventListener("mousedown", this.onGripMouseDown, true);
|
|
24571
|
+
c.removeEventListener("pointerdown", this.onModel3DPointerDown, true);
|
|
23605
24572
|
c.removeEventListener("mouseup", this.onMouseUp);
|
|
24573
|
+
c.removeEventListener("dxw-model3d-rotate", this.onModel3DRotate);
|
|
23606
24574
|
c.removeEventListener("keydown", this.onKeyDown);
|
|
23607
24575
|
this.imeEl.removeEventListener("compositionstart", this.onCompositionStart);
|
|
23608
24576
|
this.imeEl.removeEventListener("compositionupdate", this.onCompositionUpdate);
|
|
@@ -24349,6 +25317,10 @@ var _DocxEditor = class _DocxEditor {
|
|
|
24349
25317
|
document.addEventListener("mouseup", onUp);
|
|
24350
25318
|
return true;
|
|
24351
25319
|
}
|
|
25320
|
+
model3DBinding(target) {
|
|
25321
|
+
const viewer = target?.closest?.("[data-dxw-model3d-viewer]");
|
|
25322
|
+
return viewer ? this.host.getHandle()?.images.find((binding) => binding.el.contains(viewer)) : void 0;
|
|
25323
|
+
}
|
|
24352
25324
|
/** First click selects a text box as an object; the second click edits only
|
|
24353
25325
|
* its story, even when the source shape lives in a header part. */
|
|
24354
25326
|
startTextboxTextInteraction(e, target) {
|
|
@@ -24444,9 +25416,11 @@ var _DocxEditor = class _DocxEditor {
|
|
|
24444
25416
|
];
|
|
24445
25417
|
for (const [mode, label] of modes) {
|
|
24446
25418
|
const b = document.createElement("button");
|
|
25419
|
+
b.type = "button";
|
|
24447
25420
|
b.textContent = label;
|
|
24448
25421
|
const active = mode === "inline" && !isFloating || isFloating && this.currentWrap(src) === mode;
|
|
24449
|
-
b.
|
|
25422
|
+
b.setAttribute("aria-pressed", String(active));
|
|
25423
|
+
b.style.cssText = `border:1px solid ${active ? "#8ab4f8" : "transparent"};border-radius:4px;padding:3px 7px;cursor:pointer;color:${active ? "#174ea6" : "#3c4043"};font-weight:${active ? "600" : "400"};background:${active ? "#d2e3fc" : "transparent"};`;
|
|
24450
25424
|
b.addEventListener("mousedown", (me) => {
|
|
24451
25425
|
me.preventDefault();
|
|
24452
25426
|
me.stopPropagation();
|
|
@@ -24552,6 +25526,13 @@ var _DocxEditor = class _DocxEditor {
|
|
|
24552
25526
|
});
|
|
24553
25527
|
});
|
|
24554
25528
|
}
|
|
25529
|
+
const drawingBinding = kind === "drawing" ? this.host.getHandle()?.drawings.find((binding) => binding.item.src === src) : void 0;
|
|
25530
|
+
if (drawingBinding?.item.textboxStory && !isDrawingWordArt(src)) {
|
|
25531
|
+
extra("Edit text", "Edit shape text", () => {
|
|
25532
|
+
const rect = drawingBinding.el.getBoundingClientRect();
|
|
25533
|
+
this.enterTextboxStory(src, rect.left + rect.width / 2, rect.top + rect.height / 2);
|
|
25534
|
+
});
|
|
25535
|
+
}
|
|
24555
25536
|
if (kind === "drawing" && isDrawingWordArt(src)) {
|
|
24556
25537
|
extra("Edit text", "Edit WordArt text", () => this.editDrawingWordArt(src));
|
|
24557
25538
|
}
|
|
@@ -24575,6 +25556,15 @@ var _DocxEditor = class _DocxEditor {
|
|
|
24575
25556
|
this.deselectImage();
|
|
24576
25557
|
});
|
|
24577
25558
|
}
|
|
25559
|
+
if (el16.dataset.dxwModel3d) {
|
|
25560
|
+
extra("Reset 3D", "Reset 3D rotation", () => {
|
|
25561
|
+
this.host.history?.checkpoint();
|
|
25562
|
+
if (setModel3DRotation(this.host.doc, src, { x: 0, y: 0, z: 0 })) {
|
|
25563
|
+
this.host.rerender(void 0, "local");
|
|
25564
|
+
this.reselectImage(src);
|
|
25565
|
+
}
|
|
25566
|
+
});
|
|
25567
|
+
}
|
|
24578
25568
|
const surface = el16.parentElement;
|
|
24579
25569
|
surface.appendChild(overlay);
|
|
24580
25570
|
const zoom = this.host.zoom ?? 1;
|
|
@@ -24784,6 +25774,7 @@ var _DocxEditor = class _DocxEditor {
|
|
|
24784
25774
|
/** Handle mousedown on images / their resize handle. Returns true if consumed. */
|
|
24785
25775
|
startImageInteraction(e, target) {
|
|
24786
25776
|
const zoom = this.host.zoom ?? 1;
|
|
25777
|
+
if (target.closest?.("[data-dxw-model3d-viewer]")) return true;
|
|
24787
25778
|
if (target.dataset.dxwImgHandle && this.selectedImage) {
|
|
24788
25779
|
e.preventDefault();
|
|
24789
25780
|
e.stopPropagation();
|
|
@@ -26677,7 +27668,7 @@ function isRelatedHistoryPart(name) {
|
|
|
26677
27668
|
}
|
|
26678
27669
|
|
|
26679
27670
|
// ../core/src/edit/comments.ts
|
|
26680
|
-
function
|
|
27671
|
+
function el11(name, attrs = {}, children2 = [], text = "") {
|
|
26681
27672
|
return { name, attrs, children: children2, text };
|
|
26682
27673
|
}
|
|
26683
27674
|
function addComment(doc, segments, text, author, initials) {
|
|
@@ -26701,15 +27692,15 @@ function addComment(doc, segments, text, author, initials) {
|
|
|
26701
27692
|
}
|
|
26702
27693
|
const newId = String(idNum + 1);
|
|
26703
27694
|
const startIdx = firstP.children.indexOf(firstR);
|
|
26704
|
-
firstP.children.splice(startIdx, 0,
|
|
27695
|
+
firstP.children.splice(startIdx, 0, el11(`${w}commentRangeStart`, { [`${w}id`]: newId }));
|
|
26705
27696
|
const endIdx = lastP.children.indexOf(lastR);
|
|
26706
27697
|
lastP.children.splice(
|
|
26707
27698
|
endIdx + 1,
|
|
26708
27699
|
0,
|
|
26709
|
-
|
|
26710
|
-
|
|
26711
|
-
|
|
26712
|
-
|
|
27700
|
+
el11(`${w}commentRangeEnd`, { [`${w}id`]: newId }),
|
|
27701
|
+
el11(`${w}r`, {}, [
|
|
27702
|
+
el11(`${w}rPr`, {}, [el11(`${w}rStyle`, { [`${w}val`]: "CommentReference" })]),
|
|
27703
|
+
el11(`${w}commentReference`, { [`${w}id`]: newId })
|
|
26713
27704
|
])
|
|
26714
27705
|
);
|
|
26715
27706
|
const usedParaIds = new Set(doc.comments.map((c) => c.paraId).filter(Boolean));
|
|
@@ -26718,7 +27709,7 @@ function addComment(doc, segments, text, author, initials) {
|
|
|
26718
27709
|
paraId2 = Math.floor(Math.random() * 4294967280 + 1).toString(16).toUpperCase().padStart(8, "0");
|
|
26719
27710
|
} while (usedParaIds.has(paraId2));
|
|
26720
27711
|
commentsRoot.children.push(
|
|
26721
|
-
|
|
27712
|
+
el11(
|
|
26722
27713
|
`${w}comment`,
|
|
26723
27714
|
{
|
|
26724
27715
|
[`${w}id`]: newId,
|
|
@@ -26727,13 +27718,13 @@ function addComment(doc, segments, text, author, initials) {
|
|
|
26727
27718
|
[`${w}date`]: (/* @__PURE__ */ new Date()).toISOString()
|
|
26728
27719
|
},
|
|
26729
27720
|
[
|
|
26730
|
-
|
|
27721
|
+
el11(
|
|
26731
27722
|
`${w}p`,
|
|
26732
27723
|
{
|
|
26733
27724
|
"xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
|
26734
27725
|
"w14:paraId": paraId2
|
|
26735
27726
|
},
|
|
26736
|
-
[
|
|
27727
|
+
[el11(`${w}r`, {}, [el11(`${w}t`, { "xml:space": "preserve" }, [], text)])]
|
|
26737
27728
|
)
|
|
26738
27729
|
]
|
|
26739
27730
|
)
|
|
@@ -26828,7 +27819,7 @@ function replyToComment(doc, parentId, text, author, initials) {
|
|
|
26828
27819
|
}
|
|
26829
27820
|
const replyParaId = freshParaId();
|
|
26830
27821
|
commentsRoot.children.push(
|
|
26831
|
-
|
|
27822
|
+
el11(
|
|
26832
27823
|
`${w}comment`,
|
|
26833
27824
|
{
|
|
26834
27825
|
[`${w}id`]: newId,
|
|
@@ -26837,13 +27828,13 @@ function replyToComment(doc, parentId, text, author, initials) {
|
|
|
26837
27828
|
[`${w}date`]: (/* @__PURE__ */ new Date()).toISOString()
|
|
26838
27829
|
},
|
|
26839
27830
|
[
|
|
26840
|
-
|
|
27831
|
+
el11(
|
|
26841
27832
|
`${w}p`,
|
|
26842
27833
|
{
|
|
26843
27834
|
"xmlns:w14": "http://schemas.microsoft.com/office/word/2010/wordml",
|
|
26844
27835
|
"w14:paraId": replyParaId
|
|
26845
27836
|
},
|
|
26846
|
-
[
|
|
27837
|
+
[el11(`${w}r`, {}, [el11(`${w}t`, { "xml:space": "preserve" }, [], text)])]
|
|
26847
27838
|
)
|
|
26848
27839
|
]
|
|
26849
27840
|
)
|
|
@@ -26859,11 +27850,11 @@ function replyToComment(doc, parentId, text, author, initials) {
|
|
|
26859
27850
|
);
|
|
26860
27851
|
if (!hasParentEx) {
|
|
26861
27852
|
extRoot.children.push(
|
|
26862
|
-
|
|
27853
|
+
el11("w15:commentEx", { "w15:paraId": parentParaId, "w15:done": "0" })
|
|
26863
27854
|
);
|
|
26864
27855
|
}
|
|
26865
27856
|
extRoot.children.push(
|
|
26866
|
-
|
|
27857
|
+
el11("w15:commentEx", {
|
|
26867
27858
|
"w15:paraId": replyParaId,
|
|
26868
27859
|
"w15:paraIdParent": parentParaId,
|
|
26869
27860
|
"w15:done": "0"
|
|
@@ -26881,19 +27872,19 @@ function insertReplyMarkers(el0, parentId, newId, w) {
|
|
|
26881
27872
|
const c = el0.children[i];
|
|
26882
27873
|
const ln = localName(c.name);
|
|
26883
27874
|
if (ln === "commentRangeStart" && attr(c, "id") === parentId) {
|
|
26884
|
-
el0.children.splice(i + 1, 0,
|
|
27875
|
+
el0.children.splice(i + 1, 0, el11(`${w}commentRangeStart`, { [`${w}id`]: newId }));
|
|
26885
27876
|
touched = true;
|
|
26886
27877
|
i++;
|
|
26887
27878
|
continue;
|
|
26888
27879
|
}
|
|
26889
27880
|
if (ln === "commentRangeEnd" && attr(c, "id") === parentId) {
|
|
26890
|
-
el0.children.splice(i + 1, 0,
|
|
27881
|
+
el0.children.splice(i + 1, 0, el11(`${w}commentRangeEnd`, { [`${w}id`]: newId }));
|
|
26891
27882
|
touched = true;
|
|
26892
27883
|
i++;
|
|
26893
27884
|
continue;
|
|
26894
27885
|
}
|
|
26895
27886
|
if (ln === "r" && c.children.some((rc) => localName(rc.name) === "commentReference" && attr(rc, "id") === parentId)) {
|
|
26896
|
-
el0.children.splice(i + 1, 0,
|
|
27887
|
+
el0.children.splice(i + 1, 0, el11(`${w}r`, {}, [el11(`${w}commentReference`, { [`${w}id`]: newId })]));
|
|
26897
27888
|
touched = true;
|
|
26898
27889
|
i++;
|
|
26899
27890
|
continue;
|
|
@@ -26930,7 +27921,7 @@ function stripMarkers(el16, id) {
|
|
|
26930
27921
|
}
|
|
26931
27922
|
|
|
26932
27923
|
// ../core/src/edit/links.ts
|
|
26933
|
-
function
|
|
27924
|
+
function prefixOf12(e) {
|
|
26934
27925
|
return e.name.includes(":") ? e.name.slice(0, e.name.indexOf(":") + 1) : "";
|
|
26935
27926
|
}
|
|
26936
27927
|
function hyperlinkOf(doc, t) {
|
|
@@ -26975,7 +27966,7 @@ function setLink(doc, segments, url) {
|
|
|
26975
27966
|
if (runsByPara.size === 0) return false;
|
|
26976
27967
|
const relId = doc.addHyperlinkRel(url);
|
|
26977
27968
|
for (const [pEl, runs] of runsByPara) {
|
|
26978
|
-
const w =
|
|
27969
|
+
const w = prefixOf12(pEl);
|
|
26979
27970
|
const first = pEl.children.indexOf(runs[0]);
|
|
26980
27971
|
for (const rEl of runs) {
|
|
26981
27972
|
let rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
@@ -27022,13 +28013,13 @@ function removeLink(doc, t) {
|
|
|
27022
28013
|
|
|
27023
28014
|
// ../core/src/edit/paragraph.ts
|
|
27024
28015
|
var INDENT_STEP_TWIPS = 720;
|
|
27025
|
-
function
|
|
28016
|
+
function prefixOf13(e) {
|
|
27026
28017
|
return e.name.includes(":") ? e.name.slice(0, e.name.indexOf(":") + 1) : "";
|
|
27027
28018
|
}
|
|
27028
28019
|
function ensurePPr(pEl) {
|
|
27029
28020
|
let pPr = pEl.children.find((c) => localName(c.name) === "pPr");
|
|
27030
28021
|
if (!pPr) {
|
|
27031
|
-
pPr = { name: `${
|
|
28022
|
+
pPr = { name: `${prefixOf13(pEl)}pPr`, attrs: {}, children: [], text: "" };
|
|
27032
28023
|
pEl.children.unshift(pPr);
|
|
27033
28024
|
}
|
|
27034
28025
|
return pPr;
|
|
@@ -27049,7 +28040,7 @@ function adjustIndent(doc, targets, direction) {
|
|
|
27049
28040
|
if (paragraphs.size === 0) return false;
|
|
27050
28041
|
let touched = false;
|
|
27051
28042
|
for (const pEl of paragraphs) {
|
|
27052
|
-
const w =
|
|
28043
|
+
const w = prefixOf13(pEl);
|
|
27053
28044
|
const pPr = ensurePPr(pEl);
|
|
27054
28045
|
let ind = pPr.children.find((c) => localName(c.name) === "ind");
|
|
27055
28046
|
if (!ind) {
|
|
@@ -27119,7 +28110,7 @@ function setDropCapAt(doc, target, mode, lines = 3) {
|
|
|
27119
28110
|
}
|
|
27120
28111
|
if (dropParagraph) {
|
|
27121
28112
|
const frame = dropCapFrame(dropParagraph);
|
|
27122
|
-
const w2 =
|
|
28113
|
+
const w2 = prefixOf13(dropParagraph);
|
|
27123
28114
|
frame.attrs[attrKey(frame, "dropCap", w2)] = mode;
|
|
27124
28115
|
frame.attrs[attrKey(frame, "lines", w2)] = String(lines);
|
|
27125
28116
|
frame.attrs[attrKey(frame, "hSpace", w2)] = "144";
|
|
@@ -27145,7 +28136,7 @@ function setDropCapAt(doc, target, mode, lines = 3) {
|
|
|
27145
28136
|
if (chars.length === 0) return false;
|
|
27146
28137
|
const letter = chars.shift();
|
|
27147
28138
|
sourceText.text = chars.join("");
|
|
27148
|
-
const w =
|
|
28139
|
+
const w = prefixOf13(paragraph);
|
|
27149
28140
|
const rPr = sourceRun.children.find((child4) => localName(child4.name) === "rPr");
|
|
27150
28141
|
const capRun = {
|
|
27151
28142
|
name: `${w}r`,
|
|
@@ -27189,7 +28180,7 @@ function setParagraphSpacing(doc, targets, patch) {
|
|
|
27189
28180
|
const paragraphs = paragraphsOf(doc, targets);
|
|
27190
28181
|
if (paragraphs.size === 0) return false;
|
|
27191
28182
|
for (const pEl of paragraphs) {
|
|
27192
|
-
const w =
|
|
28183
|
+
const w = prefixOf13(pEl);
|
|
27193
28184
|
const pPr = ensurePPr(pEl);
|
|
27194
28185
|
let sp = pPr.children.find((c) => localName(c.name) === "spacing");
|
|
27195
28186
|
if (!sp) {
|
|
@@ -27304,7 +28295,7 @@ function transformCase(doc, segments, mode) {
|
|
|
27304
28295
|
}
|
|
27305
28296
|
|
|
27306
28297
|
// ../core/src/edit/notes.ts
|
|
27307
|
-
function
|
|
28298
|
+
function el12(name, attrs = {}, children2 = [], text = "") {
|
|
27308
28299
|
return { name, attrs, children: children2, text };
|
|
27309
28300
|
}
|
|
27310
28301
|
function insertFootnote(doc, t, offset, text) {
|
|
@@ -27324,9 +28315,9 @@ function insertFootnote(doc, t, offset, text) {
|
|
|
27324
28315
|
const newId = maxId + 1;
|
|
27325
28316
|
const rw = rEl.name.includes(":") ? rEl.name.slice(0, rEl.name.indexOf(":") + 1) : "";
|
|
27326
28317
|
const rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
27327
|
-
const refRun =
|
|
27328
|
-
|
|
27329
|
-
|
|
28318
|
+
const refRun = el12(`${rw}r`, {}, [
|
|
28319
|
+
el12(`${rw}rPr`, {}, [el12(`${rw}rStyle`, { [`${rw}val`]: "FootnoteReference" })]),
|
|
28320
|
+
el12(`${rw}footnoteReference`, { [`${rw}id`]: String(newId) })
|
|
27330
28321
|
]);
|
|
27331
28322
|
const rIdx = pEl.children.indexOf(rEl);
|
|
27332
28323
|
if (offset >= t.text.length) {
|
|
@@ -27334,20 +28325,20 @@ function insertFootnote(doc, t, offset, text) {
|
|
|
27334
28325
|
} else if (offset <= 0) {
|
|
27335
28326
|
pEl.children.splice(rIdx, 0, refRun);
|
|
27336
28327
|
} else {
|
|
27337
|
-
const tailT =
|
|
28328
|
+
const tailT = el12(`${rw}t`, { "xml:space": "preserve" }, [], t.text.slice(offset));
|
|
27338
28329
|
t.text = t.text.slice(0, offset);
|
|
27339
|
-
const tail =
|
|
28330
|
+
const tail = el12(`${rw}r`, {}, [...rPr ? [cloneShallow(rPr)] : [], tailT]);
|
|
27340
28331
|
pEl.children.splice(rIdx + 1, 0, refRun, tail);
|
|
27341
28332
|
}
|
|
27342
28333
|
notesRoot.children.push(
|
|
27343
|
-
|
|
27344
|
-
|
|
27345
|
-
|
|
27346
|
-
|
|
27347
|
-
|
|
27348
|
-
|
|
28334
|
+
el12(`${w}footnote`, { [`${w}id`]: String(newId) }, [
|
|
28335
|
+
el12(`${w}p`, {}, [
|
|
28336
|
+
el12(`${w}pPr`, {}, [el12(`${w}pStyle`, { [`${w}val`]: "FootnoteText" })]),
|
|
28337
|
+
el12(`${w}r`, {}, [
|
|
28338
|
+
el12(`${w}rPr`, {}, [el12(`${w}rStyle`, { [`${w}val`]: "FootnoteReference" })]),
|
|
28339
|
+
el12(`${w}footnoteRef`)
|
|
27349
28340
|
]),
|
|
27350
|
-
|
|
28341
|
+
el12(`${w}r`, {}, [el12(`${w}t`, { "xml:space": "preserve" }, [], " " + text.trim())])
|
|
27351
28342
|
])
|
|
27352
28343
|
])
|
|
27353
28344
|
);
|
|
@@ -27360,7 +28351,7 @@ function cloneShallow(e) {
|
|
|
27360
28351
|
}
|
|
27361
28352
|
|
|
27362
28353
|
// ../core/src/edit/fields.ts
|
|
27363
|
-
function
|
|
28354
|
+
function el13(name, attrs = {}, children2 = [], text = "") {
|
|
27364
28355
|
return { name, attrs, children: children2, text };
|
|
27365
28356
|
}
|
|
27366
28357
|
function cloneDeep2(e) {
|
|
@@ -27376,8 +28367,8 @@ function insertElementsAt(doc, t, offset, inserted) {
|
|
|
27376
28367
|
const tIdx = rEl.children.indexOf(t);
|
|
27377
28368
|
if (rIdx < 0 || tIdx < 0) return false;
|
|
27378
28369
|
const at = Math.max(0, Math.min(offset, t.text.length));
|
|
27379
|
-
const makeText = (text) =>
|
|
27380
|
-
const makeRun = (content) =>
|
|
28370
|
+
const makeText = (text) => el13(t.name, { ...t.attrs, "xml:space": "preserve" }, [], text);
|
|
28371
|
+
const makeRun = (content) => el13(rEl.name, { ...rEl.attrs }, [...rPr ? [cloneDeep2(rPr)] : [], ...content]);
|
|
27381
28372
|
const before = rEl.children.slice(0, tIdx).filter((child4) => localName(child4.name) !== "rPr");
|
|
27382
28373
|
const after = rEl.children.slice(tIdx + 1).filter((child4) => localName(child4.name) !== "rPr");
|
|
27383
28374
|
let beforeRun;
|
|
@@ -27410,11 +28401,11 @@ function insertField(doc, t, offset, instruction, cachedResult = "") {
|
|
|
27410
28401
|
if (!rEl || localName(rEl.name) !== "r") return false;
|
|
27411
28402
|
const w = rEl.name.includes(":") ? rEl.name.slice(0, rEl.name.indexOf(":") + 1) : "";
|
|
27412
28403
|
const rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
27413
|
-
const resultRun =
|
|
28404
|
+
const resultRun = el13(`${w}r`, {}, [
|
|
27414
28405
|
...rPr ? [cloneDeep2(rPr)] : [],
|
|
27415
|
-
|
|
28406
|
+
el13(`${w}t`, { "xml:space": "preserve" }, [], cachedResult)
|
|
27416
28407
|
]);
|
|
27417
|
-
const field =
|
|
28408
|
+
const field = el13(`${w}fldSimple`, { [`${w}instr`]: ` ${clean} ` }, [resultRun]);
|
|
27418
28409
|
return insertElementsAt(doc, t, offset, [field]);
|
|
27419
28410
|
}
|
|
27420
28411
|
function insertPageField(doc, t, offset, kind = "page") {
|
|
@@ -27422,9 +28413,9 @@ function insertPageField(doc, t, offset, kind = "page") {
|
|
|
27422
28413
|
if (!rEl || localName(rEl.name) !== "r") return false;
|
|
27423
28414
|
const rw = rEl.name.includes(":") ? rEl.name.slice(0, rEl.name.indexOf(":") + 1) : "";
|
|
27424
28415
|
const rPr = rEl.children.find((c) => localName(c.name) === "rPr");
|
|
27425
|
-
const run = (content) =>
|
|
27426
|
-
const textRun = (s) => run(
|
|
27427
|
-
const fld = (instr) =>
|
|
28416
|
+
const run = (content) => el13(`${rw}r`, {}, [...rPr ? [cloneDeep2(rPr)] : [], content]);
|
|
28417
|
+
const textRun = (s) => run(el13(`${rw}t`, { "xml:space": "preserve" }, [], s));
|
|
28418
|
+
const fld = (instr) => el13(`${rw}fldSimple`, { [`${rw}instr`]: ` ${instr} \\* MERGEFORMAT ` }, [textRun("1")]);
|
|
27428
28419
|
const inserted = kind === "page" ? [fld("PAGE")] : [textRun("Page "), fld("PAGE"), textRun(" of "), fld("NUMPAGES")];
|
|
27429
28420
|
return insertElementsAt(doc, t, offset, inserted);
|
|
27430
28421
|
}
|
|
@@ -27435,15 +28426,15 @@ function insertDateTimeField(doc, t, offset, kind, picture) {
|
|
|
27435
28426
|
|
|
27436
28427
|
// ../core/src/edit/charts.ts
|
|
27437
28428
|
import { strToU8 as strToU83, zipSync as zipSync2 } from "fflate";
|
|
27438
|
-
var
|
|
27439
|
-
var
|
|
27440
|
-
var
|
|
28429
|
+
var EMU_PER_PX7 = 9525;
|
|
28430
|
+
var NS_WP6 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
28431
|
+
var NS_A5 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
27441
28432
|
var NS_C = "http://schemas.openxmlformats.org/drawingml/2006/chart";
|
|
27442
|
-
var
|
|
27443
|
-
function
|
|
28433
|
+
var NS_R4 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
28434
|
+
function el14(name, attrs = {}, children2 = [], text = "") {
|
|
27444
28435
|
return { name, attrs, children: children2, text };
|
|
27445
28436
|
}
|
|
27446
|
-
function
|
|
28437
|
+
function prefixOf14(node) {
|
|
27447
28438
|
return node.name.includes(":") ? node.name.slice(0, node.name.indexOf(":") + 1) : "";
|
|
27448
28439
|
}
|
|
27449
28440
|
function descendant4(node, name) {
|
|
@@ -27510,7 +28501,7 @@ function buildChartWorkbook(input) {
|
|
|
27510
28501
|
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="xl/workbook.xml"/></Relationships>`
|
|
27511
28502
|
),
|
|
27512
28503
|
"xl/workbook.xml": strToU83(
|
|
27513
|
-
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="${
|
|
28504
|
+
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="${NS_R4}"><bookViews><workbookView/></bookViews><sheets><sheet name="Data" sheetId="1" r:id="rId1"/></sheets><calcPr calcId="191029"/></workbook>`
|
|
27514
28505
|
),
|
|
27515
28506
|
"xl/_rels/workbook.xml.rels": strToU83(
|
|
27516
28507
|
`<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/></Relationships>`
|
|
@@ -27551,7 +28542,7 @@ function chartPlot(data) {
|
|
|
27551
28542
|
}
|
|
27552
28543
|
function buildChartXml(input, workbookRelId = "rId1") {
|
|
27553
28544
|
const data = normalizeChartData(input);
|
|
27554
|
-
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><c:chartSpace xmlns:c="${NS_C}" xmlns:a="${
|
|
28545
|
+
return `<?xml version="1.0" encoding="UTF-8" standalone="yes"?><c:chartSpace xmlns:c="${NS_C}" xmlns:a="${NS_A5}" xmlns:r="${NS_R4}"><c:date1904 val="0"/><c:lang val="en-US"/><c:roundedCorners val="0"/><c:style val="2"/><c:chart>${chartTitle(data.title)}<c:autoTitleDeleted val="${data.title ? "0" : "1"}"/><c:plotArea><c:layout/>${chartPlot(data)}</c:plotArea><c:legend><c:legendPos val="r"/><c:layout/><c:overlay val="0"/></c:legend><c:plotVisOnly val="1"/><c:dispBlanksAs val="gap"/><c:showDLblsOverMax val="0"/></c:chart><c:externalData r:id="${escapeXml2(workbookRelId)}"><c:autoUpdate val="0"/></c:externalData></c:chartSpace>`;
|
|
27555
28546
|
}
|
|
27556
28547
|
function insertChartAt(doc, caretT, input) {
|
|
27557
28548
|
const caretRun = doc.findParentOf(caretT);
|
|
@@ -27559,23 +28550,23 @@ function insertChartAt(doc, caretT, input) {
|
|
|
27559
28550
|
if (!caretRun || !parent || localName(caretRun.name) !== "r") return null;
|
|
27560
28551
|
const data = normalizeChartData(input);
|
|
27561
28552
|
const { relId } = doc.addChartResource(buildChartXml(data), buildChartWorkbook(data));
|
|
27562
|
-
const w =
|
|
28553
|
+
const w = prefixOf14(caretRun);
|
|
27563
28554
|
const id = String(doc.nextDrawingId());
|
|
27564
|
-
const cx = String(Math.round(480 *
|
|
27565
|
-
const cy = String(Math.round(288 *
|
|
27566
|
-
const drawing =
|
|
27567
|
-
|
|
27568
|
-
|
|
27569
|
-
|
|
27570
|
-
|
|
27571
|
-
|
|
27572
|
-
|
|
27573
|
-
|
|
28555
|
+
const cx = String(Math.round(480 * EMU_PER_PX7));
|
|
28556
|
+
const cy = String(Math.round(288 * EMU_PER_PX7));
|
|
28557
|
+
const drawing = el14(`${w}drawing`, {}, [
|
|
28558
|
+
el14("wp:inline", { "xmlns:wp": NS_WP6, distT: "0", distB: "0", distL: "0", distR: "0" }, [
|
|
28559
|
+
el14("wp:extent", { cx, cy }),
|
|
28560
|
+
el14("wp:docPr", { id, name: `Chart ${id}` }),
|
|
28561
|
+
el14("wp:cNvGraphicFramePr"),
|
|
28562
|
+
el14("a:graphic", { "xmlns:a": NS_A5 }, [
|
|
28563
|
+
el14("a:graphicData", { uri: NS_C }, [
|
|
28564
|
+
el14("c:chart", { "xmlns:c": NS_C, "xmlns:r": NS_R4, "r:id": relId })
|
|
27574
28565
|
])
|
|
27575
28566
|
])
|
|
27576
28567
|
])
|
|
27577
28568
|
]);
|
|
27578
|
-
parent.children.splice(parent.children.indexOf(caretRun) + 1, 0,
|
|
28569
|
+
parent.children.splice(parent.children.indexOf(caretRun) + 1, 0, el14(`${w}r`, {}, [drawing]));
|
|
27579
28570
|
doc.refresh();
|
|
27580
28571
|
return drawing;
|
|
27581
28572
|
}
|
|
@@ -27597,226 +28588,6 @@ function setChartData(doc, drawing, input) {
|
|
|
27597
28588
|
return true;
|
|
27598
28589
|
}
|
|
27599
28590
|
|
|
27600
|
-
// ../core/src/edit/objects.ts
|
|
27601
|
-
var EMU_PER_PX7 = 9525;
|
|
27602
|
-
var NS_WP6 = "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing";
|
|
27603
|
-
var NS_A5 = "http://schemas.openxmlformats.org/drawingml/2006/main";
|
|
27604
|
-
var NS_PIC2 = "http://schemas.openxmlformats.org/drawingml/2006/picture";
|
|
27605
|
-
var NS_R4 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
27606
|
-
var NS_MC = "http://schemas.openxmlformats.org/markup-compatibility/2006";
|
|
27607
|
-
var NS_AM3D = "http://schemas.microsoft.com/office/drawing/2017/model3d";
|
|
27608
|
-
var NS_WP15 = "http://schemas.microsoft.com/office/word/2012/wordprocessingDrawing";
|
|
27609
|
-
function el14(name, attrs = {}, children2 = [], text = "") {
|
|
27610
|
-
return { name, attrs, children: children2, text };
|
|
27611
|
-
}
|
|
27612
|
-
function prefixOf14(node) {
|
|
27613
|
-
return node.name.includes(":") ? node.name.slice(0, node.name.indexOf(":") + 1) : "";
|
|
27614
|
-
}
|
|
27615
|
-
function insertAfterCaretRun(doc, caretT, content) {
|
|
27616
|
-
const caretRun = doc.findParentOf(caretT);
|
|
27617
|
-
const parent = caretRun && doc.findParentOf(caretRun);
|
|
27618
|
-
if (!caretRun || !parent || localName(caretRun.name) !== "r") return false;
|
|
27619
|
-
const w = prefixOf14(caretRun);
|
|
27620
|
-
parent.children.splice(parent.children.indexOf(caretRun) + 1, 0, el14(`${w}r`, {}, [content]));
|
|
27621
|
-
doc.refresh();
|
|
27622
|
-
return true;
|
|
27623
|
-
}
|
|
27624
|
-
function pictureGraphic(relId, id, cx, cy, webVideo) {
|
|
27625
|
-
const blipChildren = webVideo ? [
|
|
27626
|
-
el14("a:extLst", {}, [
|
|
27627
|
-
el14("a:ext", { uri: "{9E29B28B-C9C2-4B96-BA92-6C9A3D8F4A6A}" }, [
|
|
27628
|
-
el14("wp15:webVideoPr", {
|
|
27629
|
-
"xmlns:wp15": NS_WP15,
|
|
27630
|
-
embeddedHtml: webVideo,
|
|
27631
|
-
w: "640",
|
|
27632
|
-
h: "360"
|
|
27633
|
-
})
|
|
27634
|
-
])
|
|
27635
|
-
])
|
|
27636
|
-
] : [];
|
|
27637
|
-
return el14("a:graphic", { "xmlns:a": NS_A5 }, [
|
|
27638
|
-
el14("a:graphicData", { uri: NS_PIC2 }, [
|
|
27639
|
-
el14("pic:pic", { "xmlns:pic": NS_PIC2 }, [
|
|
27640
|
-
el14("pic:nvPicPr", {}, [
|
|
27641
|
-
el14("pic:cNvPr", { id, name: `Picture ${id}` }),
|
|
27642
|
-
el14("pic:cNvPicPr", {}, [el14("a:picLocks", { noChangeAspect: "1" })])
|
|
27643
|
-
]),
|
|
27644
|
-
el14("pic:blipFill", {}, [
|
|
27645
|
-
el14("a:blip", { "xmlns:r": NS_R4, "r:embed": relId }, blipChildren),
|
|
27646
|
-
el14("a:stretch", {}, [el14("a:fillRect")])
|
|
27647
|
-
]),
|
|
27648
|
-
el14("pic:spPr", {}, [
|
|
27649
|
-
el14("a:xfrm", {}, [el14("a:off", { x: "0", y: "0" }), el14("a:ext", { cx, cy })]),
|
|
27650
|
-
el14("a:prstGeom", { prst: "rect" }, [el14("a:avLst")])
|
|
27651
|
-
])
|
|
27652
|
-
])
|
|
27653
|
-
])
|
|
27654
|
-
]);
|
|
27655
|
-
}
|
|
27656
|
-
function inlineDrawing(id, name, descr, cx, cy, graphic) {
|
|
27657
|
-
return el14("w:drawing", {}, [
|
|
27658
|
-
el14("wp:inline", { "xmlns:wp": NS_WP6, distT: "0", distB: "0", distL: "0", distR: "0" }, [
|
|
27659
|
-
el14("wp:extent", { cx, cy }),
|
|
27660
|
-
el14("wp:effectExtent", { l: "0", t: "0", r: "0", b: "0" }),
|
|
27661
|
-
el14("wp:docPr", { id, name, descr }),
|
|
27662
|
-
el14("wp:cNvGraphicFramePr", {}, [el14("a:graphicFrameLocks", { "xmlns:a": NS_A5, noChangeAspect: "1" })]),
|
|
27663
|
-
graphic
|
|
27664
|
-
])
|
|
27665
|
-
]);
|
|
27666
|
-
}
|
|
27667
|
-
function insertModel3DAt(doc, caretT, input) {
|
|
27668
|
-
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
27669
|
-
const model = doc.addModel3DResource(input.data);
|
|
27670
|
-
const id = String(doc.nextDrawingId());
|
|
27671
|
-
const width = 320;
|
|
27672
|
-
const height = 220;
|
|
27673
|
-
const cx = String(width * EMU_PER_PX7);
|
|
27674
|
-
const cy = String(height * EMU_PER_PX7);
|
|
27675
|
-
const modelGraphic = el14("a:graphic", { "xmlns:a": NS_A5 }, [
|
|
27676
|
-
el14("a:graphicData", { uri: NS_AM3D }, [
|
|
27677
|
-
el14("am3d:model3d", { "xmlns:am3d": NS_AM3D, "xmlns:r": NS_R4, "r:embed": model.relId }, [
|
|
27678
|
-
el14("am3d:spPr", {}, [
|
|
27679
|
-
el14("a:xfrm", {}, [el14("a:off", { x: "0", y: "0" }), el14("a:ext", { cx, cy })]),
|
|
27680
|
-
el14("a:prstGeom", { prst: "rect" }, [el14("a:avLst")])
|
|
27681
|
-
]),
|
|
27682
|
-
el14("am3d:camera", {}, [
|
|
27683
|
-
el14("am3d:pos", { x: "0", y: "0", z: "77741944" }),
|
|
27684
|
-
el14("am3d:up", { dx: "0", dy: "36000000", dz: "0" }),
|
|
27685
|
-
el14("am3d:lookAt", { x: "0", y: "0", z: "0" }),
|
|
27686
|
-
el14("am3d:perspective", { fov: "2700000" })
|
|
27687
|
-
]),
|
|
27688
|
-
el14("am3d:trans", {}, [
|
|
27689
|
-
el14("am3d:meterPerModelUnit", { n: "1", d: "1" }),
|
|
27690
|
-
el14("am3d:preTrans", { dx: "0", dy: "0", dz: "0" }),
|
|
27691
|
-
el14("am3d:scale", {}, [
|
|
27692
|
-
el14("am3d:sx", { n: "1000000", d: "1000000" }),
|
|
27693
|
-
el14("am3d:sy", { n: "1000000", d: "1000000" }),
|
|
27694
|
-
el14("am3d:sz", { n: "1000000", d: "1000000" })
|
|
27695
|
-
]),
|
|
27696
|
-
el14("am3d:rot", { ax: "0", ay: "0", az: "0" }),
|
|
27697
|
-
el14("am3d:postTrans", { dx: "0", dy: "0", dz: "0" })
|
|
27698
|
-
]),
|
|
27699
|
-
el14("am3d:raster", { rName: "Office3DRenderer", rVer: "16.0" }, [
|
|
27700
|
-
el14("am3d:blip", { "r:embed": posterRelId })
|
|
27701
|
-
]),
|
|
27702
|
-
el14("am3d:objViewport", { viewportSz: cx }),
|
|
27703
|
-
el14("am3d:ambientLight", {}, [
|
|
27704
|
-
el14("am3d:clr", {}, [el14("a:scrgbClr", { r: "50000", g: "50000", b: "50000" })]),
|
|
27705
|
-
el14("am3d:illuminance", { n: "500000", d: "1000000" })
|
|
27706
|
-
]),
|
|
27707
|
-
el14("am3d:ptLight", { rad: "0" }, [
|
|
27708
|
-
el14("am3d:clr", {}, [el14("a:scrgbClr", { r: "100000", g: "100000", b: "100000" })]),
|
|
27709
|
-
el14("am3d:intensity", { n: "1000000", d: "1000000" }),
|
|
27710
|
-
el14("am3d:pos", { x: "30000000", y: "50000000", z: "50000000" })
|
|
27711
|
-
])
|
|
27712
|
-
])
|
|
27713
|
-
])
|
|
27714
|
-
]);
|
|
27715
|
-
const alt = input.alt ?? "3D model";
|
|
27716
|
-
const choice = inlineDrawing(id, `3D Model ${id}`, alt, cx, cy, modelGraphic);
|
|
27717
|
-
const fallback = inlineDrawing(id, `3D Model ${id}`, alt, cx, cy, pictureGraphic(posterRelId, id, cx, cy));
|
|
27718
|
-
const alternate = el14("mc:AlternateContent", { "xmlns:mc": NS_MC }, [
|
|
27719
|
-
el14("mc:Choice", { Requires: "am3d", "xmlns:am3d": NS_AM3D }, [choice]),
|
|
27720
|
-
el14("mc:Fallback", {}, [fallback])
|
|
27721
|
-
]);
|
|
27722
|
-
return insertAfterCaretRun(doc, caretT, alternate);
|
|
27723
|
-
}
|
|
27724
|
-
function normalizeWebVideoUrl(value) {
|
|
27725
|
-
try {
|
|
27726
|
-
const url = new URL(value.trim());
|
|
27727
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
27728
|
-
if (url.hostname === "youtu.be") return `https://www.youtube.com/embed/${url.pathname.slice(1)}`;
|
|
27729
|
-
if (url.hostname.endsWith("youtube.com") && url.pathname === "/watch") {
|
|
27730
|
-
const id = url.searchParams.get("v");
|
|
27731
|
-
if (id) return `https://www.youtube.com/embed/${id}`;
|
|
27732
|
-
}
|
|
27733
|
-
if (url.hostname.endsWith("vimeo.com") && /^\/\d+\/?$/.test(url.pathname)) {
|
|
27734
|
-
return `https://player.vimeo.com/video/${url.pathname.replace(/\//g, "")}`;
|
|
27735
|
-
}
|
|
27736
|
-
return url.href;
|
|
27737
|
-
} catch {
|
|
27738
|
-
return null;
|
|
27739
|
-
}
|
|
27740
|
-
}
|
|
27741
|
-
function insertWebVideoAt(doc, caretT, input) {
|
|
27742
|
-
const url = normalizeWebVideoUrl(input.url);
|
|
27743
|
-
if (!url) return false;
|
|
27744
|
-
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
27745
|
-
const width = input.width ?? 320;
|
|
27746
|
-
const height = input.height ?? 180;
|
|
27747
|
-
const cx = String(Math.round(width * EMU_PER_PX7));
|
|
27748
|
-
const cy = String(Math.round(height * EMU_PER_PX7));
|
|
27749
|
-
const id = String(doc.nextDrawingId());
|
|
27750
|
-
const embeddedHtml = `<iframe width="640" height="360" src="${url}" frameborder="0" allowfullscreen=""></iframe>`;
|
|
27751
|
-
return insertAfterCaretRun(
|
|
27752
|
-
doc,
|
|
27753
|
-
caretT,
|
|
27754
|
-
inlineDrawing(id, `Online Video ${id}`, url, cx, cy, pictureGraphic(posterRelId, id, cx, cy, embeddedHtml))
|
|
27755
|
-
);
|
|
27756
|
-
}
|
|
27757
|
-
function insertEmbeddedObjectAt(doc, caretT, input) {
|
|
27758
|
-
const posterRelId = doc.addImageResource(input.poster, input.posterExt ?? "png");
|
|
27759
|
-
const wordDocument = input.filename.toLowerCase().endsWith(".docx");
|
|
27760
|
-
const object = wordDocument ? doc.addEmbeddedWordDocumentResource(input.data) : doc.addEmbeddedObjectResource(buildOlePackage(input.data, input.filename));
|
|
27761
|
-
const id = String(doc.nextDrawingId());
|
|
27762
|
-
const vmlId = 1024 + Number(id);
|
|
27763
|
-
const shapeTypeId = `_x0000_t${vmlId}`;
|
|
27764
|
-
const shapeId = `_x0000_i${vmlId}`;
|
|
27765
|
-
const width = 320;
|
|
27766
|
-
const height = 180;
|
|
27767
|
-
const objectEl = el14("w:object", {
|
|
27768
|
-
"xmlns:w": "http://schemas.openxmlformats.org/wordprocessingml/2006/main",
|
|
27769
|
-
"xmlns:v": "urn:schemas-microsoft-com:vml",
|
|
27770
|
-
"xmlns:o": "urn:schemas-microsoft-com:office:office",
|
|
27771
|
-
"xmlns:r": NS_R4,
|
|
27772
|
-
"w:dxaOrig": String(width * 15),
|
|
27773
|
-
"w:dyaOrig": String(height * 15)
|
|
27774
|
-
}, [
|
|
27775
|
-
el14("v:shapetype", {
|
|
27776
|
-
id: shapeTypeId,
|
|
27777
|
-
coordsize: "21600,21600",
|
|
27778
|
-
"o:spt": "75",
|
|
27779
|
-
"o:preferrelative": "t",
|
|
27780
|
-
path: "m@4@5l@4@11@9@11@9@5xe",
|
|
27781
|
-
filled: "f",
|
|
27782
|
-
stroked: "f"
|
|
27783
|
-
}, [
|
|
27784
|
-
el14("v:stroke", { joinstyle: "miter" }),
|
|
27785
|
-
el14("v:formulas", {}, [
|
|
27786
|
-
el14("v:f", { eqn: "if lineDrawn pixelLineWidth 0" }),
|
|
27787
|
-
el14("v:f", { eqn: "sum @0 1 0" }),
|
|
27788
|
-
el14("v:f", { eqn: "sum 0 0 @1" }),
|
|
27789
|
-
el14("v:f", { eqn: "prod @2 1 2" }),
|
|
27790
|
-
el14("v:f", { eqn: "prod @3 21600 pixelWidth" }),
|
|
27791
|
-
el14("v:f", { eqn: "prod @3 21600 pixelHeight" }),
|
|
27792
|
-
el14("v:f", { eqn: "sum @0 0 1" }),
|
|
27793
|
-
el14("v:f", { eqn: "prod @6 1 2" }),
|
|
27794
|
-
el14("v:f", { eqn: "prod @7 21600 pixelWidth" }),
|
|
27795
|
-
el14("v:f", { eqn: "sum @8 21600 0" }),
|
|
27796
|
-
el14("v:f", { eqn: "prod @7 21600 pixelHeight" }),
|
|
27797
|
-
el14("v:f", { eqn: "sum @10 21600 0" })
|
|
27798
|
-
]),
|
|
27799
|
-
el14("v:path", { "o:extrusionok": "f", gradientshapeok: "t", "o:connecttype": "rect" }),
|
|
27800
|
-
el14("o:lock", { "v:ext": "edit", aspectratio: "t" })
|
|
27801
|
-
]),
|
|
27802
|
-
el14("v:shape", {
|
|
27803
|
-
id: shapeId,
|
|
27804
|
-
type: `#${shapeTypeId}`,
|
|
27805
|
-
style: `width:${width * 0.75}pt;height:${height * 0.75}pt`,
|
|
27806
|
-
"o:ole": ""
|
|
27807
|
-
}, [el14("v:imagedata", { "r:id": posterRelId, "o:title": input.filename })]),
|
|
27808
|
-
el14("o:OLEObject", {
|
|
27809
|
-
Type: "Embed",
|
|
27810
|
-
ProgID: wordDocument ? "Word.Document.12" : "Package",
|
|
27811
|
-
ShapeID: shapeId,
|
|
27812
|
-
DrawAspect: "Content",
|
|
27813
|
-
ObjectID: `_${1e9 + Number(id)}`,
|
|
27814
|
-
"r:id": object.relId
|
|
27815
|
-
}, wordDocument ? [el14("o:FieldCodes", {}, [], "\\s")] : [])
|
|
27816
|
-
]);
|
|
27817
|
-
return insertAfterCaretRun(doc, caretT, objectEl);
|
|
27818
|
-
}
|
|
27819
|
-
|
|
27820
28591
|
// ../core/src/edit/references.ts
|
|
27821
28592
|
function el15(name, attrs = {}) {
|
|
27822
28593
|
return { name, attrs, children: [], text: "" };
|
|
@@ -29124,7 +29895,10 @@ function EquationMenu({ api }) {
|
|
|
29124
29895
|
}
|
|
29125
29896
|
};
|
|
29126
29897
|
return /* @__PURE__ */ jsxs("span", { ref: rootRef, style: { position: "relative", display: "inline-block" }, children: [
|
|
29127
|
-
/* @__PURE__ */
|
|
29898
|
+
/* @__PURE__ */ jsxs("button", { title: "Insert equation", style: btnStyle(open), onMouseDown: (event) => event.preventDefault(), onClick: () => setOpen(!open), children: [
|
|
29899
|
+
/* @__PURE__ */ jsx("span", { style: { fontFamily: "'Cambria Math', serif", fontSize: 18 }, children: "\u03C0" }),
|
|
29900
|
+
/* @__PURE__ */ jsx("span", { style: { marginLeft: 5 }, children: "Equation" })
|
|
29901
|
+
] }),
|
|
29128
29902
|
open && /* @__PURE__ */ jsxs("div", { style: { position: "absolute", top: 28, right: 0, zIndex: 100, width: 340, padding: 10, background: T.popoverBg, border: `1px solid ${T.border}`, borderRadius: 8, boxShadow: T.popoverShadow }, children: [
|
|
29129
29903
|
/* @__PURE__ */ jsx("div", { style: { font: "600 12px system-ui, sans-serif", marginBottom: 5, color: T.fg }, children: "Linear equation" }),
|
|
29130
29904
|
/* @__PURE__ */ jsx(
|
|
@@ -31137,6 +31911,11 @@ function DocxView({
|
|
|
31137
31911
|
const effZoomRef = useRef2(effectiveZoom);
|
|
31138
31912
|
effZoomRef.current = effectiveZoom;
|
|
31139
31913
|
const applyZoomRef = useRef2(null);
|
|
31914
|
+
useEffect2(() => {
|
|
31915
|
+
if (editable && typeof window !== "undefined" && !customElements.get("model-viewer")) {
|
|
31916
|
+
void import("@google/model-viewer");
|
|
31917
|
+
}
|
|
31918
|
+
}, [editable]);
|
|
31140
31919
|
const recomputeFit = useCallback2(() => {
|
|
31141
31920
|
const c = containerRef.current;
|
|
31142
31921
|
if (!c) return;
|
|
@@ -31357,6 +32136,7 @@ function DocxView({
|
|
|
31357
32136
|
}
|
|
31358
32137
|
}
|
|
31359
32138
|
loads.push(document.fonts.load('16px "Cambria Math"').catch(() => []));
|
|
32139
|
+
loads.push(document.fonts.load('16px "Segoe UI Emoji"', "\u{1F680}").catch(() => []));
|
|
31360
32140
|
const cjk = [
|
|
31361
32141
|
"MS Mincho",
|
|
31362
32142
|
"MS Gothic",
|
|
@@ -31582,8 +32362,10 @@ function DocxView({
|
|
|
31582
32362
|
const target = insertionTarget();
|
|
31583
32363
|
if (!target) return false;
|
|
31584
32364
|
history.checkpoint();
|
|
31585
|
-
|
|
32365
|
+
const drawing = insertShapeAt(doc, target.t, preset, text);
|
|
32366
|
+
if (!drawing) return false;
|
|
31586
32367
|
pages = rerender(doc, void 0, "global");
|
|
32368
|
+
editor?.reselectDrawing(drawing);
|
|
31587
32369
|
return true;
|
|
31588
32370
|
},
|
|
31589
32371
|
insertWordArt: (text, preset = "plain") => {
|