@ricsam/formula-engine 0.0.13 → 0.0.15
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/dist/cjs/core/autofill-utils.cjs +107 -3
- package/dist/cjs/core/autofill-utils.cjs.map +3 -3
- package/dist/cjs/core/engine.cjs +76 -5
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/copy-manager.cjs +302 -2
- package/dist/cjs/core/managers/copy-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/style-manager.cjs +34 -9
- package/dist/cjs/core/managers/style-manager.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/autofill-utils.mjs +107 -3
- package/dist/mjs/core/autofill-utils.mjs.map +3 -3
- package/dist/mjs/core/engine.mjs +76 -5
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/copy-manager.mjs +302 -2
- package/dist/mjs/core/managers/copy-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/style-manager.mjs +39 -10
- package/dist/mjs/core/managers/style-manager.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/autofill-utils.d.ts +13 -2
- package/dist/types/core/engine.d.ts +72 -5
- package/dist/types/core/managers/copy-manager.d.ts +42 -2
- package/dist/types/core/managers/style-manager.d.ts +10 -0
- package/package.json +1 -1
|
@@ -182,9 +182,15 @@ class CopyManager {
|
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
184
|
copyFormatting(sourceCells, sourceTopLeft, target, rowOffset, colOffset) {
|
|
185
|
+
const sourceRange = this.getBoundingBox(sourceCells);
|
|
186
|
+
const targetRange = {
|
|
187
|
+
workbookName: target.workbookName,
|
|
188
|
+
sheetName: target.sheetName,
|
|
189
|
+
range: this.adjustRange(sourceRange, rowOffset, colOffset)
|
|
190
|
+
};
|
|
191
|
+
this.styleManager.clearCellStylesInRange(targetRange);
|
|
185
192
|
const allConditionalStyles = this.styleManager.getAllConditionalStyles();
|
|
186
193
|
const allCellStyles = this.styleManager.getAllCellStyles();
|
|
187
|
-
const sourceRange = this.getBoundingBox(sourceCells);
|
|
188
194
|
for (const style of allConditionalStyles) {
|
|
189
195
|
if (style.area.workbookName === sourceTopLeft.workbookName && style.area.sheetName === sourceTopLeft.sheetName) {
|
|
190
196
|
const intersection = import_range_utils.intersectRanges(style.area.range, sourceRange);
|
|
@@ -261,6 +267,300 @@ class CopyManager {
|
|
|
261
267
|
}
|
|
262
268
|
}
|
|
263
269
|
}
|
|
270
|
+
fillAreas(seedRange, targetRanges, options) {
|
|
271
|
+
for (const targetRange of targetRanges) {
|
|
272
|
+
this.fillRangeWithSeed(seedRange, targetRange, {
|
|
273
|
+
copyContent: options.target !== "style",
|
|
274
|
+
copyStyles: options.target === "all" || options.target === "style",
|
|
275
|
+
contentType: options.type,
|
|
276
|
+
adjustFormulas: true
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
if (options.cut) {
|
|
280
|
+
const seedCells = this.expandRangeToCells(seedRange);
|
|
281
|
+
this.clearSourceCells(seedCells);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
fillRangeWithSeed(seedRange, targetRange, options) {
|
|
285
|
+
if (options.copyStyles) {
|
|
286
|
+
this.styleManager.clearCellStylesInRange(targetRange);
|
|
287
|
+
}
|
|
288
|
+
const seedCells = this.expandRangeToCells(seedRange);
|
|
289
|
+
const seedWidth = this.getRangeWidth(seedRange);
|
|
290
|
+
const seedHeight = this.getRangeHeight(seedRange);
|
|
291
|
+
const targetWidth = this.getRangeWidth(targetRange);
|
|
292
|
+
const targetHeight = this.getRangeHeight(targetRange);
|
|
293
|
+
const filledColumns = new Map;
|
|
294
|
+
for (let col = 0;col < seedWidth; col++) {
|
|
295
|
+
for (let row = 0;row < targetHeight; row++) {
|
|
296
|
+
const seedRow = row % seedHeight;
|
|
297
|
+
const seedCell = seedCells.find((c) => c.colIndex === seedRange.range.start.col + col && c.rowIndex === seedRange.range.start.row + seedRow);
|
|
298
|
+
if (seedCell) {
|
|
299
|
+
const targetCell = {
|
|
300
|
+
workbookName: targetRange.workbookName,
|
|
301
|
+
sheetName: targetRange.sheetName,
|
|
302
|
+
colIndex: targetRange.range.start.col + col,
|
|
303
|
+
rowIndex: targetRange.range.start.row + row
|
|
304
|
+
};
|
|
305
|
+
const rowDelta = targetCell.rowIndex - seedCell.rowIndex;
|
|
306
|
+
const colDelta = targetCell.colIndex - seedCell.colIndex;
|
|
307
|
+
if (options.copyContent) {
|
|
308
|
+
this.copyCellContentWithOffset(seedCell, targetCell, rowDelta, colDelta, {
|
|
309
|
+
type: options.contentType,
|
|
310
|
+
cut: false,
|
|
311
|
+
target: "content"
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (options.copyStyles) {
|
|
315
|
+
this.copyCellFormatting(seedCell, targetCell);
|
|
316
|
+
}
|
|
317
|
+
const key = `${targetCell.colIndex}-${targetCell.rowIndex}`;
|
|
318
|
+
const sheet = this.workbookManager.getSheet({
|
|
319
|
+
workbookName: targetCell.workbookName,
|
|
320
|
+
sheetName: targetCell.sheetName
|
|
321
|
+
});
|
|
322
|
+
const cellKey = `${String.fromCharCode(65 + targetCell.colIndex)}${targetCell.rowIndex + 1}`;
|
|
323
|
+
const content = sheet?.content.get(cellKey) || "";
|
|
324
|
+
filledColumns.set(key, { cell: targetCell, content });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (targetWidth > seedWidth) {
|
|
329
|
+
for (let col = seedWidth;col < targetWidth; col++) {
|
|
330
|
+
const sourceCol = col % seedWidth;
|
|
331
|
+
for (let row = 0;row < targetHeight; row++) {
|
|
332
|
+
const sourceCell = {
|
|
333
|
+
workbookName: targetRange.workbookName,
|
|
334
|
+
sheetName: targetRange.sheetName,
|
|
335
|
+
colIndex: targetRange.range.start.col + sourceCol,
|
|
336
|
+
rowIndex: targetRange.range.start.row + row
|
|
337
|
+
};
|
|
338
|
+
const targetCell = {
|
|
339
|
+
workbookName: targetRange.workbookName,
|
|
340
|
+
sheetName: targetRange.sheetName,
|
|
341
|
+
colIndex: targetRange.range.start.col + col,
|
|
342
|
+
rowIndex: targetRange.range.start.row + row
|
|
343
|
+
};
|
|
344
|
+
const colDelta = targetCell.colIndex - sourceCell.colIndex;
|
|
345
|
+
if (options.copyContent) {
|
|
346
|
+
this.copyCellContentWithOffset(sourceCell, targetCell, 0, colDelta, {
|
|
347
|
+
type: options.contentType,
|
|
348
|
+
cut: false,
|
|
349
|
+
target: "content"
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
if (options.copyStyles) {
|
|
353
|
+
this.copyCellFormatting(sourceCell, targetCell);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
getRangeWidth(range) {
|
|
360
|
+
if (range.range.end.col.type === "infinity") {
|
|
361
|
+
return 100;
|
|
362
|
+
}
|
|
363
|
+
return range.range.end.col.value - range.range.start.col + 1;
|
|
364
|
+
}
|
|
365
|
+
getRangeHeight(range) {
|
|
366
|
+
if (range.range.end.row.type === "infinity") {
|
|
367
|
+
return 100;
|
|
368
|
+
}
|
|
369
|
+
return range.range.end.row.value - range.range.start.row + 1;
|
|
370
|
+
}
|
|
371
|
+
expandRangeToCells(rangeAddress) {
|
|
372
|
+
const { workbookName, sheetName, range } = rangeAddress;
|
|
373
|
+
const cells = [];
|
|
374
|
+
const startCol = range.start.col;
|
|
375
|
+
const startRow = range.start.row;
|
|
376
|
+
let endCol;
|
|
377
|
+
if (range.end.col.type === "infinity") {
|
|
378
|
+
endCol = startCol + 99;
|
|
379
|
+
} else {
|
|
380
|
+
endCol = range.end.col.value;
|
|
381
|
+
}
|
|
382
|
+
let endRow;
|
|
383
|
+
if (range.end.row.type === "infinity") {
|
|
384
|
+
endRow = startRow + 99;
|
|
385
|
+
} else {
|
|
386
|
+
endRow = range.end.row.value;
|
|
387
|
+
}
|
|
388
|
+
for (let row = startRow;row <= endRow; row++) {
|
|
389
|
+
for (let col = startCol;col <= endCol; col++) {
|
|
390
|
+
cells.push({
|
|
391
|
+
workbookName,
|
|
392
|
+
sheetName,
|
|
393
|
+
colIndex: col,
|
|
394
|
+
rowIndex: row
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
return cells;
|
|
399
|
+
}
|
|
400
|
+
copyCellContentWithOffset(sourceCell, targetCell, rowDelta, colDelta, options) {
|
|
401
|
+
const sheet = this.workbookManager.getSheet({
|
|
402
|
+
workbookName: sourceCell.workbookName,
|
|
403
|
+
sheetName: sourceCell.sheetName
|
|
404
|
+
});
|
|
405
|
+
if (!sheet) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${sourceCell.rowIndex + 1}`;
|
|
409
|
+
const cellContent = sheet.content.get(key);
|
|
410
|
+
if (!cellContent) {
|
|
411
|
+
const targetSheet2 = this.workbookManager.getSheet({
|
|
412
|
+
workbookName: targetCell.workbookName,
|
|
413
|
+
sheetName: targetCell.sheetName
|
|
414
|
+
});
|
|
415
|
+
if (targetSheet2) {
|
|
416
|
+
const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${targetCell.rowIndex + 1}`;
|
|
417
|
+
targetSheet2.content.delete(targetKey);
|
|
418
|
+
}
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
let targetContent;
|
|
422
|
+
if (options.type === "value") {
|
|
423
|
+
const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);
|
|
424
|
+
if (!evalResult || evalResult.type !== "value") {
|
|
425
|
+
targetContent = cellContent;
|
|
426
|
+
} else {
|
|
427
|
+
const result = evalResult.result;
|
|
428
|
+
if (result.type === "number") {
|
|
429
|
+
targetContent = result.value;
|
|
430
|
+
} else if (result.type === "string") {
|
|
431
|
+
targetContent = result.value;
|
|
432
|
+
} else if (result.type === "boolean") {
|
|
433
|
+
targetContent = result.value;
|
|
434
|
+
} else {
|
|
435
|
+
targetContent = cellContent;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
if (typeof cellContent === "string" && cellContent.startsWith("=")) {
|
|
440
|
+
targetContent = this.adjustFormulaWithOffset(cellContent, rowDelta, colDelta);
|
|
441
|
+
} else {
|
|
442
|
+
targetContent = cellContent;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
const targetSheet = this.workbookManager.getSheet({
|
|
446
|
+
workbookName: targetCell.workbookName,
|
|
447
|
+
sheetName: targetCell.sheetName
|
|
448
|
+
});
|
|
449
|
+
if (targetSheet) {
|
|
450
|
+
const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${targetCell.rowIndex + 1}`;
|
|
451
|
+
targetSheet.content.set(targetKey, targetContent);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
adjustFormulaWithOffset(formula, rowDelta, colDelta) {
|
|
455
|
+
try {
|
|
456
|
+
const ast = import_parser.parseFormula(formula.slice(1));
|
|
457
|
+
const adjustedAst = import_ast_traverser.transformAST(ast, (node) => {
|
|
458
|
+
if (node.type === "reference") {
|
|
459
|
+
const refNode = node;
|
|
460
|
+
return {
|
|
461
|
+
...refNode,
|
|
462
|
+
address: {
|
|
463
|
+
colIndex: refNode.isAbsolute.col ? refNode.address.colIndex : refNode.address.colIndex + colDelta,
|
|
464
|
+
rowIndex: refNode.isAbsolute.row ? refNode.address.rowIndex : refNode.address.rowIndex + rowDelta
|
|
465
|
+
}
|
|
466
|
+
};
|
|
467
|
+
} else if (node.type === "range") {
|
|
468
|
+
const rangeNode = node;
|
|
469
|
+
return {
|
|
470
|
+
...rangeNode,
|
|
471
|
+
range: {
|
|
472
|
+
start: {
|
|
473
|
+
col: rangeNode.isAbsolute.start.col ? rangeNode.range.start.col : rangeNode.range.start.col + colDelta,
|
|
474
|
+
row: rangeNode.isAbsolute.start.row ? rangeNode.range.start.row : rangeNode.range.start.row + rowDelta
|
|
475
|
+
},
|
|
476
|
+
end: {
|
|
477
|
+
col: rangeNode.range.end.col.type === "number" ? rangeNode.isAbsolute.end.col ? rangeNode.range.end.col : {
|
|
478
|
+
type: "number",
|
|
479
|
+
value: rangeNode.range.end.col.value + colDelta
|
|
480
|
+
} : rangeNode.range.end.col,
|
|
481
|
+
row: rangeNode.range.end.row.type === "number" ? rangeNode.isAbsolute.end.row ? rangeNode.range.end.row : {
|
|
482
|
+
type: "number",
|
|
483
|
+
value: rangeNode.range.end.row.value + rowDelta
|
|
484
|
+
} : rangeNode.range.end.row
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
return node;
|
|
490
|
+
});
|
|
491
|
+
return `=${import_formatter.astToString(adjustedAst)}`;
|
|
492
|
+
} catch (error) {
|
|
493
|
+
console.warn("Failed to adjust formula with offset:", error);
|
|
494
|
+
return formula;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
copyCellFormatting(sourceCell, targetCell) {
|
|
498
|
+
const targetCellRange = {
|
|
499
|
+
workbookName: targetCell.workbookName,
|
|
500
|
+
sheetName: targetCell.sheetName,
|
|
501
|
+
range: {
|
|
502
|
+
start: { col: targetCell.colIndex, row: targetCell.rowIndex },
|
|
503
|
+
end: {
|
|
504
|
+
col: { type: "number", value: targetCell.colIndex },
|
|
505
|
+
row: { type: "number", value: targetCell.rowIndex }
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
this.styleManager.clearCellStylesInRange(targetCellRange);
|
|
510
|
+
const allConditionalStyles = this.styleManager.getAllConditionalStyles();
|
|
511
|
+
const allCellStyles = this.styleManager.getAllCellStyles();
|
|
512
|
+
const sourceCellRange = {
|
|
513
|
+
start: { col: sourceCell.colIndex, row: sourceCell.rowIndex },
|
|
514
|
+
end: {
|
|
515
|
+
col: { type: "number", value: sourceCell.colIndex },
|
|
516
|
+
row: { type: "number", value: sourceCell.rowIndex }
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
for (const style of allConditionalStyles) {
|
|
520
|
+
if (style.area.workbookName === sourceCell.workbookName && style.area.sheetName === sourceCell.sheetName) {
|
|
521
|
+
const intersection = import_range_utils.intersectRanges(style.area.range, sourceCellRange);
|
|
522
|
+
if (intersection) {
|
|
523
|
+
const newStyle = {
|
|
524
|
+
area: {
|
|
525
|
+
workbookName: targetCell.workbookName,
|
|
526
|
+
sheetName: targetCell.sheetName,
|
|
527
|
+
range: {
|
|
528
|
+
start: { col: targetCell.colIndex, row: targetCell.rowIndex },
|
|
529
|
+
end: {
|
|
530
|
+
col: { type: "number", value: targetCell.colIndex },
|
|
531
|
+
row: { type: "number", value: targetCell.rowIndex }
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
},
|
|
535
|
+
condition: style.condition
|
|
536
|
+
};
|
|
537
|
+
this.styleManager.addConditionalStyle(newStyle);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
for (const style of allCellStyles) {
|
|
542
|
+
if (style.area.workbookName === sourceCell.workbookName && style.area.sheetName === sourceCell.sheetName) {
|
|
543
|
+
const intersection = import_range_utils.intersectRanges(style.area.range, sourceCellRange);
|
|
544
|
+
if (intersection) {
|
|
545
|
+
const newStyle = {
|
|
546
|
+
area: {
|
|
547
|
+
workbookName: targetCell.workbookName,
|
|
548
|
+
sheetName: targetCell.sheetName,
|
|
549
|
+
range: {
|
|
550
|
+
start: { col: targetCell.colIndex, row: targetCell.rowIndex },
|
|
551
|
+
end: {
|
|
552
|
+
col: { type: "number", value: targetCell.colIndex },
|
|
553
|
+
row: { type: "number", value: targetCell.rowIndex }
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
},
|
|
557
|
+
style: style.style
|
|
558
|
+
};
|
|
559
|
+
this.styleManager.addCellStyle(newStyle);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
}
|
|
264
564
|
}
|
|
265
565
|
|
|
266
|
-
//# debugId=
|
|
566
|
+
//# debugId=9442C2DD8C5DC2E064756E2164756E21
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/core/managers/copy-manager.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { isCellInRange } from \"../utils.cjs\";\nimport { intersectRanges } from \"../utils/range-utils.cjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Copy cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents (skip if only copying style)\n if (options.target !== 'style') {\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n }\n\n // Copy formatting if requested\n if (options.target === 'all' || options.target === 'style') {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // Find styles that intersect with source cells\n const sourceRange = this.getBoundingBox(sourceCells);\n\n // Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n // Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n}\n\n"
|
|
5
|
+
"/**\n * CopyManager - Manages cell copy/paste operations\n */\n\nimport type {\n CellAddress,\n CopyCellsOptions,\n ConditionalStyle,\n DirectCellStyle,\n LocalCellAddress,\n RangeAddress,\n SerializedCellValue,\n SpreadsheetRange,\n} from \"../types.cjs\";\nimport type { WorkbookManager } from \"./workbook-manager.cjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.cjs\";\nimport type { StyleManager } from \"./style-manager.cjs\";\nimport { parseFormula } from \"../../parser/parser.cjs\";\nimport { astToString } from \"../../parser/formatter.cjs\";\nimport { transformAST } from \"../ast-traverser.cjs\";\nimport type { ReferenceNode, RangeNode } from \"../../parser/ast.cjs\";\nimport { isCellInRange } from \"../utils.cjs\";\nimport { intersectRanges } from \"../utils/range-utils.cjs\";\n\nexport class CopyManager {\n constructor(\n private workbookManager: WorkbookManager,\n private evaluationManager: EvaluationManager,\n private styleManager: StyleManager\n ) {}\n\n /**\n * Paste cells from source to target\n */\n copyCells(\n source: CellAddress[],\n target: CellAddress,\n options: CopyCellsOptions\n ): void {\n if (source.length === 0) {\n return;\n }\n\n // Find top-left cell of source (minimum row/col indices)\n const topLeft = this.findTopLeft(source);\n\n // Calculate offset from source top-left to target\n const rowOffset = target.rowIndex - topLeft.rowIndex;\n const colOffset = target.colIndex - topLeft.colIndex;\n\n // Copy cell contents (skip if only copying style)\n if (options.target !== 'style') {\n for (const sourceCell of source) {\n const targetCell: CellAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n colIndex: sourceCell.colIndex + colOffset,\n rowIndex: sourceCell.rowIndex + rowOffset,\n };\n\n this.copyCellContent(sourceCell, targetCell, topLeft, options);\n }\n }\n\n // Copy formatting if requested\n if (options.target === 'all' || options.target === 'style') {\n this.copyFormatting(source, topLeft, target, rowOffset, colOffset);\n }\n\n // Clear source cells if cut\n if (options.cut) {\n this.clearSourceCells(source);\n }\n }\n\n /**\n * Find the top-left cell (minimum row/col indices)\n */\n private findTopLeft(cells: CellAddress[]): CellAddress {\n let minRow = Infinity;\n let minCol = Infinity;\n let topLeftCell = cells[0]!;\n\n for (const cell of cells) {\n if (\n cell.rowIndex < minRow ||\n (cell.rowIndex === minRow && cell.colIndex < minCol)\n ) {\n minRow = cell.rowIndex;\n minCol = cell.colIndex;\n topLeftCell = cell;\n }\n }\n\n return topLeftCell;\n }\n\n /**\n * Copy content from one cell to another\n */\n private copyCellContent(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n sourceTopLeft: CellAddress,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references\n targetContent = this.adjustFormulaReferences(\n cellContent,\n {\n colIndex: sourceCell.colIndex,\n rowIndex: sourceCell.rowIndex,\n },\n {\n colIndex: targetCell.colIndex,\n rowIndex: targetCell.rowIndex,\n }\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content (using the engine's method through workbook manager)\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references when copying\n * Based on autofill-utils.ts adjustFormulaReferences\n */\n private adjustFormulaReferences(\n formula: string,\n sourceAddress: LocalCellAddress,\n targetAddress: LocalCellAddress\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const rowDelta = targetAddress.rowIndex - sourceAddress.rowIndex;\n const colDelta = targetAddress.colIndex - sourceAddress.colIndex;\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula references:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting (cellStyles and conditionalStyles) from source to target\n * Clears existing cell styles in target range first (Excel behavior)\n */\n private copyFormatting(\n sourceCells: CellAddress[],\n sourceTopLeft: CellAddress,\n target: CellAddress,\n rowOffset: number,\n colOffset: number\n ): void {\n // STEP 1: Clear existing cell styles in target range (Excel-like replacement)\n const sourceRange = this.getBoundingBox(sourceCells);\n const targetRange: RangeAddress = {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(sourceRange, rowOffset, colOffset),\n };\n \n this.styleManager.clearCellStylesInRange(targetRange);\n\n // Get all styles for the source workbook\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n // STEP 2: Copy conditional styles\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n // STEP 3: Copy cell styles\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceTopLeft.workbookName &&\n style.area.sheetName === sourceTopLeft.sheetName\n ) {\n // Calculate intersection of style range with source bounding box\n const intersection = intersectRanges(style.area.range, sourceRange);\n if (intersection) {\n // Copy only the intersection, offset to target\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: target.workbookName,\n sheetName: target.sheetName,\n range: this.adjustRange(intersection, rowOffset, colOffset),\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n\n /**\n * Get bounding box for a set of cells\n */\n private getBoundingBox(cells: CellAddress[]): SpreadsheetRange {\n let minRow = Infinity;\n let maxRow = -Infinity;\n let minCol = Infinity;\n let maxCol = -Infinity;\n\n for (const cell of cells) {\n minRow = Math.min(minRow, cell.rowIndex);\n maxRow = Math.max(maxRow, cell.rowIndex);\n minCol = Math.min(minCol, cell.colIndex);\n maxCol = Math.max(maxCol, cell.colIndex);\n }\n\n return {\n start: { col: minCol, row: minRow },\n end: {\n col: { type: \"number\", value: maxCol },\n row: { type: \"number\", value: maxRow },\n },\n };\n }\n\n\n /**\n * Adjust a range by row and column offsets\n */\n private adjustRange(\n range: SpreadsheetRange,\n rowOffset: number,\n colOffset: number\n ): SpreadsheetRange {\n return {\n start: {\n col: range.start.col + colOffset,\n row: range.start.row + rowOffset,\n },\n end: {\n col:\n range.end.col.type === \"number\"\n ? { type: \"number\", value: range.end.col.value + colOffset }\n : range.end.col,\n row:\n range.end.row.type === \"number\"\n ? { type: \"number\", value: range.end.row.value + rowOffset }\n : range.end.row,\n },\n };\n }\n\n /**\n * Clear source cells (for cut operation)\n */\n private clearSourceCells(cells: CellAddress[]): void {\n for (const cell of cells) {\n const sheet = this.workbookManager.getSheet({\n workbookName: cell.workbookName,\n sheetName: cell.sheetName,\n });\n\n if (sheet) {\n const key = `${String.fromCharCode(65 + cell.colIndex)}${\n cell.rowIndex + 1\n }`;\n sheet.content.delete(key);\n }\n }\n }\n\n /**\n * Fill one or more areas with a seed range's content/style\n * Uses column-first strategy: fills down, then replicates right\n * Formulas are adjusted based on each target cell's offset from the seed\n */\n fillAreas(\n seedRange: RangeAddress,\n targetRanges: RangeAddress[],\n options: CopyCellsOptions\n ): void {\n for (const targetRange of targetRanges) {\n this.fillRangeWithSeed(seedRange, targetRange, {\n copyContent: options.target !== 'style',\n copyStyles: options.target === 'all' || options.target === 'style',\n contentType: options.type,\n adjustFormulas: true,\n });\n }\n\n // Clear seed range if cut operation\n if (options.cut) {\n const seedCells = this.expandRangeToCells(seedRange);\n this.clearSourceCells(seedCells);\n }\n }\n\n /**\n * Fill a target range with a seed range using column-first strategy\n * Step 0: Clear existing cell styles in target (Excel behavior)\n * Step 1: Fill down - extend seed pattern vertically to match target height\n * Step 2: Replicate right - copy filled columns horizontally\n */\n private fillRangeWithSeed(\n seedRange: RangeAddress,\n targetRange: RangeAddress,\n options: {\n copyContent: boolean;\n copyStyles: boolean;\n contentType: \"value\" | \"formula\";\n adjustFormulas: boolean;\n }\n ): void {\n // Step 0: Clear existing cell styles in target range (Excel-like replacement)\n if (options.copyStyles) {\n this.styleManager.clearCellStylesInRange(targetRange);\n }\n\n const seedCells = this.expandRangeToCells(seedRange);\n const seedWidth = this.getRangeWidth(seedRange);\n const seedHeight = this.getRangeHeight(seedRange);\n const targetWidth = this.getRangeWidth(targetRange);\n const targetHeight = this.getRangeHeight(targetRange);\n\n // Step 1: Fill down - replicate seed pattern vertically\n const filledColumns: Map<string, { cell: CellAddress; content: SerializedCellValue }> = new Map();\n \n for (let col = 0; col < seedWidth; col++) {\n for (let row = 0; row < targetHeight; row++) {\n const seedRow = row % seedHeight;\n const seedCell = seedCells.find(\n (c) => \n c.colIndex === seedRange.range.start.col + col &&\n c.rowIndex === seedRange.range.start.row + seedRow\n );\n\n if (seedCell) {\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const rowDelta = targetCell.rowIndex - seedCell.rowIndex;\n const colDelta = targetCell.colIndex - seedCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(seedCell, targetCell, rowDelta, colDelta, {\n type: options.contentType,\n cut: false,\n target: 'content',\n });\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(seedCell, targetCell);\n }\n\n // Store filled column for horizontal replication\n const key = `${targetCell.colIndex}-${targetCell.rowIndex}`;\n const sheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n const cellKey = `${String.fromCharCode(65 + targetCell.colIndex)}${targetCell.rowIndex + 1}`;\n const content = sheet?.content.get(cellKey) || \"\";\n filledColumns.set(key, { cell: targetCell, content });\n }\n }\n }\n\n // Step 2: Replicate right - copy filled columns horizontally\n if (targetWidth > seedWidth) {\n for (let col = seedWidth; col < targetWidth; col++) {\n const sourceCol = col % seedWidth;\n \n for (let row = 0; row < targetHeight; row++) {\n const sourceCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + sourceCol,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const targetCell: CellAddress = {\n workbookName: targetRange.workbookName,\n sheetName: targetRange.sheetName,\n colIndex: targetRange.range.start.col + col,\n rowIndex: targetRange.range.start.row + row,\n };\n\n const colDelta = targetCell.colIndex - sourceCell.colIndex;\n\n if (options.copyContent) {\n this.copyCellContentWithOffset(sourceCell, targetCell, 0, colDelta, {\n type: options.contentType,\n cut: false,\n target: 'content',\n });\n }\n\n if (options.copyStyles) {\n this.copyCellFormatting(sourceCell, targetCell);\n }\n }\n }\n }\n }\n\n /**\n * Get the width of a range (number of columns)\n */\n private getRangeWidth(range: RangeAddress): number {\n if (range.range.end.col.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.col.value - range.range.start.col + 1;\n }\n\n /**\n * Get the height of a range (number of rows)\n */\n private getRangeHeight(range: RangeAddress): number {\n if (range.range.end.row.type === \"infinity\") {\n return 100; // Default for infinite\n }\n return range.range.end.row.value - range.range.start.row + 1;\n }\n\n /**\n * Expand a RangeAddress into an array of CellAddress\n * Handles finite ranges, row-bounded, and column-bounded ranges\n */\n private expandRangeToCells(rangeAddress: RangeAddress): CellAddress[] {\n const { workbookName, sheetName, range } = rangeAddress;\n const cells: CellAddress[] = [];\n\n const startCol = range.start.col;\n const startRow = range.start.row;\n\n // Determine end column\n let endCol: number;\n if (range.end.col.type === \"infinity\") {\n // Limit infinite column ranges to a reasonable size (e.g., 100 columns)\n endCol = startCol + 99;\n } else {\n endCol = range.end.col.value;\n }\n\n // Determine end row\n let endRow: number;\n if (range.end.row.type === \"infinity\") {\n // Limit infinite row ranges to a reasonable size (e.g., 100 rows)\n endRow = startRow + 99;\n } else {\n endRow = range.end.row.value;\n }\n\n // Generate all cells in the range\n for (let row = startRow; row <= endRow; row++) {\n for (let col = startCol; col <= endCol; col++) {\n cells.push({\n workbookName,\n sheetName,\n colIndex: col,\n rowIndex: row,\n });\n }\n }\n\n return cells;\n }\n\n /**\n * Copy cell content with explicit row/column offset for fill operations\n */\n private copyCellContentWithOffset(\n sourceCell: CellAddress,\n targetCell: CellAddress,\n rowDelta: number,\n colDelta: number,\n options: CopyCellsOptions\n ): void {\n const sheet = this.workbookManager.getSheet({\n workbookName: sourceCell.workbookName,\n sheetName: sourceCell.sheetName,\n });\n\n if (!sheet) {\n return;\n }\n\n const key = `${String.fromCharCode(65 + sourceCell.colIndex)}${\n sourceCell.rowIndex + 1\n }`;\n const cellContent = sheet.content.get(key);\n\n if (!cellContent) {\n // Source cell is empty - clear target\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.delete(targetKey);\n }\n return;\n }\n\n let targetContent: SerializedCellValue;\n\n if (options.type === \"value\") {\n // Copy evaluated value\n const evalResult = this.evaluationManager.getCellEvaluationResult(sourceCell);\n \n if (!evalResult || evalResult.type !== \"value\") {\n // If evaluation failed or is not a value, copy as-is\n targetContent = cellContent;\n } else {\n // Convert to literal value\n const result = evalResult.result;\n if (result.type === \"number\") {\n targetContent = result.value;\n } else if (result.type === \"string\") {\n targetContent = result.value;\n } else if (result.type === \"boolean\") {\n targetContent = result.value;\n } else {\n // Error or other type, copy as-is\n targetContent = cellContent;\n }\n }\n } else {\n // Copy formula with offset adjustment\n if (typeof cellContent === \"string\" && cellContent.startsWith(\"=\")) {\n // Adjust formula references based on offset\n targetContent = this.adjustFormulaWithOffset(\n cellContent,\n rowDelta,\n colDelta\n );\n } else {\n // Not a formula, copy as-is\n targetContent = cellContent;\n }\n }\n\n // Set target cell content\n const targetSheet = this.workbookManager.getSheet({\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n });\n\n if (targetSheet) {\n const targetKey = `${String.fromCharCode(65 + targetCell.colIndex)}${\n targetCell.rowIndex + 1\n }`;\n targetSheet.content.set(targetKey, targetContent);\n }\n }\n\n /**\n * Adjust formula references by a specific row/column offset\n */\n private adjustFormulaWithOffset(\n formula: string,\n rowDelta: number,\n colDelta: number\n ): string {\n try {\n const ast = parseFormula(formula.slice(1)); // Remove the \"=\" sign\n\n const adjustedAst = transformAST(ast, (node) => {\n if (node.type === \"reference\") {\n const refNode = node as ReferenceNode;\n return {\n ...refNode,\n address: {\n colIndex: refNode.isAbsolute.col\n ? refNode.address.colIndex\n : refNode.address.colIndex + colDelta,\n rowIndex: refNode.isAbsolute.row\n ? refNode.address.rowIndex\n : refNode.address.rowIndex + rowDelta,\n },\n };\n } else if (node.type === \"range\") {\n const rangeNode = node as RangeNode;\n return {\n ...rangeNode,\n range: {\n start: {\n col: rangeNode.isAbsolute.start.col\n ? rangeNode.range.start.col\n : rangeNode.range.start.col + colDelta,\n row: rangeNode.isAbsolute.start.row\n ? rangeNode.range.start.row\n : rangeNode.range.start.row + rowDelta,\n },\n end: {\n col:\n rangeNode.range.end.col.type === \"number\"\n ? rangeNode.isAbsolute.end.col\n ? rangeNode.range.end.col\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.col.value + colDelta,\n }\n : rangeNode.range.end.col,\n row:\n rangeNode.range.end.row.type === \"number\"\n ? rangeNode.isAbsolute.end.row\n ? rangeNode.range.end.row\n : {\n type: \"number\" as const,\n value: rangeNode.range.end.row.value + rowDelta,\n }\n : rangeNode.range.end.row,\n },\n },\n };\n }\n return node;\n });\n\n return `=${astToString(adjustedAst)}`;\n } catch (error) {\n // If parsing fails, return the original formula\n console.warn(\"Failed to adjust formula with offset:\", error);\n return formula;\n }\n }\n\n /**\n * Copy formatting from one cell to another\n * Clears existing cell styles at target (Excel behavior) before copying new ones\n */\n private copyCellFormatting(\n sourceCell: CellAddress,\n targetCell: CellAddress\n ): void {\n // STEP 1: Clear existing cell styles at target cell (Excel-like replacement)\n const targetCellRange: RangeAddress = {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n };\n \n this.styleManager.clearCellStylesInRange(targetCellRange);\n\n // Get all styles that intersect with the source cell\n const allConditionalStyles = this.styleManager.getAllConditionalStyles();\n const allCellStyles = this.styleManager.getAllCellStyles();\n\n const sourceCellRange: SpreadsheetRange = {\n start: { col: sourceCell.colIndex, row: sourceCell.rowIndex },\n end: {\n col: { type: \"number\", value: sourceCell.colIndex },\n row: { type: \"number\", value: sourceCell.rowIndex },\n },\n };\n\n // STEP 2: Copy conditional styles that apply to source cell\n for (const style of allConditionalStyles) {\n if (\n style.area.workbookName === sourceCell.workbookName &&\n style.area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(style.area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: ConditionalStyle = {\n area: {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n condition: style.condition,\n };\n this.styleManager.addConditionalStyle(newStyle);\n }\n }\n }\n\n // STEP 3: Copy cell styles that apply to source cell\n for (const style of allCellStyles) {\n if (\n style.area.workbookName === sourceCell.workbookName &&\n style.area.sheetName === sourceCell.sheetName\n ) {\n const intersection = intersectRanges(style.area.range, sourceCellRange);\n if (intersection) {\n // Apply style to target cell\n const newStyle: DirectCellStyle = {\n area: {\n workbookName: targetCell.workbookName,\n sheetName: targetCell.sheetName,\n range: {\n start: { col: targetCell.colIndex, row: targetCell.rowIndex },\n end: {\n col: { type: \"number\", value: targetCell.colIndex },\n row: { type: \"number\", value: targetCell.rowIndex },\n },\n },\n },\n style: style.style,\n };\n this.styleManager.addCellStyle(newStyle);\n }\n }\n }\n }\n}\n\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgB6B,IAA7B;AAC4B,IAA5B;AAC6B,IAA7B;AAGgC,IAAhC;AAAA;AAEO,MAAM,YAAY;AAAA,EAEb;AAAA,EACA;AAAA,EACA;AAAA,EAHV,WAAW,CACD,iBACA,mBACA,cACR;AAAA,IAHQ;AAAA,IACA;AAAA,IACA;AAAA;AAAA,EAMV,SAAS,CACP,QACA,QACA,SACM;AAAA,IACN,IAAI,OAAO,WAAW,GAAG;AAAA,MACvB;AAAA,IACF;AAAA,IAGA,MAAM,UAAU,KAAK,YAAY,MAAM;AAAA,IAGvC,MAAM,YAAY,OAAO,WAAW,QAAQ;AAAA,IAC5C,MAAM,YAAY,OAAO,WAAW,QAAQ;AAAA,IAG5C,IAAI,QAAQ,WAAW,SAAS;AAAA,MAC9B,WAAW,cAAc,QAAQ;AAAA,QAC/B,MAAM,aAA0B;AAAA,UAC9B,cAAc,OAAO;AAAA,UACrB,WAAW,OAAO;AAAA,UAClB,UAAU,WAAW,WAAW;AAAA,UAChC,UAAU,WAAW,WAAW;AAAA,QAClC;AAAA,QAEA,KAAK,gBAAgB,YAAY,YAAY,SAAS,OAAO;AAAA,MAC/D;AAAA,IACF;AAAA,IAGA,IAAI,QAAQ,WAAW,SAAS,QAAQ,WAAW,SAAS;AAAA,MAC1D,KAAK,eAAe,QAAQ,SAAS,QAAQ,WAAW,SAAS;AAAA,IACnE;AAAA,IAGA,IAAI,QAAQ,KAAK;AAAA,MACf,KAAK,iBAAiB,MAAM;AAAA,IAC9B;AAAA;AAAA,EAMM,WAAW,CAAC,OAAmC;AAAA,IACrD,IAAI,SAAS;AAAA,IACb,IAAI,SAAS;AAAA,IACb,IAAI,cAAc,MAAM;AAAA,IAExB,WAAW,QAAQ,OAAO;AAAA,MACxB,IACE,KAAK,WAAW,UACf,KAAK,aAAa,UAAU,KAAK,WAAW,QAC7C;AAAA,QACA,SAAS,KAAK;AAAA,QACd,SAAS,KAAK;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,IAEA,OAAO;AAAA;AAAA,EAMD,eAAe,CACrB,YACA,YACA,eACA,SACM;AAAA,IACN,MAAM,QAAQ,KAAK,gBAAgB,SAAS;AAAA,MAC1C,cAAc,WAAW;AAAA,MACzB,WAAW,WAAW;AAAA,IACxB,CAAC;AAAA,IAED,IAAI,CAAC,OAAO;AAAA,MACV;AAAA,IACF;AAAA,IAEA,MAAM,MAAM,GAAG,OAAO,aAAa,KAAK,WAAW,QAAQ,IACzD,WAAW,WAAW;AAAA,IAExB,MAAM,cAAc,MAAM,QAAQ,IAAI,GAAG;AAAA,IAEzC,IAAI,CAAC,aAAa;AAAA,MAEhB;AAAA,IACF;AAAA,IAEA,IAAI;AAAA,IAEJ,IAAI,QAAQ,SAAS,SAAS;AAAA,MAE5B,MAAM,aAAa,KAAK,kBAAkB,wBAAwB,UAAU;AAAA,MAE5E,IAAI,CAAC,cAAc,WAAW,SAAS,SAAS;AAAA,QAE9C,gBAAgB;AAAA,MAClB,EAAO;AAAA,QAEL,MAAM,SAAS,WAAW;AAAA,QAC1B,IAAI,OAAO,SAAS,UAAU;AAAA,UAC5B,gBAAgB,OAAO;AAAA,QACzB,EAAO,SAAI,OAAO,SAAS,UAAU;AAAA,UACnC,gBAAgB,OAAO;AAAA,QACzB,EAAO,SAAI,OAAO,SAAS,WAAW;AAAA,UACpC,gBAAgB,OAAO;AAAA,QACzB,EAAO;AAAA,UAEL,gBAAgB;AAAA;AAAA;AAAA,IAGtB,EAAO;AAAA,MAEL,IAAI,OAAO,gBAAgB,YAAY,YAAY,WAAW,GAAG,GAAG;AAAA,QAElE,gBAAgB,KAAK,wBACnB,aACA;AAAA,UACE,UAAU,WAAW;AAAA,UACrB,UAAU,WAAW;AAAA,QACvB,GACA;AAAA,UACE,UAAU,WAAW;AAAA,UACrB,UAAU,WAAW;AAAA,QACvB,CACF;AAAA,MACF,EAAO;AAAA,QAEL,gBAAgB;AAAA;AAAA;AAAA,IAKpB,MAAM,cAAc,KAAK,gBAAgB,SAAS;AAAA,MAChD,cAAc,WAAW;AAAA,MACzB,WAAW,WAAW;AAAA,IACxB,CAAC;AAAA,IAED,IAAI,aAAa;AAAA,MACf,MAAM,YAAY,GAAG,OAAO,aAAa,KAAK,WAAW,QAAQ,IAC/D,WAAW,WAAW;AAAA,MAExB,YAAY,QAAQ,IAAI,WAAW,aAAa;AAAA,IAClD;AAAA;AAAA,EAOM,uBAAuB,CAC7B,SACA,eACA,eACQ;AAAA,IACR,IAAI;AAAA,MACF,MAAM,MAAM,2BAAa,QAAQ,MAAM,CAAC,CAAC;AAAA,MAEzC,MAAM,WAAW,cAAc,WAAW,cAAc;AAAA,MACxD,MAAM,WAAW,cAAc,WAAW,cAAc;AAAA,MAExD,MAAM,cAAc,kCAAa,KAAK,CAAC,SAAS;AAAA,QAC9C,IAAI,KAAK,SAAS,aAAa;AAAA,UAC7B,MAAM,UAAU;AAAA,UAChB,OAAO;AAAA,eACF;AAAA,YACH,SAAS;AAAA,cACP,UAAU,QAAQ,WAAW,MACzB,QAAQ,QAAQ,WAChB,QAAQ,QAAQ,WAAW;AAAA,cAC/B,UAAU,QAAQ,WAAW,MACzB,QAAQ,QAAQ,WAChB,QAAQ,QAAQ,WAAW;AAAA,YACjC;AAAA,UACF;AAAA,QACF,EAAO,SAAI,KAAK,SAAS,SAAS;AAAA,UAChC,MAAM,YAAY;AAAA,UAClB,OAAO;AAAA,eACF;AAAA,YACH,OAAO;AAAA,cACL,OAAO;AAAA,gBACL,KAAK,UAAU,WAAW,MAAM,MAC5B,UAAU,MAAM,MAAM,MACtB,UAAU,MAAM,MAAM,MAAM;AAAA,gBAChC,KAAK,UAAU,WAAW,MAAM,MAC5B,UAAU,MAAM,MAAM,MACtB,UAAU,MAAM,MAAM,MAAM;AAAA,cAClC;AAAA,cACA,KAAK;AAAA,gBACH,KACE,UAAU,MAAM,IAAI,IAAI,SAAS,WAC7B,UAAU,WAAW,IAAI,MACvB,UAAU,MAAM,IAAI,MACpB;AAAA,kBACE,MAAM;AAAA,kBACN,OAAO,UAAU,MAAM,IAAI,IAAI,QAAQ;AAAA,gBACzC,IACF,UAAU,MAAM,IAAI;AAAA,gBAC1B,KACE,UAAU,MAAM,IAAI,IAAI,SAAS,WAC7B,UAAU,WAAW,IAAI,MACvB,UAAU,MAAM,IAAI,MACpB;AAAA,kBACE,MAAM;AAAA,kBACN,OAAO,UAAU,MAAM,IAAI,IAAI,QAAQ;AAAA,gBACzC,IACF,UAAU,MAAM,IAAI;AAAA,cAC5B;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,OAAO;AAAA,OACR;AAAA,MAED,OAAO,IAAI,6BAAY,WAAW;AAAA,MAClC,OAAO,OAAO;AAAA,MAEd,QAAQ,KAAK,wCAAwC,KAAK;AAAA,MAC1D,OAAO;AAAA;AAAA;AAAA,EAOH,cAAc,CACpB,aACA,eACA,QACA,WACA,WACM;AAAA,IAEN,MAAM,uBAAuB,KAAK,aAAa,wBAAwB;AAAA,IACvE,MAAM,gBAAgB,KAAK,aAAa,iBAAiB;AAAA,IAGzD,MAAM,cAAc,KAAK,eAAe,WAAW;AAAA,IAGnD,WAAW,SAAS,sBAAsB;AAAA,MACxC,IACE,MAAM,KAAK,iBAAiB,cAAc,gBAC1C,MAAM,KAAK,cAAc,cAAc,WACvC;AAAA,QAEA,MAAM,eAAe,mCAAgB,MAAM,KAAK,OAAO,WAAW;AAAA,QAClE,IAAI,cAAc;AAAA,UAEhB,MAAM,WAA6B;AAAA,YACjC,MAAM;AAAA,cACJ,cAAc,OAAO;AAAA,cACrB,WAAW,OAAO;AAAA,cAClB,OAAO,KAAK,YAAY,cAAc,WAAW,SAAS;AAAA,YAC5D;AAAA,YACA,WAAW,MAAM;AAAA,UACnB;AAAA,UACA,KAAK,aAAa,oBAAoB,QAAQ;AAAA,QAChD;AAAA,MACF;AAAA,IACF;AAAA,IAGA,WAAW,SAAS,eAAe;AAAA,MACjC,IACE,MAAM,KAAK,iBAAiB,cAAc,gBAC1C,MAAM,KAAK,cAAc,cAAc,WACvC;AAAA,QAEA,MAAM,eAAe,mCAAgB,MAAM,KAAK,OAAO,WAAW;AAAA,QAClE,IAAI,cAAc;AAAA,UAEhB,MAAM,WAA4B;AAAA,YAChC,MAAM;AAAA,cACJ,cAAc,OAAO;AAAA,cACrB,WAAW,OAAO;AAAA,cAClB,OAAO,KAAK,YAAY,cAAc,WAAW,SAAS;AAAA,YAC5D;AAAA,YACA,OAAO,MAAM;AAAA,UACf;AAAA,UACA,KAAK,aAAa,aAAa,QAAQ;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA;AAAA,EAMM,cAAc,CAAC,OAAwC;AAAA,IAC7D,IAAI,SAAS;AAAA,IACb,IAAI,SAAS;AAAA,IACb,IAAI,SAAS;AAAA,IACb,IAAI,SAAS;AAAA,IAEb,WAAW,QAAQ,OAAO;AAAA,MACxB,SAAS,KAAK,IAAI,QAAQ,KAAK,QAAQ;AAAA,MACvC,SAAS,KAAK,IAAI,QAAQ,KAAK,QAAQ;AAAA,MACvC,SAAS,KAAK,IAAI,QAAQ,KAAK,QAAQ;AAAA,MACvC,SAAS,KAAK,IAAI,QAAQ,KAAK,QAAQ;AAAA,IACzC;AAAA,IAEA,OAAO;AAAA,MACL,OAAO,EAAE,KAAK,QAAQ,KAAK,OAAO;AAAA,MAClC,KAAK;AAAA,QACH,KAAK,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,QACrC,KAAK,EAAE,MAAM,UAAU,OAAO,OAAO;AAAA,MACvC;AAAA,IACF;AAAA;AAAA,EAOM,WAAW,CACjB,OACA,WACA,WACkB;AAAA,IAClB,OAAO;AAAA,MACL,OAAO;AAAA,QACL,KAAK,MAAM,MAAM,MAAM;AAAA,QACvB,KAAK,MAAM,MAAM,MAAM;AAAA,MACzB;AAAA,MACA,KAAK;AAAA,QACH,KACE,MAAM,IAAI,IAAI,SAAS,WACnB,EAAE,MAAM,UAAU,OAAO,MAAM,IAAI,IAAI,QAAQ,UAAU,IACzD,MAAM,IAAI;AAAA,QAChB,KACE,MAAM,IAAI,IAAI,SAAS,WACnB,EAAE,MAAM,UAAU,OAAO,MAAM,IAAI,IAAI,QAAQ,UAAU,IACzD,MAAM,IAAI;AAAA,MAClB;AAAA,IACF;AAAA;AAAA,EAMM,gBAAgB,CAAC,OAA4B;AAAA,IACnD,WAAW,QAAQ,OAAO;AAAA,MACxB,MAAM,QAAQ,KAAK,gBAAgB,SAAS;AAAA,QAC1C,cAAc,KAAK;AAAA,QACnB,WAAW,KAAK;AAAA,MAClB,CAAC;AAAA,MAED,IAAI,OAAO;AAAA,QACT,MAAM,MAAM,GAAG,OAAO,aAAa,KAAK,KAAK,QAAQ,IACnD,KAAK,WAAW;AAAA,QAElB,MAAM,QAAQ,OAAO,GAAG;AAAA,MAC1B;AAAA,IACF;AAAA;AAEJ;",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "9442C2DD8C5DC2E064756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -176,14 +176,6 @@ class StyleManager {
|
|
|
176
176
|
this.cellStyles = this.cellStyles.filter((style) => !(style.area.workbookName === workbookName && style.area.sheetName === sheetName));
|
|
177
177
|
}
|
|
178
178
|
getCellStyle(cellAddress) {
|
|
179
|
-
for (const cellStyle of this.cellStyles) {
|
|
180
|
-
if (!cellStyle || !cellStyle.area) {
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
if (cellStyle.area.workbookName === cellAddress.workbookName && cellStyle.area.sheetName === cellAddress.sheetName && import_utils.isCellInRange(cellAddress, cellStyle.area.range)) {
|
|
184
|
-
return cellStyle.style;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
179
|
for (const style of this.conditionalStyles) {
|
|
188
180
|
if (!style || !style.area) {
|
|
189
181
|
continue;
|
|
@@ -204,6 +196,14 @@ class StyleManager {
|
|
|
204
196
|
return result;
|
|
205
197
|
}
|
|
206
198
|
}
|
|
199
|
+
for (const cellStyle of this.cellStyles) {
|
|
200
|
+
if (!cellStyle || !cellStyle.area) {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (cellStyle.area.workbookName === cellAddress.workbookName && cellStyle.area.sheetName === cellAddress.sheetName && import_utils.isCellInRange(cellAddress, cellStyle.area.range)) {
|
|
204
|
+
return cellStyle.style;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
evaluateFormulaCondition(cellAddress, style) {
|
|
@@ -394,6 +394,31 @@ class StyleManager {
|
|
|
394
394
|
}
|
|
395
395
|
this.conditionalStyles = newConditionalStyles;
|
|
396
396
|
}
|
|
397
|
+
clearCellStylesInRange(range) {
|
|
398
|
+
const newCellStyles = [];
|
|
399
|
+
for (const style of this.cellStyles) {
|
|
400
|
+
if (style.area.workbookName !== range.workbookName || style.area.sheetName !== range.sheetName) {
|
|
401
|
+
newCellStyles.push(style);
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
if (!import_range_utils.rangesIntersect(style.area.range, range.range)) {
|
|
405
|
+
newCellStyles.push(style);
|
|
406
|
+
continue;
|
|
407
|
+
}
|
|
408
|
+
const remainingRanges = import_range_utils.subtractRange(style.area.range, range.range);
|
|
409
|
+
for (const remainingRange of remainingRanges) {
|
|
410
|
+
newCellStyles.push({
|
|
411
|
+
area: {
|
|
412
|
+
workbookName: style.area.workbookName,
|
|
413
|
+
sheetName: style.area.sheetName,
|
|
414
|
+
range: remainingRange
|
|
415
|
+
},
|
|
416
|
+
style: style.style
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
this.cellStyles = newCellStyles;
|
|
421
|
+
}
|
|
397
422
|
}
|
|
398
423
|
|
|
399
|
-
//# debugId=
|
|
424
|
+
//# debugId=90FE8BBF6E4815D964756E2164756E21
|