@ricsam/formula-engine 0.2.12 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/cjs/core/managers/style-manager.cjs +19 -14
- package/dist/cjs/core/managers/style-manager.cjs.map +3 -3
- package/dist/cjs/core/managers/workbook-manager.cjs +89 -55
- package/dist/cjs/core/managers/workbook-manager.cjs.map +3 -3
- package/dist/cjs/core/types.cjs +4 -2
- package/dist/cjs/core/types.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/managers/style-manager.mjs +19 -14
- package/dist/mjs/core/managers/style-manager.mjs.map +3 -3
- package/dist/mjs/core/managers/workbook-manager.mjs +91 -55
- package/dist/mjs/core/managers/workbook-manager.mjs.map +3 -3
- package/dist/mjs/core/types.mjs +4 -2
- package/dist/mjs/core/types.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/managers/style-manager.d.ts +4 -3
- package/dist/types/core/managers/workbook-manager.d.ts +2 -0
- package/dist/types/core/types.d.ts +15 -0
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/core/managers/style-manager.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"/**\n * StyleManager - Manages conditional styling for cells\n */\n\nimport type {\n CellAddress,\n CellStyle,\n ConditionalStyle,\n DirectCellStyle,\n RangeAddress,\n SerializedCellValue,\n} from \"../types.mjs\";\nimport type { StyleManagerSnapshot } from \"../engine-snapshot.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.mjs\";\nimport { isCellInRange } from \"../utils.mjs\";\nimport {\n calculateGradientFactor,\n interpolateLCH,\n lchToHex,\n} from \"../utils/color-utils.mjs\";\nimport {\n subtractRange,\n rangesIntersect,\n isRangeContained,\n} from \"../utils/range-utils.mjs\";\n\nexport class StyleManager {\n private conditionalStyles: ConditionalStyle[] = [];\n private cellStyles: DirectCellStyle[] = [];\n\n constructor(private evaluationManager: EvaluationManager) {}\n\n /**\n * Add a conditional style rule\n */\n addConditionalStyle(style: ConditionalStyle): void {\n this.conditionalStyles.push(style);\n }\n\n /**\n * Remove a conditional style rule by index for a specific workbook\n */\n removeConditionalStyle(workbookName: string, index: number): boolean {\n const workbookStyles = this.conditionalStyles.filter(\n (style) => style.areas.some(area => area.workbookName === workbookName)\n );\n if (index < 0 || index >= workbookStyles.length) {\n return false;\n }\n // Find the actual index in the full array\n let currentIndex = 0;\n for (let i = 0; i < this.conditionalStyles.length; i++) {\n const style = this.conditionalStyles[i];\n if (style && style.areas.some(area => area.workbookName === workbookName)) {\n if (currentIndex === index) {\n this.conditionalStyles.splice(i, 1);\n return true;\n }\n currentIndex++;\n }\n }\n return false;\n }\n\n /**\n * Get all conditional styles intersecting with a range\n */\n getConditionalStylesIntersectingWithRange(\n range: RangeAddress\n ): ConditionalStyle[] {\n return this.conditionalStyles.filter(\n (style) =>\n style.areas.some(area =>\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n )\n );\n }\n\n /**\n * Add a direct cell style rule\n */\n addCellStyle(style: DirectCellStyle): void {\n this.cellStyles.push(style);\n }\n\n /**\n * Remove a direct cell style rule by index for a specific workbook\n */\n removeCellStyle(workbookName: string, index: number): boolean {\n const workbookStyles = this.cellStyles.filter(\n (style) => style && style.areas && style.areas.some(area => area.workbookName === workbookName)\n );\n if (index < 0 || index >= workbookStyles.length) {\n return false;\n }\n // Find the actual index in the full array\n let currentIndex = 0;\n for (let i = 0; i < this.cellStyles.length; i++) {\n const style = this.cellStyles[i];\n if (style && style.areas && style.areas.some(area => area.workbookName === workbookName)) {\n if (currentIndex === index) {\n this.cellStyles.splice(i, 1);\n return true;\n }\n currentIndex++;\n }\n }\n return false;\n }\n\n /**\n * Get all direct cell styles intersecting with a range\n */\n getStylesIntersectingWithRange(range: RangeAddress): DirectCellStyle[] {\n return this.cellStyles.filter(\n (style) =>\n style &&\n style.areas.some(area =>\n area.sheetName === range.sheetName &&\n area.workbookName === range.workbookName &&\n rangesIntersect(area.range, range.range)\n )\n );\n }\n\n /**\n * Get the style for a range if all cells in the range have the same style\n * Returns the DirectCellStyle if the range is completely contained within a single style's areas\n * Returns undefined if multiple styles, partial coverage, or no styles apply\n */\n getStyleForRange(range: RangeAddress): DirectCellStyle | undefined {\n const intersectingStyles = this.getStylesIntersectingWithRange(range);\n\n // If no styles intersect, return undefined\n if (intersectingStyles.length === 0) {\n return undefined;\n }\n\n // If multiple styles intersect, return undefined (range has mixed styles)\n if (intersectingStyles.length > 1) {\n return undefined;\n }\n\n // Check if the range is completely contained within any of the single style's areas\n const style = intersectingStyles[0]!;\n const isContained = style.areas.some(area =>\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n isRangeContained(range.range, area.range)\n );\n \n if (isContained) {\n return style;\n }\n\n // Range is not completely contained, return undefined\n return undefined;\n }\n\n /**\n * Get all conditional styles across all workbooks (for serialization)\n */\n getAllConditionalStyles(): ConditionalStyle[] {\n return [...this.conditionalStyles];\n }\n\n /**\n * Get all cell styles (for serialization)\n */\n getAllCellStyles(): DirectCellStyle[] {\n return [...this.cellStyles];\n }\n\n /**\n * Reset all styles (for deserialization)\n */\n resetStyles(\n conditionalStyles?: ConditionalStyle[],\n cellStyles?: DirectCellStyle[]\n ): void {\n this.conditionalStyles = conditionalStyles ? [...conditionalStyles] : [];\n this.cellStyles = cellStyles ? [...cellStyles] : [];\n }\n\n toSnapshot(): StyleManagerSnapshot {\n return {\n conditionalStyles: this.getAllConditionalStyles(),\n cellStyles: this.getAllCellStyles(),\n };\n }\n\n restoreFromSnapshot(snapshot: StyleManagerSnapshot): void {\n this.resetStyles(snapshot.conditionalStyles, snapshot.cellStyles);\n }\n\n /**\n * Remove all styles for a workbook\n */\n removeWorkbookStyles(workbookName: string): void {\n this.conditionalStyles = this.conditionalStyles.filter(\n (style) => !style.areas.some(area => area.workbookName === workbookName)\n );\n this.cellStyles = this.cellStyles.filter(\n (style) => !style.areas.some(area => area.workbookName === workbookName)\n );\n }\n\n /**\n * Update workbook name in all style references\n */\n updateWorkbookName(oldName: string, newName: string): void {\n // Update conditional styles\n this.conditionalStyles = this.conditionalStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === oldName\n ? { ...area, workbookName: newName }\n : area\n )\n }));\n // Update cell styles\n this.cellStyles = this.cellStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === oldName\n ? { ...area, workbookName: newName }\n : area\n )\n }));\n }\n\n /**\n * Update sheet name in style references\n */\n updateSheetName(\n workbookName: string,\n oldSheetName: string,\n newSheetName: string\n ): void {\n // Update conditional styles\n this.conditionalStyles = this.conditionalStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === workbookName && area.sheetName === oldSheetName\n ? { ...area, sheetName: newSheetName }\n : area\n )\n }));\n // Update cell styles\n this.cellStyles = this.cellStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === workbookName && area.sheetName === oldSheetName\n ? { ...area, sheetName: newSheetName }\n : area\n )\n }));\n }\n\n /**\n * Remove styles that reference a deleted sheet\n */\n removeSheetStyles(workbookName: string, sheetName: string): void {\n this.conditionalStyles = this.conditionalStyles.filter(\n (style) =>\n !style.areas.some(area =>\n area.workbookName === workbookName &&\n area.sheetName === sheetName\n )\n );\n this.cellStyles = this.cellStyles.filter(\n (style) =>\n !style.areas.some(area =>\n area.workbookName === workbookName &&\n area.sheetName === sheetName\n )\n );\n }\n\n /**\n * Get the style for a specific cell\n * Returns the first matching style (first match wins)\n * Checks cellStyles first, then conditionalStyles\n */\n getCellStyle(cellAddress: CellAddress): CellStyle | undefined {\n // First check conditional styles\n for (const style of this.conditionalStyles) {\n if (!style || !style.areas) {\n continue;\n }\n \n // Check if cell is in any of the style's areas\n for (const area of style.areas) {\n if (\n area.sheetName !== cellAddress.sheetName ||\n area.workbookName !== cellAddress.workbookName\n ) {\n continue;\n }\n\n if (!isCellInRange(cellAddress, area.range)) {\n continue;\n }\n\n // Cell is in area, evaluate condition\n if (style.condition.type === \"formula\") {\n const result = this.evaluateFormulaCondition(cellAddress, style, area);\n if (result) return result;\n } else {\n const result = this.evaluateGradientCondition(cellAddress, style, area);\n if (result) return result;\n }\n }\n }\n\n // Then check direct cell styles\n for (const cellStyle of this.cellStyles) {\n if (!cellStyle || !cellStyle.areas) {\n continue;\n }\n \n for (const area of cellStyle.areas) {\n if (\n area.workbookName === cellAddress.workbookName &&\n area.sheetName === cellAddress.sheetName &&\n isCellInRange(cellAddress, area.range)\n ) {\n return cellStyle.style;\n }\n }\n }\n\n return undefined;\n }\n\n /**\n * Evaluate a formula-based style condition\n */\n private evaluateFormulaCondition(\n cellAddress: CellAddress,\n style: ConditionalStyle,\n area: RangeAddress\n ): CellStyle | undefined {\n if (style.condition.type !== \"formula\") {\n return undefined;\n }\n\n try {\n // Evaluate formula in context of the cell\n // evaluateFormula expects a full cell value (with = prefix for formulas)\n const formula = style.condition.formula.startsWith(\"=\")\n ? style.condition.formula\n : `=${style.condition.formula}`;\n\n const result = this.evaluationManager.evaluateFormula(\n formula,\n cellAddress\n );\n\n // Check if result is truthy\n const isTruthy =\n result === true ||\n result === \"TRUE\" ||\n (typeof result === \"number\" && result !== 0);\n\n if (isTruthy) {\n return {\n backgroundColor: lchToHex(style.condition.color),\n };\n }\n } catch (error) {\n // If formula evaluation fails, don't apply style\n console.warn(\"Failed to evaluate formula condition:\", error);\n }\n\n return undefined;\n }\n\n /**\n * Evaluate a gradient-based style condition\n */\n private evaluateGradientCondition(\n cellAddress: CellAddress,\n style: ConditionalStyle,\n area: RangeAddress\n ): CellStyle | undefined {\n if (style.condition.type !== \"gradient\") {\n return undefined;\n }\n\n try {\n // Get the cell's evaluation result\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(cellAddress);\n if (!evalResult || evalResult.type !== \"value\") {\n return undefined;\n }\n if (evalResult.result.type !== \"number\") {\n return undefined;\n }\n const cellValue = evalResult.result.value;\n\n // Calculate min and max values for the gradient\n const { min: minValue, max: maxValue} = this.calculateGradientBounds(\n style,\n cellAddress,\n area\n );\n\n if (minValue === null || maxValue === null) {\n return undefined;\n }\n\n // Calculate interpolation factor\n const factor = calculateGradientFactor(cellValue, minValue, maxValue);\n\n // Interpolate between min and max colors\n const minColor = style.condition.min.color;\n const maxColor = style.condition.max.color;\n const interpolatedColor = interpolateLCH(minColor, maxColor, factor);\n\n return {\n backgroundColor: lchToHex(interpolatedColor),\n };\n } catch (error) {\n console.warn(\"Failed to evaluate gradient condition:\", error);\n return undefined;\n }\n }\n\n /**\n * Calculate min and max bounds for a gradient\n */\n private calculateGradientBounds(\n style: ConditionalStyle,\n cellAddress: CellAddress,\n area: RangeAddress\n ): { min: number | null; max: number | null } {\n if (style.condition.type !== \"gradient\") {\n return { min: null, max: null };\n }\n\n const { min: minConfig, max: maxConfig } = style.condition;\n const topLeftCell: CellAddress = {\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n colIndex: area.range.start.col,\n rowIndex: area.range.start.row,\n };\n\n // Calculate min value\n let minValue: number | null = null;\n if (minConfig.type === \"lowest_value\") {\n // Evaluate MIN(range) formula directly\n try {\n const rangeRef = this.getRangeReference(area);\n const result = this.evaluationManager.evaluateFormula(\n `=MIN(${rangeRef})`,\n topLeftCell\n );\n if (typeof result === \"number\") {\n minValue = result;\n }\n } catch (error) {\n console.warn(\"Failed to calculate MIN:\", error);\n }\n } else {\n // Evaluate valueFormula in context of area's top-left cell\n const formula = minConfig.valueFormula.startsWith(\"=\")\n ? minConfig.valueFormula\n : `=${minConfig.valueFormula}`;\n const result = this.evaluationManager.evaluateFormula(\n formula,\n topLeftCell\n );\n if (typeof result === \"number\") {\n minValue = result;\n }\n }\n\n // Calculate max value\n let maxValue: number | null = null;\n if (maxConfig.type === \"highest_value\") {\n // Evaluate MAX(range) formula directly\n try {\n const rangeRef = this.getRangeReference(area);\n const result = this.evaluationManager.evaluateFormula(\n `=MAX(${rangeRef})`,\n topLeftCell\n );\n if (typeof result === \"number\") {\n maxValue = result;\n }\n } catch (error) {\n console.warn(\"Failed to calculate MAX:\", error);\n }\n } else {\n // Evaluate valueFormula in context of area's top-left cell\n const formula = maxConfig.valueFormula.startsWith(\"=\")\n ? maxConfig.valueFormula\n : `=${maxConfig.valueFormula}`;\n const result = this.evaluationManager.evaluateFormula(\n formula,\n topLeftCell\n );\n if (typeof result === \"number\") {\n maxValue = result;\n }\n }\n\n return { min: minValue, max: maxValue };\n }\n\n /**\n * Get a range reference string from a RangeAddress\n * Follows CANONICAL_RANGES.md format:\n * - Closed: A5:D10\n * - Row-bounded (col-open): A5:10\n * - Col-bounded (row-open): A5:D\n * - Open both: A5:INFINITY\n */\n private getRangeReference(area: RangeAddress): string {\n const colToLetter = (col: number): string => {\n let result = \"\";\n let c = col;\n while (c >= 0) {\n result = String.fromCharCode(65 + (c % 26)) + result;\n c = Math.floor(c / 26) - 1;\n }\n return result;\n };\n\n const startCol = colToLetter(area.range.start.col);\n const startRow = area.range.start.row + 1; // Convert to 1-based\n\n const isColInfinity = area.range.end.col.type === \"infinity\";\n const isRowInfinity = area.range.end.row.type === \"infinity\";\n\n let rangeStr: string;\n\n if (isColInfinity && isRowInfinity) {\n // Open both: A5:INFINITY\n rangeStr = `${startCol}${startRow}:INFINITY`;\n } else if (isColInfinity) {\n // Row-bounded (col-open): A5:10\n if (area.range.end.row.type === \"number\") {\n const endRow = area.range.end.row.value + 1; // Convert to 1-based\n rangeStr = `${startCol}${startRow}:${endRow}`;\n } else {\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n } else if (isRowInfinity) {\n // Col-bounded (row-open): A5:D\n if (area.range.end.col.type === \"number\") {\n const endCol = colToLetter(area.range.end.col.value);\n rangeStr = `${startCol}${startRow}:${endCol}`;\n } else {\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n } else {\n // Closed rectangle: A5:D10\n if (\n area.range.end.col.type === \"number\" &&\n area.range.end.row.type === \"number\"\n ) {\n const endCol = colToLetter(area.range.end.col.value);\n const endRow = area.range.end.row.value + 1; // Convert to 1-based\n rangeStr = `${startCol}${startRow}:${endCol}${endRow}`;\n } else {\n // Fallback to INFINITY if types don't match\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n }\n\n // Quote sheet name if it contains spaces or special characters\n const needsQuotes = /[ '!]/.test(area.sheetName);\n const sheetRef = needsQuotes\n ? `'${area.sheetName.replace(/'/g, \"''\")}'`\n : area.sheetName;\n\n // Construct the full reference: [workbook]'sheet'!range\n return `[${area.workbookName}]${sheetRef}!${rangeStr}`;\n }\n\n /**\n * Clear cell styles and conditional styles for a given range\n * Adjusts existing style ranges rather than deleting them entirely\n */\n clearCellStyles(range: RangeAddress): void {\n // Process cellStyles - punch holes in areas\n this.cellStyles = this.cellStyles.map(cellStyle => {\n if (!cellStyle || !cellStyle.areas) {\n return cellStyle;\n }\n\n const newAreas: RangeAddress[] = [];\n \n for (const area of cellStyle.areas) {\n // Check if this area intersects with the clear range\n if (\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n ) {\n // Subtract the clear range from this area\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n } else {\n // No intersection, keep the area as-is\n newAreas.push(area);\n }\n }\n \n return { ...cellStyle, areas: newAreas };\n }).filter(style => style.areas.length > 0);\n\n // Process conditionalStyles - punch holes in areas\n this.conditionalStyles = this.conditionalStyles.map(conditionalStyle => {\n if (!conditionalStyle || !conditionalStyle.areas) {\n return conditionalStyle;\n }\n\n const newAreas: RangeAddress[] = [];\n \n for (const area of conditionalStyle.areas) {\n // Check if this area intersects with the clear range\n if (\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n ) {\n // Subtract the clear range from this area\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n } else {\n // No intersection, keep the area as-is\n newAreas.push(area);\n }\n }\n \n return { ...conditionalStyle, areas: newAreas };\n }).filter(style => style.areas.length > 0);\n }\n\n /**\n * Clear cell styles in a range using subtraction\n * For each intersecting style, subtract the cleared range from its areas:\n * - If an area is completely contained: remove that area\n * - If an area partially overlaps: split into remaining rectangles (hole punching)\n * - If no intersection: keep area unchanged\n * \n * This matches Excel's behavior where cutting/pasting creates multi-area styles\n */\n clearCellStylesInRange(range: RangeAddress): void {\n this.cellStyles = this.cellStyles.map(style => {\n const newAreas: RangeAddress[] = [];\n \n for (const area of style.areas) {\n // Skip areas from different sheets/workbooks\n if (\n area.workbookName !== range.workbookName ||\n area.sheetName !== range.sheetName\n ) {\n newAreas.push(area);\n continue;\n }\n\n // Check if this area intersects with the range to clear\n if (!rangesIntersect(area.range, range.range)) {\n // No intersection, keep the area unchanged\n newAreas.push(area);\n continue;\n }\n\n // Area intersects - subtract the cleared range (may produce multiple ranges)\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas for this style\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n }\n \n return { ...style, areas: newAreas };\n }).filter(style => style.areas.length > 0); // Remove styles with no areas left\n }\n}\n"
|
|
5
|
+
"/**\n * StyleManager - Manages conditional styling for cells\n */\n\nimport type {\n CellAddress,\n CellStyle,\n ConditionalStyle,\n DirectCellStyle,\n RangeAddress,\n SerializedCellValue,\n} from \"../types.mjs\";\nimport type { StyleManagerSnapshot } from \"../engine-snapshot.mjs\";\nimport type { WorkbookManager } from \"./workbook-manager.mjs\";\nimport type { EvaluationManager } from \"./evaluation-manager.mjs\";\nimport { isCellInRange } from \"../utils.mjs\";\nimport {\n calculateGradientFactor,\n interpolateLCH,\n lchToHex,\n} from \"../utils/color-utils.mjs\";\nimport {\n subtractRange,\n rangesIntersect,\n isRangeContained,\n} from \"../utils/range-utils.mjs\";\n\nexport class StyleManager {\n private conditionalStyles: ConditionalStyle[] = [];\n private cellStyles: DirectCellStyle[] = [];\n\n constructor(private evaluationManager: EvaluationManager) {}\n\n /**\n * Add a conditional style rule\n */\n addConditionalStyle(style: ConditionalStyle): void {\n this.conditionalStyles.push(style);\n }\n\n /**\n * Remove a conditional style rule by index for a specific workbook\n */\n removeConditionalStyle(workbookName: string, index: number): boolean {\n const workbookStyles = this.conditionalStyles.filter(\n (style) => style.areas.some(area => area.workbookName === workbookName)\n );\n if (index < 0 || index >= workbookStyles.length) {\n return false;\n }\n // Find the actual index in the full array\n let currentIndex = 0;\n for (let i = 0; i < this.conditionalStyles.length; i++) {\n const style = this.conditionalStyles[i];\n if (style && style.areas.some(area => area.workbookName === workbookName)) {\n if (currentIndex === index) {\n this.conditionalStyles.splice(i, 1);\n return true;\n }\n currentIndex++;\n }\n }\n return false;\n }\n\n /**\n * Get all conditional styles intersecting with a range\n */\n getConditionalStylesIntersectingWithRange(\n range: RangeAddress\n ): ConditionalStyle[] {\n return this.conditionalStyles.filter(\n (style) =>\n style.areas.some(area =>\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n )\n );\n }\n\n /**\n * Add a direct cell style rule\n */\n addCellStyle(style: DirectCellStyle): void {\n this.cellStyles.push(style);\n }\n\n /**\n * Remove a direct cell style rule by index for a specific workbook\n */\n removeCellStyle(workbookName: string, index: number): boolean {\n const workbookStyles = this.cellStyles.filter(\n (style) => style && style.areas && style.areas.some(area => area.workbookName === workbookName)\n );\n if (index < 0 || index >= workbookStyles.length) {\n return false;\n }\n // Find the actual index in the full array\n let currentIndex = 0;\n for (let i = 0; i < this.cellStyles.length; i++) {\n const style = this.cellStyles[i];\n if (style && style.areas && style.areas.some(area => area.workbookName === workbookName)) {\n if (currentIndex === index) {\n this.cellStyles.splice(i, 1);\n return true;\n }\n currentIndex++;\n }\n }\n return false;\n }\n\n /**\n * Get all direct cell styles intersecting with a range\n */\n getStylesIntersectingWithRange(range: RangeAddress): DirectCellStyle[] {\n return this.cellStyles.filter(\n (style) =>\n style &&\n style.areas.some(area =>\n area.sheetName === range.sheetName &&\n area.workbookName === range.workbookName &&\n rangesIntersect(area.range, range.range)\n )\n );\n }\n\n /**\n * Get the style for a range if all cells in the range have the same style\n * Returns the DirectCellStyle if the range is completely contained within a single style's areas\n * Returns undefined if multiple styles, partial coverage, or no styles apply\n */\n getStyleForRange(range: RangeAddress): DirectCellStyle | undefined {\n const intersectingStyles = this.getStylesIntersectingWithRange(range);\n\n // If no styles intersect, return undefined\n if (intersectingStyles.length === 0) {\n return undefined;\n }\n\n // If multiple styles intersect, return undefined (range has mixed styles)\n if (intersectingStyles.length > 1) {\n return undefined;\n }\n\n // Check if the range is completely contained within any of the single style's areas\n const style = intersectingStyles[0]!;\n const isContained = style.areas.some(area =>\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n isRangeContained(range.range, area.range)\n );\n \n if (isContained) {\n return style;\n }\n\n // Range is not completely contained, return undefined\n return undefined;\n }\n\n /**\n * Get all conditional styles across all workbooks (for serialization)\n */\n getAllConditionalStyles(): ConditionalStyle[] {\n return [...this.conditionalStyles];\n }\n\n /**\n * Get all cell styles (for serialization)\n */\n getAllCellStyles(): DirectCellStyle[] {\n return [...this.cellStyles];\n }\n\n /**\n * Reset all styles (for deserialization)\n */\n resetStyles(\n conditionalStyles?: ConditionalStyle[],\n cellStyles?: DirectCellStyle[]\n ): void {\n this.conditionalStyles = conditionalStyles ? [...conditionalStyles] : [];\n this.cellStyles = cellStyles ? [...cellStyles] : [];\n }\n\n toSnapshot(): StyleManagerSnapshot {\n return {\n conditionalStyles: this.getAllConditionalStyles(),\n cellStyles: this.getAllCellStyles(),\n };\n }\n\n restoreFromSnapshot(snapshot: StyleManagerSnapshot): void {\n this.resetStyles(snapshot.conditionalStyles, snapshot.cellStyles);\n }\n\n /**\n * Remove all styles for a workbook\n */\n removeWorkbookStyles(workbookName: string): void {\n this.conditionalStyles = this.conditionalStyles.filter(\n (style) => !style.areas.some(area => area.workbookName === workbookName)\n );\n this.cellStyles = this.cellStyles.filter(\n (style) => !style.areas.some(area => area.workbookName === workbookName)\n );\n }\n\n /**\n * Update workbook name in all style references\n */\n updateWorkbookName(oldName: string, newName: string): void {\n // Update conditional styles\n this.conditionalStyles = this.conditionalStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === oldName\n ? { ...area, workbookName: newName }\n : area\n )\n }));\n // Update cell styles\n this.cellStyles = this.cellStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === oldName\n ? { ...area, workbookName: newName }\n : area\n )\n }));\n }\n\n /**\n * Update sheet name in style references\n */\n updateSheetName(\n workbookName: string,\n oldSheetName: string,\n newSheetName: string\n ): void {\n // Update conditional styles\n this.conditionalStyles = this.conditionalStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === workbookName && area.sheetName === oldSheetName\n ? { ...area, sheetName: newSheetName }\n : area\n )\n }));\n // Update cell styles\n this.cellStyles = this.cellStyles.map((style) => ({\n ...style,\n areas: style.areas.map(area =>\n area.workbookName === workbookName && area.sheetName === oldSheetName\n ? { ...area, sheetName: newSheetName }\n : area\n )\n }));\n }\n\n /**\n * Remove styles that reference a deleted sheet\n */\n removeSheetStyles(workbookName: string, sheetName: string): void {\n this.conditionalStyles = this.conditionalStyles.filter(\n (style) =>\n !style.areas.some(area =>\n area.workbookName === workbookName &&\n area.sheetName === sheetName\n )\n );\n this.cellStyles = this.cellStyles.filter(\n (style) =>\n !style.areas.some(area =>\n area.workbookName === workbookName &&\n area.sheetName === sheetName\n )\n );\n }\n\n /**\n * Get the style for a specific cell.\n * Direct cell styles compose in insertion order, with later styles overriding\n * earlier styles for the same properties. Conditional styles then layer over\n * direct styles for the properties they define.\n */\n getCellStyle(cellAddress: CellAddress): CellStyle | undefined {\n let resolvedStyle: CellStyle | undefined;\n\n for (const cellStyle of this.cellStyles) {\n if (!cellStyle || !cellStyle.areas) {\n continue;\n }\n\n for (const area of cellStyle.areas) {\n if (\n area.workbookName === cellAddress.workbookName &&\n area.sheetName === cellAddress.sheetName &&\n isCellInRange(cellAddress, area.range)\n ) {\n resolvedStyle = {\n ...resolvedStyle,\n ...cellStyle.style,\n };\n break;\n }\n }\n }\n\n for (const style of this.conditionalStyles) {\n if (!style || !style.areas) {\n continue;\n }\n \n // Check if cell is in any of the style's areas\n for (const area of style.areas) {\n if (\n area.sheetName !== cellAddress.sheetName ||\n area.workbookName !== cellAddress.workbookName\n ) {\n continue;\n }\n\n if (!isCellInRange(cellAddress, area.range)) {\n continue;\n }\n\n // Cell is in area, evaluate condition\n if (style.condition.type === \"formula\") {\n const result = this.evaluateFormulaCondition(cellAddress, style, area);\n if (result) return { ...resolvedStyle, ...result };\n } else {\n const result = this.evaluateGradientCondition(cellAddress, style, area);\n if (result) return { ...resolvedStyle, ...result };\n }\n }\n }\n\n return resolvedStyle;\n }\n\n /**\n * Evaluate a formula-based style condition\n */\n private evaluateFormulaCondition(\n cellAddress: CellAddress,\n style: ConditionalStyle,\n area: RangeAddress\n ): CellStyle | undefined {\n if (style.condition.type !== \"formula\") {\n return undefined;\n }\n\n try {\n // Evaluate formula in context of the cell\n // evaluateFormula expects a full cell value (with = prefix for formulas)\n const formula = style.condition.formula.startsWith(\"=\")\n ? style.condition.formula\n : `=${style.condition.formula}`;\n\n const result = this.evaluationManager.evaluateFormula(\n formula,\n cellAddress\n );\n\n // Check if result is truthy\n const isTruthy =\n result === true ||\n result === \"TRUE\" ||\n (typeof result === \"number\" && result !== 0);\n\n if (isTruthy) {\n return {\n backgroundColor: lchToHex(style.condition.color),\n };\n }\n } catch (error) {\n // If formula evaluation fails, don't apply style\n console.warn(\"Failed to evaluate formula condition:\", error);\n }\n\n return undefined;\n }\n\n /**\n * Evaluate a gradient-based style condition\n */\n private evaluateGradientCondition(\n cellAddress: CellAddress,\n style: ConditionalStyle,\n area: RangeAddress\n ): CellStyle | undefined {\n if (style.condition.type !== \"gradient\") {\n return undefined;\n }\n\n try {\n // Get the cell's evaluation result\n const evalResult =\n this.evaluationManager.getCellEvaluationResult(cellAddress);\n if (!evalResult || evalResult.type !== \"value\") {\n return undefined;\n }\n if (evalResult.result.type !== \"number\") {\n return undefined;\n }\n const cellValue = evalResult.result.value;\n\n // Calculate min and max values for the gradient\n const { min: minValue, max: maxValue} = this.calculateGradientBounds(\n style,\n cellAddress,\n area\n );\n\n if (minValue === null || maxValue === null) {\n return undefined;\n }\n\n // Calculate interpolation factor\n const factor = calculateGradientFactor(cellValue, minValue, maxValue);\n\n // Interpolate between min and max colors\n const minColor = style.condition.min.color;\n const maxColor = style.condition.max.color;\n const interpolatedColor = interpolateLCH(minColor, maxColor, factor);\n\n return {\n backgroundColor: lchToHex(interpolatedColor),\n };\n } catch (error) {\n console.warn(\"Failed to evaluate gradient condition:\", error);\n return undefined;\n }\n }\n\n /**\n * Calculate min and max bounds for a gradient\n */\n private calculateGradientBounds(\n style: ConditionalStyle,\n cellAddress: CellAddress,\n area: RangeAddress\n ): { min: number | null; max: number | null } {\n if (style.condition.type !== \"gradient\") {\n return { min: null, max: null };\n }\n\n const { min: minConfig, max: maxConfig } = style.condition;\n const topLeftCell: CellAddress = {\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n colIndex: area.range.start.col,\n rowIndex: area.range.start.row,\n };\n\n // Calculate min value\n let minValue: number | null = null;\n if (minConfig.type === \"lowest_value\") {\n // Evaluate MIN(range) formula directly\n try {\n const rangeRef = this.getRangeReference(area);\n const result = this.evaluationManager.evaluateFormula(\n `=MIN(${rangeRef})`,\n topLeftCell\n );\n if (typeof result === \"number\") {\n minValue = result;\n }\n } catch (error) {\n console.warn(\"Failed to calculate MIN:\", error);\n }\n } else {\n // Evaluate valueFormula in context of area's top-left cell\n const formula = minConfig.valueFormula.startsWith(\"=\")\n ? minConfig.valueFormula\n : `=${minConfig.valueFormula}`;\n const result = this.evaluationManager.evaluateFormula(\n formula,\n topLeftCell\n );\n if (typeof result === \"number\") {\n minValue = result;\n }\n }\n\n // Calculate max value\n let maxValue: number | null = null;\n if (maxConfig.type === \"highest_value\") {\n // Evaluate MAX(range) formula directly\n try {\n const rangeRef = this.getRangeReference(area);\n const result = this.evaluationManager.evaluateFormula(\n `=MAX(${rangeRef})`,\n topLeftCell\n );\n if (typeof result === \"number\") {\n maxValue = result;\n }\n } catch (error) {\n console.warn(\"Failed to calculate MAX:\", error);\n }\n } else {\n // Evaluate valueFormula in context of area's top-left cell\n const formula = maxConfig.valueFormula.startsWith(\"=\")\n ? maxConfig.valueFormula\n : `=${maxConfig.valueFormula}`;\n const result = this.evaluationManager.evaluateFormula(\n formula,\n topLeftCell\n );\n if (typeof result === \"number\") {\n maxValue = result;\n }\n }\n\n return { min: minValue, max: maxValue };\n }\n\n /**\n * Get a range reference string from a RangeAddress\n * Follows CANONICAL_RANGES.md format:\n * - Closed: A5:D10\n * - Row-bounded (col-open): A5:10\n * - Col-bounded (row-open): A5:D\n * - Open both: A5:INFINITY\n */\n private getRangeReference(area: RangeAddress): string {\n const colToLetter = (col: number): string => {\n let result = \"\";\n let c = col;\n while (c >= 0) {\n result = String.fromCharCode(65 + (c % 26)) + result;\n c = Math.floor(c / 26) - 1;\n }\n return result;\n };\n\n const startCol = colToLetter(area.range.start.col);\n const startRow = area.range.start.row + 1; // Convert to 1-based\n\n const isColInfinity = area.range.end.col.type === \"infinity\";\n const isRowInfinity = area.range.end.row.type === \"infinity\";\n\n let rangeStr: string;\n\n if (isColInfinity && isRowInfinity) {\n // Open both: A5:INFINITY\n rangeStr = `${startCol}${startRow}:INFINITY`;\n } else if (isColInfinity) {\n // Row-bounded (col-open): A5:10\n if (area.range.end.row.type === \"number\") {\n const endRow = area.range.end.row.value + 1; // Convert to 1-based\n rangeStr = `${startCol}${startRow}:${endRow}`;\n } else {\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n } else if (isRowInfinity) {\n // Col-bounded (row-open): A5:D\n if (area.range.end.col.type === \"number\") {\n const endCol = colToLetter(area.range.end.col.value);\n rangeStr = `${startCol}${startRow}:${endCol}`;\n } else {\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n } else {\n // Closed rectangle: A5:D10\n if (\n area.range.end.col.type === \"number\" &&\n area.range.end.row.type === \"number\"\n ) {\n const endCol = colToLetter(area.range.end.col.value);\n const endRow = area.range.end.row.value + 1; // Convert to 1-based\n rangeStr = `${startCol}${startRow}:${endCol}${endRow}`;\n } else {\n // Fallback to INFINITY if types don't match\n rangeStr = `${startCol}${startRow}:INFINITY`;\n }\n }\n\n // Quote sheet name if it contains spaces or special characters\n const needsQuotes = /[ '!]/.test(area.sheetName);\n const sheetRef = needsQuotes\n ? `'${area.sheetName.replace(/'/g, \"''\")}'`\n : area.sheetName;\n\n // Construct the full reference: [workbook]'sheet'!range\n return `[${area.workbookName}]${sheetRef}!${rangeStr}`;\n }\n\n /**\n * Clear cell styles and conditional styles for a given range\n * Adjusts existing style ranges rather than deleting them entirely\n */\n clearCellStyles(range: RangeAddress): void {\n // Process cellStyles - punch holes in areas\n this.cellStyles = this.cellStyles.map(cellStyle => {\n if (!cellStyle || !cellStyle.areas) {\n return cellStyle;\n }\n\n const newAreas: RangeAddress[] = [];\n \n for (const area of cellStyle.areas) {\n // Check if this area intersects with the clear range\n if (\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n ) {\n // Subtract the clear range from this area\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n } else {\n // No intersection, keep the area as-is\n newAreas.push(area);\n }\n }\n \n return { ...cellStyle, areas: newAreas };\n }).filter(style => style.areas.length > 0);\n\n // Process conditionalStyles - punch holes in areas\n this.conditionalStyles = this.conditionalStyles.map(conditionalStyle => {\n if (!conditionalStyle || !conditionalStyle.areas) {\n return conditionalStyle;\n }\n\n const newAreas: RangeAddress[] = [];\n \n for (const area of conditionalStyle.areas) {\n // Check if this area intersects with the clear range\n if (\n area.workbookName === range.workbookName &&\n area.sheetName === range.sheetName &&\n rangesIntersect(area.range, range.range)\n ) {\n // Subtract the clear range from this area\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n } else {\n // No intersection, keep the area as-is\n newAreas.push(area);\n }\n }\n \n return { ...conditionalStyle, areas: newAreas };\n }).filter(style => style.areas.length > 0);\n }\n\n /**\n * Clear cell styles in a range using subtraction\n * For each intersecting style, subtract the cleared range from its areas:\n * - If an area is completely contained: remove that area\n * - If an area partially overlaps: split into remaining rectangles (hole punching)\n * - If no intersection: keep area unchanged\n * \n * This matches Excel's behavior where cutting/pasting creates multi-area styles\n */\n clearCellStylesInRange(range: RangeAddress): void {\n this.cellStyles = this.cellStyles.map(style => {\n const newAreas: RangeAddress[] = [];\n \n for (const area of style.areas) {\n // Skip areas from different sheets/workbooks\n if (\n area.workbookName !== range.workbookName ||\n area.sheetName !== range.sheetName\n ) {\n newAreas.push(area);\n continue;\n }\n\n // Check if this area intersects with the range to clear\n if (!rangesIntersect(area.range, range.range)) {\n // No intersection, keep the area unchanged\n newAreas.push(area);\n continue;\n }\n\n // Area intersects - subtract the cleared range (may produce multiple ranges)\n const remainingRanges = subtractRange(area.range, range.range);\n\n // Add all remaining ranges as new areas for this style\n for (const remainingRange of remainingRanges) {\n newAreas.push({\n workbookName: area.workbookName,\n sheetName: area.sheetName,\n range: remainingRange,\n });\n }\n }\n \n return { ...style, areas: newAreas };\n }).filter(style => style.areas.length > 0); // Remove styles with no areas left\n }\n}\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": "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",
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "3DC8521C7F85157164756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// src/core/managers/workbook-manager.ts
|
|
2
|
+
import {
|
|
3
|
+
DEFAULT_SEARCH_MAX_RESULTS
|
|
4
|
+
} from "../types.mjs";
|
|
2
5
|
import { getCellReference, parseCellReference } from "../utils.mjs";
|
|
3
6
|
import { buildRangeEvalOrder } from "./range-eval-order-builder.mjs";
|
|
4
7
|
import {
|
|
@@ -383,15 +386,15 @@ class WorkbookManager {
|
|
|
383
386
|
getStringContentKind(cellContent) {
|
|
384
387
|
return cellContent.startsWith("=") ? "formula" : "text";
|
|
385
388
|
}
|
|
386
|
-
findMatchesInString(cellContent, query, caseSensitive) {
|
|
387
|
-
if (query.length === 0) {
|
|
389
|
+
findMatchesInString(cellContent, query, caseSensitive, maxMatches = Number.POSITIVE_INFINITY) {
|
|
390
|
+
if (query.length === 0 || maxMatches <= 0) {
|
|
388
391
|
return [];
|
|
389
392
|
}
|
|
390
393
|
const normalizedContent = caseSensitive ? cellContent : cellContent.toLowerCase();
|
|
391
394
|
const normalizedQuery = caseSensitive ? query : query.toLowerCase();
|
|
392
395
|
const matches = [];
|
|
393
396
|
let searchFromIndex = 0;
|
|
394
|
-
while (searchFromIndex <= normalizedContent.length - normalizedQuery.length) {
|
|
397
|
+
while (matches.length < maxMatches && searchFromIndex <= normalizedContent.length - normalizedQuery.length) {
|
|
395
398
|
const startIndex = normalizedContent.indexOf(normalizedQuery, searchFromIndex);
|
|
396
399
|
if (startIndex === -1) {
|
|
397
400
|
break;
|
|
@@ -407,45 +410,84 @@ class WorkbookManager {
|
|
|
407
410
|
}
|
|
408
411
|
return matches;
|
|
409
412
|
}
|
|
410
|
-
|
|
411
|
-
|
|
413
|
+
normalizeSearchMaxResults(maxResults) {
|
|
414
|
+
if (maxResults === undefined) {
|
|
415
|
+
return DEFAULT_SEARCH_MAX_RESULTS;
|
|
416
|
+
}
|
|
417
|
+
if (maxResults === Number.POSITIVE_INFINITY) {
|
|
418
|
+
return Number.POSITIVE_INFINITY;
|
|
419
|
+
}
|
|
420
|
+
if (!Number.isFinite(maxResults) || maxResults <= 0) {
|
|
421
|
+
return 0;
|
|
422
|
+
}
|
|
423
|
+
return Math.floor(maxResults);
|
|
424
|
+
}
|
|
425
|
+
*iterateStringCellsInSearchOrder(scopedSheets) {
|
|
412
426
|
for (const { workbookName, sheet } of scopedSheets) {
|
|
413
|
-
const
|
|
414
|
-
|
|
415
|
-
|
|
427
|
+
const indexes = this.getSheetIndexes({
|
|
428
|
+
workbookName,
|
|
429
|
+
sheetName: sheet.name
|
|
430
|
+
});
|
|
431
|
+
const rowIndexes = Array.from(indexes.rowGroups.keys()).sort((left, right) => left - right);
|
|
432
|
+
for (const rowIndex of rowIndexes) {
|
|
433
|
+
const rowGroup = indexes.rowGroups.get(rowIndex);
|
|
434
|
+
if (!rowGroup) {
|
|
416
435
|
continue;
|
|
417
436
|
}
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
|
|
437
|
+
for (const { number: colIndex, key: cellReference } of rowGroup) {
|
|
438
|
+
const cellContent = sheet.content.get(cellReference);
|
|
439
|
+
if (typeof cellContent !== "string") {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
yield {
|
|
443
|
+
workbookName,
|
|
444
|
+
sheetName: sheet.name,
|
|
445
|
+
cellReference,
|
|
446
|
+
cellContent,
|
|
447
|
+
rowIndex,
|
|
448
|
+
colIndex
|
|
449
|
+
};
|
|
421
450
|
}
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
buildSearchMatchesInScope(query, scopedSheets, caseSensitive, maxResults) {
|
|
455
|
+
const results = [];
|
|
456
|
+
if (maxResults <= 0) {
|
|
457
|
+
return results;
|
|
458
|
+
}
|
|
459
|
+
for (const cell of this.iterateStringCellsInSearchOrder(scopedSheets)) {
|
|
460
|
+
const matches = this.findMatchesInString(cell.cellContent, query, caseSensitive, maxResults - results.length);
|
|
461
|
+
if (matches.length === 0) {
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
const contentKind = this.getStringContentKind(cell.cellContent);
|
|
465
|
+
for (const match of matches) {
|
|
466
|
+
results.push({
|
|
467
|
+
workbookName: cell.workbookName,
|
|
468
|
+
sheetName: cell.sheetName,
|
|
469
|
+
cellReference: cell.cellReference,
|
|
470
|
+
cellContent: cell.cellContent,
|
|
429
471
|
contentKind,
|
|
430
472
|
occurrenceIndex: match.occurrenceIndex,
|
|
431
473
|
startIndex: match.startIndex,
|
|
432
474
|
endIndexExclusive: match.endIndexExclusive,
|
|
433
|
-
matchedText: match.matchedText
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
475
|
+
matchedText: match.matchedText
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
if (results.length >= maxResults) {
|
|
479
|
+
return results;
|
|
437
480
|
}
|
|
438
|
-
sheetMatches.sort((left, right) => left.rowIndex - right.rowIndex || left.colIndex - right.colIndex || left.occurrenceIndex - right.occurrenceIndex);
|
|
439
|
-
results.push(...sheetMatches.map(({ rowIndex: _rowIndex, colIndex: _colIndex, ...match }) => match));
|
|
440
481
|
}
|
|
441
482
|
return results;
|
|
442
483
|
}
|
|
443
484
|
search(query, options) {
|
|
444
485
|
const scopedSheets = this.resolveSearchScope(options);
|
|
486
|
+
const maxResults = this.normalizeSearchMaxResults(options?.maxResults);
|
|
445
487
|
if (query.length === 0) {
|
|
446
488
|
return [];
|
|
447
489
|
}
|
|
448
|
-
return this.buildSearchMatchesInScope(query, scopedSheets, options?.caseSensitive === true);
|
|
490
|
+
return this.buildSearchMatchesInScope(query, scopedSheets, options?.caseSensitive === true, maxResults);
|
|
449
491
|
}
|
|
450
492
|
buildReplacedContent(beforeContent, matches, replacement) {
|
|
451
493
|
let cursor = 0;
|
|
@@ -502,47 +544,41 @@ class WorkbookManager {
|
|
|
502
544
|
if (query.length === 0) {
|
|
503
545
|
throw new Error("replaceAll requires a non-empty query");
|
|
504
546
|
}
|
|
505
|
-
const
|
|
506
|
-
const
|
|
507
|
-
for (const
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
existing.push(match);
|
|
512
|
-
} else {
|
|
513
|
-
matchesByCell.set(cellKey, [match]);
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
return Array.from(matchesByCell.values()).map((cellMatches) => {
|
|
517
|
-
const [firstMatch] = cellMatches;
|
|
518
|
-
if (!firstMatch) {
|
|
519
|
-
throw new Error("Expected at least one match per cell");
|
|
547
|
+
const replacements = [];
|
|
548
|
+
const caseSensitive = options?.caseSensitive === true;
|
|
549
|
+
for (const cell of this.iterateStringCellsInSearchOrder(scopedSheets)) {
|
|
550
|
+
const matches = this.findMatchesInString(cell.cellContent, query, caseSensitive);
|
|
551
|
+
if (matches.length === 0) {
|
|
552
|
+
continue;
|
|
520
553
|
}
|
|
521
554
|
const address = {
|
|
522
|
-
workbookName:
|
|
523
|
-
sheetName:
|
|
524
|
-
|
|
555
|
+
workbookName: cell.workbookName,
|
|
556
|
+
sheetName: cell.sheetName,
|
|
557
|
+
rowIndex: cell.rowIndex,
|
|
558
|
+
colIndex: cell.colIndex
|
|
525
559
|
};
|
|
526
|
-
const afterContent = this.buildReplacedContent(
|
|
527
|
-
|
|
560
|
+
const afterContent = this.buildReplacedContent(cell.cellContent, matches, replacement);
|
|
561
|
+
const contentKind = this.getStringContentKind(cell.cellContent);
|
|
562
|
+
replacements.push({
|
|
528
563
|
address,
|
|
529
|
-
beforeContent:
|
|
564
|
+
beforeContent: cell.cellContent,
|
|
530
565
|
afterContent,
|
|
531
|
-
changes:
|
|
532
|
-
workbookName:
|
|
533
|
-
sheetName:
|
|
534
|
-
cellReference:
|
|
535
|
-
contentKind
|
|
566
|
+
changes: matches.map((match) => ({
|
|
567
|
+
workbookName: cell.workbookName,
|
|
568
|
+
sheetName: cell.sheetName,
|
|
569
|
+
cellReference: cell.cellReference,
|
|
570
|
+
contentKind,
|
|
536
571
|
occurrenceIndex: match.occurrenceIndex,
|
|
537
572
|
startIndex: match.startIndex,
|
|
538
573
|
endIndexExclusive: match.endIndexExclusive,
|
|
539
574
|
matchedText: match.matchedText,
|
|
540
575
|
replacementText: replacement,
|
|
541
|
-
beforeContent:
|
|
576
|
+
beforeContent: cell.cellContent,
|
|
542
577
|
afterContent
|
|
543
578
|
}))
|
|
544
|
-
};
|
|
545
|
-
}
|
|
579
|
+
});
|
|
580
|
+
}
|
|
581
|
+
return replacements;
|
|
546
582
|
}
|
|
547
583
|
addCellToGroups(indexes, rowIndex, colIndex, key) {
|
|
548
584
|
let rowGroup = indexes.rowGroups.get(rowIndex);
|
|
@@ -800,4 +836,4 @@ export {
|
|
|
800
836
|
IndexEntryBinarySearch
|
|
801
837
|
};
|
|
802
838
|
|
|
803
|
-
//# debugId=
|
|
839
|
+
//# debugId=7B5AEB063A61FBB964756E2164756E21
|