ooxml-core 1.3.0 → 1.5.0
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 +2 -0
- package/dist/automation/index.cjs +6089 -5381
- package/dist/automation/index.mjs +6089 -5381
- package/dist/teams/index.cjs +73 -23
- package/dist/teams/index.mjs +73 -23
- package/dist/visio/basic-shapes.d.ts +18 -0
- package/dist/visio/basic-shapes.d.ts.map +1 -0
- package/dist/visio/edit-commands.d.ts +13 -2
- package/dist/visio/edit-commands.d.ts.map +1 -1
- package/dist/visio/edit-page-size.d.ts +5 -0
- package/dist/visio/edit-page-size.d.ts.map +1 -0
- package/dist/visio/edit-pages.d.ts.map +1 -1
- package/dist/visio/edit-shape-create.d.ts.map +1 -1
- package/dist/visio/edit-text-range-commands.d.ts +21 -0
- package/dist/visio/edit-text-range-commands.d.ts.map +1 -0
- package/dist/visio/edit-text-range-plan.d.ts +7 -0
- package/dist/visio/edit-text-range-plan.d.ts.map +1 -0
- package/dist/visio/edit-text-ranges.d.ts +4 -0
- package/dist/visio/edit-text-ranges.d.ts.map +1 -0
- package/dist/visio/edit-text-target.d.ts +3 -0
- package/dist/visio/edit-text-target.d.ts.map +1 -0
- package/dist/visio/edit-text.d.ts.map +1 -1
- package/dist/visio/edit.d.ts +1 -1
- package/dist/visio/edit.d.ts.map +1 -1
- package/dist/visio/index.cjs +623 -49
- package/dist/visio/index.d.ts +2 -1
- package/dist/visio/index.d.ts.map +1 -1
- package/dist/visio/index.mjs +621 -50
- package/dist/visio/model.d.ts +3 -0
- package/dist/visio/model.d.ts.map +1 -1
- package/dist/visio/parser.d.ts.map +1 -1
- package/dist/visio/ui/draw-plan.d.ts +4 -1
- package/dist/visio/ui/draw-plan.d.ts.map +1 -1
- package/dist/visio/ui/edit-commands.d.ts.map +1 -1
- package/dist/visio/ui/index.cjs +139 -14
- package/dist/visio/ui/index.d.ts +1 -0
- package/dist/visio/ui/index.d.ts.map +1 -1
- package/dist/visio/ui/index.mjs +135 -15
- package/dist/visio/ui/page-size.d.ts +31 -0
- package/dist/visio/ui/page-size.d.ts.map +1 -0
- package/dist/visio/ui/scene-validation.d.ts.map +1 -1
- package/dist/visio/ui/snapshot-scene.d.ts.map +1 -1
- package/dist/visio/ui/text-replace-types.d.ts +6 -2
- package/dist/visio/ui/text-replace-types.d.ts.map +1 -1
- package/dist/visio/ui/text-replace.d.ts +3 -4
- package/dist/visio/ui/text-replace.d.ts.map +1 -1
- package/dist/visio/xml-validation.d.ts.map +1 -1
- package/dist/xlsx/collab/codec.d.ts +2 -0
- package/dist/xlsx/collab/codec.d.ts.map +1 -1
- package/dist/xlsx/collab/index.cjs +5 -0
- package/dist/xlsx/collab/index.mjs +5 -0
- package/dist/xlsx/display-text.d.ts +4 -0
- package/dist/xlsx/display-text.d.ts.map +1 -0
- package/dist/xlsx/edit/cell-values.d.ts +4 -3
- package/dist/xlsx/edit/cell-values.d.ts.map +1 -1
- package/dist/xlsx/edit/clipboard.d.ts.map +1 -1
- package/dist/xlsx/edit/context.d.ts +7 -5
- package/dist/xlsx/edit/context.d.ts.map +1 -1
- package/dist/xlsx/edit/deps.d.ts +1 -1
- package/dist/xlsx/edit/deps.d.ts.map +1 -1
- package/dist/xlsx/edit/dimensions.d.ts.map +1 -1
- package/dist/xlsx/edit/fill.d.ts.map +1 -1
- package/dist/xlsx/edit/filter.d.ts.map +1 -1
- package/dist/xlsx/edit/find.d.ts.map +1 -1
- package/dist/xlsx/edit/paste-selection.d.ts.map +1 -1
- package/dist/xlsx/edit/shift-formulas.d.ts +10 -4
- package/dist/xlsx/edit/shift-formulas.d.ts.map +1 -1
- package/dist/xlsx/edit/shift-sheet.d.ts.map +1 -1
- package/dist/xlsx/edit/structure.d.ts +1 -1
- package/dist/xlsx/edit/structure.d.ts.map +1 -1
- package/dist/xlsx/edit/table-header-names.d.ts +3 -0
- package/dist/xlsx/edit/table-header-names.d.ts.map +1 -0
- package/dist/xlsx/edit/tables.d.ts +1 -2
- package/dist/xlsx/edit/tables.d.ts.map +1 -1
- package/dist/xlsx/filter-rows.d.ts +12 -0
- package/dist/xlsx/filter-rows.d.ts.map +1 -0
- package/dist/xlsx/formula/functions/math-sum.d.ts.map +1 -1
- package/dist/xlsx/formula/table-refs.d.ts +2 -0
- package/dist/xlsx/formula/table-refs.d.ts.map +1 -1
- package/dist/xlsx/index.cjs +466 -329
- package/dist/xlsx/index.mjs +466 -329
- package/dist/xlsx/load/index.cjs +7622 -7585
- package/dist/xlsx/load/index.mjs +7622 -7585
- package/dist/xlsx/model.d.ts +4 -0
- package/dist/xlsx/model.d.ts.map +1 -1
- package/dist/xlsx/read/load.d.ts.map +1 -1
- package/dist/xlsx/ui/index.cjs +464 -329
- package/dist/xlsx/ui/index.mjs +464 -329
- package/dist/xlsx/ui/locales/de/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/en/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/es/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/fr/shell.d.ts.map +1 -1
- package/dist/xlsx/ui/locales/zh-CN/shell.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/visio/index.cjs
CHANGED
|
@@ -233,6 +233,19 @@ var attribute = new RegExp(
|
|
|
233
233
|
"uy"
|
|
234
234
|
);
|
|
235
235
|
var xmlWhitespace = (value) => /^[ \t\r\n]*$/.test(value);
|
|
236
|
+
var reservedNamespaces = /* @__PURE__ */ new Map([
|
|
237
|
+
["xml", "http://www.w3.org/XML/1998/namespace"],
|
|
238
|
+
["xmlns", "http://www.w3.org/2000/xmlns/"]
|
|
239
|
+
]);
|
|
240
|
+
function lookupNamespace(scope, prefix) {
|
|
241
|
+
const reserved = reservedNamespaces.get(prefix);
|
|
242
|
+
if (reserved !== void 0) return reserved;
|
|
243
|
+
for (; scope; scope = scope.parent) {
|
|
244
|
+
const uri = scope.bindings.get(prefix);
|
|
245
|
+
if (uri !== void 0) return uri;
|
|
246
|
+
}
|
|
247
|
+
return void 0;
|
|
248
|
+
}
|
|
236
249
|
function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
237
250
|
if (xml.length > limits.maxXmlChars) fail("LIMIT_XML", "XML character limit exceeded");
|
|
238
251
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml) || /[\u0000-\u0008\u000b\u000c\u000e-\u001f\ufffe\uffff]/.test(xml))
|
|
@@ -298,9 +311,7 @@ function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
|
298
311
|
fail("INVALID_XML", "Mismatched XML closing tag");
|
|
299
312
|
} else {
|
|
300
313
|
const attrs = /* @__PURE__ */ new Set();
|
|
301
|
-
const namespaces =
|
|
302
|
-
namespaces["xml"] = "http://www.w3.org/XML/1998/namespace";
|
|
303
|
-
namespaces["xmlns"] = "http://www.w3.org/2000/xmlns/";
|
|
314
|
+
const namespaces = { bindings: /* @__PURE__ */ new Map(), parent: stack.at(-1)?.namespaces };
|
|
304
315
|
while (!xmlWhitespace(body.slice(cursor))) {
|
|
305
316
|
attribute.lastIndex = cursor;
|
|
306
317
|
const match = attribute.exec(body);
|
|
@@ -310,14 +321,14 @@ function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
|
310
321
|
const value = match[2] ?? match[3] ?? "";
|
|
311
322
|
text(value);
|
|
312
323
|
if (match[1]?.startsWith("xmlns:"))
|
|
313
|
-
namespaces
|
|
324
|
+
namespaces.bindings.set(match[1].slice(6), decodeXmlAttribute(value));
|
|
314
325
|
node();
|
|
315
326
|
cursor = attribute.lastIndex;
|
|
316
327
|
}
|
|
317
328
|
const expanded = /* @__PURE__ */ new Set();
|
|
318
329
|
for (const attr2 of attrs) {
|
|
319
330
|
const colon = attr2.indexOf(":");
|
|
320
|
-
const uri = colon < 0 ? "" : namespaces
|
|
331
|
+
const uri = colon < 0 ? "" : lookupNamespace(namespaces, attr2.slice(0, colon));
|
|
321
332
|
if (uri === void 0) fail("INVALID_XML", "Unbound XML attribute prefix");
|
|
322
333
|
const key2 = `${uri}\0${attr2.slice(colon + 1)}`;
|
|
323
334
|
if (expanded.has(key2)) fail("INVALID_XML", "Duplicate expanded XML attribute name");
|
|
@@ -6601,11 +6612,23 @@ async function parseVsdx(input, options = {}) {
|
|
|
6601
6612
|
};
|
|
6602
6613
|
visit(shapes);
|
|
6603
6614
|
const connectors = connections(root2, localReport);
|
|
6615
|
+
const pageModes = {};
|
|
6616
|
+
for (const [name, key2] of [
|
|
6617
|
+
["DrawingSizeType", "drawingSizeType"],
|
|
6618
|
+
["DrawingResizeType", "drawingResizeType"]
|
|
6619
|
+
]) {
|
|
6620
|
+
const source = sheet.cells.get(name);
|
|
6621
|
+
if (!source || source.error !== void 0 || source.formula === "Inh" || source.unit !== void 0 && !["NUM", "BOOL"].includes(source.unit))
|
|
6622
|
+
continue;
|
|
6623
|
+
const value = number(sheet.cells, name, Number.NaN, localReport);
|
|
6624
|
+
if (Number.isSafeInteger(value) && value >= 0 && value <= 255) pageModes[key2] = value;
|
|
6625
|
+
}
|
|
6604
6626
|
for (const connection of connectors)
|
|
6605
6627
|
if (!seen.has(connection.fromShapeId) || !seen.has(connection.toShapeId))
|
|
6606
6628
|
localReport("dangling-connection", "A connection references a missing shape.");
|
|
6607
6629
|
pages.push({
|
|
6608
6630
|
id,
|
|
6631
|
+
...pageModes,
|
|
6609
6632
|
...drawingToPageScale === 1 ? {} : { drawingToPageScale },
|
|
6610
6633
|
name: metadata(
|
|
6611
6634
|
attribute2(page, "Name") ?? attribute2(page, "NameU") ?? `Page ${id}`,
|
|
@@ -15234,10 +15257,10 @@ function replaceRecord(input, drawing, record5, replacement) {
|
|
|
15234
15257
|
if (!(block.format & 2) || ![8, 12, 13].includes(block.format >>> 4))
|
|
15235
15258
|
throw new VsdError("unsafe-block-relocation");
|
|
15236
15259
|
try {
|
|
15237
|
-
const
|
|
15238
|
-
if (!
|
|
15260
|
+
const fit2 = encodeVsdBlockToSize(decoded, block.length);
|
|
15261
|
+
if (!fit2)
|
|
15239
15262
|
throw new VsdError("unsafe-block-relocation");
|
|
15240
|
-
stored =
|
|
15263
|
+
stored = fit2.bytes;
|
|
15241
15264
|
} catch (error) {
|
|
15242
15265
|
if (error instanceof VsdCompressionFitError)
|
|
15243
15266
|
throw new VsdError(`compression-${error.reason}`);
|
|
@@ -17417,8 +17440,8 @@ function assertUnlayeredShape(shape, document) {
|
|
|
17417
17440
|
}
|
|
17418
17441
|
}
|
|
17419
17442
|
|
|
17420
|
-
// visio/edit-text.ts
|
|
17421
|
-
|
|
17443
|
+
// visio/edit-text-target.ts
|
|
17444
|
+
function localTextTarget(root2, document, shapeId, check) {
|
|
17422
17445
|
const shapeChildren = (parent) => {
|
|
17423
17446
|
const containers = children2(parent, "Shapes");
|
|
17424
17447
|
if (containers.length > 1)
|
|
@@ -17426,37 +17449,38 @@ async function replacePlainText(root2, document, shapeId, text, check, assertDep
|
|
|
17426
17449
|
return children2(containers[0], "Shape");
|
|
17427
17450
|
};
|
|
17428
17451
|
const shapes = /* @__PURE__ */ new Map();
|
|
17429
|
-
const pending = shapeChildren(root2).map((
|
|
17430
|
-
node: node2,
|
|
17431
|
-
inherited: false,
|
|
17432
|
-
deleted: false
|
|
17433
|
-
}));
|
|
17452
|
+
const pending = shapeChildren(root2).map((node) => ({ node, inherited: false, deleted: false }));
|
|
17434
17453
|
while (pending.length) {
|
|
17435
17454
|
check();
|
|
17436
|
-
const item = pending.pop();
|
|
17437
|
-
const id = attribute2(item.node, "ID");
|
|
17455
|
+
const item = pending.pop(), id = attribute2(item.node, "ID");
|
|
17438
17456
|
if (!id || shapes.has(id))
|
|
17439
17457
|
fail("INVALID_SHAPE_ID", "Local shape IDs must be present and unique.");
|
|
17440
17458
|
const inherited = item.inherited || item.node.hasAttribute("Master") || item.node.hasAttribute("MasterShape");
|
|
17441
17459
|
const deleted = item.deleted || ["1", "true"].includes(attribute2(item.node, "Del") ?? "");
|
|
17442
17460
|
shapes.set(id, { node: item.node, inherited, deleted });
|
|
17443
|
-
for (const
|
|
17461
|
+
for (const node of shapeChildren(item.node)) pending.push({ node, inherited, deleted });
|
|
17444
17462
|
}
|
|
17445
17463
|
const target = shapes.get(shapeId);
|
|
17446
17464
|
if (!target) fail("EDIT_TARGET_NOT_FOUND", "Local shape does not exist.");
|
|
17447
17465
|
if (target.inherited || target.deleted)
|
|
17448
17466
|
fail("UNSUPPORTED_TEXT_EDIT", "Master-linked or deleted shapes cannot be edited.");
|
|
17449
17467
|
assertShapeLocks(target.node, document, ["LockTextEdit"]);
|
|
17450
|
-
|
|
17468
|
+
return target.node;
|
|
17469
|
+
}
|
|
17470
|
+
|
|
17471
|
+
// visio/edit-text.ts
|
|
17472
|
+
async function replacePlainText(root2, document, shapeId, text, check, assertDependencies2) {
|
|
17473
|
+
const target = localTextTarget(root2, document, shapeId, check);
|
|
17474
|
+
const texts = children2(target, "Text");
|
|
17451
17475
|
if (texts.length !== 1)
|
|
17452
17476
|
fail("UNSUPPORTED_TEXT_EDIT", "Editing requires one existing local Text element.");
|
|
17453
17477
|
const node = texts[0];
|
|
17454
17478
|
if (Array.from(node.childNodes).some((item) => item.nodeType !== 3 && item.nodeType !== 4))
|
|
17455
17479
|
fail("UNSUPPORTED_TEXT_EDIT", "Rich text, fields and unknown text markup cannot be edited.");
|
|
17456
|
-
if (children2(target
|
|
17480
|
+
if (children2(target, "Section").some((section) => attribute2(section, "N") === "Field"))
|
|
17457
17481
|
fail("UNSUPPORTED_TEXT_EDIT", "Shapes with text fields cannot be edited.");
|
|
17458
17482
|
if (decodeVisioPlainText(node.textContent ?? "") === text) return false;
|
|
17459
|
-
await
|
|
17483
|
+
await assertDependencies2(target, node);
|
|
17460
17484
|
check();
|
|
17461
17485
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
17462
17486
|
node.appendChild(node.ownerDocument.createTextNode(encodeVisioPlainText(text)));
|
|
@@ -17550,6 +17574,394 @@ function replaceScopedPlainText(pkg, pagePaths, roots, document, edit, check) {
|
|
|
17550
17574
|
);
|
|
17551
17575
|
}
|
|
17552
17576
|
|
|
17577
|
+
// visio/edit-text-range-plan.ts
|
|
17578
|
+
function textRangeNodes(node, edit) {
|
|
17579
|
+
const tokens2 = [];
|
|
17580
|
+
let stored = "";
|
|
17581
|
+
for (const part of Array.from(node.childNodes)) {
|
|
17582
|
+
const start = stored.length;
|
|
17583
|
+
if (part.nodeType === 3 || part.nodeType === 4) stored += part.nodeValue ?? "";
|
|
17584
|
+
tokens2.push({ node: part, start, end: stored.length });
|
|
17585
|
+
}
|
|
17586
|
+
if (decodeVisioPlainText(stored) !== edit.expectedText)
|
|
17587
|
+
fail("EDIT_STALE_TEXT", "Original text no longer matches the range command.");
|
|
17588
|
+
const changed = edit.ranges.some(
|
|
17589
|
+
(range) => edit.expectedText.slice(range.start, range.end) !== range.text
|
|
17590
|
+
);
|
|
17591
|
+
if (!changed) return { changed: false, nodes: [] };
|
|
17592
|
+
const starts = [], deltas = [];
|
|
17593
|
+
let delta = 0;
|
|
17594
|
+
for (const range of edit.ranges) {
|
|
17595
|
+
starts.push(range.start + delta);
|
|
17596
|
+
delta += range.text.length - (range.end - range.start);
|
|
17597
|
+
deltas.push(delta);
|
|
17598
|
+
}
|
|
17599
|
+
const length = edit.expectedText.length + delta;
|
|
17600
|
+
if (!length && tokens2.some((token) => token.node.nodeType === 1))
|
|
17601
|
+
fail(
|
|
17602
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17603
|
+
"Deleting all rich text has unproven native insertion-style behavior."
|
|
17604
|
+
);
|
|
17605
|
+
if (tokens2.some((token) => token.node.nodeType === 1)) {
|
|
17606
|
+
let start = 0, index = 0;
|
|
17607
|
+
while (start < edit.expectedText.length) {
|
|
17608
|
+
const newline = edit.expectedText.indexOf("\n", start), end = newline < 0 ? edit.expectedText.length : newline;
|
|
17609
|
+
let bodyLength = end - start;
|
|
17610
|
+
while (index < edit.ranges.length && edit.ranges[index].start < end) {
|
|
17611
|
+
const range = edit.ranges[index++];
|
|
17612
|
+
bodyLength += range.text.length - (range.end - range.start);
|
|
17613
|
+
}
|
|
17614
|
+
if (end > start && !bodyLength)
|
|
17615
|
+
fail(
|
|
17616
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17617
|
+
"Deleting an entire rich paragraph body has unproven native insertion-style behavior."
|
|
17618
|
+
);
|
|
17619
|
+
start = end + 1;
|
|
17620
|
+
}
|
|
17621
|
+
}
|
|
17622
|
+
const position = (offset) => {
|
|
17623
|
+
let low = 0, high = edit.ranges.length;
|
|
17624
|
+
while (low < high) {
|
|
17625
|
+
const middle = low + high >>> 1;
|
|
17626
|
+
if (edit.ranges[middle].start < offset) low = middle + 1;
|
|
17627
|
+
else high = middle;
|
|
17628
|
+
}
|
|
17629
|
+
const index = low - 1;
|
|
17630
|
+
if (index < 0) return offset;
|
|
17631
|
+
const range = edit.ranges[index];
|
|
17632
|
+
return offset <= range.end ? starts[index] + range.text.length : offset + deltas[index];
|
|
17633
|
+
};
|
|
17634
|
+
const output = [];
|
|
17635
|
+
const append = (token, start, end) => {
|
|
17636
|
+
if (end <= start) return;
|
|
17637
|
+
const part = start === token.start && end === token.end ? token.node : token.node.cloneNode(false);
|
|
17638
|
+
if (part !== token.node)
|
|
17639
|
+
part.nodeValue = (token.node.nodeValue ?? "").slice(start - token.start, end - token.start);
|
|
17640
|
+
output.push({ position: position(start), priority: 2, node: part });
|
|
17641
|
+
};
|
|
17642
|
+
let first2 = 0;
|
|
17643
|
+
for (const token of tokens2) {
|
|
17644
|
+
if (token.node.nodeType === 1) {
|
|
17645
|
+
output.push({ position: position(token.start), priority: 0, node: token.node });
|
|
17646
|
+
continue;
|
|
17647
|
+
}
|
|
17648
|
+
const end = length ? token.end : Math.min(token.end, edit.expectedText.length);
|
|
17649
|
+
let cursor = token.start;
|
|
17650
|
+
while (first2 < edit.ranges.length && edit.ranges[first2].end <= cursor) first2++;
|
|
17651
|
+
for (let index = first2; index < edit.ranges.length && edit.ranges[index].start < end; index++) {
|
|
17652
|
+
const range = edit.ranges[index];
|
|
17653
|
+
append(token, cursor, Math.min(end, range.start));
|
|
17654
|
+
cursor = Math.max(cursor, Math.min(end, range.end));
|
|
17655
|
+
}
|
|
17656
|
+
append(token, cursor, end);
|
|
17657
|
+
}
|
|
17658
|
+
for (let index = 0; index < edit.ranges.length; index++) {
|
|
17659
|
+
const text = edit.ranges[index].text;
|
|
17660
|
+
if (text)
|
|
17661
|
+
output.push({
|
|
17662
|
+
position: starts[index],
|
|
17663
|
+
priority: 1,
|
|
17664
|
+
node: node.ownerDocument.createTextNode(text)
|
|
17665
|
+
});
|
|
17666
|
+
}
|
|
17667
|
+
output.sort((a, b) => a.position - b.position || a.priority - b.priority);
|
|
17668
|
+
let characterPosition = -1, characterRow = null;
|
|
17669
|
+
for (const item of output) {
|
|
17670
|
+
if (item.node.nodeType !== 1 || item.node.localName !== "cp") continue;
|
|
17671
|
+
const row = item.node.getAttribute("IX");
|
|
17672
|
+
if (item.position === characterPosition && row !== characterRow)
|
|
17673
|
+
fail(
|
|
17674
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17675
|
+
"Consuming complete character runs creates ambiguous native marker boundaries."
|
|
17676
|
+
);
|
|
17677
|
+
characterPosition = item.position;
|
|
17678
|
+
characterRow = row;
|
|
17679
|
+
}
|
|
17680
|
+
return { changed: true, nodes: output.map((item) => item.node) };
|
|
17681
|
+
}
|
|
17682
|
+
|
|
17683
|
+
// visio/edit-text-ranges.ts
|
|
17684
|
+
async function replaceScopedTextRanges(pkg, pagePaths, roots, document, edit, check) {
|
|
17685
|
+
const shape = localTextTarget(roots.get(edit.pageId), document, edit.shapeId, check);
|
|
17686
|
+
if (children2(shape, "Section").some((section) => attribute2(section, "N") === "Field"))
|
|
17687
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Text range editing of shapes with fields is unsupported.");
|
|
17688
|
+
const texts = children2(shape, "Text");
|
|
17689
|
+
if (texts.length !== 1)
|
|
17690
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Range editing requires one existing local Text element.");
|
|
17691
|
+
const text = texts[0];
|
|
17692
|
+
if (Array.from(text.childNodes).some((node) => ![3, 4].includes(node.nodeType))) {
|
|
17693
|
+
const characters = effectiveFormattingRows(shape, document, "Character"), paragraphs = effectiveFormattingRows(shape, document, "Paragraph");
|
|
17694
|
+
assertFormattingText(shape, characters, paragraphs);
|
|
17695
|
+
}
|
|
17696
|
+
if (Array.from(text.childNodes).some(
|
|
17697
|
+
(node) => node.nodeType === 1 && node.localName === "fld"
|
|
17698
|
+
))
|
|
17699
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Text range editing of fields is unsupported.");
|
|
17700
|
+
let preceding = "";
|
|
17701
|
+
for (const node of Array.from(text.childNodes)) {
|
|
17702
|
+
if (node.nodeType === 3 || node.nodeType === 4) preceding += node.nodeValue ?? "";
|
|
17703
|
+
else {
|
|
17704
|
+
const marker2 = node;
|
|
17705
|
+
if (marker2.localName === "pp" && preceding && !preceding.endsWith("\n") || marker2.localName === "tp" && attribute2(marker2, "IX") !== "0")
|
|
17706
|
+
fail(
|
|
17707
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17708
|
+
"Noncanonical paragraph or tab marker placement cannot be edited."
|
|
17709
|
+
);
|
|
17710
|
+
}
|
|
17711
|
+
}
|
|
17712
|
+
const plan = textRangeNodes(text, edit);
|
|
17713
|
+
if (!plan.changed) return false;
|
|
17714
|
+
await assertFormattingDependencies(
|
|
17715
|
+
pkg,
|
|
17716
|
+
pagePaths,
|
|
17717
|
+
roots,
|
|
17718
|
+
edit.pageId,
|
|
17719
|
+
shape,
|
|
17720
|
+
/* @__PURE__ */ new Map([["TheText", text]]),
|
|
17721
|
+
check
|
|
17722
|
+
);
|
|
17723
|
+
check();
|
|
17724
|
+
while (text.firstChild) text.removeChild(text.firstChild);
|
|
17725
|
+
for (const node of plan.nodes) text.appendChild(node);
|
|
17726
|
+
return true;
|
|
17727
|
+
}
|
|
17728
|
+
|
|
17729
|
+
// visio/basic-shapes.ts
|
|
17730
|
+
var VISIO_BASIC_SHAPES = [
|
|
17731
|
+
"rectangle",
|
|
17732
|
+
"square",
|
|
17733
|
+
"triangle",
|
|
17734
|
+
"right-triangle",
|
|
17735
|
+
"pentagon",
|
|
17736
|
+
"hexagon",
|
|
17737
|
+
"octagon",
|
|
17738
|
+
"star",
|
|
17739
|
+
"diamond",
|
|
17740
|
+
"rounded-rectangle",
|
|
17741
|
+
"cross",
|
|
17742
|
+
"parallelogram",
|
|
17743
|
+
"trapezoid",
|
|
17744
|
+
"can",
|
|
17745
|
+
"cube",
|
|
17746
|
+
"chevron"
|
|
17747
|
+
];
|
|
17748
|
+
var isVisioBasicShape = (value) => VISIO_BASIC_SHAPES.includes(value);
|
|
17749
|
+
function fit(points) {
|
|
17750
|
+
const xs = points.map(([x]) => x), ys = points.map(([, y]) => y);
|
|
17751
|
+
const left = Math.min(...xs), bottom = Math.min(...ys);
|
|
17752
|
+
const width = Math.max(...xs) - left, height = Math.max(...ys) - bottom;
|
|
17753
|
+
return points.map(([x, y]) => [(x - left) / width, (y - bottom) / height]);
|
|
17754
|
+
}
|
|
17755
|
+
function polygon(count, inner) {
|
|
17756
|
+
const steps = inner === void 0 ? count : count * 2;
|
|
17757
|
+
return fit(
|
|
17758
|
+
Array.from({ length: steps }, (_, index) => {
|
|
17759
|
+
const radius = inner !== void 0 && index % 2 ? inner : 1;
|
|
17760
|
+
const angle = Math.PI / 2 + index * 2 * Math.PI / steps;
|
|
17761
|
+
return [radius * Math.cos(angle), radius * Math.sin(angle)];
|
|
17762
|
+
})
|
|
17763
|
+
);
|
|
17764
|
+
}
|
|
17765
|
+
function arc(cy, ry, from, to) {
|
|
17766
|
+
const segments = 12;
|
|
17767
|
+
return Array.from({ length: segments + 1 }, (_, index) => {
|
|
17768
|
+
const angle = from + (to - from) * index / segments;
|
|
17769
|
+
return [0.5 + 0.5 * Math.cos(angle), cy + ry * Math.sin(angle)];
|
|
17770
|
+
});
|
|
17771
|
+
}
|
|
17772
|
+
var box = [
|
|
17773
|
+
[0, 0],
|
|
17774
|
+
[1, 0],
|
|
17775
|
+
[1, 1],
|
|
17776
|
+
[0, 1]
|
|
17777
|
+
];
|
|
17778
|
+
var LID = 0.2;
|
|
17779
|
+
var CUT = 1 / (2 + Math.SQRT2);
|
|
17780
|
+
var OUTLINES = {
|
|
17781
|
+
rectangle: { paths: [box] },
|
|
17782
|
+
square: { paths: [box] },
|
|
17783
|
+
triangle: {
|
|
17784
|
+
paths: [
|
|
17785
|
+
[
|
|
17786
|
+
[0, 0],
|
|
17787
|
+
[1, 0],
|
|
17788
|
+
[0.5, 1]
|
|
17789
|
+
]
|
|
17790
|
+
]
|
|
17791
|
+
},
|
|
17792
|
+
"right-triangle": {
|
|
17793
|
+
paths: [
|
|
17794
|
+
[
|
|
17795
|
+
[0, 0],
|
|
17796
|
+
[1, 0],
|
|
17797
|
+
[0, 1]
|
|
17798
|
+
]
|
|
17799
|
+
]
|
|
17800
|
+
},
|
|
17801
|
+
pentagon: { paths: [polygon(5)] },
|
|
17802
|
+
hexagon: {
|
|
17803
|
+
paths: [
|
|
17804
|
+
[
|
|
17805
|
+
[0.25, 0],
|
|
17806
|
+
[0.75, 0],
|
|
17807
|
+
[1, 0.5],
|
|
17808
|
+
[0.75, 1],
|
|
17809
|
+
[0.25, 1],
|
|
17810
|
+
[0, 0.5]
|
|
17811
|
+
]
|
|
17812
|
+
]
|
|
17813
|
+
},
|
|
17814
|
+
octagon: {
|
|
17815
|
+
paths: [
|
|
17816
|
+
[
|
|
17817
|
+
[CUT, 0],
|
|
17818
|
+
[1 - CUT, 0],
|
|
17819
|
+
[1, CUT],
|
|
17820
|
+
[1, 1 - CUT],
|
|
17821
|
+
[1 - CUT, 1],
|
|
17822
|
+
[CUT, 1],
|
|
17823
|
+
[0, 1 - CUT],
|
|
17824
|
+
[0, CUT]
|
|
17825
|
+
]
|
|
17826
|
+
]
|
|
17827
|
+
},
|
|
17828
|
+
star: { paths: [polygon(5, 0.382)] },
|
|
17829
|
+
diamond: {
|
|
17830
|
+
paths: [
|
|
17831
|
+
[
|
|
17832
|
+
[0.5, 0],
|
|
17833
|
+
[1, 0.5],
|
|
17834
|
+
[0.5, 1],
|
|
17835
|
+
[0, 0.5]
|
|
17836
|
+
]
|
|
17837
|
+
]
|
|
17838
|
+
},
|
|
17839
|
+
"rounded-rectangle": { paths: [box], rounding: 0.15 },
|
|
17840
|
+
cross: {
|
|
17841
|
+
paths: [
|
|
17842
|
+
[
|
|
17843
|
+
[1 / 3, 0],
|
|
17844
|
+
[2 / 3, 0],
|
|
17845
|
+
[2 / 3, 1 / 3],
|
|
17846
|
+
[1, 1 / 3],
|
|
17847
|
+
[1, 2 / 3],
|
|
17848
|
+
[2 / 3, 2 / 3],
|
|
17849
|
+
[2 / 3, 1],
|
|
17850
|
+
[1 / 3, 1],
|
|
17851
|
+
[1 / 3, 2 / 3],
|
|
17852
|
+
[0, 2 / 3],
|
|
17853
|
+
[0, 1 / 3],
|
|
17854
|
+
[1 / 3, 1 / 3]
|
|
17855
|
+
]
|
|
17856
|
+
]
|
|
17857
|
+
},
|
|
17858
|
+
parallelogram: {
|
|
17859
|
+
paths: [
|
|
17860
|
+
[
|
|
17861
|
+
[0, 0],
|
|
17862
|
+
[0.75, 0],
|
|
17863
|
+
[1, 1],
|
|
17864
|
+
[0.25, 1]
|
|
17865
|
+
]
|
|
17866
|
+
]
|
|
17867
|
+
},
|
|
17868
|
+
trapezoid: {
|
|
17869
|
+
paths: [
|
|
17870
|
+
[
|
|
17871
|
+
[0, 0],
|
|
17872
|
+
[1, 0],
|
|
17873
|
+
[0.75, 1],
|
|
17874
|
+
[0.25, 1]
|
|
17875
|
+
]
|
|
17876
|
+
]
|
|
17877
|
+
},
|
|
17878
|
+
can: {
|
|
17879
|
+
paths: [
|
|
17880
|
+
// The body: down the left side, round the front of the base, up the right side and
|
|
17881
|
+
// back along the front of the lid.
|
|
17882
|
+
[...arc(LID / 2, LID / 2, Math.PI, 2 * Math.PI), ...arc(1 - LID / 2, LID / 2, 0, -Math.PI)],
|
|
17883
|
+
// The lid, drawn over the body.
|
|
17884
|
+
arc(1 - LID / 2, LID / 2, 0, 2 * Math.PI).slice(0, -1)
|
|
17885
|
+
]
|
|
17886
|
+
},
|
|
17887
|
+
cube: {
|
|
17888
|
+
paths: [
|
|
17889
|
+
[
|
|
17890
|
+
[0, 0],
|
|
17891
|
+
[0.75, 0],
|
|
17892
|
+
[0.75, 0.75],
|
|
17893
|
+
[0, 0.75]
|
|
17894
|
+
],
|
|
17895
|
+
[
|
|
17896
|
+
[0, 0.75],
|
|
17897
|
+
[0.75, 0.75],
|
|
17898
|
+
[1, 1],
|
|
17899
|
+
[0.25, 1]
|
|
17900
|
+
],
|
|
17901
|
+
[
|
|
17902
|
+
[0.75, 0],
|
|
17903
|
+
[1, 0.25],
|
|
17904
|
+
[1, 1],
|
|
17905
|
+
[0.75, 0.75]
|
|
17906
|
+
]
|
|
17907
|
+
]
|
|
17908
|
+
},
|
|
17909
|
+
chevron: {
|
|
17910
|
+
paths: [
|
|
17911
|
+
[
|
|
17912
|
+
[0, 0],
|
|
17913
|
+
[0.75, 0],
|
|
17914
|
+
[1, 0.5],
|
|
17915
|
+
[0.75, 1],
|
|
17916
|
+
[0, 1],
|
|
17917
|
+
[0.25, 0.5]
|
|
17918
|
+
]
|
|
17919
|
+
]
|
|
17920
|
+
}
|
|
17921
|
+
};
|
|
17922
|
+
function visioBasicShapeOutline(shape) {
|
|
17923
|
+
return OUTLINES[shape];
|
|
17924
|
+
}
|
|
17925
|
+
|
|
17926
|
+
// visio/edit-text-range-commands.ts
|
|
17927
|
+
var invalidXmlText = /[\u0000-\u0008\u000b\u000c\u000d\u000e-\u001f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/u;
|
|
17928
|
+
function textRangeBoundary(text, offset) {
|
|
17929
|
+
return !(offset > 0 && offset < text.length && /[\ud800-\udbff]/.test(text[offset - 1]) && /[\udc00-\udfff]/.test(text[offset]));
|
|
17930
|
+
}
|
|
17931
|
+
function snapshotTextRanges(edit, consume) {
|
|
17932
|
+
let characters = 0;
|
|
17933
|
+
const text = (value) => {
|
|
17934
|
+
if (typeof value !== "string" || invalidXmlText.test(value))
|
|
17935
|
+
fail("INVALID_EDIT_TEXT", "Range replacement requires valid XML text.");
|
|
17936
|
+
characters += value.length;
|
|
17937
|
+
if (characters > 1e6)
|
|
17938
|
+
fail("LIMIT_EDIT_TEXT", "Range replacement text exceeds input limits.");
|
|
17939
|
+
return consume ? consume(value) : value;
|
|
17940
|
+
};
|
|
17941
|
+
const pageId = edit.pageId, shapeId = edit.shapeId;
|
|
17942
|
+
if ([pageId, shapeId].some((id) => typeof id !== "string" || !id || id.length > 256))
|
|
17943
|
+
fail("INVALID_EDIT", "Invalid text range target.");
|
|
17944
|
+
const expectedText = text(edit.expectedText), original = edit.ranges;
|
|
17945
|
+
if (!Array.isArray(original)) fail("INVALID_EDIT", "Text ranges require an array.");
|
|
17946
|
+
const length = original.length;
|
|
17947
|
+
if (!Number.isSafeInteger(length) || length < 1 || length > 1e4)
|
|
17948
|
+
fail("LIMIT_EDITS", "Range replacement requires 1-10000 ranges.");
|
|
17949
|
+
const ranges = [];
|
|
17950
|
+
let end = 0, output = expectedText.length;
|
|
17951
|
+
for (let index = 0; index < length; index++) {
|
|
17952
|
+
const input = original[index], start = input.start, nextEnd = input.end, replacement = text(input.text);
|
|
17953
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(nextEnd) || start < end || nextEnd <= start || nextEnd > expectedText.length || !textRangeBoundary(expectedText, start) || !textRangeBoundary(expectedText, nextEnd))
|
|
17954
|
+
fail("INVALID_EDIT", "Text ranges require ascending nonoverlapping UTF16 scalar boundaries.");
|
|
17955
|
+
if (replacement.includes("\n") || expectedText.slice(start, nextEnd).includes("\n"))
|
|
17956
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Range replacement across paragraph breaks is unsupported.");
|
|
17957
|
+
ranges.push({ start, end: nextEnd, text: replacement });
|
|
17958
|
+
end = nextEnd;
|
|
17959
|
+
output += replacement.length - (nextEnd - start);
|
|
17960
|
+
}
|
|
17961
|
+
if (output > 1e6) fail("LIMIT_EDIT_TEXT", "Range replacement output exceeds limits.");
|
|
17962
|
+
return { type: "replace-text-ranges", pageId, shapeId, expectedText, ranges };
|
|
17963
|
+
}
|
|
17964
|
+
|
|
17553
17965
|
// visio/resize-anchor.ts
|
|
17554
17966
|
function snapshotResizeAnchor(value) {
|
|
17555
17967
|
if (value === void 0) return void 0;
|
|
@@ -17782,7 +18194,7 @@ function snapshotFormatting(edit) {
|
|
|
17782
18194
|
}
|
|
17783
18195
|
|
|
17784
18196
|
// visio/edit-commands.ts
|
|
17785
|
-
var isVisioPageEdit = (edit) => edit.type === "insert-page" || edit.type === "reorder-page" || edit.type === "rename-page" || edit.type === "delete-page";
|
|
18197
|
+
var isVisioPageEdit = (edit) => edit.type === "insert-page" || edit.type === "reorder-page" || edit.type === "rename-page" || edit.type === "delete-page" || edit.type === "set-page-size";
|
|
17786
18198
|
function geometryChangedCells(edit) {
|
|
17787
18199
|
if (edit.type === "create-line")
|
|
17788
18200
|
return [
|
|
@@ -17840,6 +18252,13 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17840
18252
|
if (edit.type === "duplicate-shapes") return snapshotDuplicateShapes(edit);
|
|
17841
18253
|
if (edit.type === "paste-shapes") return snapshotPasteShapes(edit);
|
|
17842
18254
|
if (edit.type === "delete-page") return { type: edit.type, pageId: edit.pageId };
|
|
18255
|
+
if (edit.type === "set-page-size")
|
|
18256
|
+
return {
|
|
18257
|
+
type: edit.type,
|
|
18258
|
+
pageId: edit.pageId,
|
|
18259
|
+
width: numeric5(edit.width, true),
|
|
18260
|
+
height: numeric5(edit.height, true)
|
|
18261
|
+
};
|
|
17843
18262
|
if (edit.type === "reorder-page") {
|
|
17844
18263
|
if (!Number.isSafeInteger(edit.index) || edit.index < 0 || edit.index > 1e6)
|
|
17845
18264
|
fail("INVALID_EDIT", "Page order requires a bounded zero-based integer index.");
|
|
@@ -17862,6 +18281,7 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17862
18281
|
const target = { pageId: edit.pageId, shapeId: edit.shapeId };
|
|
17863
18282
|
if (edit.type === "replace-plain-text")
|
|
17864
18283
|
return { ...target, type: edit.type, text: text(edit.text) };
|
|
18284
|
+
if (edit.type === "replace-text-ranges") return snapshotTextRanges(edit, text);
|
|
17865
18285
|
if (isVisioFormatEdit(edit)) return snapshotFormatting(edit);
|
|
17866
18286
|
if (edit.type === "reorder-shape") {
|
|
17867
18287
|
if (!["front", "back", "forward", "backward"].includes(edit.order))
|
|
@@ -17888,7 +18308,10 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17888
18308
|
return { ...target, type: edit.type, beginX, beginY, endX, endY };
|
|
17889
18309
|
}
|
|
17890
18310
|
case "create-rectangle":
|
|
17891
|
-
case "create-ellipse":
|
|
18311
|
+
case "create-ellipse": {
|
|
18312
|
+
const shape = edit.type === "create-rectangle" ? edit.shape : void 0;
|
|
18313
|
+
if (shape !== void 0 && !isVisioBasicShape(shape))
|
|
18314
|
+
fail("INVALID_EDIT", "Unknown basic shape.");
|
|
17892
18315
|
return {
|
|
17893
18316
|
...target,
|
|
17894
18317
|
type: edit.type,
|
|
@@ -17896,8 +18319,10 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17896
18319
|
y: numeric5(edit.y),
|
|
17897
18320
|
width: numeric5(edit.width, true),
|
|
17898
18321
|
height: numeric5(edit.height, true),
|
|
17899
|
-
...edit.text === void 0 ? {} : { text: text(edit.text) }
|
|
18322
|
+
...edit.text === void 0 ? {} : { text: text(edit.text) },
|
|
18323
|
+
...shape === void 0 ? {} : { shape }
|
|
17900
18324
|
};
|
|
18325
|
+
}
|
|
17901
18326
|
case "rotate-shape":
|
|
17902
18327
|
return { ...target, type: edit.type, angle: numeric5(edit.angle) };
|
|
17903
18328
|
case "flip-shape":
|
|
@@ -18311,24 +18736,25 @@ function createRectangle(root2, document, edit) {
|
|
|
18311
18736
|
}
|
|
18312
18737
|
const doc = root2.ownerDocument;
|
|
18313
18738
|
const node = (name) => doc.createElementNS(root2.namespaceURI, name);
|
|
18314
|
-
const
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18324
|
-
|
|
18325
|
-
|
|
18326
|
-
|
|
18327
|
-
|
|
18328
|
-
|
|
18329
|
-
|
|
18739
|
+
const outline = visioBasicShapeOutline(
|
|
18740
|
+
edit.type === "create-rectangle" ? edit.shape ?? "rectangle" : "rectangle"
|
|
18741
|
+
);
|
|
18742
|
+
if (outline.rounding)
|
|
18743
|
+
setCell(shape, "Rounding", outline.rounding * Math.min(edit.width, edit.height));
|
|
18744
|
+
for (const [sectionIndex, points] of outline.paths.entries()) {
|
|
18745
|
+
const section = node("Section");
|
|
18746
|
+
section.setAttribute("N", "Geometry");
|
|
18747
|
+
section.setAttribute("IX", String(sectionIndex));
|
|
18748
|
+
for (const [index, [x, y]] of [...points, points[0]].entries()) {
|
|
18749
|
+
const row = node("Row");
|
|
18750
|
+
row.setAttribute("IX", String(index + 1));
|
|
18751
|
+
row.setAttribute("T", index ? "RelLineTo" : "RelMoveTo");
|
|
18752
|
+
setCell(row, "X", x);
|
|
18753
|
+
setCell(row, "Y", y);
|
|
18754
|
+
section.appendChild(row);
|
|
18755
|
+
}
|
|
18756
|
+
shape.appendChild(section);
|
|
18330
18757
|
}
|
|
18331
|
-
shape.appendChild(section);
|
|
18332
18758
|
const text = node("Text");
|
|
18333
18759
|
text.appendChild(doc.createTextNode(encodeVisioPlainText(edit.text ?? "")));
|
|
18334
18760
|
shape.appendChild(text);
|
|
@@ -20560,6 +20986,145 @@ function addReplacementPage(pagesPart, pages, rels, types, pagePaths, parts, dir
|
|
|
20560
20986
|
);
|
|
20561
20987
|
}
|
|
20562
20988
|
|
|
20989
|
+
// visio/edit-page-size.ts
|
|
20990
|
+
function constant(node, length) {
|
|
20991
|
+
if (!node || node.hasAttribute("E") || attribute2(node, "F") === "Inh")
|
|
20992
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "A valid explicit page size or mode cache is required.");
|
|
20993
|
+
const value = visioFormulaCachedValue(attribute2(node, "V") ?? "", attribute2(node, "U"));
|
|
20994
|
+
if (!Number.isFinite(value.value) || !["scalar", ...length ? ["length"] : []].includes(value.unit))
|
|
20995
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page size or mode has incompatible units.");
|
|
20996
|
+
const formula = executableCellFormula(attribute2(node, "F"));
|
|
20997
|
+
if (formula) {
|
|
20998
|
+
const analysis = analyzeVisioFormula(formula);
|
|
20999
|
+
if (analysis.guarded || analysis.dynamic || analysis.references.length || analysis.unsupportedFunctions.length)
|
|
21000
|
+
fail("EDIT_PROTECTED_CELL", "Protected or dependent page settings cannot be overwritten.");
|
|
21001
|
+
const result = evaluateVisioFormula(
|
|
21002
|
+
formula,
|
|
21003
|
+
() => fail("EDIT_PROTECTED_CELL", "Unsupported page dependency.")
|
|
21004
|
+
);
|
|
21005
|
+
if (result.value !== value.value || !["scalar", ...length ? ["length"] : []].includes(result.unit))
|
|
21006
|
+
fail("EDIT_PROTECTED_CELL", "Page setting formula cache cannot be proven.");
|
|
21007
|
+
}
|
|
21008
|
+
return value.value;
|
|
21009
|
+
}
|
|
21010
|
+
var escape3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21011
|
+
function assertDependencies(roots, pagesPart, pages, pagePaths, pageId, changed, check) {
|
|
21012
|
+
const page = children2(pages, "Page").find((node) => attribute2(node, "ID") === pageId);
|
|
21013
|
+
const targetNames = new Set(
|
|
21014
|
+
["Name", "NameU"].map((name) => attribute2(page, name)?.toLowerCase())
|
|
21015
|
+
);
|
|
21016
|
+
const otherNames = children2(pages, "Page").filter((node) => node !== page).flatMap((node) => ["Name", "NameU"].map((name) => attribute2(node, name))).filter((name) => !!name && !targetNames.has(name.toLowerCase()));
|
|
21017
|
+
const cells4 = changed.map(escape3).join("|");
|
|
21018
|
+
const reference = new RegExp(`(?:^|[^a-z0-9_.])(?:${cells4})(?:$|[^a-z0-9_.])`, "i");
|
|
21019
|
+
const other = otherNames.length ? new RegExp(
|
|
21020
|
+
`Pages\\[(?:${otherNames.map(escape3).join("|")})\\]!(?:ThePage!)?(?:${cells4})(?![a-z0-9_.])`,
|
|
21021
|
+
"gi"
|
|
21022
|
+
) : void 0;
|
|
21023
|
+
const paths = new Map([...pagePaths].map(([id, path]) => [path, id]));
|
|
21024
|
+
for (const [path, root2] of roots)
|
|
21025
|
+
for (const node of [root2, ...Array.from(root2.getElementsByTagName("*"))]) {
|
|
21026
|
+
check();
|
|
21027
|
+
const formula = executableCellFormula(attribute2(node, "F"));
|
|
21028
|
+
if (!formula) continue;
|
|
21029
|
+
let code = unquotedVisioFormula(formula);
|
|
21030
|
+
const name = attribute2(node, "N") ?? "";
|
|
21031
|
+
if (inertDoubleClickFormula(name, formula)) continue;
|
|
21032
|
+
const owner = node.parentNode, container = owner?.parentNode;
|
|
21033
|
+
const ownerId = attribute2(owner ?? void 0, "ID");
|
|
21034
|
+
const connected = ownerId && /^[1-9]\d{0,9}$/.test(ownerId) && owner?.localName === "Shape" && owner.namespaceURI === root2.namespaceURI && (!attribute2(owner, "Type") || attribute2(owner, "Type") === "Shape") && !owner.hasAttribute("Master") && !owner.hasAttribute("MasterShape") && !children2(owner, "Shapes").length && ["BeginX", "BeginY", "EndX", "EndY"].every(
|
|
21035
|
+
(name2) => children2(owner, "Cell").filter((cell) => attribute2(cell, "N") === name2).length === 1
|
|
21036
|
+
) && container?.localName === "Shapes" && container.parentNode === root2 && children2(root2, "Connects").some(
|
|
21037
|
+
(connections2) => children2(connections2, "Connect").some(
|
|
21038
|
+
(connection) => attribute2(connection, "FromSheet") === ownerId
|
|
21039
|
+
)
|
|
21040
|
+
);
|
|
21041
|
+
const nativeGlue = paths.has(path) && connected && node.localName === "Cell" && node.namespaceURI === root2.namespaceURI && (/^(BeginX|BeginY|EndX|EndY)$/.test(name) && /^\s*_WALKGLUE\((?:BegTrigger,EndTrigger|EndTrigger,BegTrigger),WalkPreference\)\s*$/i.test(
|
|
21042
|
+
code
|
|
21043
|
+
) || /^(BegTrigger|EndTrigger)$/.test(name) && /^\s*_XFTRIGGER\(Sheet\.[1-9]\d*!EventXFMod\)\s*$/i.test(code));
|
|
21044
|
+
let dynamic2 = false;
|
|
21045
|
+
if (!nativeGlue) {
|
|
21046
|
+
try {
|
|
21047
|
+
dynamic2 = analyzeVisioFormula(
|
|
21048
|
+
mapVisioFormulaSyntax(
|
|
21049
|
+
formula,
|
|
21050
|
+
(part) => (other ? part.replace(other, "0") : part).replace(/Pages\[[^\]]+\]!/gi, "").replace(/ThePage!/gi, "")
|
|
21051
|
+
)
|
|
21052
|
+
).dynamic;
|
|
21053
|
+
} catch {
|
|
21054
|
+
dynamic2 = true;
|
|
21055
|
+
}
|
|
21056
|
+
}
|
|
21057
|
+
if (dynamic2)
|
|
21058
|
+
fail(
|
|
21059
|
+
"EDIT_UNSUPPORTED_PAGE_SIZE_DEPENDENCY",
|
|
21060
|
+
"Dynamic or unknown page-size dependencies cannot be safely refreshed."
|
|
21061
|
+
);
|
|
21062
|
+
let local = paths.get(path);
|
|
21063
|
+
if (path === pagesPart) {
|
|
21064
|
+
let ancestor = node;
|
|
21065
|
+
while (ancestor && ancestor.localName !== "Page")
|
|
21066
|
+
ancestor = ancestor.parentNode;
|
|
21067
|
+
local = ancestor ? attribute2(ancestor, "ID") : void 0;
|
|
21068
|
+
}
|
|
21069
|
+
if (other) code = code.replace(other, "0");
|
|
21070
|
+
if (!reference.test(code)) continue;
|
|
21071
|
+
if (local && local !== pageId && !/\bPages\[/i.test(code)) continue;
|
|
21072
|
+
fail(
|
|
21073
|
+
"EDIT_UNSUPPORTED_PAGE_SIZE_DEPENDENCY",
|
|
21074
|
+
"Page-size formula caches cannot be safely refreshed."
|
|
21075
|
+
);
|
|
21076
|
+
}
|
|
21077
|
+
}
|
|
21078
|
+
async function setVisioPageSize(pkg, pagesPart, pages, pagePaths, dirty, command2, check) {
|
|
21079
|
+
const page = children2(pages, "Page").find((node) => attribute2(node, "ID") === command2.pageId);
|
|
21080
|
+
if (!page) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
|
|
21081
|
+
if (children2(page, "PageSheet").length !== 1)
|
|
21082
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "One explicit PageSheet is required.");
|
|
21083
|
+
const sheet = child(page, "PageSheet"), cells4 = uniqueFormattingCells(sheet);
|
|
21084
|
+
for (const name of [
|
|
21085
|
+
"PageWidth",
|
|
21086
|
+
"PageHeight",
|
|
21087
|
+
"PageScale",
|
|
21088
|
+
"DrawingScale",
|
|
21089
|
+
"DrawingSizeType",
|
|
21090
|
+
"DrawingResizeType"
|
|
21091
|
+
])
|
|
21092
|
+
if (!cells4.has(name) && [...cells4.keys()].some((key2) => key2.toLowerCase() === name.toLowerCase()))
|
|
21093
|
+
fail("EDIT_AMBIGUOUS_CELL", "Page settings require canonical cell names.");
|
|
21094
|
+
const pageScale = constant(cells4.get("PageScale"), true), drawingScale = constant(cells4.get("DrawingScale"), true);
|
|
21095
|
+
if (pageScale <= 0 || drawingScale <= 0)
|
|
21096
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page and drawing scales must be positive.");
|
|
21097
|
+
const width = constant(cells4.get("PageWidth"), true), height = constant(cells4.get("PageHeight"), true);
|
|
21098
|
+
const size = constant(cells4.get("DrawingSizeType"), false);
|
|
21099
|
+
const resize = cells4.has("DrawingResizeType") ? constant(cells4.get("DrawingResizeType"), false) : void 0;
|
|
21100
|
+
if (width <= 0 || height <= 0 || ![0, 1, 2, 3, 4].includes(size) || resize !== void 0 && ![0, 1, 2].includes(resize))
|
|
21101
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page dimensions or size modes are unsupported.");
|
|
21102
|
+
const targetWidth = command2.width === width * (pageScale / drawingScale) ? width : command2.width * drawingScale / pageScale, targetHeight = command2.height === height * (pageScale / drawingScale) ? height : command2.height * drawingScale / pageScale;
|
|
21103
|
+
if (![targetWidth, targetHeight].every(
|
|
21104
|
+
(value) => Number.isFinite(value) && value > 0 && value <= 1e6
|
|
21105
|
+
))
|
|
21106
|
+
fail("INVALID_PAGE_SIZE", "Converted drawing-page dimensions exceed limits.");
|
|
21107
|
+
const values = /* @__PURE__ */ new Map([
|
|
21108
|
+
["PageWidth", targetWidth],
|
|
21109
|
+
["PageHeight", targetHeight],
|
|
21110
|
+
["DrawingSizeType", 3],
|
|
21111
|
+
["DrawingResizeType", 0]
|
|
21112
|
+
]);
|
|
21113
|
+
const changed = [...values.keys()].filter(
|
|
21114
|
+
(name) => name === "PageWidth" ? width !== targetWidth : name === "PageHeight" ? height !== targetHeight : name === "DrawingSizeType" ? size !== 3 : resize !== 0
|
|
21115
|
+
);
|
|
21116
|
+
if (!changed.length) return;
|
|
21117
|
+
const roots = await editableVisioPageRoots(pkg, pagesPart, pages, pagePaths, dirty, check);
|
|
21118
|
+
for (const path of pkg.paths())
|
|
21119
|
+
if (/^visio\/.*\.xml$/i.test(path) && !roots.has(path)) {
|
|
21120
|
+
check();
|
|
21121
|
+
roots.set(path, dirty.get(path) ?? await pkg.readXml(path));
|
|
21122
|
+
}
|
|
21123
|
+
assertDependencies(roots, pagesPart, pages, pagePaths, command2.pageId, changed, check);
|
|
21124
|
+
for (const name of changed) setCell(sheet, name, values.get(name));
|
|
21125
|
+
dirty.set(pagesPart, pages);
|
|
21126
|
+
}
|
|
21127
|
+
|
|
20563
21128
|
// visio/edit-pages.ts
|
|
20564
21129
|
var officeRel2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
20565
21130
|
var pageType2 = "http://schemas.microsoft.com/visio/2010/relationships/page";
|
|
@@ -20595,6 +21160,10 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20595
21160
|
for (const command2 of commands) {
|
|
20596
21161
|
check();
|
|
20597
21162
|
const existing = children2(pages, "Page");
|
|
21163
|
+
if (command2.type === "set-page-size") {
|
|
21164
|
+
await setVisioPageSize(pkg, pagesPart, pages, pagePaths, dirty, command2, check);
|
|
21165
|
+
continue;
|
|
21166
|
+
}
|
|
20598
21167
|
if (command2.type === "delete-page") {
|
|
20599
21168
|
await deleteVisioPage(
|
|
20600
21169
|
pkg,
|
|
@@ -20698,8 +21267,10 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20698
21267
|
fail("LIMIT_EDIT_OUTPUT", "Saved package exceeds output limit.");
|
|
20699
21268
|
return { bytes: original, changedParts: [], diagnostics: [] };
|
|
20700
21269
|
}
|
|
20701
|
-
|
|
20702
|
-
|
|
21270
|
+
if (commands.some((command2) => command2.type !== "set-page-size")) {
|
|
21271
|
+
await updatePageAppProperties(pkg, pages, priorCount, dirty, limits, check);
|
|
21272
|
+
await recalculatePageFormulas(pkg, pagesPart, pages, pagePaths, dirty, check);
|
|
21273
|
+
}
|
|
20703
21274
|
if ((/* @__PURE__ */ new Set([...parts.keys(), ...dirty.keys()])).size > limits.maxEntries)
|
|
20704
21275
|
fail("LIMIT_ENTRIES", "Page insertion exceeds package entry limit.");
|
|
20705
21276
|
let total = [...parts.values()].reduce((sum, bytes2) => sum + bytes2.length, 0), nodes = 0;
|
|
@@ -20727,8 +21298,8 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20727
21298
|
changedParts: [.../* @__PURE__ */ new Set([...removed, ...dirty.keys()])],
|
|
20728
21299
|
diagnostics: [
|
|
20729
21300
|
{
|
|
20730
|
-
code: "edit-pages-experimental",
|
|
20731
|
-
message: "Page metadata and supported local numeric page-dependent caches were updated. Inherited, string and background-render-context formulas remain unsupported."
|
|
21301
|
+
code: commands.every((command2) => command2.type === "set-page-size") ? "edit-page-size-experimental" : "edit-pages-experimental",
|
|
21302
|
+
message: commands.every((command2) => command2.type === "set-page-size") ? "Fixed custom drawing-page dimensions were updated. Shape positions and printer settings were retained; affected page-size formula caches remain unsupported." : "Page metadata and supported local numeric page-dependent caches were updated. Inherited, string and background-render-context formulas remain unsupported."
|
|
20732
21303
|
}
|
|
20733
21304
|
]
|
|
20734
21305
|
};
|
|
@@ -21557,12 +22128,12 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
21557
22128
|
const dirty = /* @__PURE__ */ new Map();
|
|
21558
22129
|
const roots = /* @__PURE__ */ new Map();
|
|
21559
22130
|
const geometryCommands = commands.filter(
|
|
21560
|
-
(command2) => command2.type !== "replace-plain-text" && command2.type !== "reorder-shape" && command2.type !== "duplicate-shapes" && command2.type !== "paste-shapes" && !isVisioFormatEdit(command2)
|
|
22131
|
+
(command2) => command2.type !== "replace-plain-text" && command2.type !== "replace-text-ranges" && command2.type !== "reorder-shape" && command2.type !== "duplicate-shapes" && command2.type !== "paste-shapes" && !isVisioFormatEdit(command2)
|
|
21561
22132
|
);
|
|
21562
22133
|
let document;
|
|
21563
22134
|
let masterMovePins = emptyMasterMoveProof();
|
|
21564
22135
|
if (geometryCommands.length || commands.some(
|
|
21565
|
-
(command2) => command2.type === "replace-plain-text" || isVisioFormatEdit(command2) || command2.type === "reorder-shape" || command2.type === "duplicate-shapes" || command2.type === "paste-shapes"
|
|
22136
|
+
(command2) => command2.type === "replace-plain-text" || command2.type === "replace-text-ranges" || isVisioFormatEdit(command2) || command2.type === "reorder-shape" || command2.type === "duplicate-shapes" || command2.type === "paste-shapes"
|
|
21566
22137
|
)) {
|
|
21567
22138
|
for (const [pageId, path2] of pages) {
|
|
21568
22139
|
const sourceRoot = await visioXml(pkg, path2, "PageContents");
|
|
@@ -21609,8 +22180,8 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
21609
22180
|
root2 = sourceRoot.ownerDocument.cloneNode(true).documentElement;
|
|
21610
22181
|
roots.set(command2.pageId, root2);
|
|
21611
22182
|
}
|
|
21612
|
-
if (command2.type === "replace-plain-text") {
|
|
21613
|
-
if (await replaceScopedPlainText(pkg, new Set(pages.values()), roots, document, command2, check)) {
|
|
22183
|
+
if (command2.type === "replace-plain-text" || command2.type === "replace-text-ranges") {
|
|
22184
|
+
if (await (command2.type === "replace-plain-text" ? replaceScopedPlainText(pkg, new Set(pages.values()), roots, document, command2, check) : replaceScopedTextRanges(pkg, new Set(pages.values()), roots, document, command2, check))) {
|
|
21614
22185
|
dirty.set(path, root2);
|
|
21615
22186
|
textChanged = true;
|
|
21616
22187
|
}
|
|
@@ -22057,6 +22628,7 @@ function trimVisioArrowLine(path, start, end, beginExtension = 0) {
|
|
|
22057
22628
|
return `M ${point2(start)}${base > start ? ` L ${point2(base)}` : ""} L ${point2(length - end)}`;
|
|
22058
22629
|
}
|
|
22059
22630
|
|
|
22631
|
+
exports.VISIO_BASIC_SHAPES = VISIO_BASIC_SHAPES;
|
|
22060
22632
|
exports.VISIO_CLIPBOARD_MAGIC = VISIO_CLIPBOARD_MAGIC;
|
|
22061
22633
|
exports.VISIO_CLIPBOARD_MAX_CHARS = VISIO_CLIPBOARD_MAX_CHARS;
|
|
22062
22634
|
exports.VISIO_EMF_ADMISSION_LIMITS = VISIO_EMF_ADMISSION_LIMITS;
|
|
@@ -22077,6 +22649,7 @@ exports.evaluateVisioFormula = evaluateVisioFormula;
|
|
|
22077
22649
|
exports.getVisioPageLayers = getVisioPageLayers;
|
|
22078
22650
|
exports.inspectVisioEmfAdmission = inspectVisioEmfAdmission;
|
|
22079
22651
|
exports.inspectVisioRasterImage = inspectVisioRasterImage;
|
|
22652
|
+
exports.isVisioBasicShape = isVisioBasicShape;
|
|
22080
22653
|
exports.layoutVisioFilledArrowLine = layoutVisioFilledArrowLine;
|
|
22081
22654
|
exports.loadVisio = loadVisio;
|
|
22082
22655
|
exports.parseLegacyVsd = parseLegacyVsd;
|
|
@@ -22087,6 +22660,7 @@ exports.sanitizeVisioForeignVectorTree = sanitizeVisioForeignVectorTree;
|
|
|
22087
22660
|
exports.serializeVisioClipboard = serializeVisioClipboard;
|
|
22088
22661
|
exports.trimVisioArrowLine = trimVisioArrowLine;
|
|
22089
22662
|
exports.validateVisioForeignVector = validateVisioForeignVector;
|
|
22663
|
+
exports.visioBasicShapeOutline = visioBasicShapeOutline;
|
|
22090
22664
|
exports.visioFilledArrow = visioFilledArrow;
|
|
22091
22665
|
exports.visioFormulaCachedValue = visioFormulaCachedValue;
|
|
22092
22666
|
exports.visioOpenArrowExtent = visioOpenArrowExtent;
|