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.mjs
CHANGED
|
@@ -227,6 +227,19 @@ var attribute = new RegExp(
|
|
|
227
227
|
"uy"
|
|
228
228
|
);
|
|
229
229
|
var xmlWhitespace = (value) => /^[ \t\r\n]*$/.test(value);
|
|
230
|
+
var reservedNamespaces = /* @__PURE__ */ new Map([
|
|
231
|
+
["xml", "http://www.w3.org/XML/1998/namespace"],
|
|
232
|
+
["xmlns", "http://www.w3.org/2000/xmlns/"]
|
|
233
|
+
]);
|
|
234
|
+
function lookupNamespace(scope, prefix) {
|
|
235
|
+
const reserved = reservedNamespaces.get(prefix);
|
|
236
|
+
if (reserved !== void 0) return reserved;
|
|
237
|
+
for (; scope; scope = scope.parent) {
|
|
238
|
+
const uri = scope.bindings.get(prefix);
|
|
239
|
+
if (uri !== void 0) return uri;
|
|
240
|
+
}
|
|
241
|
+
return void 0;
|
|
242
|
+
}
|
|
230
243
|
function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
231
244
|
if (xml.length > limits.maxXmlChars) fail("LIMIT_XML", "XML character limit exceeded");
|
|
232
245
|
if (/<!DOCTYPE|<!ENTITY/i.test(xml) || /[\u0000-\u0008\u000b\u000c\u000e-\u001f\ufffe\uffff]/.test(xml))
|
|
@@ -292,9 +305,7 @@ function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
|
292
305
|
fail("INVALID_XML", "Mismatched XML closing tag");
|
|
293
306
|
} else {
|
|
294
307
|
const attrs = /* @__PURE__ */ new Set();
|
|
295
|
-
const namespaces =
|
|
296
|
-
namespaces["xml"] = "http://www.w3.org/XML/1998/namespace";
|
|
297
|
-
namespaces["xmlns"] = "http://www.w3.org/2000/xmlns/";
|
|
308
|
+
const namespaces = { bindings: /* @__PURE__ */ new Map(), parent: stack.at(-1)?.namespaces };
|
|
298
309
|
while (!xmlWhitespace(body.slice(cursor))) {
|
|
299
310
|
attribute.lastIndex = cursor;
|
|
300
311
|
const match = attribute.exec(body);
|
|
@@ -304,14 +315,14 @@ function inspectXml(xml, limits, check, encoding = "utf-8") {
|
|
|
304
315
|
const value = match[2] ?? match[3] ?? "";
|
|
305
316
|
text(value);
|
|
306
317
|
if (match[1]?.startsWith("xmlns:"))
|
|
307
|
-
namespaces
|
|
318
|
+
namespaces.bindings.set(match[1].slice(6), decodeXmlAttribute(value));
|
|
308
319
|
node();
|
|
309
320
|
cursor = attribute.lastIndex;
|
|
310
321
|
}
|
|
311
322
|
const expanded = /* @__PURE__ */ new Set();
|
|
312
323
|
for (const attr2 of attrs) {
|
|
313
324
|
const colon = attr2.indexOf(":");
|
|
314
|
-
const uri = colon < 0 ? "" : namespaces
|
|
325
|
+
const uri = colon < 0 ? "" : lookupNamespace(namespaces, attr2.slice(0, colon));
|
|
315
326
|
if (uri === void 0) fail("INVALID_XML", "Unbound XML attribute prefix");
|
|
316
327
|
const key2 = `${uri}\0${attr2.slice(colon + 1)}`;
|
|
317
328
|
if (expanded.has(key2)) fail("INVALID_XML", "Duplicate expanded XML attribute name");
|
|
@@ -6595,11 +6606,23 @@ async function parseVsdx(input, options = {}) {
|
|
|
6595
6606
|
};
|
|
6596
6607
|
visit(shapes);
|
|
6597
6608
|
const connectors = connections(root2, localReport);
|
|
6609
|
+
const pageModes = {};
|
|
6610
|
+
for (const [name, key2] of [
|
|
6611
|
+
["DrawingSizeType", "drawingSizeType"],
|
|
6612
|
+
["DrawingResizeType", "drawingResizeType"]
|
|
6613
|
+
]) {
|
|
6614
|
+
const source = sheet.cells.get(name);
|
|
6615
|
+
if (!source || source.error !== void 0 || source.formula === "Inh" || source.unit !== void 0 && !["NUM", "BOOL"].includes(source.unit))
|
|
6616
|
+
continue;
|
|
6617
|
+
const value = number(sheet.cells, name, Number.NaN, localReport);
|
|
6618
|
+
if (Number.isSafeInteger(value) && value >= 0 && value <= 255) pageModes[key2] = value;
|
|
6619
|
+
}
|
|
6598
6620
|
for (const connection of connectors)
|
|
6599
6621
|
if (!seen.has(connection.fromShapeId) || !seen.has(connection.toShapeId))
|
|
6600
6622
|
localReport("dangling-connection", "A connection references a missing shape.");
|
|
6601
6623
|
pages.push({
|
|
6602
6624
|
id,
|
|
6625
|
+
...pageModes,
|
|
6603
6626
|
...drawingToPageScale === 1 ? {} : { drawingToPageScale },
|
|
6604
6627
|
name: metadata(
|
|
6605
6628
|
attribute2(page, "Name") ?? attribute2(page, "NameU") ?? `Page ${id}`,
|
|
@@ -15228,10 +15251,10 @@ function replaceRecord(input, drawing, record5, replacement) {
|
|
|
15228
15251
|
if (!(block.format & 2) || ![8, 12, 13].includes(block.format >>> 4))
|
|
15229
15252
|
throw new VsdError("unsafe-block-relocation");
|
|
15230
15253
|
try {
|
|
15231
|
-
const
|
|
15232
|
-
if (!
|
|
15254
|
+
const fit2 = encodeVsdBlockToSize(decoded, block.length);
|
|
15255
|
+
if (!fit2)
|
|
15233
15256
|
throw new VsdError("unsafe-block-relocation");
|
|
15234
|
-
stored =
|
|
15257
|
+
stored = fit2.bytes;
|
|
15235
15258
|
} catch (error) {
|
|
15236
15259
|
if (error instanceof VsdCompressionFitError)
|
|
15237
15260
|
throw new VsdError(`compression-${error.reason}`);
|
|
@@ -17411,8 +17434,8 @@ function assertUnlayeredShape(shape, document) {
|
|
|
17411
17434
|
}
|
|
17412
17435
|
}
|
|
17413
17436
|
|
|
17414
|
-
// visio/edit-text.ts
|
|
17415
|
-
|
|
17437
|
+
// visio/edit-text-target.ts
|
|
17438
|
+
function localTextTarget(root2, document, shapeId, check) {
|
|
17416
17439
|
const shapeChildren = (parent) => {
|
|
17417
17440
|
const containers = children2(parent, "Shapes");
|
|
17418
17441
|
if (containers.length > 1)
|
|
@@ -17420,37 +17443,38 @@ async function replacePlainText(root2, document, shapeId, text, check, assertDep
|
|
|
17420
17443
|
return children2(containers[0], "Shape");
|
|
17421
17444
|
};
|
|
17422
17445
|
const shapes = /* @__PURE__ */ new Map();
|
|
17423
|
-
const pending = shapeChildren(root2).map((
|
|
17424
|
-
node: node2,
|
|
17425
|
-
inherited: false,
|
|
17426
|
-
deleted: false
|
|
17427
|
-
}));
|
|
17446
|
+
const pending = shapeChildren(root2).map((node) => ({ node, inherited: false, deleted: false }));
|
|
17428
17447
|
while (pending.length) {
|
|
17429
17448
|
check();
|
|
17430
|
-
const item = pending.pop();
|
|
17431
|
-
const id = attribute2(item.node, "ID");
|
|
17449
|
+
const item = pending.pop(), id = attribute2(item.node, "ID");
|
|
17432
17450
|
if (!id || shapes.has(id))
|
|
17433
17451
|
fail("INVALID_SHAPE_ID", "Local shape IDs must be present and unique.");
|
|
17434
17452
|
const inherited = item.inherited || item.node.hasAttribute("Master") || item.node.hasAttribute("MasterShape");
|
|
17435
17453
|
const deleted = item.deleted || ["1", "true"].includes(attribute2(item.node, "Del") ?? "");
|
|
17436
17454
|
shapes.set(id, { node: item.node, inherited, deleted });
|
|
17437
|
-
for (const
|
|
17455
|
+
for (const node of shapeChildren(item.node)) pending.push({ node, inherited, deleted });
|
|
17438
17456
|
}
|
|
17439
17457
|
const target = shapes.get(shapeId);
|
|
17440
17458
|
if (!target) fail("EDIT_TARGET_NOT_FOUND", "Local shape does not exist.");
|
|
17441
17459
|
if (target.inherited || target.deleted)
|
|
17442
17460
|
fail("UNSUPPORTED_TEXT_EDIT", "Master-linked or deleted shapes cannot be edited.");
|
|
17443
17461
|
assertShapeLocks(target.node, document, ["LockTextEdit"]);
|
|
17444
|
-
|
|
17462
|
+
return target.node;
|
|
17463
|
+
}
|
|
17464
|
+
|
|
17465
|
+
// visio/edit-text.ts
|
|
17466
|
+
async function replacePlainText(root2, document, shapeId, text, check, assertDependencies2) {
|
|
17467
|
+
const target = localTextTarget(root2, document, shapeId, check);
|
|
17468
|
+
const texts = children2(target, "Text");
|
|
17445
17469
|
if (texts.length !== 1)
|
|
17446
17470
|
fail("UNSUPPORTED_TEXT_EDIT", "Editing requires one existing local Text element.");
|
|
17447
17471
|
const node = texts[0];
|
|
17448
17472
|
if (Array.from(node.childNodes).some((item) => item.nodeType !== 3 && item.nodeType !== 4))
|
|
17449
17473
|
fail("UNSUPPORTED_TEXT_EDIT", "Rich text, fields and unknown text markup cannot be edited.");
|
|
17450
|
-
if (children2(target
|
|
17474
|
+
if (children2(target, "Section").some((section) => attribute2(section, "N") === "Field"))
|
|
17451
17475
|
fail("UNSUPPORTED_TEXT_EDIT", "Shapes with text fields cannot be edited.");
|
|
17452
17476
|
if (decodeVisioPlainText(node.textContent ?? "") === text) return false;
|
|
17453
|
-
await
|
|
17477
|
+
await assertDependencies2(target, node);
|
|
17454
17478
|
check();
|
|
17455
17479
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
17456
17480
|
node.appendChild(node.ownerDocument.createTextNode(encodeVisioPlainText(text)));
|
|
@@ -17544,6 +17568,394 @@ function replaceScopedPlainText(pkg, pagePaths, roots, document, edit, check) {
|
|
|
17544
17568
|
);
|
|
17545
17569
|
}
|
|
17546
17570
|
|
|
17571
|
+
// visio/edit-text-range-plan.ts
|
|
17572
|
+
function textRangeNodes(node, edit) {
|
|
17573
|
+
const tokens2 = [];
|
|
17574
|
+
let stored = "";
|
|
17575
|
+
for (const part of Array.from(node.childNodes)) {
|
|
17576
|
+
const start = stored.length;
|
|
17577
|
+
if (part.nodeType === 3 || part.nodeType === 4) stored += part.nodeValue ?? "";
|
|
17578
|
+
tokens2.push({ node: part, start, end: stored.length });
|
|
17579
|
+
}
|
|
17580
|
+
if (decodeVisioPlainText(stored) !== edit.expectedText)
|
|
17581
|
+
fail("EDIT_STALE_TEXT", "Original text no longer matches the range command.");
|
|
17582
|
+
const changed = edit.ranges.some(
|
|
17583
|
+
(range) => edit.expectedText.slice(range.start, range.end) !== range.text
|
|
17584
|
+
);
|
|
17585
|
+
if (!changed) return { changed: false, nodes: [] };
|
|
17586
|
+
const starts = [], deltas = [];
|
|
17587
|
+
let delta = 0;
|
|
17588
|
+
for (const range of edit.ranges) {
|
|
17589
|
+
starts.push(range.start + delta);
|
|
17590
|
+
delta += range.text.length - (range.end - range.start);
|
|
17591
|
+
deltas.push(delta);
|
|
17592
|
+
}
|
|
17593
|
+
const length = edit.expectedText.length + delta;
|
|
17594
|
+
if (!length && tokens2.some((token) => token.node.nodeType === 1))
|
|
17595
|
+
fail(
|
|
17596
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17597
|
+
"Deleting all rich text has unproven native insertion-style behavior."
|
|
17598
|
+
);
|
|
17599
|
+
if (tokens2.some((token) => token.node.nodeType === 1)) {
|
|
17600
|
+
let start = 0, index = 0;
|
|
17601
|
+
while (start < edit.expectedText.length) {
|
|
17602
|
+
const newline = edit.expectedText.indexOf("\n", start), end = newline < 0 ? edit.expectedText.length : newline;
|
|
17603
|
+
let bodyLength = end - start;
|
|
17604
|
+
while (index < edit.ranges.length && edit.ranges[index].start < end) {
|
|
17605
|
+
const range = edit.ranges[index++];
|
|
17606
|
+
bodyLength += range.text.length - (range.end - range.start);
|
|
17607
|
+
}
|
|
17608
|
+
if (end > start && !bodyLength)
|
|
17609
|
+
fail(
|
|
17610
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17611
|
+
"Deleting an entire rich paragraph body has unproven native insertion-style behavior."
|
|
17612
|
+
);
|
|
17613
|
+
start = end + 1;
|
|
17614
|
+
}
|
|
17615
|
+
}
|
|
17616
|
+
const position = (offset) => {
|
|
17617
|
+
let low = 0, high = edit.ranges.length;
|
|
17618
|
+
while (low < high) {
|
|
17619
|
+
const middle = low + high >>> 1;
|
|
17620
|
+
if (edit.ranges[middle].start < offset) low = middle + 1;
|
|
17621
|
+
else high = middle;
|
|
17622
|
+
}
|
|
17623
|
+
const index = low - 1;
|
|
17624
|
+
if (index < 0) return offset;
|
|
17625
|
+
const range = edit.ranges[index];
|
|
17626
|
+
return offset <= range.end ? starts[index] + range.text.length : offset + deltas[index];
|
|
17627
|
+
};
|
|
17628
|
+
const output = [];
|
|
17629
|
+
const append = (token, start, end) => {
|
|
17630
|
+
if (end <= start) return;
|
|
17631
|
+
const part = start === token.start && end === token.end ? token.node : token.node.cloneNode(false);
|
|
17632
|
+
if (part !== token.node)
|
|
17633
|
+
part.nodeValue = (token.node.nodeValue ?? "").slice(start - token.start, end - token.start);
|
|
17634
|
+
output.push({ position: position(start), priority: 2, node: part });
|
|
17635
|
+
};
|
|
17636
|
+
let first2 = 0;
|
|
17637
|
+
for (const token of tokens2) {
|
|
17638
|
+
if (token.node.nodeType === 1) {
|
|
17639
|
+
output.push({ position: position(token.start), priority: 0, node: token.node });
|
|
17640
|
+
continue;
|
|
17641
|
+
}
|
|
17642
|
+
const end = length ? token.end : Math.min(token.end, edit.expectedText.length);
|
|
17643
|
+
let cursor = token.start;
|
|
17644
|
+
while (first2 < edit.ranges.length && edit.ranges[first2].end <= cursor) first2++;
|
|
17645
|
+
for (let index = first2; index < edit.ranges.length && edit.ranges[index].start < end; index++) {
|
|
17646
|
+
const range = edit.ranges[index];
|
|
17647
|
+
append(token, cursor, Math.min(end, range.start));
|
|
17648
|
+
cursor = Math.max(cursor, Math.min(end, range.end));
|
|
17649
|
+
}
|
|
17650
|
+
append(token, cursor, end);
|
|
17651
|
+
}
|
|
17652
|
+
for (let index = 0; index < edit.ranges.length; index++) {
|
|
17653
|
+
const text = edit.ranges[index].text;
|
|
17654
|
+
if (text)
|
|
17655
|
+
output.push({
|
|
17656
|
+
position: starts[index],
|
|
17657
|
+
priority: 1,
|
|
17658
|
+
node: node.ownerDocument.createTextNode(text)
|
|
17659
|
+
});
|
|
17660
|
+
}
|
|
17661
|
+
output.sort((a, b) => a.position - b.position || a.priority - b.priority);
|
|
17662
|
+
let characterPosition = -1, characterRow = null;
|
|
17663
|
+
for (const item of output) {
|
|
17664
|
+
if (item.node.nodeType !== 1 || item.node.localName !== "cp") continue;
|
|
17665
|
+
const row = item.node.getAttribute("IX");
|
|
17666
|
+
if (item.position === characterPosition && row !== characterRow)
|
|
17667
|
+
fail(
|
|
17668
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17669
|
+
"Consuming complete character runs creates ambiguous native marker boundaries."
|
|
17670
|
+
);
|
|
17671
|
+
characterPosition = item.position;
|
|
17672
|
+
characterRow = row;
|
|
17673
|
+
}
|
|
17674
|
+
return { changed: true, nodes: output.map((item) => item.node) };
|
|
17675
|
+
}
|
|
17676
|
+
|
|
17677
|
+
// visio/edit-text-ranges.ts
|
|
17678
|
+
async function replaceScopedTextRanges(pkg, pagePaths, roots, document, edit, check) {
|
|
17679
|
+
const shape = localTextTarget(roots.get(edit.pageId), document, edit.shapeId, check);
|
|
17680
|
+
if (children2(shape, "Section").some((section) => attribute2(section, "N") === "Field"))
|
|
17681
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Text range editing of shapes with fields is unsupported.");
|
|
17682
|
+
const texts = children2(shape, "Text");
|
|
17683
|
+
if (texts.length !== 1)
|
|
17684
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Range editing requires one existing local Text element.");
|
|
17685
|
+
const text = texts[0];
|
|
17686
|
+
if (Array.from(text.childNodes).some((node) => ![3, 4].includes(node.nodeType))) {
|
|
17687
|
+
const characters = effectiveFormattingRows(shape, document, "Character"), paragraphs = effectiveFormattingRows(shape, document, "Paragraph");
|
|
17688
|
+
assertFormattingText(shape, characters, paragraphs);
|
|
17689
|
+
}
|
|
17690
|
+
if (Array.from(text.childNodes).some(
|
|
17691
|
+
(node) => node.nodeType === 1 && node.localName === "fld"
|
|
17692
|
+
))
|
|
17693
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Text range editing of fields is unsupported.");
|
|
17694
|
+
let preceding = "";
|
|
17695
|
+
for (const node of Array.from(text.childNodes)) {
|
|
17696
|
+
if (node.nodeType === 3 || node.nodeType === 4) preceding += node.nodeValue ?? "";
|
|
17697
|
+
else {
|
|
17698
|
+
const marker2 = node;
|
|
17699
|
+
if (marker2.localName === "pp" && preceding && !preceding.endsWith("\n") || marker2.localName === "tp" && attribute2(marker2, "IX") !== "0")
|
|
17700
|
+
fail(
|
|
17701
|
+
"UNSUPPORTED_TEXT_RANGE",
|
|
17702
|
+
"Noncanonical paragraph or tab marker placement cannot be edited."
|
|
17703
|
+
);
|
|
17704
|
+
}
|
|
17705
|
+
}
|
|
17706
|
+
const plan = textRangeNodes(text, edit);
|
|
17707
|
+
if (!plan.changed) return false;
|
|
17708
|
+
await assertFormattingDependencies(
|
|
17709
|
+
pkg,
|
|
17710
|
+
pagePaths,
|
|
17711
|
+
roots,
|
|
17712
|
+
edit.pageId,
|
|
17713
|
+
shape,
|
|
17714
|
+
/* @__PURE__ */ new Map([["TheText", text]]),
|
|
17715
|
+
check
|
|
17716
|
+
);
|
|
17717
|
+
check();
|
|
17718
|
+
while (text.firstChild) text.removeChild(text.firstChild);
|
|
17719
|
+
for (const node of plan.nodes) text.appendChild(node);
|
|
17720
|
+
return true;
|
|
17721
|
+
}
|
|
17722
|
+
|
|
17723
|
+
// visio/basic-shapes.ts
|
|
17724
|
+
var VISIO_BASIC_SHAPES = [
|
|
17725
|
+
"rectangle",
|
|
17726
|
+
"square",
|
|
17727
|
+
"triangle",
|
|
17728
|
+
"right-triangle",
|
|
17729
|
+
"pentagon",
|
|
17730
|
+
"hexagon",
|
|
17731
|
+
"octagon",
|
|
17732
|
+
"star",
|
|
17733
|
+
"diamond",
|
|
17734
|
+
"rounded-rectangle",
|
|
17735
|
+
"cross",
|
|
17736
|
+
"parallelogram",
|
|
17737
|
+
"trapezoid",
|
|
17738
|
+
"can",
|
|
17739
|
+
"cube",
|
|
17740
|
+
"chevron"
|
|
17741
|
+
];
|
|
17742
|
+
var isVisioBasicShape = (value) => VISIO_BASIC_SHAPES.includes(value);
|
|
17743
|
+
function fit(points) {
|
|
17744
|
+
const xs = points.map(([x]) => x), ys = points.map(([, y]) => y);
|
|
17745
|
+
const left = Math.min(...xs), bottom = Math.min(...ys);
|
|
17746
|
+
const width = Math.max(...xs) - left, height = Math.max(...ys) - bottom;
|
|
17747
|
+
return points.map(([x, y]) => [(x - left) / width, (y - bottom) / height]);
|
|
17748
|
+
}
|
|
17749
|
+
function polygon(count, inner) {
|
|
17750
|
+
const steps = inner === void 0 ? count : count * 2;
|
|
17751
|
+
return fit(
|
|
17752
|
+
Array.from({ length: steps }, (_, index) => {
|
|
17753
|
+
const radius = inner !== void 0 && index % 2 ? inner : 1;
|
|
17754
|
+
const angle = Math.PI / 2 + index * 2 * Math.PI / steps;
|
|
17755
|
+
return [radius * Math.cos(angle), radius * Math.sin(angle)];
|
|
17756
|
+
})
|
|
17757
|
+
);
|
|
17758
|
+
}
|
|
17759
|
+
function arc(cy, ry, from, to) {
|
|
17760
|
+
const segments = 12;
|
|
17761
|
+
return Array.from({ length: segments + 1 }, (_, index) => {
|
|
17762
|
+
const angle = from + (to - from) * index / segments;
|
|
17763
|
+
return [0.5 + 0.5 * Math.cos(angle), cy + ry * Math.sin(angle)];
|
|
17764
|
+
});
|
|
17765
|
+
}
|
|
17766
|
+
var box = [
|
|
17767
|
+
[0, 0],
|
|
17768
|
+
[1, 0],
|
|
17769
|
+
[1, 1],
|
|
17770
|
+
[0, 1]
|
|
17771
|
+
];
|
|
17772
|
+
var LID = 0.2;
|
|
17773
|
+
var CUT = 1 / (2 + Math.SQRT2);
|
|
17774
|
+
var OUTLINES = {
|
|
17775
|
+
rectangle: { paths: [box] },
|
|
17776
|
+
square: { paths: [box] },
|
|
17777
|
+
triangle: {
|
|
17778
|
+
paths: [
|
|
17779
|
+
[
|
|
17780
|
+
[0, 0],
|
|
17781
|
+
[1, 0],
|
|
17782
|
+
[0.5, 1]
|
|
17783
|
+
]
|
|
17784
|
+
]
|
|
17785
|
+
},
|
|
17786
|
+
"right-triangle": {
|
|
17787
|
+
paths: [
|
|
17788
|
+
[
|
|
17789
|
+
[0, 0],
|
|
17790
|
+
[1, 0],
|
|
17791
|
+
[0, 1]
|
|
17792
|
+
]
|
|
17793
|
+
]
|
|
17794
|
+
},
|
|
17795
|
+
pentagon: { paths: [polygon(5)] },
|
|
17796
|
+
hexagon: {
|
|
17797
|
+
paths: [
|
|
17798
|
+
[
|
|
17799
|
+
[0.25, 0],
|
|
17800
|
+
[0.75, 0],
|
|
17801
|
+
[1, 0.5],
|
|
17802
|
+
[0.75, 1],
|
|
17803
|
+
[0.25, 1],
|
|
17804
|
+
[0, 0.5]
|
|
17805
|
+
]
|
|
17806
|
+
]
|
|
17807
|
+
},
|
|
17808
|
+
octagon: {
|
|
17809
|
+
paths: [
|
|
17810
|
+
[
|
|
17811
|
+
[CUT, 0],
|
|
17812
|
+
[1 - CUT, 0],
|
|
17813
|
+
[1, CUT],
|
|
17814
|
+
[1, 1 - CUT],
|
|
17815
|
+
[1 - CUT, 1],
|
|
17816
|
+
[CUT, 1],
|
|
17817
|
+
[0, 1 - CUT],
|
|
17818
|
+
[0, CUT]
|
|
17819
|
+
]
|
|
17820
|
+
]
|
|
17821
|
+
},
|
|
17822
|
+
star: { paths: [polygon(5, 0.382)] },
|
|
17823
|
+
diamond: {
|
|
17824
|
+
paths: [
|
|
17825
|
+
[
|
|
17826
|
+
[0.5, 0],
|
|
17827
|
+
[1, 0.5],
|
|
17828
|
+
[0.5, 1],
|
|
17829
|
+
[0, 0.5]
|
|
17830
|
+
]
|
|
17831
|
+
]
|
|
17832
|
+
},
|
|
17833
|
+
"rounded-rectangle": { paths: [box], rounding: 0.15 },
|
|
17834
|
+
cross: {
|
|
17835
|
+
paths: [
|
|
17836
|
+
[
|
|
17837
|
+
[1 / 3, 0],
|
|
17838
|
+
[2 / 3, 0],
|
|
17839
|
+
[2 / 3, 1 / 3],
|
|
17840
|
+
[1, 1 / 3],
|
|
17841
|
+
[1, 2 / 3],
|
|
17842
|
+
[2 / 3, 2 / 3],
|
|
17843
|
+
[2 / 3, 1],
|
|
17844
|
+
[1 / 3, 1],
|
|
17845
|
+
[1 / 3, 2 / 3],
|
|
17846
|
+
[0, 2 / 3],
|
|
17847
|
+
[0, 1 / 3],
|
|
17848
|
+
[1 / 3, 1 / 3]
|
|
17849
|
+
]
|
|
17850
|
+
]
|
|
17851
|
+
},
|
|
17852
|
+
parallelogram: {
|
|
17853
|
+
paths: [
|
|
17854
|
+
[
|
|
17855
|
+
[0, 0],
|
|
17856
|
+
[0.75, 0],
|
|
17857
|
+
[1, 1],
|
|
17858
|
+
[0.25, 1]
|
|
17859
|
+
]
|
|
17860
|
+
]
|
|
17861
|
+
},
|
|
17862
|
+
trapezoid: {
|
|
17863
|
+
paths: [
|
|
17864
|
+
[
|
|
17865
|
+
[0, 0],
|
|
17866
|
+
[1, 0],
|
|
17867
|
+
[0.75, 1],
|
|
17868
|
+
[0.25, 1]
|
|
17869
|
+
]
|
|
17870
|
+
]
|
|
17871
|
+
},
|
|
17872
|
+
can: {
|
|
17873
|
+
paths: [
|
|
17874
|
+
// The body: down the left side, round the front of the base, up the right side and
|
|
17875
|
+
// back along the front of the lid.
|
|
17876
|
+
[...arc(LID / 2, LID / 2, Math.PI, 2 * Math.PI), ...arc(1 - LID / 2, LID / 2, 0, -Math.PI)],
|
|
17877
|
+
// The lid, drawn over the body.
|
|
17878
|
+
arc(1 - LID / 2, LID / 2, 0, 2 * Math.PI).slice(0, -1)
|
|
17879
|
+
]
|
|
17880
|
+
},
|
|
17881
|
+
cube: {
|
|
17882
|
+
paths: [
|
|
17883
|
+
[
|
|
17884
|
+
[0, 0],
|
|
17885
|
+
[0.75, 0],
|
|
17886
|
+
[0.75, 0.75],
|
|
17887
|
+
[0, 0.75]
|
|
17888
|
+
],
|
|
17889
|
+
[
|
|
17890
|
+
[0, 0.75],
|
|
17891
|
+
[0.75, 0.75],
|
|
17892
|
+
[1, 1],
|
|
17893
|
+
[0.25, 1]
|
|
17894
|
+
],
|
|
17895
|
+
[
|
|
17896
|
+
[0.75, 0],
|
|
17897
|
+
[1, 0.25],
|
|
17898
|
+
[1, 1],
|
|
17899
|
+
[0.75, 0.75]
|
|
17900
|
+
]
|
|
17901
|
+
]
|
|
17902
|
+
},
|
|
17903
|
+
chevron: {
|
|
17904
|
+
paths: [
|
|
17905
|
+
[
|
|
17906
|
+
[0, 0],
|
|
17907
|
+
[0.75, 0],
|
|
17908
|
+
[1, 0.5],
|
|
17909
|
+
[0.75, 1],
|
|
17910
|
+
[0, 1],
|
|
17911
|
+
[0.25, 0.5]
|
|
17912
|
+
]
|
|
17913
|
+
]
|
|
17914
|
+
}
|
|
17915
|
+
};
|
|
17916
|
+
function visioBasicShapeOutline(shape) {
|
|
17917
|
+
return OUTLINES[shape];
|
|
17918
|
+
}
|
|
17919
|
+
|
|
17920
|
+
// visio/edit-text-range-commands.ts
|
|
17921
|
+
var invalidXmlText = /[\u0000-\u0008\u000b\u000c\u000d\u000e-\u001f\ufffe\uffff]|[\ud800-\udbff](?![\udc00-\udfff])|(?<![\ud800-\udbff])[\udc00-\udfff]/u;
|
|
17922
|
+
function textRangeBoundary(text, offset) {
|
|
17923
|
+
return !(offset > 0 && offset < text.length && /[\ud800-\udbff]/.test(text[offset - 1]) && /[\udc00-\udfff]/.test(text[offset]));
|
|
17924
|
+
}
|
|
17925
|
+
function snapshotTextRanges(edit, consume) {
|
|
17926
|
+
let characters = 0;
|
|
17927
|
+
const text = (value) => {
|
|
17928
|
+
if (typeof value !== "string" || invalidXmlText.test(value))
|
|
17929
|
+
fail("INVALID_EDIT_TEXT", "Range replacement requires valid XML text.");
|
|
17930
|
+
characters += value.length;
|
|
17931
|
+
if (characters > 1e6)
|
|
17932
|
+
fail("LIMIT_EDIT_TEXT", "Range replacement text exceeds input limits.");
|
|
17933
|
+
return consume ? consume(value) : value;
|
|
17934
|
+
};
|
|
17935
|
+
const pageId = edit.pageId, shapeId = edit.shapeId;
|
|
17936
|
+
if ([pageId, shapeId].some((id) => typeof id !== "string" || !id || id.length > 256))
|
|
17937
|
+
fail("INVALID_EDIT", "Invalid text range target.");
|
|
17938
|
+
const expectedText = text(edit.expectedText), original = edit.ranges;
|
|
17939
|
+
if (!Array.isArray(original)) fail("INVALID_EDIT", "Text ranges require an array.");
|
|
17940
|
+
const length = original.length;
|
|
17941
|
+
if (!Number.isSafeInteger(length) || length < 1 || length > 1e4)
|
|
17942
|
+
fail("LIMIT_EDITS", "Range replacement requires 1-10000 ranges.");
|
|
17943
|
+
const ranges = [];
|
|
17944
|
+
let end = 0, output = expectedText.length;
|
|
17945
|
+
for (let index = 0; index < length; index++) {
|
|
17946
|
+
const input = original[index], start = input.start, nextEnd = input.end, replacement = text(input.text);
|
|
17947
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(nextEnd) || start < end || nextEnd <= start || nextEnd > expectedText.length || !textRangeBoundary(expectedText, start) || !textRangeBoundary(expectedText, nextEnd))
|
|
17948
|
+
fail("INVALID_EDIT", "Text ranges require ascending nonoverlapping UTF16 scalar boundaries.");
|
|
17949
|
+
if (replacement.includes("\n") || expectedText.slice(start, nextEnd).includes("\n"))
|
|
17950
|
+
fail("UNSUPPORTED_TEXT_RANGE", "Range replacement across paragraph breaks is unsupported.");
|
|
17951
|
+
ranges.push({ start, end: nextEnd, text: replacement });
|
|
17952
|
+
end = nextEnd;
|
|
17953
|
+
output += replacement.length - (nextEnd - start);
|
|
17954
|
+
}
|
|
17955
|
+
if (output > 1e6) fail("LIMIT_EDIT_TEXT", "Range replacement output exceeds limits.");
|
|
17956
|
+
return { type: "replace-text-ranges", pageId, shapeId, expectedText, ranges };
|
|
17957
|
+
}
|
|
17958
|
+
|
|
17547
17959
|
// visio/resize-anchor.ts
|
|
17548
17960
|
function snapshotResizeAnchor(value) {
|
|
17549
17961
|
if (value === void 0) return void 0;
|
|
@@ -17776,7 +18188,7 @@ function snapshotFormatting(edit) {
|
|
|
17776
18188
|
}
|
|
17777
18189
|
|
|
17778
18190
|
// visio/edit-commands.ts
|
|
17779
|
-
var isVisioPageEdit = (edit) => edit.type === "insert-page" || edit.type === "reorder-page" || edit.type === "rename-page" || edit.type === "delete-page";
|
|
18191
|
+
var isVisioPageEdit = (edit) => edit.type === "insert-page" || edit.type === "reorder-page" || edit.type === "rename-page" || edit.type === "delete-page" || edit.type === "set-page-size";
|
|
17780
18192
|
function geometryChangedCells(edit) {
|
|
17781
18193
|
if (edit.type === "create-line")
|
|
17782
18194
|
return [
|
|
@@ -17834,6 +18246,13 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17834
18246
|
if (edit.type === "duplicate-shapes") return snapshotDuplicateShapes(edit);
|
|
17835
18247
|
if (edit.type === "paste-shapes") return snapshotPasteShapes(edit);
|
|
17836
18248
|
if (edit.type === "delete-page") return { type: edit.type, pageId: edit.pageId };
|
|
18249
|
+
if (edit.type === "set-page-size")
|
|
18250
|
+
return {
|
|
18251
|
+
type: edit.type,
|
|
18252
|
+
pageId: edit.pageId,
|
|
18253
|
+
width: numeric5(edit.width, true),
|
|
18254
|
+
height: numeric5(edit.height, true)
|
|
18255
|
+
};
|
|
17837
18256
|
if (edit.type === "reorder-page") {
|
|
17838
18257
|
if (!Number.isSafeInteger(edit.index) || edit.index < 0 || edit.index > 1e6)
|
|
17839
18258
|
fail("INVALID_EDIT", "Page order requires a bounded zero-based integer index.");
|
|
@@ -17856,6 +18275,7 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17856
18275
|
const target = { pageId: edit.pageId, shapeId: edit.shapeId };
|
|
17857
18276
|
if (edit.type === "replace-plain-text")
|
|
17858
18277
|
return { ...target, type: edit.type, text: text(edit.text) };
|
|
18278
|
+
if (edit.type === "replace-text-ranges") return snapshotTextRanges(edit, text);
|
|
17859
18279
|
if (isVisioFormatEdit(edit)) return snapshotFormatting(edit);
|
|
17860
18280
|
if (edit.type === "reorder-shape") {
|
|
17861
18281
|
if (!["front", "back", "forward", "backward"].includes(edit.order))
|
|
@@ -17882,7 +18302,10 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17882
18302
|
return { ...target, type: edit.type, beginX, beginY, endX, endY };
|
|
17883
18303
|
}
|
|
17884
18304
|
case "create-rectangle":
|
|
17885
|
-
case "create-ellipse":
|
|
18305
|
+
case "create-ellipse": {
|
|
18306
|
+
const shape = edit.type === "create-rectangle" ? edit.shape : void 0;
|
|
18307
|
+
if (shape !== void 0 && !isVisioBasicShape(shape))
|
|
18308
|
+
fail("INVALID_EDIT", "Unknown basic shape.");
|
|
17886
18309
|
return {
|
|
17887
18310
|
...target,
|
|
17888
18311
|
type: edit.type,
|
|
@@ -17890,8 +18313,10 @@ function snapshotVisioEdits(edits, maxEdits, maxText) {
|
|
|
17890
18313
|
y: numeric5(edit.y),
|
|
17891
18314
|
width: numeric5(edit.width, true),
|
|
17892
18315
|
height: numeric5(edit.height, true),
|
|
17893
|
-
...edit.text === void 0 ? {} : { text: text(edit.text) }
|
|
18316
|
+
...edit.text === void 0 ? {} : { text: text(edit.text) },
|
|
18317
|
+
...shape === void 0 ? {} : { shape }
|
|
17894
18318
|
};
|
|
18319
|
+
}
|
|
17895
18320
|
case "rotate-shape":
|
|
17896
18321
|
return { ...target, type: edit.type, angle: numeric5(edit.angle) };
|
|
17897
18322
|
case "flip-shape":
|
|
@@ -18305,24 +18730,25 @@ function createRectangle(root2, document, edit) {
|
|
|
18305
18730
|
}
|
|
18306
18731
|
const doc = root2.ownerDocument;
|
|
18307
18732
|
const node = (name) => doc.createElementNS(root2.namespaceURI, name);
|
|
18308
|
-
const
|
|
18309
|
-
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
|
|
18314
|
-
|
|
18315
|
-
|
|
18316
|
-
|
|
18317
|
-
|
|
18318
|
-
|
|
18319
|
-
|
|
18320
|
-
|
|
18321
|
-
|
|
18322
|
-
|
|
18323
|
-
|
|
18733
|
+
const outline = visioBasicShapeOutline(
|
|
18734
|
+
edit.type === "create-rectangle" ? edit.shape ?? "rectangle" : "rectangle"
|
|
18735
|
+
);
|
|
18736
|
+
if (outline.rounding)
|
|
18737
|
+
setCell(shape, "Rounding", outline.rounding * Math.min(edit.width, edit.height));
|
|
18738
|
+
for (const [sectionIndex, points] of outline.paths.entries()) {
|
|
18739
|
+
const section = node("Section");
|
|
18740
|
+
section.setAttribute("N", "Geometry");
|
|
18741
|
+
section.setAttribute("IX", String(sectionIndex));
|
|
18742
|
+
for (const [index, [x, y]] of [...points, points[0]].entries()) {
|
|
18743
|
+
const row = node("Row");
|
|
18744
|
+
row.setAttribute("IX", String(index + 1));
|
|
18745
|
+
row.setAttribute("T", index ? "RelLineTo" : "RelMoveTo");
|
|
18746
|
+
setCell(row, "X", x);
|
|
18747
|
+
setCell(row, "Y", y);
|
|
18748
|
+
section.appendChild(row);
|
|
18749
|
+
}
|
|
18750
|
+
shape.appendChild(section);
|
|
18324
18751
|
}
|
|
18325
|
-
shape.appendChild(section);
|
|
18326
18752
|
const text = node("Text");
|
|
18327
18753
|
text.appendChild(doc.createTextNode(encodeVisioPlainText(edit.text ?? "")));
|
|
18328
18754
|
shape.appendChild(text);
|
|
@@ -20554,6 +20980,145 @@ function addReplacementPage(pagesPart, pages, rels, types, pagePaths, parts, dir
|
|
|
20554
20980
|
);
|
|
20555
20981
|
}
|
|
20556
20982
|
|
|
20983
|
+
// visio/edit-page-size.ts
|
|
20984
|
+
function constant(node, length) {
|
|
20985
|
+
if (!node || node.hasAttribute("E") || attribute2(node, "F") === "Inh")
|
|
20986
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "A valid explicit page size or mode cache is required.");
|
|
20987
|
+
const value = visioFormulaCachedValue(attribute2(node, "V") ?? "", attribute2(node, "U"));
|
|
20988
|
+
if (!Number.isFinite(value.value) || !["scalar", ...length ? ["length"] : []].includes(value.unit))
|
|
20989
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page size or mode has incompatible units.");
|
|
20990
|
+
const formula = executableCellFormula(attribute2(node, "F"));
|
|
20991
|
+
if (formula) {
|
|
20992
|
+
const analysis = analyzeVisioFormula(formula);
|
|
20993
|
+
if (analysis.guarded || analysis.dynamic || analysis.references.length || analysis.unsupportedFunctions.length)
|
|
20994
|
+
fail("EDIT_PROTECTED_CELL", "Protected or dependent page settings cannot be overwritten.");
|
|
20995
|
+
const result = evaluateVisioFormula(
|
|
20996
|
+
formula,
|
|
20997
|
+
() => fail("EDIT_PROTECTED_CELL", "Unsupported page dependency.")
|
|
20998
|
+
);
|
|
20999
|
+
if (result.value !== value.value || !["scalar", ...length ? ["length"] : []].includes(result.unit))
|
|
21000
|
+
fail("EDIT_PROTECTED_CELL", "Page setting formula cache cannot be proven.");
|
|
21001
|
+
}
|
|
21002
|
+
return value.value;
|
|
21003
|
+
}
|
|
21004
|
+
var escape3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21005
|
+
function assertDependencies(roots, pagesPart, pages, pagePaths, pageId, changed, check) {
|
|
21006
|
+
const page = children2(pages, "Page").find((node) => attribute2(node, "ID") === pageId);
|
|
21007
|
+
const targetNames = new Set(
|
|
21008
|
+
["Name", "NameU"].map((name) => attribute2(page, name)?.toLowerCase())
|
|
21009
|
+
);
|
|
21010
|
+
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()));
|
|
21011
|
+
const cells4 = changed.map(escape3).join("|");
|
|
21012
|
+
const reference = new RegExp(`(?:^|[^a-z0-9_.])(?:${cells4})(?:$|[^a-z0-9_.])`, "i");
|
|
21013
|
+
const other = otherNames.length ? new RegExp(
|
|
21014
|
+
`Pages\\[(?:${otherNames.map(escape3).join("|")})\\]!(?:ThePage!)?(?:${cells4})(?![a-z0-9_.])`,
|
|
21015
|
+
"gi"
|
|
21016
|
+
) : void 0;
|
|
21017
|
+
const paths = new Map([...pagePaths].map(([id, path]) => [path, id]));
|
|
21018
|
+
for (const [path, root2] of roots)
|
|
21019
|
+
for (const node of [root2, ...Array.from(root2.getElementsByTagName("*"))]) {
|
|
21020
|
+
check();
|
|
21021
|
+
const formula = executableCellFormula(attribute2(node, "F"));
|
|
21022
|
+
if (!formula) continue;
|
|
21023
|
+
let code = unquotedVisioFormula(formula);
|
|
21024
|
+
const name = attribute2(node, "N") ?? "";
|
|
21025
|
+
if (inertDoubleClickFormula(name, formula)) continue;
|
|
21026
|
+
const owner = node.parentNode, container = owner?.parentNode;
|
|
21027
|
+
const ownerId = attribute2(owner ?? void 0, "ID");
|
|
21028
|
+
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(
|
|
21029
|
+
(name2) => children2(owner, "Cell").filter((cell) => attribute2(cell, "N") === name2).length === 1
|
|
21030
|
+
) && container?.localName === "Shapes" && container.parentNode === root2 && children2(root2, "Connects").some(
|
|
21031
|
+
(connections2) => children2(connections2, "Connect").some(
|
|
21032
|
+
(connection) => attribute2(connection, "FromSheet") === ownerId
|
|
21033
|
+
)
|
|
21034
|
+
);
|
|
21035
|
+
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(
|
|
21036
|
+
code
|
|
21037
|
+
) || /^(BegTrigger|EndTrigger)$/.test(name) && /^\s*_XFTRIGGER\(Sheet\.[1-9]\d*!EventXFMod\)\s*$/i.test(code));
|
|
21038
|
+
let dynamic2 = false;
|
|
21039
|
+
if (!nativeGlue) {
|
|
21040
|
+
try {
|
|
21041
|
+
dynamic2 = analyzeVisioFormula(
|
|
21042
|
+
mapVisioFormulaSyntax(
|
|
21043
|
+
formula,
|
|
21044
|
+
(part) => (other ? part.replace(other, "0") : part).replace(/Pages\[[^\]]+\]!/gi, "").replace(/ThePage!/gi, "")
|
|
21045
|
+
)
|
|
21046
|
+
).dynamic;
|
|
21047
|
+
} catch {
|
|
21048
|
+
dynamic2 = true;
|
|
21049
|
+
}
|
|
21050
|
+
}
|
|
21051
|
+
if (dynamic2)
|
|
21052
|
+
fail(
|
|
21053
|
+
"EDIT_UNSUPPORTED_PAGE_SIZE_DEPENDENCY",
|
|
21054
|
+
"Dynamic or unknown page-size dependencies cannot be safely refreshed."
|
|
21055
|
+
);
|
|
21056
|
+
let local = paths.get(path);
|
|
21057
|
+
if (path === pagesPart) {
|
|
21058
|
+
let ancestor = node;
|
|
21059
|
+
while (ancestor && ancestor.localName !== "Page")
|
|
21060
|
+
ancestor = ancestor.parentNode;
|
|
21061
|
+
local = ancestor ? attribute2(ancestor, "ID") : void 0;
|
|
21062
|
+
}
|
|
21063
|
+
if (other) code = code.replace(other, "0");
|
|
21064
|
+
if (!reference.test(code)) continue;
|
|
21065
|
+
if (local && local !== pageId && !/\bPages\[/i.test(code)) continue;
|
|
21066
|
+
fail(
|
|
21067
|
+
"EDIT_UNSUPPORTED_PAGE_SIZE_DEPENDENCY",
|
|
21068
|
+
"Page-size formula caches cannot be safely refreshed."
|
|
21069
|
+
);
|
|
21070
|
+
}
|
|
21071
|
+
}
|
|
21072
|
+
async function setVisioPageSize(pkg, pagesPart, pages, pagePaths, dirty, command2, check) {
|
|
21073
|
+
const page = children2(pages, "Page").find((node) => attribute2(node, "ID") === command2.pageId);
|
|
21074
|
+
if (!page) fail("EDIT_TARGET_NOT_FOUND", "Page does not exist.");
|
|
21075
|
+
if (children2(page, "PageSheet").length !== 1)
|
|
21076
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "One explicit PageSheet is required.");
|
|
21077
|
+
const sheet = child(page, "PageSheet"), cells4 = uniqueFormattingCells(sheet);
|
|
21078
|
+
for (const name of [
|
|
21079
|
+
"PageWidth",
|
|
21080
|
+
"PageHeight",
|
|
21081
|
+
"PageScale",
|
|
21082
|
+
"DrawingScale",
|
|
21083
|
+
"DrawingSizeType",
|
|
21084
|
+
"DrawingResizeType"
|
|
21085
|
+
])
|
|
21086
|
+
if (!cells4.has(name) && [...cells4.keys()].some((key2) => key2.toLowerCase() === name.toLowerCase()))
|
|
21087
|
+
fail("EDIT_AMBIGUOUS_CELL", "Page settings require canonical cell names.");
|
|
21088
|
+
const pageScale = constant(cells4.get("PageScale"), true), drawingScale = constant(cells4.get("DrawingScale"), true);
|
|
21089
|
+
if (pageScale <= 0 || drawingScale <= 0)
|
|
21090
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page and drawing scales must be positive.");
|
|
21091
|
+
const width = constant(cells4.get("PageWidth"), true), height = constant(cells4.get("PageHeight"), true);
|
|
21092
|
+
const size = constant(cells4.get("DrawingSizeType"), false);
|
|
21093
|
+
const resize = cells4.has("DrawingResizeType") ? constant(cells4.get("DrawingResizeType"), false) : void 0;
|
|
21094
|
+
if (width <= 0 || height <= 0 || ![0, 1, 2, 3, 4].includes(size) || resize !== void 0 && ![0, 1, 2].includes(resize))
|
|
21095
|
+
fail("EDIT_UNSUPPORTED_PAGE_SIZE", "Page dimensions or size modes are unsupported.");
|
|
21096
|
+
const targetWidth = command2.width === width * (pageScale / drawingScale) ? width : command2.width * drawingScale / pageScale, targetHeight = command2.height === height * (pageScale / drawingScale) ? height : command2.height * drawingScale / pageScale;
|
|
21097
|
+
if (![targetWidth, targetHeight].every(
|
|
21098
|
+
(value) => Number.isFinite(value) && value > 0 && value <= 1e6
|
|
21099
|
+
))
|
|
21100
|
+
fail("INVALID_PAGE_SIZE", "Converted drawing-page dimensions exceed limits.");
|
|
21101
|
+
const values = /* @__PURE__ */ new Map([
|
|
21102
|
+
["PageWidth", targetWidth],
|
|
21103
|
+
["PageHeight", targetHeight],
|
|
21104
|
+
["DrawingSizeType", 3],
|
|
21105
|
+
["DrawingResizeType", 0]
|
|
21106
|
+
]);
|
|
21107
|
+
const changed = [...values.keys()].filter(
|
|
21108
|
+
(name) => name === "PageWidth" ? width !== targetWidth : name === "PageHeight" ? height !== targetHeight : name === "DrawingSizeType" ? size !== 3 : resize !== 0
|
|
21109
|
+
);
|
|
21110
|
+
if (!changed.length) return;
|
|
21111
|
+
const roots = await editableVisioPageRoots(pkg, pagesPart, pages, pagePaths, dirty, check);
|
|
21112
|
+
for (const path of pkg.paths())
|
|
21113
|
+
if (/^visio\/.*\.xml$/i.test(path) && !roots.has(path)) {
|
|
21114
|
+
check();
|
|
21115
|
+
roots.set(path, dirty.get(path) ?? await pkg.readXml(path));
|
|
21116
|
+
}
|
|
21117
|
+
assertDependencies(roots, pagesPart, pages, pagePaths, command2.pageId, changed, check);
|
|
21118
|
+
for (const name of changed) setCell(sheet, name, values.get(name));
|
|
21119
|
+
dirty.set(pagesPart, pages);
|
|
21120
|
+
}
|
|
21121
|
+
|
|
20557
21122
|
// visio/edit-pages.ts
|
|
20558
21123
|
var officeRel2 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
20559
21124
|
var pageType2 = "http://schemas.microsoft.com/visio/2010/relationships/page";
|
|
@@ -20589,6 +21154,10 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20589
21154
|
for (const command2 of commands) {
|
|
20590
21155
|
check();
|
|
20591
21156
|
const existing = children2(pages, "Page");
|
|
21157
|
+
if (command2.type === "set-page-size") {
|
|
21158
|
+
await setVisioPageSize(pkg, pagesPart, pages, pagePaths, dirty, command2, check);
|
|
21159
|
+
continue;
|
|
21160
|
+
}
|
|
20592
21161
|
if (command2.type === "delete-page") {
|
|
20593
21162
|
await deleteVisioPage(
|
|
20594
21163
|
pkg,
|
|
@@ -20692,8 +21261,10 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20692
21261
|
fail("LIMIT_EDIT_OUTPUT", "Saved package exceeds output limit.");
|
|
20693
21262
|
return { bytes: original, changedParts: [], diagnostics: [] };
|
|
20694
21263
|
}
|
|
20695
|
-
|
|
20696
|
-
|
|
21264
|
+
if (commands.some((command2) => command2.type !== "set-page-size")) {
|
|
21265
|
+
await updatePageAppProperties(pkg, pages, priorCount, dirty, limits, check);
|
|
21266
|
+
await recalculatePageFormulas(pkg, pagesPart, pages, pagePaths, dirty, check);
|
|
21267
|
+
}
|
|
20697
21268
|
if ((/* @__PURE__ */ new Set([...parts.keys(), ...dirty.keys()])).size > limits.maxEntries)
|
|
20698
21269
|
fail("LIMIT_ENTRIES", "Page insertion exceeds package entry limit.");
|
|
20699
21270
|
let total = [...parts.values()].reduce((sum, bytes2) => sum + bytes2.length, 0), nodes = 0;
|
|
@@ -20721,8 +21292,8 @@ async function editVsdxPages(original, pkg, parts, commands, limits, maxOutput,
|
|
|
20721
21292
|
changedParts: [.../* @__PURE__ */ new Set([...removed, ...dirty.keys()])],
|
|
20722
21293
|
diagnostics: [
|
|
20723
21294
|
{
|
|
20724
|
-
code: "edit-pages-experimental",
|
|
20725
|
-
message: "Page metadata and supported local numeric page-dependent caches were updated. Inherited, string and background-render-context formulas remain unsupported."
|
|
21295
|
+
code: commands.every((command2) => command2.type === "set-page-size") ? "edit-page-size-experimental" : "edit-pages-experimental",
|
|
21296
|
+
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."
|
|
20726
21297
|
}
|
|
20727
21298
|
]
|
|
20728
21299
|
};
|
|
@@ -21551,12 +22122,12 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
21551
22122
|
const dirty = /* @__PURE__ */ new Map();
|
|
21552
22123
|
const roots = /* @__PURE__ */ new Map();
|
|
21553
22124
|
const geometryCommands = commands.filter(
|
|
21554
|
-
(command2) => command2.type !== "replace-plain-text" && command2.type !== "reorder-shape" && command2.type !== "duplicate-shapes" && command2.type !== "paste-shapes" && !isVisioFormatEdit(command2)
|
|
22125
|
+
(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)
|
|
21555
22126
|
);
|
|
21556
22127
|
let document;
|
|
21557
22128
|
let masterMovePins = emptyMasterMoveProof();
|
|
21558
22129
|
if (geometryCommands.length || commands.some(
|
|
21559
|
-
(command2) => command2.type === "replace-plain-text" || isVisioFormatEdit(command2) || command2.type === "reorder-shape" || command2.type === "duplicate-shapes" || command2.type === "paste-shapes"
|
|
22130
|
+
(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"
|
|
21560
22131
|
)) {
|
|
21561
22132
|
for (const [pageId, path2] of pages) {
|
|
21562
22133
|
const sourceRoot = await visioXml(pkg, path2, "PageContents");
|
|
@@ -21603,8 +22174,8 @@ async function editVsdx(input, edits, options = {}) {
|
|
|
21603
22174
|
root2 = sourceRoot.ownerDocument.cloneNode(true).documentElement;
|
|
21604
22175
|
roots.set(command2.pageId, root2);
|
|
21605
22176
|
}
|
|
21606
|
-
if (command2.type === "replace-plain-text") {
|
|
21607
|
-
if (await replaceScopedPlainText(pkg, new Set(pages.values()), roots, document, command2, check)) {
|
|
22177
|
+
if (command2.type === "replace-plain-text" || command2.type === "replace-text-ranges") {
|
|
22178
|
+
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))) {
|
|
21608
22179
|
dirty.set(path, root2);
|
|
21609
22180
|
textChanged = true;
|
|
21610
22181
|
}
|
|
@@ -22051,4 +22622,4 @@ function trimVisioArrowLine(path, start, end, beginExtension = 0) {
|
|
|
22051
22622
|
return `M ${point2(start)}${base > start ? ` L ${point2(base)}` : ""} L ${point2(length - end)}`;
|
|
22052
22623
|
}
|
|
22053
22624
|
|
|
22054
|
-
export { VISIO_CLIPBOARD_MAGIC, VISIO_CLIPBOARD_MAX_CHARS, VISIO_EMF_ADMISSION_LIMITS, VISIO_FOREIGN_VECTOR_LIMITS, VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, VisioForeignVectorError, VisioFormulaError, VisioImageError, VisioPackageError, analyzeVisioFormula, captureVisioClipboard, convertVisioMetafile, createVsdx, deserializeVisioClipboard, editVsdx, evaluateVisioFormula, getVisioPageLayers, inspectVisioEmfAdmission, inspectVisioRasterImage, layoutVisioFilledArrowLine, loadVisio, parseLegacyVsd, parseVisioFormula, parseVsdx, resolveVisioPageVisibility, sanitizeVisioForeignVectorTree, serializeVisioClipboard, trimVisioArrowLine, validateVisioForeignVector, visioFilledArrow, visioFormulaCachedValue, visioOpenArrowExtent, visioOpenArrowPath };
|
|
22625
|
+
export { VISIO_BASIC_SHAPES, VISIO_CLIPBOARD_MAGIC, VISIO_CLIPBOARD_MAX_CHARS, VISIO_EMF_ADMISSION_LIMITS, VISIO_FOREIGN_VECTOR_LIMITS, VISIO_RASTER_IMAGE_LIMITS, VISIO_VISIBILITY_LIMITS, VisioForeignVectorError, VisioFormulaError, VisioImageError, VisioPackageError, analyzeVisioFormula, captureVisioClipboard, convertVisioMetafile, createVsdx, deserializeVisioClipboard, editVsdx, evaluateVisioFormula, getVisioPageLayers, inspectVisioEmfAdmission, inspectVisioRasterImage, isVisioBasicShape, layoutVisioFilledArrowLine, loadVisio, parseLegacyVsd, parseVisioFormula, parseVsdx, resolveVisioPageVisibility, sanitizeVisioForeignVectorTree, serializeVisioClipboard, trimVisioArrowLine, validateVisioForeignVector, visioBasicShapeOutline, visioFilledArrow, visioFormulaCachedValue, visioOpenArrowExtent, visioOpenArrowPath };
|