@a3s-lab/office 0.26.0 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -2
- package/dist/0~4595.js +16 -2
- package/dist/0~5093.js +563 -201
- package/dist/0~6090.js +77 -77
- package/dist/{0~2805.js → 0~7043.js} +305 -2
- package/dist/0~document-editor.js +2633 -976
- package/dist/0~spreadsheet-editor.js +1324 -378
- package/dist/0~work-docx-export.js +737 -17
- package/dist/0~work-docx-import.js +173 -98
- package/dist/0~work-office-diagnostics.js +250 -5
- package/dist/{164.js → 1544.js} +1083 -785
- package/dist/4104.js +145 -29
- package/dist/5184.js +13 -0
- package/dist/6282.js +1898 -345
- package/dist/core.js +1 -1
- package/dist/index.js +1 -1
- package/dist/internal/features/work/editors/document-command-catalog.d.ts +102 -0
- package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +111 -0
- package/dist/internal/features/work/editors/document-font-dialog-script-font-model.d.ts +18 -0
- package/dist/internal/features/work/editors/document-font-dialog.d.ts +9 -0
- package/dist/internal/features/work/editors/document-home-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-page-chrome-editor.d.ts +6 -0
- package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
- package/dist/internal/features/work/editors/document-strike-ribbon.d.ts +7 -0
- package/dist/internal/features/work/editors/document-text-case-ribbon.d.ts +4 -0
- package/dist/internal/features/work/editors/document-toolbar.d.ts +3 -1
- package/dist/internal/features/work/editors/document-underline-ribbon.d.ts +9 -0
- package/dist/internal/features/work/editors/document-wps-shortcuts.d.ts +1 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-fill-format.d.ts +11 -0
- package/dist/internal/features/work/editors/spreadsheet-cell-format.d.ts +2 -1
- package/dist/internal/features/work/editors/spreadsheet-format-cells-dialog-model.d.ts +13 -2
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-panel.d.ts +13 -0
- package/dist/internal/features/work/editors/spreadsheet-format-cells-fill-preview.d.ts +6 -0
- package/dist/internal/features/work/editors/spreadsheet-format-painter.d.ts +1 -1
- package/dist/internal/features/work/editors/work-office-chrome.d.ts +9 -1
- package/dist/internal/features/work/work-document-character-formatting.d.ts +16 -1
- package/dist/internal/features/work/work-document-character-position.d.ts +9 -0
- package/dist/internal/features/work/work-document-character-scale.d.ts +8 -0
- package/dist/internal/features/work/work-document-character-spacing.d.ts +8 -0
- package/dist/internal/features/work/work-document-emphasis.d.ts +7 -0
- package/dist/internal/features/work/work-document-equations.d.ts +2 -1
- package/dist/internal/features/work/work-document-format-changes.d.ts +20 -2
- package/dist/internal/features/work/work-document-hidden-text.d.ts +5 -0
- package/dist/internal/features/work/work-document-kerning.d.ts +10 -0
- package/dist/internal/features/work/work-document-legacy-text-effects.d.ts +27 -0
- package/dist/internal/features/work/work-document-script-font-extension.d.ts +2 -0
- package/dist/internal/features/work/work-document-script-fonts.d.ts +51 -0
- package/dist/internal/features/work/work-document-strike.d.ts +21 -0
- package/dist/internal/features/work/work-document-text-case.d.ts +10 -0
- package/dist/internal/features/work/work-document-underline.d.ts +37 -0
- package/dist/internal/features/work/work-document-word-line-metrics.d.ts +16 -0
- package/dist/internal/features/work/work-docx-character-position.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-scale.d.ts +2 -0
- package/dist/internal/features/work/work-docx-character-spacing.d.ts +4 -0
- package/dist/internal/features/work/work-docx-emphasis-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-emphasis.d.ts +14 -0
- package/dist/internal/features/work/work-docx-hidden-text-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-hidden-text-export.d.ts +17 -0
- package/dist/internal/features/work/work-docx-hidden-text.d.ts +11 -0
- package/dist/internal/features/work/work-docx-kerning-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-kerning.d.ts +14 -0
- package/dist/internal/features/work/work-docx-legacy-text-effects-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-legacy-text-effects-export.d.ts +18 -0
- package/dist/internal/features/work/work-docx-legacy-text-effects.d.ts +12 -0
- package/dist/internal/features/work/work-docx-run-fonts-diagnostics.d.ts +3 -0
- package/dist/internal/features/work/work-docx-run-fonts-export.d.ts +14 -0
- package/dist/internal/features/work/work-docx-run-fonts.d.ts +13 -0
- package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +27 -2
- package/dist/internal/features/work/work-docx-run-property-order.d.ts +2 -0
- package/dist/internal/features/work/work-docx-run-script-font-import.d.ts +9 -0
- package/dist/internal/features/work/work-docx-strike.d.ts +8 -0
- package/dist/internal/features/work/work-docx-theme-reference.d.ts +1 -1
- package/dist/internal/features/work/work-docx-twips.d.ts +6 -0
- package/dist/internal/features/work/work-docx-underline.d.ts +3 -0
- package/dist/internal/features/work/work-spreadsheet-gradient-fill-canvas.d.ts +10 -0
- package/dist/internal/features/work/work-spreadsheet-native-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-spreadsheet-pattern-fill-canvas.d.ts +8 -0
- package/dist/internal/features/work/work-xlsx-cell-style-origin.d.ts +2 -1
- package/dist/internal/features/work/work-xlsx-cell-style-writer.d.ts +3 -0
- package/dist/internal/features/work/work-xlsx-cell-styles.d.ts +4 -0
- package/dist/internal/features/work/work-xlsx-gradient-fill.d.ts +31 -0
- package/dist/internal/features/work/work-xlsx-native-fill.d.ts +17 -0
- package/dist/internal/features/work/work-xlsx-pattern-fill.d.ts +21 -0
- package/dist/office-kernel.wasm +0 -0
- package/dist/styles.css +809 -78
- package/docs/latest/en/browser-editor-architecture.md +24 -0
- package/package.json +35 -1
package/dist/{164.js → 1544.js}
RENAMED
|
@@ -1713,595 +1713,115 @@ function spreadsheetFormulaHistoryCellType(cellType) {
|
|
|
1713
1713
|
};
|
|
1714
1714
|
return Object.keys(normalized).length ? normalized : void 0;
|
|
1715
1715
|
}
|
|
1716
|
-
const
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1716
|
+
const borderChildOrder = [
|
|
1717
|
+
'start',
|
|
1718
|
+
'end',
|
|
1719
|
+
'left',
|
|
1720
|
+
'right',
|
|
1721
|
+
'top',
|
|
1722
|
+
'bottom',
|
|
1723
|
+
'diagonal',
|
|
1724
|
+
'vertical',
|
|
1725
|
+
'horizontal',
|
|
1726
|
+
'extLst'
|
|
1727
|
+
];
|
|
1728
|
+
function ensureXlsxStyleCollection(document, name, anchors) {
|
|
1729
|
+
const root = document.documentElement;
|
|
1730
|
+
const existing = directChild(root, name);
|
|
1731
|
+
if (existing) return existing;
|
|
1732
|
+
const collection = document.createElementNS(root.namespaceURI, name);
|
|
1733
|
+
root.insertBefore(collection, directChildren(root).find((child)=>anchors.includes(child.localName)) ?? null);
|
|
1734
|
+
return collection;
|
|
1726
1735
|
}
|
|
1727
|
-
function
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
row.length = Math.max(row.length, options.columnCount);
|
|
1734
|
-
Object.freeze(row);
|
|
1735
|
-
}
|
|
1736
|
-
}
|
|
1737
|
-
registerSpreadsheetMatrixProfile(data, options);
|
|
1736
|
+
function defaultXlsxFill(document, patternType) {
|
|
1737
|
+
const fill = document.createElementNS(document.documentElement.namespaceURI, 'fill');
|
|
1738
|
+
const pattern = document.createElementNS(document.documentElement.namespaceURI, 'patternFill');
|
|
1739
|
+
pattern.setAttribute('patternType', patternType);
|
|
1740
|
+
fill.append(pattern);
|
|
1741
|
+
return fill;
|
|
1738
1742
|
}
|
|
1739
|
-
function
|
|
1740
|
-
const
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
const coordinateKey = spreadsheetCoordinateKey(row, column);
|
|
1761
|
-
if (null == previous && null != current) populatedCellCount += 1;
|
|
1762
|
-
if (null != previous && null == current) populatedCellCount -= 1;
|
|
1763
|
-
if (current?.f) formulaCells.set(coordinateKey, {
|
|
1764
|
-
column,
|
|
1765
|
-
row
|
|
1766
|
-
});
|
|
1767
|
-
else formulaCells.delete(coordinateKey);
|
|
1768
|
-
if (current?.ps?.isShow) shownCommentCells.set(coordinateKey, {
|
|
1769
|
-
c: column,
|
|
1770
|
-
r: row
|
|
1771
|
-
});
|
|
1772
|
-
else shownCommentCells.delete(coordinateKey);
|
|
1773
|
-
if (spreadsheetProtectionSignature(previous) !== spreadsheetProtectionSignature(current)) {
|
|
1774
|
-
protectionCells ??= spreadsheetProtectionCells(protectionCellKey);
|
|
1775
|
-
const signature = spreadsheetProtectionSignature(current);
|
|
1776
|
-
if (null === signature) protectionCells.delete(coordinateKey);
|
|
1777
|
-
else protectionCells.set(coordinateKey, signature);
|
|
1743
|
+
function defaultXlsxBorder(document) {
|
|
1744
|
+
const border = document.createElementNS(document.documentElement.namespaceURI, 'border');
|
|
1745
|
+
for (const name of [
|
|
1746
|
+
'left',
|
|
1747
|
+
'right',
|
|
1748
|
+
'top',
|
|
1749
|
+
'bottom',
|
|
1750
|
+
'diagonal'
|
|
1751
|
+
])border.append(document.createElementNS(document.documentElement.namespaceURI, name));
|
|
1752
|
+
return border;
|
|
1753
|
+
}
|
|
1754
|
+
function setXlsxBorderLine(document, border, name, line) {
|
|
1755
|
+
removeXlsxChildren(border, name);
|
|
1756
|
+
const element = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
1757
|
+
if (line) {
|
|
1758
|
+
element.setAttribute('style', line.style);
|
|
1759
|
+
const color = xlsxRgbColor(line.color);
|
|
1760
|
+
if (color) {
|
|
1761
|
+
const child = document.createElementNS(document.documentElement.namespaceURI, 'color');
|
|
1762
|
+
child.setAttribute('rgb', color);
|
|
1763
|
+
element.append(child);
|
|
1778
1764
|
}
|
|
1779
|
-
const changedRow = data[row];
|
|
1780
|
-
if (changedRow && !Object.isFrozen(changedRow)) Object.freeze(changedRow);
|
|
1781
1765
|
}
|
|
1782
|
-
|
|
1783
|
-
coordinate,
|
|
1784
|
-
value
|
|
1785
|
-
})).sort((left, right)=>compareSpreadsheetCoordinates(left.coordinate, right.coordinate)).map(({ coordinate, value })=>`${coordinate}:${value}`).join(',');
|
|
1786
|
-
registerSpreadsheetMatrixProfile(data, {
|
|
1787
|
-
columnCount: Math.max(sourceProfile.columnCount, ...changes.map(({ column, row })=>Math.max(column + 1, data[row]?.length ?? 0))),
|
|
1788
|
-
formulaCells: Array.from(formulaCells.values()).sort(compareSpreadsheetCells),
|
|
1789
|
-
fortuneReady: true,
|
|
1790
|
-
populatedCellCount: Math.max(0, populatedCellCount),
|
|
1791
|
-
protectionCellKey,
|
|
1792
|
-
rowCount: Math.max(sourceProfile.rowCount, data.length, ...changes.map(({ row })=>row + 1)),
|
|
1793
|
-
shownCommentCells: Array.from(shownCommentCells.values()).sort((left, right)=>left.r - right.r || left.c - right.c)
|
|
1794
|
-
}, {
|
|
1795
|
-
historyRoot: sourceProfile.historyRoot,
|
|
1796
|
-
historyState: changes.some(({ current, previous })=>!sameSpreadsheetHistoryValue(current, previous)) ? Object.freeze({}) : sourceProfile.historyState
|
|
1797
|
-
});
|
|
1798
|
-
return true;
|
|
1799
|
-
}
|
|
1800
|
-
function spreadsheetMatrixProfile(data) {
|
|
1801
|
-
return data ? spreadsheetMatrixProfiles.get(data) : void 0;
|
|
1802
|
-
}
|
|
1803
|
-
function attachSpreadsheetShownCommentCells(data, cells) {
|
|
1804
|
-
Object.defineProperty(data, SPREADSHEET_SHOWN_COMMENT_CELLS_PROPERTY, {
|
|
1805
|
-
configurable: false,
|
|
1806
|
-
enumerable: false,
|
|
1807
|
-
value: cells,
|
|
1808
|
-
writable: false
|
|
1809
|
-
});
|
|
1810
|
-
}
|
|
1811
|
-
function registerSpreadsheetMatrixProfile(data, options, history) {
|
|
1812
|
-
const initialHistoryState = Object.freeze({});
|
|
1813
|
-
const profile = Object.freeze({
|
|
1814
|
-
columnCount: options.columnCount,
|
|
1815
|
-
formulaCells: Object.freeze(options.formulaCells.map((cell)=>Object.freeze({
|
|
1816
|
-
...cell
|
|
1817
|
-
}))),
|
|
1818
|
-
fortuneReady: options.fortuneReady,
|
|
1819
|
-
historyRoot: history?.historyRoot ?? initialHistoryState,
|
|
1820
|
-
historyState: history?.historyState ?? initialHistoryState,
|
|
1821
|
-
populatedCellCount: options.populatedCellCount,
|
|
1822
|
-
protectionCellKey: options.protectionCellKey,
|
|
1823
|
-
rowCount: options.rowCount,
|
|
1824
|
-
shownCommentCells: Object.freeze(options.shownCommentCells.map((cell)=>Object.freeze({
|
|
1825
|
-
...cell
|
|
1826
|
-
})))
|
|
1827
|
-
});
|
|
1828
|
-
attachSpreadsheetShownCommentCells(data, profile.shownCommentCells);
|
|
1829
|
-
Object.freeze(data);
|
|
1830
|
-
spreadsheetMatrixProfiles.set(data, profile);
|
|
1766
|
+
insertXlsxOrderedChild(border, element, borderChildOrder);
|
|
1831
1767
|
}
|
|
1832
|
-
function
|
|
1833
|
-
|
|
1834
|
-
|
|
1835
|
-
|
|
1836
|
-
|
|
1837
|
-
|
|
1768
|
+
function writeXlsxAlignment(document, xf, style) {
|
|
1769
|
+
let alignment = directChild(xf, 'alignment');
|
|
1770
|
+
if (!alignment) {
|
|
1771
|
+
alignment = document.createElementNS(document.documentElement.namespaceURI, 'alignment');
|
|
1772
|
+
xf.insertBefore(alignment, directChildren(xf).find((child)=>[
|
|
1773
|
+
'protection',
|
|
1774
|
+
'extLst'
|
|
1775
|
+
].includes(child.localName)) ?? null);
|
|
1838
1776
|
}
|
|
1839
|
-
|
|
1777
|
+
if (void 0 !== style.horizontal) alignment.setAttribute('horizontal', style.horizontal);
|
|
1778
|
+
if (void 0 !== style.vertical) alignment.setAttribute('vertical', style.vertical);
|
|
1779
|
+
if (void 0 !== style.wrapText) alignment.setAttribute('wrapText', style.wrapText ? '1' : '0');
|
|
1780
|
+
if (void 0 !== style.textRotation && Number.isInteger(style.textRotation) && (style.textRotation >= 0 && style.textRotation <= 180 || 255 === style.textRotation)) alignment.setAttribute('textRotation', String(style.textRotation));
|
|
1840
1781
|
}
|
|
1841
|
-
function
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1782
|
+
function setXlsxValueChild(document, parent, name, value, order) {
|
|
1783
|
+
removeXlsxChildren(parent, name);
|
|
1784
|
+
const child = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
1785
|
+
child.setAttribute('val', value);
|
|
1786
|
+
insertXlsxOrderedChild(parent, child, order);
|
|
1845
1787
|
}
|
|
1846
|
-
function
|
|
1847
|
-
|
|
1788
|
+
function setXlsxColorChild(document, parent, color, order) {
|
|
1789
|
+
removeXlsxChildren(parent, 'color');
|
|
1790
|
+
const child = document.createElementNS(document.documentElement.namespaceURI, 'color');
|
|
1791
|
+
child.setAttribute('rgb', color);
|
|
1792
|
+
insertXlsxOrderedChild(parent, child, order);
|
|
1848
1793
|
}
|
|
1849
|
-
function
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1794
|
+
function setXlsxToggleChild(document, parent, name, enabled, order) {
|
|
1795
|
+
removeXlsxChildren(parent, name);
|
|
1796
|
+
if (!enabled) return;
|
|
1797
|
+
const child = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
1798
|
+
child.setAttribute('val', '1');
|
|
1799
|
+
insertXlsxOrderedChild(parent, child, order);
|
|
1853
1800
|
}
|
|
1854
|
-
function
|
|
1855
|
-
|
|
1801
|
+
function setXlsxUnderlineChild(document, parent, style, order) {
|
|
1802
|
+
removeXlsxChildren(parent, 'u');
|
|
1803
|
+
if ('none' === style) return;
|
|
1804
|
+
const child = document.createElementNS(document.documentElement.namespaceURI, 'u');
|
|
1805
|
+
child.setAttribute('val', style);
|
|
1806
|
+
insertXlsxOrderedChild(parent, child, order);
|
|
1856
1807
|
}
|
|
1857
|
-
function
|
|
1858
|
-
if (
|
|
1808
|
+
function xlsxRgbColor(value) {
|
|
1809
|
+
if ('string' != typeof value) return null;
|
|
1810
|
+
const color = value.trim().replace('#', '').toUpperCase();
|
|
1811
|
+
if (/^[0-9A-F]{6}$/.test(color)) return `FF${color}`;
|
|
1812
|
+
if (/^[0-9A-F]{8}$/.test(color)) return color;
|
|
1813
|
+
if (/^[0-9A-F]{3}$/.test(color)) return `FF${[
|
|
1814
|
+
...color
|
|
1815
|
+
].map((character)=>character.repeat(2)).join('')}`;
|
|
1816
|
+
return null;
|
|
1859
1817
|
}
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
return {
|
|
1863
|
-
sheet: enabled ? 1 : 0,
|
|
1864
|
-
selectLockedCells: 1,
|
|
1865
|
-
selectunLockedCells: 1,
|
|
1866
|
-
formatCells: 0,
|
|
1867
|
-
formatColumns: 0,
|
|
1868
|
-
formatRows: 0,
|
|
1869
|
-
insertColumns: 0,
|
|
1870
|
-
insertRows: 0,
|
|
1871
|
-
insertHyperlinks: 0,
|
|
1872
|
-
deleteColumns: 0,
|
|
1873
|
-
deleteRows: 0,
|
|
1874
|
-
sort: 0,
|
|
1875
|
-
filter: 0,
|
|
1876
|
-
usePivotTablereports: 0,
|
|
1877
|
-
editObjects: 0,
|
|
1878
|
-
editScenarios: 0,
|
|
1879
|
-
hintText: '',
|
|
1880
|
-
defaultSheetHintText: DEFAULT_PROTECTION_HINT,
|
|
1881
|
-
allowRangeList: [],
|
|
1882
|
-
cellProtectionRanges: []
|
|
1883
|
-
};
|
|
1818
|
+
function removeXlsxChildren(parent, name) {
|
|
1819
|
+
for (const child of directChildren(parent, name))child.remove();
|
|
1884
1820
|
}
|
|
1885
|
-
function
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
const defaults = defaultSheetProtectionAuthority();
|
|
1890
|
-
if (!source || 'object' != typeof source) return defaults;
|
|
1891
|
-
const authority = source;
|
|
1892
|
-
return {
|
|
1893
|
-
sheet: flag(authority.sheet, defaults.sheet),
|
|
1894
|
-
selectLockedCells: flag(authority.selectLockedCells, defaults.selectLockedCells),
|
|
1895
|
-
selectunLockedCells: flag(authority.selectunLockedCells, defaults.selectunLockedCells),
|
|
1896
|
-
formatCells: flag(authority.formatCells, defaults.formatCells),
|
|
1897
|
-
formatColumns: flag(authority.formatColumns, defaults.formatColumns),
|
|
1898
|
-
formatRows: flag(authority.formatRows, defaults.formatRows),
|
|
1899
|
-
insertColumns: flag(authority.insertColumns, defaults.insertColumns),
|
|
1900
|
-
insertRows: flag(authority.insertRows, defaults.insertRows),
|
|
1901
|
-
insertHyperlinks: flag(authority.insertHyperlinks, defaults.insertHyperlinks),
|
|
1902
|
-
deleteColumns: flag(authority.deleteColumns, defaults.deleteColumns),
|
|
1903
|
-
deleteRows: flag(authority.deleteRows, defaults.deleteRows),
|
|
1904
|
-
sort: flag(authority.sort, defaults.sort),
|
|
1905
|
-
filter: flag(authority.filter, defaults.filter),
|
|
1906
|
-
usePivotTablereports: flag(authority.usePivotTablereports, defaults.usePivotTablereports),
|
|
1907
|
-
editObjects: flag(authority.editObjects, defaults.editObjects),
|
|
1908
|
-
editScenarios: flag(authority.editScenarios, defaults.editScenarios),
|
|
1909
|
-
hintText: stringValue(authority.hintText),
|
|
1910
|
-
defaultSheetHintText: stringValue(authority.defaultSheetHintText) || DEFAULT_PROTECTION_HINT,
|
|
1911
|
-
allowRangeList: editableRangeList(authority.allowRangeList),
|
|
1912
|
-
cellProtectionRanges: cellProtectionRangeList(authority.cellProtectionRanges),
|
|
1913
|
-
xlsxAttributes: stringRecord(authority.xlsxAttributes)
|
|
1914
|
-
};
|
|
1915
|
-
}
|
|
1916
|
-
function importedSheetProtectionAuthority(authority, cellProtectionRanges) {
|
|
1917
|
-
if (!authority && !cellProtectionRanges.length) return;
|
|
1918
|
-
const normalized = normalizeSheetProtectionAuthority(authority);
|
|
1919
|
-
normalized.cellProtectionRanges = [
|
|
1920
|
-
...cellProtectionRanges,
|
|
1921
|
-
...normalized.allowRangeList.filter((range)=>!editableRangeRequiresCredentials(range)).flatMap((range)=>work_spreadsheet_ranges_parseSpreadsheetCellRanges(range.sqref) ?? []).map((range)=>({
|
|
1922
|
-
range,
|
|
1923
|
-
locked: false,
|
|
1924
|
-
hidden: false
|
|
1925
|
-
}))
|
|
1926
|
-
];
|
|
1927
|
-
return normalized;
|
|
1928
|
-
}
|
|
1929
|
-
function withSheetProtection(sheet, enabled) {
|
|
1930
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
1931
|
-
authority.sheet = enabled ? 1 : 0;
|
|
1932
|
-
return withAuthority(sheet, authority);
|
|
1933
|
-
}
|
|
1934
|
-
function withSheetSelectionPermissions(sheet, permissions) {
|
|
1935
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
1936
|
-
if (void 0 !== permissions.selectLockedCells) authority.selectLockedCells = permissions.selectLockedCells ? 1 : 0;
|
|
1937
|
-
if (void 0 !== permissions.selectUnlockedCells) authority.selectunLockedCells = permissions.selectUnlockedCells ? 1 : 0;
|
|
1938
|
-
return withAuthority(sheet, authority);
|
|
1939
|
-
}
|
|
1940
|
-
function withEditableRange(sheet, index, editableRange) {
|
|
1941
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
1942
|
-
const nextRange = {
|
|
1943
|
-
name: editableRange.name.trim(),
|
|
1944
|
-
sqref: canonicalRangeReference(editableRange.sqref),
|
|
1945
|
-
hintText: editableRange.hintText?.trim() || void 0,
|
|
1946
|
-
xlsxAttributes: editableRange.xlsxAttributes
|
|
1947
|
-
};
|
|
1948
|
-
if (null !== index && authority.allowRangeList[index]) authority.allowRangeList[index] = nextRange;
|
|
1949
|
-
else authority.allowRangeList.push(nextRange);
|
|
1950
|
-
const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(nextRange.sqref) ?? [];
|
|
1951
|
-
const next = withCellProtection(sheet, ranges, false);
|
|
1952
|
-
const nextAuthority = sheetProtectionAuthority(next);
|
|
1953
|
-
nextAuthority.allowRangeList = authority.allowRangeList;
|
|
1954
|
-
return withAuthority(next, nextAuthority);
|
|
1955
|
-
}
|
|
1956
|
-
function withoutEditableRange(sheet, index) {
|
|
1957
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
1958
|
-
const removed = authority.allowRangeList[index];
|
|
1959
|
-
if (!removed) return sheet;
|
|
1960
|
-
authority.allowRangeList.splice(index, 1);
|
|
1961
|
-
const removedRanges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(removed.sqref) ?? [];
|
|
1962
|
-
let next = withCellProtection(sheet, removedRanges, true);
|
|
1963
|
-
for (const editableRange of authority.allowRangeList)if (!editableRangeRequiresCredentials(editableRange)) next = withCellProtection(next, work_spreadsheet_ranges_parseSpreadsheetCellRanges(editableRange.sqref) ?? [], false);
|
|
1964
|
-
const nextAuthority = sheetProtectionAuthority(next);
|
|
1965
|
-
nextAuthority.allowRangeList = authority.allowRangeList;
|
|
1966
|
-
return withAuthority(next, nextAuthority);
|
|
1967
|
-
}
|
|
1968
|
-
function withCellProtection(sheet, ranges, locked, hidden = false) {
|
|
1969
|
-
if (!ranges.length) return sheet;
|
|
1970
|
-
const data = cloneSparseMatrix(sheet.data);
|
|
1971
|
-
let rowCount = Math.max(sheet.row ?? 0, data.length);
|
|
1972
|
-
let columnCount = Math.max(sheet.column ?? 0, sparseMatrixColumnCount(data));
|
|
1973
|
-
for (const range of ranges){
|
|
1974
|
-
rowCount = Math.max(rowCount, range.row[1] + 1);
|
|
1975
|
-
columnCount = Math.max(columnCount, range.column[1] + 1);
|
|
1976
|
-
for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(data))if (!(row < range.row[0]) && !(row > range.row[1])) for (const [column, source] of spreadsheet_sparse_sparseArrayEntries(values)){
|
|
1977
|
-
if (column < range.column[0] || column > range.column[1]) continue;
|
|
1978
|
-
const cell = {
|
|
1979
|
-
...source ?? {}
|
|
1980
|
-
};
|
|
1981
|
-
cell.lo = locked ? 1 : 0;
|
|
1982
|
-
if (hidden) cell.hi = 1;
|
|
1983
|
-
else if (void 0 !== cell.hi) delete cell.hi;
|
|
1984
|
-
data[row][column] = cell;
|
|
1985
|
-
}
|
|
1986
|
-
}
|
|
1987
|
-
normalizeMatrix(data, rowCount, columnCount);
|
|
1988
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
1989
|
-
authority.cellProtectionRanges.push(...ranges.map((range)=>({
|
|
1990
|
-
range,
|
|
1991
|
-
locked,
|
|
1992
|
-
hidden
|
|
1993
|
-
})));
|
|
1994
|
-
return withAuthority({
|
|
1995
|
-
...sheet,
|
|
1996
|
-
row: rowCount,
|
|
1997
|
-
column: columnCount,
|
|
1998
|
-
data
|
|
1999
|
-
}, authority);
|
|
2000
|
-
}
|
|
2001
|
-
function editableRangeRequiresCredentials(range) {
|
|
2002
|
-
const attributes = range.xlsxAttributes ?? {};
|
|
2003
|
-
return Boolean(attributes.password || attributes.hashValue || attributes.saltValue || attributes.securityDescriptor || attributes.securitydescriptor);
|
|
2004
|
-
}
|
|
2005
|
-
function sheetHasProtectionState(sheet) {
|
|
2006
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
2007
|
-
if (1 === authority.sheet || authority.allowRangeList.length || Object.keys(authority.xlsxAttributes ?? {}).length) return true;
|
|
2008
|
-
return (sheet.data ?? []).some((row)=>row.some((cell)=>cell?.lo !== void 0 || cell?.hi !== void 0));
|
|
2009
|
-
}
|
|
2010
|
-
function protectedSheetCount(sheets) {
|
|
2011
|
-
return sheets.filter((sheet)=>1 === sheetProtectionAuthority(sheet).sheet).length;
|
|
2012
|
-
}
|
|
2013
|
-
function unlockedCellCount(sheet) {
|
|
2014
|
-
return (sheet.data ?? []).reduce((total, row)=>total + row.reduce((rowTotal, cell)=>rowTotal + (cell?.lo === 0 ? 1 : 0), 0), 0);
|
|
2015
|
-
}
|
|
2016
|
-
function spreadsheetProtectionKey(sheets) {
|
|
2017
|
-
return sheets.map((sheet)=>{
|
|
2018
|
-
const authority = sheetProtectionAuthority(sheet);
|
|
2019
|
-
const profile = spreadsheetMatrixProfile(sheet.data);
|
|
2020
|
-
let protectionCellKey = profile?.protectionCellKey;
|
|
2021
|
-
if (void 0 === protectionCellKey) {
|
|
2022
|
-
const cells = [];
|
|
2023
|
-
for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(sheet.data))for (const [column, cell] of spreadsheet_sparse_sparseArrayEntries(values)){
|
|
2024
|
-
const hidden = cell?.hi;
|
|
2025
|
-
if (cell?.lo !== void 0 || void 0 !== hidden) cells.push(`${row}_${column}:${cell?.lo ?? ''}:${hidden ?? ''}`);
|
|
2026
|
-
}
|
|
2027
|
-
protectionCellKey = cells.join(',');
|
|
2028
|
-
}
|
|
2029
|
-
return `${sheet.id ?? sheet.name}:${JSON.stringify(authority)}:${protectionCellKey}`;
|
|
2030
|
-
}).join('|');
|
|
2031
|
-
}
|
|
2032
|
-
function editableRangeCellCount(ranges) {
|
|
2033
|
-
return ranges.reduce((total, range)=>total + (range.row[1] - range.row[0] + 1) * (range.column[1] - range.column[0] + 1), 0);
|
|
2034
|
-
}
|
|
2035
|
-
function withAuthority(sheet, authority) {
|
|
2036
|
-
return {
|
|
2037
|
-
...sheet,
|
|
2038
|
-
config: {
|
|
2039
|
-
...sheet.config ?? {},
|
|
2040
|
-
authority
|
|
2041
|
-
}
|
|
2042
|
-
};
|
|
2043
|
-
}
|
|
2044
|
-
function editableRangeList(value) {
|
|
2045
|
-
if (!Array.isArray(value)) return [];
|
|
2046
|
-
return value.flatMap((item, index)=>{
|
|
2047
|
-
if (!item || 'object' != typeof item) return [];
|
|
2048
|
-
const range = item;
|
|
2049
|
-
const sqref = stringValue(range.sqref);
|
|
2050
|
-
if (!sqref || !work_spreadsheet_ranges_parseSpreadsheetCellRanges(sqref)) return [];
|
|
2051
|
-
return [
|
|
2052
|
-
{
|
|
2053
|
-
name: stringValue(range.name) || `Range ${index + 1}`,
|
|
2054
|
-
sqref: canonicalRangeReference(sqref),
|
|
2055
|
-
hintText: stringValue(range.hintText) || void 0,
|
|
2056
|
-
xlsxAttributes: stringRecord(range.xlsxAttributes)
|
|
2057
|
-
}
|
|
2058
|
-
];
|
|
2059
|
-
});
|
|
2060
|
-
}
|
|
2061
|
-
function canonicalRangeReference(value) {
|
|
2062
|
-
const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(value);
|
|
2063
|
-
return ranges ? formatSpreadsheetCellRanges(ranges) : value.trim();
|
|
2064
|
-
}
|
|
2065
|
-
function normalizeMatrix(data, rows, columns) {
|
|
2066
|
-
data.length = Math.max(data.length, rows);
|
|
2067
|
-
for (const [, row] of spreadsheet_sparse_sparseArrayEntries(data))row.length = Math.max(row.length, columns);
|
|
2068
|
-
}
|
|
2069
|
-
function cellProtectionRangeList(value) {
|
|
2070
|
-
if (!Array.isArray(value)) return [];
|
|
2071
|
-
return value.flatMap((item)=>{
|
|
2072
|
-
if (!item || 'object' != typeof item) return [];
|
|
2073
|
-
const candidate = item;
|
|
2074
|
-
const range = candidate.range;
|
|
2075
|
-
if (!range || !Array.isArray(range.row) || !Array.isArray(range.column) || range.row.length < 2 || range.column.length < 2 || ![
|
|
2076
|
-
...range.row,
|
|
2077
|
-
...range.column
|
|
2078
|
-
].every((index)=>Number.isSafeInteger(index) && index >= 0)) return [];
|
|
2079
|
-
return [
|
|
2080
|
-
{
|
|
2081
|
-
range: {
|
|
2082
|
-
row: [
|
|
2083
|
-
Math.min(range.row[0], range.row[1]),
|
|
2084
|
-
Math.max(range.row[0], range.row[1])
|
|
2085
|
-
],
|
|
2086
|
-
column: [
|
|
2087
|
-
Math.min(range.column[0], range.column[1]),
|
|
2088
|
-
Math.max(range.column[0], range.column[1])
|
|
2089
|
-
]
|
|
2090
|
-
},
|
|
2091
|
-
locked: false !== candidate.locked,
|
|
2092
|
-
hidden: true === candidate.hidden
|
|
2093
|
-
}
|
|
2094
|
-
];
|
|
2095
|
-
});
|
|
2096
|
-
}
|
|
2097
|
-
function flag(value, fallback) {
|
|
2098
|
-
if (1 === value || true === value || '1' === value) return 1;
|
|
2099
|
-
if (0 === value || false === value || '0' === value) return 0;
|
|
2100
|
-
return fallback;
|
|
2101
|
-
}
|
|
2102
|
-
function stringValue(value) {
|
|
2103
|
-
return 'string' == typeof value ? value : '';
|
|
2104
|
-
}
|
|
2105
|
-
function stringRecord(value) {
|
|
2106
|
-
if (!value || 'object' != typeof value || Array.isArray(value)) return;
|
|
2107
|
-
const entries = Object.entries(value).filter((entry)=>'string' == typeof entry[1]);
|
|
2108
|
-
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
2109
|
-
}
|
|
2110
|
-
const MILLISECONDS_PER_DAY = 86400000;
|
|
2111
|
-
function normalizeSpreadsheetDateValidationBoundary(value, uses1904DateSystem = false) {
|
|
2112
|
-
const trimmed = value.trim().replace(/^=/, '');
|
|
2113
|
-
const iso = normalizeIsoDate(trimmed);
|
|
2114
|
-
if (iso) return iso;
|
|
2115
|
-
const formula = /^DATE\((\d{4}),\s*(\d{1,2}),\s*(\d{1,2})\)$/i.exec(trimmed);
|
|
2116
|
-
if (formula) return normalizeIsoDate(`${formula[1]}-${String(formula[2]).padStart(2, '0')}-${String(formula[3]).padStart(2, '0')}`);
|
|
2117
|
-
const serial = Number(trimmed);
|
|
2118
|
-
if (!Number.isInteger(serial) || serial < 0) return null;
|
|
2119
|
-
if (!uses1904DateSystem && (0 === serial || 60 === serial)) return null;
|
|
2120
|
-
const adjustedSerial = uses1904DateSystem ? serial : serial > 60 ? serial - 1 : serial;
|
|
2121
|
-
const epoch = uses1904DateSystem ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 31);
|
|
2122
|
-
return isoDateFromTimestamp(epoch + adjustedSerial * MILLISECONDS_PER_DAY);
|
|
2123
|
-
}
|
|
2124
|
-
function spreadsheetDateValidationFormula(value) {
|
|
2125
|
-
const normalized = normalizeIsoDate(value.trim());
|
|
2126
|
-
if (!normalized) return value.trim().replace(/^=/, '');
|
|
2127
|
-
const [year, month, day] = normalized.split('-');
|
|
2128
|
-
return `DATE(${year},${Number(month)},${Number(day)})`;
|
|
2129
|
-
}
|
|
2130
|
-
function normalizeIsoDate(value) {
|
|
2131
|
-
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
2132
|
-
if (!match) return null;
|
|
2133
|
-
const timestamp = Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
|
|
2134
|
-
const normalized = isoDateFromTimestamp(timestamp);
|
|
2135
|
-
return normalized === value ? normalized : null;
|
|
2136
|
-
}
|
|
2137
|
-
function isoDateFromTimestamp(timestamp) {
|
|
2138
|
-
const date = new Date(timestamp);
|
|
2139
|
-
const year = date.getUTCFullYear();
|
|
2140
|
-
if (!Number.isFinite(timestamp) || year < 1900 || year > 9999) return null;
|
|
2141
|
-
return `${String(year).padStart(4, '0')}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;
|
|
2142
|
-
}
|
|
2143
|
-
const A3S_DIAGONAL_BORDER_KEY = 'a3sDiagonal';
|
|
2144
|
-
function spreadsheetDiagonalBorderFromCellValue(value) {
|
|
2145
|
-
if (!isRecord(value)) return;
|
|
2146
|
-
const metadata = value[A3S_DIAGONAL_BORDER_KEY];
|
|
2147
|
-
if (isRecord(metadata)) {
|
|
2148
|
-
const up = metadata.up;
|
|
2149
|
-
const down = metadata.down;
|
|
2150
|
-
const line = spreadsheetDiagonalBorderLine(metadata.line);
|
|
2151
|
-
if ('boolean' == typeof up && 'boolean' == typeof down) {
|
|
2152
|
-
if (!up && !down) return null;
|
|
2153
|
-
if (line) return {
|
|
2154
|
-
down,
|
|
2155
|
-
line,
|
|
2156
|
-
up
|
|
2157
|
-
};
|
|
2158
|
-
}
|
|
2159
|
-
}
|
|
2160
|
-
if (null === value.s) return null;
|
|
2161
|
-
const legacyLine = spreadsheetDiagonalBorderLine(value.s);
|
|
2162
|
-
return legacyLine ? {
|
|
2163
|
-
down: true,
|
|
2164
|
-
line: legacyLine,
|
|
2165
|
-
up: false
|
|
2166
|
-
} : void 0;
|
|
2167
|
-
}
|
|
2168
|
-
function spreadsheetCellValueWithDiagonalBorder(value, border) {
|
|
2169
|
-
const next = {
|
|
2170
|
-
...value
|
|
2171
|
-
};
|
|
2172
|
-
delete next.s;
|
|
2173
|
-
delete next[A3S_DIAGONAL_BORDER_KEY];
|
|
2174
|
-
if (!border) return next;
|
|
2175
|
-
const line = {
|
|
2176
|
-
...border.line
|
|
2177
|
-
};
|
|
2178
|
-
next[A3S_DIAGONAL_BORDER_KEY] = {
|
|
2179
|
-
down: border.down,
|
|
2180
|
-
line,
|
|
2181
|
-
up: border.up
|
|
2182
|
-
};
|
|
2183
|
-
if (border.down) next.s = line;
|
|
2184
|
-
return next;
|
|
2185
|
-
}
|
|
2186
|
-
function spreadsheetDiagonalBorderLine(value) {
|
|
2187
|
-
if (!isRecord(value)) return null;
|
|
2188
|
-
return 'string' == typeof value.color && 'string' == typeof value.style ? {
|
|
2189
|
-
color: value.color,
|
|
2190
|
-
style: value.style
|
|
2191
|
-
} : null;
|
|
2192
|
-
}
|
|
2193
|
-
function isRecord(value) {
|
|
2194
|
-
return Boolean(value && 'object' == typeof value && !Array.isArray(value));
|
|
2195
|
-
}
|
|
2196
|
-
const borderChildOrder = [
|
|
2197
|
-
'start',
|
|
2198
|
-
'end',
|
|
2199
|
-
'left',
|
|
2200
|
-
'right',
|
|
2201
|
-
'top',
|
|
2202
|
-
'bottom',
|
|
2203
|
-
'diagonal',
|
|
2204
|
-
'vertical',
|
|
2205
|
-
'horizontal',
|
|
2206
|
-
'extLst'
|
|
2207
|
-
];
|
|
2208
|
-
function ensureXlsxStyleCollection(document, name, anchors) {
|
|
2209
|
-
const root = document.documentElement;
|
|
2210
|
-
const existing = directChild(root, name);
|
|
2211
|
-
if (existing) return existing;
|
|
2212
|
-
const collection = document.createElementNS(root.namespaceURI, name);
|
|
2213
|
-
root.insertBefore(collection, directChildren(root).find((child)=>anchors.includes(child.localName)) ?? null);
|
|
2214
|
-
return collection;
|
|
2215
|
-
}
|
|
2216
|
-
function defaultXlsxFill(document, patternType) {
|
|
2217
|
-
const fill = document.createElementNS(document.documentElement.namespaceURI, 'fill');
|
|
2218
|
-
const pattern = document.createElementNS(document.documentElement.namespaceURI, 'patternFill');
|
|
2219
|
-
pattern.setAttribute('patternType', patternType);
|
|
2220
|
-
fill.append(pattern);
|
|
2221
|
-
return fill;
|
|
2222
|
-
}
|
|
2223
|
-
function defaultXlsxBorder(document) {
|
|
2224
|
-
const border = document.createElementNS(document.documentElement.namespaceURI, 'border');
|
|
2225
|
-
for (const name of [
|
|
2226
|
-
'left',
|
|
2227
|
-
'right',
|
|
2228
|
-
'top',
|
|
2229
|
-
'bottom',
|
|
2230
|
-
'diagonal'
|
|
2231
|
-
])border.append(document.createElementNS(document.documentElement.namespaceURI, name));
|
|
2232
|
-
return border;
|
|
2233
|
-
}
|
|
2234
|
-
function setXlsxBorderLine(document, border, name, line) {
|
|
2235
|
-
removeXlsxChildren(border, name);
|
|
2236
|
-
const element = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
2237
|
-
if (line) {
|
|
2238
|
-
element.setAttribute('style', line.style);
|
|
2239
|
-
const color = xlsxRgbColor(line.color);
|
|
2240
|
-
if (color) {
|
|
2241
|
-
const child = document.createElementNS(document.documentElement.namespaceURI, 'color');
|
|
2242
|
-
child.setAttribute('rgb', color);
|
|
2243
|
-
element.append(child);
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
|
-
insertXlsxOrderedChild(border, element, borderChildOrder);
|
|
2247
|
-
}
|
|
2248
|
-
function writeXlsxAlignment(document, xf, style) {
|
|
2249
|
-
let alignment = directChild(xf, 'alignment');
|
|
2250
|
-
if (!alignment) {
|
|
2251
|
-
alignment = document.createElementNS(document.documentElement.namespaceURI, 'alignment');
|
|
2252
|
-
xf.insertBefore(alignment, directChildren(xf).find((child)=>[
|
|
2253
|
-
'protection',
|
|
2254
|
-
'extLst'
|
|
2255
|
-
].includes(child.localName)) ?? null);
|
|
2256
|
-
}
|
|
2257
|
-
if (void 0 !== style.horizontal) alignment.setAttribute('horizontal', style.horizontal);
|
|
2258
|
-
if (void 0 !== style.vertical) alignment.setAttribute('vertical', style.vertical);
|
|
2259
|
-
if (void 0 !== style.wrapText) alignment.setAttribute('wrapText', style.wrapText ? '1' : '0');
|
|
2260
|
-
if (void 0 !== style.textRotation && Number.isInteger(style.textRotation) && (style.textRotation >= 0 && style.textRotation <= 180 || 255 === style.textRotation)) alignment.setAttribute('textRotation', String(style.textRotation));
|
|
2261
|
-
}
|
|
2262
|
-
function setXlsxValueChild(document, parent, name, value, order) {
|
|
2263
|
-
removeXlsxChildren(parent, name);
|
|
2264
|
-
const child = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
2265
|
-
child.setAttribute('val', value);
|
|
2266
|
-
insertXlsxOrderedChild(parent, child, order);
|
|
2267
|
-
}
|
|
2268
|
-
function setXlsxColorChild(document, parent, color, order) {
|
|
2269
|
-
removeXlsxChildren(parent, 'color');
|
|
2270
|
-
const child = document.createElementNS(document.documentElement.namespaceURI, 'color');
|
|
2271
|
-
child.setAttribute('rgb', color);
|
|
2272
|
-
insertXlsxOrderedChild(parent, child, order);
|
|
2273
|
-
}
|
|
2274
|
-
function setXlsxToggleChild(document, parent, name, enabled, order) {
|
|
2275
|
-
removeXlsxChildren(parent, name);
|
|
2276
|
-
if (!enabled) return;
|
|
2277
|
-
const child = document.createElementNS(document.documentElement.namespaceURI, name);
|
|
2278
|
-
child.setAttribute('val', '1');
|
|
2279
|
-
insertXlsxOrderedChild(parent, child, order);
|
|
2280
|
-
}
|
|
2281
|
-
function setXlsxUnderlineChild(document, parent, style, order) {
|
|
2282
|
-
removeXlsxChildren(parent, 'u');
|
|
2283
|
-
if ('none' === style) return;
|
|
2284
|
-
const child = document.createElementNS(document.documentElement.namespaceURI, 'u');
|
|
2285
|
-
child.setAttribute('val', style);
|
|
2286
|
-
insertXlsxOrderedChild(parent, child, order);
|
|
2287
|
-
}
|
|
2288
|
-
function xlsxRgbColor(value) {
|
|
2289
|
-
if ('string' != typeof value) return null;
|
|
2290
|
-
const color = value.trim().replace('#', '').toUpperCase();
|
|
2291
|
-
if (/^[0-9A-F]{6}$/.test(color)) return `FF${color}`;
|
|
2292
|
-
if (/^[0-9A-F]{8}$/.test(color)) return color;
|
|
2293
|
-
if (/^[0-9A-F]{3}$/.test(color)) return `FF${[
|
|
2294
|
-
...color
|
|
2295
|
-
].map((character)=>character.repeat(2)).join('')}`;
|
|
2296
|
-
return null;
|
|
2297
|
-
}
|
|
2298
|
-
function removeXlsxChildren(parent, name) {
|
|
2299
|
-
for (const child of directChildren(parent, name))child.remove();
|
|
2300
|
-
}
|
|
2301
|
-
function insertXlsxOrderedChild(parent, child, order) {
|
|
2302
|
-
const requested = order.indexOf(child.localName);
|
|
2303
|
-
const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
|
|
2304
|
-
parent.insertBefore(child, anchor ?? null);
|
|
1821
|
+
function insertXlsxOrderedChild(parent, child, order) {
|
|
1822
|
+
const requested = order.indexOf(child.localName);
|
|
1823
|
+
const anchor = directChildren(parent).find((candidate)=>order.indexOf(candidate.localName) > requested);
|
|
1824
|
+
parent.insertBefore(child, anchor ?? null);
|
|
2305
1825
|
}
|
|
2306
1826
|
const defaultThemeColors = [
|
|
2307
1827
|
'ffffff',
|
|
@@ -2547,247 +2067,997 @@ function readXlsxSemanticColorOrigin(element, colors) {
|
|
|
2547
2067
|
tint
|
|
2548
2068
|
}
|
|
2549
2069
|
};
|
|
2550
|
-
const indexed = work_xlsx_cell_style_origin_boundedInteger(attribute(element, 'indexed'), MAX_INDEXED_COLOR);
|
|
2551
|
-
if (null !== indexed && colors.indexed[indexed]) return {
|
|
2552
|
-
kind: 'indexed',
|
|
2553
|
-
baseColor: `#${colors.indexed[indexed]}`,
|
|
2554
|
-
index: indexed,
|
|
2070
|
+
const indexed = work_xlsx_cell_style_origin_boundedInteger(attribute(element, 'indexed'), MAX_INDEXED_COLOR);
|
|
2071
|
+
if (null !== indexed && colors.indexed[indexed]) return {
|
|
2072
|
+
kind: 'indexed',
|
|
2073
|
+
baseColor: `#${colors.indexed[indexed]}`,
|
|
2074
|
+
index: indexed,
|
|
2075
|
+
renderedColor,
|
|
2076
|
+
...null === tint ? {} : {
|
|
2077
|
+
tint
|
|
2078
|
+
}
|
|
2079
|
+
};
|
|
2080
|
+
if (xlsxBooleanAttribute(element, 'auto')) return {
|
|
2081
|
+
kind: 'automatic',
|
|
2082
|
+
baseColor: '#000000',
|
|
2083
|
+
renderedColor,
|
|
2084
|
+
...null === tint ? {} : {
|
|
2085
|
+
tint
|
|
2086
|
+
}
|
|
2087
|
+
};
|
|
2088
|
+
}
|
|
2089
|
+
function withXlsxCellStyleOrigin(cell, origin) {
|
|
2090
|
+
return origin && xlsxCellStyleOriginHasValues(origin) ? {
|
|
2091
|
+
...cell,
|
|
2092
|
+
a3sXlsxStyleOrigin: origin
|
|
2093
|
+
} : cell;
|
|
2094
|
+
}
|
|
2095
|
+
function xlsxCellStyleOrigin(cell) {
|
|
2096
|
+
const candidate = cell?.a3sXlsxStyleOrigin;
|
|
2097
|
+
if (!isRecord(candidate)) return;
|
|
2098
|
+
const fontColor = normalizeXlsxSemanticColorOrigin(candidate.fontColor);
|
|
2099
|
+
const fillColor = normalizeXlsxSemanticColorOrigin(candidate.fillColor);
|
|
2100
|
+
const borderColors = normalizedBorderColors(candidate.borderColors);
|
|
2101
|
+
const origin = {
|
|
2102
|
+
...fontColor ? {
|
|
2103
|
+
fontColor
|
|
2104
|
+
} : {},
|
|
2105
|
+
...fillColor ? {
|
|
2106
|
+
fillColor
|
|
2107
|
+
} : {},
|
|
2108
|
+
...borderColors ? {
|
|
2109
|
+
borderColors
|
|
2110
|
+
} : {}
|
|
2111
|
+
};
|
|
2112
|
+
return xlsxCellStyleOriginHasValues(origin) ? origin : void 0;
|
|
2113
|
+
}
|
|
2114
|
+
function xlsxSemanticColorMatchesValue(origin, value) {
|
|
2115
|
+
return work_xlsx_cell_style_origin_normalizedColor(value) === origin.renderedColor.toLowerCase();
|
|
2116
|
+
}
|
|
2117
|
+
function xlsxColorElementMatchesOrigin(element, origin) {
|
|
2118
|
+
if (!element || attribute(element, 'rgb')) return false;
|
|
2119
|
+
if ('theme' === origin.kind) {
|
|
2120
|
+
if (attribute(element, 'theme') !== String(origin.index)) return false;
|
|
2121
|
+
} else if ('indexed' === origin.kind) {
|
|
2122
|
+
if (attribute(element, 'indexed') !== String(origin.index)) return false;
|
|
2123
|
+
} else if (!xlsxBooleanAttribute(element, 'auto')) return false;
|
|
2124
|
+
const tint = boundedTint(attribute(element, 'tint'));
|
|
2125
|
+
return tint === (origin.tint ?? null);
|
|
2126
|
+
}
|
|
2127
|
+
function applyXlsxSemanticColorOrigin(element, origin) {
|
|
2128
|
+
for (const name of [
|
|
2129
|
+
'rgb',
|
|
2130
|
+
'theme',
|
|
2131
|
+
'indexed',
|
|
2132
|
+
'auto',
|
|
2133
|
+
'tint'
|
|
2134
|
+
])element.removeAttribute(name);
|
|
2135
|
+
if ('theme' === origin.kind) element.setAttribute('theme', String(origin.index));
|
|
2136
|
+
else if ('indexed' === origin.kind) element.setAttribute('indexed', String(origin.index));
|
|
2137
|
+
else element.setAttribute('auto', '1');
|
|
2138
|
+
if (void 0 !== origin.tint) element.setAttribute('tint', String(origin.tint));
|
|
2139
|
+
}
|
|
2140
|
+
function xlsxSemanticColorOriginKey(origin) {
|
|
2141
|
+
return origin ? `${origin.kind}:${'index' in origin ? origin.index : ''}:${origin.baseColor}:${origin.renderedColor}:${origin.tint ?? ''}` : '';
|
|
2142
|
+
}
|
|
2143
|
+
function xlsxSemanticColorOriginSupported(origin, palette) {
|
|
2144
|
+
if ('automatic' === origin.kind) return true;
|
|
2145
|
+
return palette?.[origin.kind].get(origin.index)?.toLowerCase() === origin.baseColor.toLowerCase();
|
|
2146
|
+
}
|
|
2147
|
+
function prepareXlsxSemanticPalette(styles, theme, colors) {
|
|
2148
|
+
const candidates = semanticPaletteCandidates(colors);
|
|
2149
|
+
const supportedTheme = new Map();
|
|
2150
|
+
let themeChanged = false;
|
|
2151
|
+
const scheme = theme ? firstDescendant(theme, 'clrScheme') : void 0;
|
|
2152
|
+
for (const [index, color] of candidates.theme){
|
|
2153
|
+
const name = THEME_COLOR_NAMES[index];
|
|
2154
|
+
const entry = name && scheme ? directChild(scheme, name) : void 0;
|
|
2155
|
+
if (entry) {
|
|
2156
|
+
themeChanged = writeThemeColor(entry, color) || themeChanged;
|
|
2157
|
+
supportedTheme.set(index, color);
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
const supportedIndexed = new Map();
|
|
2161
|
+
let stylesChanged = false;
|
|
2162
|
+
if (candidates.indexed.size) {
|
|
2163
|
+
const colors = ensureXlsxStyleCollection(styles, 'colors', [
|
|
2164
|
+
'extLst'
|
|
2165
|
+
]);
|
|
2166
|
+
let indexedColors = directChild(colors, 'indexedColors');
|
|
2167
|
+
if (!indexedColors) {
|
|
2168
|
+
indexedColors = styles.createElementNS(styles.documentElement.namespaceURI, 'indexedColors');
|
|
2169
|
+
colors.prepend(indexedColors);
|
|
2170
|
+
stylesChanged = true;
|
|
2171
|
+
}
|
|
2172
|
+
const resolver = createXlsxColorResolver(styles, theme);
|
|
2173
|
+
const highestIndex = Math.max(...candidates.indexed.keys());
|
|
2174
|
+
while(directChildren(indexedColors, 'rgbColor').length <= highestIndex){
|
|
2175
|
+
const index = directChildren(indexedColors, 'rgbColor').length;
|
|
2176
|
+
const element = styles.createElementNS(styles.documentElement.namespaceURI, 'rgbColor');
|
|
2177
|
+
element.setAttribute('rgb', `FF${(resolver.indexed[index] ?? '000000').toUpperCase()}`);
|
|
2178
|
+
indexedColors.append(element);
|
|
2179
|
+
stylesChanged = true;
|
|
2180
|
+
}
|
|
2181
|
+
const entries = directChildren(indexedColors, 'rgbColor');
|
|
2182
|
+
for (const [index, color] of candidates.indexed){
|
|
2183
|
+
const expected = `FF${color.slice(1).toUpperCase()}`;
|
|
2184
|
+
const entry = entries[index];
|
|
2185
|
+
if (entry) {
|
|
2186
|
+
if (attribute(entry, 'rgb')?.toUpperCase() !== expected) {
|
|
2187
|
+
entry.setAttribute('rgb', expected);
|
|
2188
|
+
stylesChanged = true;
|
|
2189
|
+
}
|
|
2190
|
+
supportedIndexed.set(index, color);
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
}
|
|
2194
|
+
return {
|
|
2195
|
+
palette: {
|
|
2196
|
+
indexed: supportedIndexed,
|
|
2197
|
+
theme: supportedTheme
|
|
2198
|
+
},
|
|
2199
|
+
stylesChanged,
|
|
2200
|
+
themeChanged
|
|
2201
|
+
};
|
|
2202
|
+
}
|
|
2203
|
+
function semanticPaletteCandidates(colors) {
|
|
2204
|
+
const theme = new Map();
|
|
2205
|
+
const indexed = new Map();
|
|
2206
|
+
const themeConflicts = new Set();
|
|
2207
|
+
const indexedConflicts = new Set();
|
|
2208
|
+
for (const color of colors){
|
|
2209
|
+
if ('automatic' === color.kind) continue;
|
|
2210
|
+
const target = 'theme' === color.kind ? theme : indexed;
|
|
2211
|
+
const conflicts = 'theme' === color.kind ? themeConflicts : indexedConflicts;
|
|
2212
|
+
const current = target.get(color.index);
|
|
2213
|
+
if (current && current.toLowerCase() !== color.baseColor.toLowerCase()) conflicts.add(color.index);
|
|
2214
|
+
else if (!current) target.set(color.index, color.baseColor);
|
|
2215
|
+
}
|
|
2216
|
+
for (const index of themeConflicts)theme.delete(index);
|
|
2217
|
+
for (const index of indexedConflicts)indexed.delete(index);
|
|
2218
|
+
return {
|
|
2219
|
+
indexed,
|
|
2220
|
+
theme
|
|
2221
|
+
};
|
|
2222
|
+
}
|
|
2223
|
+
function xlsxCellStyleOriginSemanticColors(origin) {
|
|
2224
|
+
return [
|
|
2225
|
+
origin.fontColor,
|
|
2226
|
+
origin.fillColor,
|
|
2227
|
+
...Object.values(origin.borderColors ?? {})
|
|
2228
|
+
].filter((value)=>Boolean(value));
|
|
2229
|
+
}
|
|
2230
|
+
function writeThemeColor(entry, color) {
|
|
2231
|
+
const current = directChildren(entry)[0];
|
|
2232
|
+
if (current?.localName === 'srgbClr' && attribute(current, 'val')?.toLowerCase() === color.slice(1).toLowerCase()) return false;
|
|
2233
|
+
for (const child of directChildren(entry))child.remove();
|
|
2234
|
+
const qualifiedName = entry.prefix ? `${entry.prefix}:srgbClr` : 'srgbClr';
|
|
2235
|
+
const replacement = entry.ownerDocument.createElementNS(entry.namespaceURI, qualifiedName);
|
|
2236
|
+
replacement.setAttribute('val', color.slice(1).toUpperCase());
|
|
2237
|
+
entry.append(replacement);
|
|
2238
|
+
return true;
|
|
2239
|
+
}
|
|
2240
|
+
function normalizedBorderColors(value) {
|
|
2241
|
+
if (!isRecord(value)) return;
|
|
2242
|
+
const result = {};
|
|
2243
|
+
for (const side of [
|
|
2244
|
+
'bottom',
|
|
2245
|
+
'diagonal',
|
|
2246
|
+
'left',
|
|
2247
|
+
'right',
|
|
2248
|
+
'top'
|
|
2249
|
+
]){
|
|
2250
|
+
const color = normalizeXlsxSemanticColorOrigin(value[side]);
|
|
2251
|
+
if (color) result[side] = color;
|
|
2252
|
+
}
|
|
2253
|
+
return Object.keys(result).length ? result : void 0;
|
|
2254
|
+
}
|
|
2255
|
+
function normalizeXlsxSemanticColorOrigin(value) {
|
|
2256
|
+
if (!isRecord(value)) return;
|
|
2257
|
+
const baseColor = work_xlsx_cell_style_origin_normalizedColor(value.baseColor);
|
|
2258
|
+
const renderedColor = work_xlsx_cell_style_origin_normalizedColor(value.renderedColor);
|
|
2259
|
+
const tint = normalizedTint(value.tint);
|
|
2260
|
+
if (!baseColor || !renderedColor || void 0 === tint) return;
|
|
2261
|
+
if ('automatic' === value.kind) return {
|
|
2262
|
+
kind: 'automatic',
|
|
2263
|
+
baseColor,
|
|
2264
|
+
renderedColor,
|
|
2265
|
+
...null === tint ? {} : {
|
|
2266
|
+
tint
|
|
2267
|
+
}
|
|
2268
|
+
};
|
|
2269
|
+
const maximum = 'theme' === value.kind ? THEME_COLOR_NAMES.length - 1 : MAX_INDEXED_COLOR;
|
|
2270
|
+
const index = boundedNumber(value.index, maximum);
|
|
2271
|
+
if ('theme' !== value.kind && 'indexed' !== value.kind || null === index) return;
|
|
2272
|
+
return {
|
|
2273
|
+
kind: value.kind,
|
|
2274
|
+
baseColor,
|
|
2275
|
+
index,
|
|
2555
2276
|
renderedColor,
|
|
2556
2277
|
...null === tint ? {} : {
|
|
2557
2278
|
tint
|
|
2558
2279
|
}
|
|
2559
2280
|
};
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2281
|
+
}
|
|
2282
|
+
function xlsxCellStyleOriginHasValues(origin) {
|
|
2283
|
+
return Boolean(origin.fontColor || origin.fillColor || Object.keys(origin.borderColors ?? {}).length);
|
|
2284
|
+
}
|
|
2285
|
+
function work_xlsx_cell_style_origin_normalizedColor(value) {
|
|
2286
|
+
const rgb = xlsxRgbColor(value);
|
|
2287
|
+
return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
|
|
2288
|
+
}
|
|
2289
|
+
function normalizedTint(value) {
|
|
2290
|
+
if (void 0 === value) return null;
|
|
2291
|
+
return 'number' == typeof value && Number.isFinite(value) && value >= -1 && value <= 1 ? value : void 0;
|
|
2292
|
+
}
|
|
2293
|
+
function boundedTint(value) {
|
|
2294
|
+
if (null === value) return null;
|
|
2295
|
+
const tint = Number(value);
|
|
2296
|
+
return Number.isFinite(tint) && tint >= -1 && tint <= 1 ? tint : null;
|
|
2297
|
+
}
|
|
2298
|
+
function work_xlsx_cell_style_origin_boundedInteger(value, maximum) {
|
|
2299
|
+
if (null === value || !/^\d+$/.test(value)) return null;
|
|
2300
|
+
return boundedNumber(Number(value), maximum);
|
|
2301
|
+
}
|
|
2302
|
+
function boundedNumber(value, maximum) {
|
|
2303
|
+
return 'number' == typeof value && Number.isSafeInteger(value) && value >= 0 && value <= maximum ? value : null;
|
|
2304
|
+
}
|
|
2305
|
+
function xlsxBooleanAttribute(element, name) {
|
|
2306
|
+
const value = attribute(element, name)?.trim().toLowerCase();
|
|
2307
|
+
return '1' === value || 'true' === value || 'on' === value;
|
|
2308
|
+
}
|
|
2309
|
+
function isRecord(value) {
|
|
2310
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
2311
|
+
}
|
|
2312
|
+
const XLSX_GRADIENT_FILL_CELL_KEY = 'a3sXlsxGradientFill';
|
|
2313
|
+
const MAX_XLSX_GRADIENT_STOPS = 256;
|
|
2314
|
+
function readXlsxGradientFill(element, colors) {
|
|
2315
|
+
if (!element) return;
|
|
2316
|
+
const type = attribute(element, 'type') ?? 'linear';
|
|
2317
|
+
if ('linear' !== type && 'path' !== type) return;
|
|
2318
|
+
const children = directChildren(element);
|
|
2319
|
+
if (children.length < 2 || children.length > MAX_XLSX_GRADIENT_STOPS || children.some((child)=>'stop' !== child.localName)) return;
|
|
2320
|
+
const stops = [];
|
|
2321
|
+
for (const stop of children){
|
|
2322
|
+
const position = unitInterval(attribute(stop, 'position'));
|
|
2323
|
+
const stopChildren = directChildren(stop);
|
|
2324
|
+
const colorElement = stopChildren[0];
|
|
2325
|
+
if (null === position || 1 !== stopChildren.length || colorElement?.localName !== 'color') return;
|
|
2326
|
+
const renderedColor = resolveXlsxColor(colorElement, colors);
|
|
2327
|
+
const color = work_xlsx_gradient_fill_normalizedColor(renderedColor);
|
|
2328
|
+
if (!color || (stops.at(-1)?.position ?? 0) > position) return;
|
|
2329
|
+
const colorOrigin = readXlsxSemanticColorOrigin(colorElement, colors);
|
|
2330
|
+
stops.push({
|
|
2331
|
+
color,
|
|
2332
|
+
...colorOrigin ? {
|
|
2333
|
+
colorOrigin
|
|
2334
|
+
} : {},
|
|
2335
|
+
position
|
|
2336
|
+
});
|
|
2337
|
+
}
|
|
2338
|
+
if ('linear' === type) {
|
|
2339
|
+
const degree = optionalFiniteNumber(attribute(element, 'degree'), 0);
|
|
2340
|
+
return null === degree ? void 0 : {
|
|
2341
|
+
degree,
|
|
2342
|
+
stops,
|
|
2343
|
+
type
|
|
2344
|
+
};
|
|
2345
|
+
}
|
|
2346
|
+
const left = optionalUnitInterval(attribute(element, 'left'), 0);
|
|
2347
|
+
const right = optionalUnitInterval(attribute(element, 'right'), 0);
|
|
2348
|
+
const top = optionalUnitInterval(attribute(element, 'top'), 0);
|
|
2349
|
+
const bottom = optionalUnitInterval(attribute(element, 'bottom'), 0);
|
|
2350
|
+
if (null === left || null === right || null === top || null === bottom || left > right || top > bottom) return;
|
|
2351
|
+
return {
|
|
2352
|
+
bottom,
|
|
2353
|
+
left,
|
|
2354
|
+
right,
|
|
2355
|
+
stops,
|
|
2356
|
+
top,
|
|
2357
|
+
type
|
|
2358
|
+
};
|
|
2359
|
+
}
|
|
2360
|
+
function withXlsxGradientFill(cell, fill) {
|
|
2361
|
+
const normalized = normalizeXlsxGradientFill(fill);
|
|
2362
|
+
return normalized ? {
|
|
2363
|
+
...cell,
|
|
2364
|
+
[XLSX_GRADIENT_FILL_CELL_KEY]: normalized
|
|
2365
|
+
} : cell;
|
|
2366
|
+
}
|
|
2367
|
+
function deleteXlsxGradientFill(cell) {
|
|
2368
|
+
delete cell[XLSX_GRADIENT_FILL_CELL_KEY];
|
|
2369
|
+
}
|
|
2370
|
+
function xlsxGradientFill(cell) {
|
|
2371
|
+
return normalizeXlsxGradientFill(cell?.[XLSX_GRADIENT_FILL_CELL_KEY]);
|
|
2372
|
+
}
|
|
2373
|
+
function activeXlsxGradientFill(cell) {
|
|
2374
|
+
const fill = xlsxGradientFill(cell);
|
|
2375
|
+
return fill && work_xlsx_gradient_fill_normalizedColor(cell?.bg) === xlsxGradientFillFallbackColor(fill) ? fill : void 0;
|
|
2376
|
+
}
|
|
2377
|
+
function normalizeXlsxGradientFill(value) {
|
|
2378
|
+
if (!work_xlsx_gradient_fill_isRecord(value) || !Array.isArray(value.stops)) return;
|
|
2379
|
+
if (value.stops.length < 2 || value.stops.length > MAX_XLSX_GRADIENT_STOPS) return;
|
|
2380
|
+
const stops = [];
|
|
2381
|
+
for (const valueStop of value.stops){
|
|
2382
|
+
if (!work_xlsx_gradient_fill_isRecord(valueStop)) return;
|
|
2383
|
+
const position = normalizedUnitInterval(valueStop.position);
|
|
2384
|
+
const color = work_xlsx_gradient_fill_normalizedColor(valueStop.color);
|
|
2385
|
+
if (null === position || !color || (stops.at(-1)?.position ?? 0) > position) return;
|
|
2386
|
+
const colorOrigin = normalizeXlsxSemanticColorOrigin(valueStop.colorOrigin);
|
|
2387
|
+
stops.push({
|
|
2388
|
+
color,
|
|
2389
|
+
...colorOrigin ? {
|
|
2390
|
+
colorOrigin
|
|
2391
|
+
} : {},
|
|
2392
|
+
position
|
|
2393
|
+
});
|
|
2394
|
+
}
|
|
2395
|
+
if ('linear' === value.type) {
|
|
2396
|
+
const degree = finiteNumber(value.degree);
|
|
2397
|
+
return null === degree ? void 0 : {
|
|
2398
|
+
degree,
|
|
2399
|
+
stops,
|
|
2400
|
+
type: 'linear'
|
|
2401
|
+
};
|
|
2402
|
+
}
|
|
2403
|
+
if ('path' !== value.type) return;
|
|
2404
|
+
const left = normalizedUnitInterval(value.left);
|
|
2405
|
+
const right = normalizedUnitInterval(value.right);
|
|
2406
|
+
const top = normalizedUnitInterval(value.top);
|
|
2407
|
+
const bottom = normalizedUnitInterval(value.bottom);
|
|
2408
|
+
if (null === left || null === right || null === top || null === bottom || left > right || top > bottom) return;
|
|
2409
|
+
return {
|
|
2410
|
+
bottom,
|
|
2411
|
+
left,
|
|
2412
|
+
right,
|
|
2413
|
+
stops,
|
|
2414
|
+
top,
|
|
2415
|
+
type: 'path'
|
|
2416
|
+
};
|
|
2417
|
+
}
|
|
2418
|
+
function xlsxGradientFillFallbackColor(fill) {
|
|
2419
|
+
return fill.stops[0]?.color ?? '#ffffff';
|
|
2420
|
+
}
|
|
2421
|
+
function xlsxGradientFillSemanticColors(fill) {
|
|
2422
|
+
return (fill?.stops ?? []).flatMap((stop)=>stop.colorOrigin ? [
|
|
2423
|
+
stop.colorOrigin
|
|
2424
|
+
] : []);
|
|
2425
|
+
}
|
|
2426
|
+
function xlsxGradientFillKey(fill) {
|
|
2427
|
+
if (!fill) return '';
|
|
2428
|
+
const geometry = 'linear' === fill.type ? `linear:${fill.degree}` : `path:${fill.left}:${fill.right}:${fill.top}:${fill.bottom}`;
|
|
2429
|
+
return `${geometry}:${fill.stops.map((stop)=>`${stop.position}:${stop.color}:${xlsxSemanticColorOriginKey(stop.colorOrigin)}`).join('|')}`;
|
|
2430
|
+
}
|
|
2431
|
+
function unitInterval(value) {
|
|
2432
|
+
if (null === value || !value.trim()) return null;
|
|
2433
|
+
return normalizedUnitInterval(Number(value));
|
|
2434
|
+
}
|
|
2435
|
+
function optionalUnitInterval(value, fallback) {
|
|
2436
|
+
return null === value ? fallback : unitInterval(value);
|
|
2437
|
+
}
|
|
2438
|
+
function normalizedUnitInterval(value) {
|
|
2439
|
+
return 'number' == typeof value && Number.isFinite(value) && value >= 0 && value <= 1 ? value : null;
|
|
2440
|
+
}
|
|
2441
|
+
function optionalFiniteNumber(value, fallback) {
|
|
2442
|
+
if (null === value) return fallback;
|
|
2443
|
+
if (!value.trim()) return null;
|
|
2444
|
+
return finiteNumber(Number(value));
|
|
2445
|
+
}
|
|
2446
|
+
function finiteNumber(value) {
|
|
2447
|
+
return 'number' == typeof value && Number.isFinite(value) ? value : null;
|
|
2448
|
+
}
|
|
2449
|
+
function work_xlsx_gradient_fill_normalizedColor(value) {
|
|
2450
|
+
const rgb = xlsxRgbColor(value);
|
|
2451
|
+
return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
|
|
2452
|
+
}
|
|
2453
|
+
function work_xlsx_gradient_fill_isRecord(value) {
|
|
2454
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
2455
|
+
}
|
|
2456
|
+
const XLSX_PATTERN_FILL_CELL_KEY = 'a3sXlsxPatternFill';
|
|
2457
|
+
const xlsxPatternFillTypes = [
|
|
2458
|
+
'darkDown',
|
|
2459
|
+
'darkGray',
|
|
2460
|
+
'darkGrid',
|
|
2461
|
+
'darkHorizontal',
|
|
2462
|
+
'darkTrellis',
|
|
2463
|
+
'darkUp',
|
|
2464
|
+
'darkVertical',
|
|
2465
|
+
'gray0625',
|
|
2466
|
+
'gray125',
|
|
2467
|
+
'lightDown',
|
|
2468
|
+
'lightGray',
|
|
2469
|
+
'lightGrid',
|
|
2470
|
+
'lightHorizontal',
|
|
2471
|
+
'lightTrellis',
|
|
2472
|
+
'lightUp',
|
|
2473
|
+
'lightVertical',
|
|
2474
|
+
'mediumGray'
|
|
2475
|
+
];
|
|
2476
|
+
const xlsxPatternFillTypeSet = new Set(xlsxPatternFillTypes);
|
|
2477
|
+
function readXlsxPatternFill(pattern, colors) {
|
|
2478
|
+
if (!pattern) return;
|
|
2479
|
+
const patternType = attribute(pattern, 'patternType');
|
|
2480
|
+
if (!patternType || !isXlsxPatternFillType(patternType)) return;
|
|
2481
|
+
const foreground = directChild(pattern, 'fgColor');
|
|
2482
|
+
const background = directChild(pattern, 'bgColor');
|
|
2483
|
+
const foregroundColor = foreground ? resolveXlsxColor(foreground, colors) : '#000000';
|
|
2484
|
+
const backgroundColor = background ? resolveXlsxColor(background, colors) : '#ffffff';
|
|
2485
|
+
const normalizedForegroundColor = work_xlsx_pattern_fill_normalizedColor(foregroundColor);
|
|
2486
|
+
const normalizedBackgroundColor = work_xlsx_pattern_fill_normalizedColor(backgroundColor);
|
|
2487
|
+
if (!normalizedForegroundColor || !normalizedBackgroundColor) return;
|
|
2488
|
+
const foregroundColorOrigin = readXlsxSemanticColorOrigin(foreground, colors);
|
|
2489
|
+
const backgroundColorOrigin = readXlsxSemanticColorOrigin(background, colors);
|
|
2490
|
+
return {
|
|
2491
|
+
backgroundColor: normalizedBackgroundColor,
|
|
2492
|
+
...backgroundColorOrigin ? {
|
|
2493
|
+
backgroundColorOrigin
|
|
2494
|
+
} : {},
|
|
2495
|
+
foregroundColor: normalizedForegroundColor,
|
|
2496
|
+
...foregroundColorOrigin ? {
|
|
2497
|
+
foregroundColorOrigin
|
|
2498
|
+
} : {},
|
|
2499
|
+
patternType
|
|
2500
|
+
};
|
|
2501
|
+
}
|
|
2502
|
+
function withXlsxPatternFill(cell, fill) {
|
|
2503
|
+
const normalized = normalizeXlsxPatternFill(fill);
|
|
2504
|
+
return normalized ? {
|
|
2505
|
+
...cell,
|
|
2506
|
+
[XLSX_PATTERN_FILL_CELL_KEY]: normalized
|
|
2507
|
+
} : cell;
|
|
2508
|
+
}
|
|
2509
|
+
function deleteXlsxPatternFill(cell) {
|
|
2510
|
+
delete cell[XLSX_PATTERN_FILL_CELL_KEY];
|
|
2511
|
+
}
|
|
2512
|
+
function xlsxPatternFill(cell) {
|
|
2513
|
+
return normalizeXlsxPatternFill(cell?.[XLSX_PATTERN_FILL_CELL_KEY]);
|
|
2514
|
+
}
|
|
2515
|
+
function activeXlsxPatternFill(cell) {
|
|
2516
|
+
const fill = xlsxPatternFill(cell);
|
|
2517
|
+
return fill && work_xlsx_pattern_fill_normalizedColor(cell?.bg) === fill.backgroundColor ? fill : void 0;
|
|
2518
|
+
}
|
|
2519
|
+
function normalizeXlsxPatternFill(value) {
|
|
2520
|
+
if (!work_xlsx_pattern_fill_isRecord(value) || !isXlsxPatternFillType(value.patternType)) return;
|
|
2521
|
+
const foregroundColor = work_xlsx_pattern_fill_normalizedColor(value.foregroundColor);
|
|
2522
|
+
const backgroundColor = work_xlsx_pattern_fill_normalizedColor(value.backgroundColor);
|
|
2523
|
+
if (!foregroundColor || !backgroundColor) return;
|
|
2524
|
+
const foregroundColorOrigin = normalizeXlsxSemanticColorOrigin(value.foregroundColorOrigin);
|
|
2525
|
+
const backgroundColorOrigin = normalizeXlsxSemanticColorOrigin(value.backgroundColorOrigin);
|
|
2526
|
+
return {
|
|
2527
|
+
backgroundColor,
|
|
2528
|
+
...backgroundColorOrigin ? {
|
|
2529
|
+
backgroundColorOrigin
|
|
2530
|
+
} : {},
|
|
2531
|
+
foregroundColor,
|
|
2532
|
+
...foregroundColorOrigin ? {
|
|
2533
|
+
foregroundColorOrigin
|
|
2534
|
+
} : {},
|
|
2535
|
+
patternType: value.patternType
|
|
2536
|
+
};
|
|
2537
|
+
}
|
|
2538
|
+
function xlsxPatternFillSemanticColors(fill) {
|
|
2539
|
+
return fill ? [
|
|
2540
|
+
fill.foregroundColorOrigin,
|
|
2541
|
+
fill.backgroundColorOrigin
|
|
2542
|
+
].filter((value)=>Boolean(value)) : [];
|
|
2543
|
+
}
|
|
2544
|
+
function xlsxPatternFillKey(fill) {
|
|
2545
|
+
return fill ? [
|
|
2546
|
+
fill.patternType,
|
|
2547
|
+
fill.foregroundColor,
|
|
2548
|
+
xlsxSemanticColorOriginKey(fill.foregroundColorOrigin),
|
|
2549
|
+
fill.backgroundColor,
|
|
2550
|
+
xlsxSemanticColorOriginKey(fill.backgroundColorOrigin)
|
|
2551
|
+
].join(':') : '';
|
|
2552
|
+
}
|
|
2553
|
+
function isXlsxPatternFillType(value) {
|
|
2554
|
+
return 'string' == typeof value && xlsxPatternFillTypeSet.has(value);
|
|
2555
|
+
}
|
|
2556
|
+
function work_xlsx_pattern_fill_normalizedColor(value) {
|
|
2557
|
+
const rgb = xlsxRgbColor(value);
|
|
2558
|
+
return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
|
|
2559
|
+
}
|
|
2560
|
+
function work_xlsx_pattern_fill_isRecord(value) {
|
|
2561
|
+
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
2562
|
+
}
|
|
2563
|
+
const SPREADSHEET_SHOWN_COMMENT_CELLS_PROPERTY = '__a3sShownCommentCells';
|
|
2564
|
+
const spreadsheetMatrixProfiles = new WeakMap();
|
|
2565
|
+
function freezeImportedSpreadsheetCell(cell) {
|
|
2566
|
+
const gradientFill = cell[XLSX_GRADIENT_FILL_CELL_KEY];
|
|
2567
|
+
if (gradientFill && 'object' == typeof gradientFill) {
|
|
2568
|
+
const stops = gradientFill.stops;
|
|
2569
|
+
if (Array.isArray(stops)) {
|
|
2570
|
+
for (const stop of stops)if (stop && 'object' == typeof stop) {
|
|
2571
|
+
freezeObject(stop.colorOrigin);
|
|
2572
|
+
freezeObject(stop);
|
|
2573
|
+
}
|
|
2574
|
+
Object.freeze(stops);
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
freezeObject(gradientFill);
|
|
2578
|
+
const patternFill = cell[XLSX_PATTERN_FILL_CELL_KEY];
|
|
2579
|
+
if (patternFill && 'object' == typeof patternFill) {
|
|
2580
|
+
const record = patternFill;
|
|
2581
|
+
freezeObject(record.foregroundColorOrigin);
|
|
2582
|
+
freezeObject(record.backgroundColorOrigin);
|
|
2583
|
+
}
|
|
2584
|
+
freezeObject(patternFill);
|
|
2585
|
+
freezeObject(cell.mc);
|
|
2586
|
+
freezeObject(cell.ct?.s);
|
|
2587
|
+
freezeObject(cell.ct);
|
|
2588
|
+
freezeObject(cell.ps);
|
|
2589
|
+
freezeObject(cell.hl);
|
|
2590
|
+
freezeObject(cell.spl);
|
|
2591
|
+
return Object.freeze(cell);
|
|
2592
|
+
}
|
|
2593
|
+
function registerImportedSpreadsheetMatrix(data, options) {
|
|
2594
|
+
data.length = Math.max(data.length, options.rowCount);
|
|
2595
|
+
data[0] ??= [];
|
|
2596
|
+
for (const rowIndex of sparseArrayIndexes(data)){
|
|
2597
|
+
const row = data[rowIndex];
|
|
2598
|
+
if (row) {
|
|
2599
|
+
row.length = Math.max(row.length, options.columnCount);
|
|
2600
|
+
Object.freeze(row);
|
|
2601
|
+
}
|
|
2602
|
+
}
|
|
2603
|
+
registerSpreadsheetMatrixProfile(data, options);
|
|
2604
|
+
}
|
|
2605
|
+
function registerDerivedSpreadsheetMatrix(data, source, changes) {
|
|
2606
|
+
const sourceProfile = spreadsheetMatrixProfiles.get(source);
|
|
2607
|
+
if (!sourceProfile?.fortuneReady) return false;
|
|
2608
|
+
const formulaCells = new Map(sourceProfile.formulaCells.map(({ column, row })=>[
|
|
2609
|
+
spreadsheetCoordinateKey(row, column),
|
|
2610
|
+
{
|
|
2611
|
+
column,
|
|
2612
|
+
row
|
|
2613
|
+
}
|
|
2614
|
+
]));
|
|
2615
|
+
const shownCommentCells = new Map(sourceProfile.shownCommentCells.map(({ c, r })=>[
|
|
2616
|
+
spreadsheetCoordinateKey(r, c),
|
|
2617
|
+
{
|
|
2618
|
+
c,
|
|
2619
|
+
r
|
|
2620
|
+
}
|
|
2621
|
+
]));
|
|
2622
|
+
let populatedCellCount = sourceProfile.populatedCellCount;
|
|
2623
|
+
let protectionCellKey = sourceProfile.protectionCellKey;
|
|
2624
|
+
let protectionCells;
|
|
2625
|
+
for (const { column, current, previous, row } of changes){
|
|
2626
|
+
const coordinateKey = spreadsheetCoordinateKey(row, column);
|
|
2627
|
+
if (null == previous && null != current) populatedCellCount += 1;
|
|
2628
|
+
if (null != previous && null == current) populatedCellCount -= 1;
|
|
2629
|
+
if (current?.f) formulaCells.set(coordinateKey, {
|
|
2630
|
+
column,
|
|
2631
|
+
row
|
|
2632
|
+
});
|
|
2633
|
+
else formulaCells.delete(coordinateKey);
|
|
2634
|
+
if (current?.ps?.isShow) shownCommentCells.set(coordinateKey, {
|
|
2635
|
+
c: column,
|
|
2636
|
+
r: row
|
|
2637
|
+
});
|
|
2638
|
+
else shownCommentCells.delete(coordinateKey);
|
|
2639
|
+
if (spreadsheetProtectionSignature(previous) !== spreadsheetProtectionSignature(current)) {
|
|
2640
|
+
protectionCells ??= spreadsheetProtectionCells(protectionCellKey);
|
|
2641
|
+
const signature = spreadsheetProtectionSignature(current);
|
|
2642
|
+
if (null === signature) protectionCells.delete(coordinateKey);
|
|
2643
|
+
else protectionCells.set(coordinateKey, signature);
|
|
2566
2644
|
}
|
|
2645
|
+
const changedRow = data[row];
|
|
2646
|
+
if (changedRow && !Object.isFrozen(changedRow)) Object.freeze(changedRow);
|
|
2647
|
+
}
|
|
2648
|
+
if (protectionCells) protectionCellKey = Array.from(protectionCells, ([coordinate, value])=>({
|
|
2649
|
+
coordinate,
|
|
2650
|
+
value
|
|
2651
|
+
})).sort((left, right)=>compareSpreadsheetCoordinates(left.coordinate, right.coordinate)).map(({ coordinate, value })=>`${coordinate}:${value}`).join(',');
|
|
2652
|
+
registerSpreadsheetMatrixProfile(data, {
|
|
2653
|
+
columnCount: Math.max(sourceProfile.columnCount, ...changes.map(({ column, row })=>Math.max(column + 1, data[row]?.length ?? 0))),
|
|
2654
|
+
formulaCells: Array.from(formulaCells.values()).sort(compareSpreadsheetCells),
|
|
2655
|
+
fortuneReady: true,
|
|
2656
|
+
populatedCellCount: Math.max(0, populatedCellCount),
|
|
2657
|
+
protectionCellKey,
|
|
2658
|
+
rowCount: Math.max(sourceProfile.rowCount, data.length, ...changes.map(({ row })=>row + 1)),
|
|
2659
|
+
shownCommentCells: Array.from(shownCommentCells.values()).sort((left, right)=>left.r - right.r || left.c - right.c)
|
|
2660
|
+
}, {
|
|
2661
|
+
historyRoot: sourceProfile.historyRoot,
|
|
2662
|
+
historyState: changes.some(({ current, previous })=>!sameSpreadsheetHistoryValue(current, previous)) ? Object.freeze({}) : sourceProfile.historyState
|
|
2663
|
+
});
|
|
2664
|
+
return true;
|
|
2665
|
+
}
|
|
2666
|
+
function spreadsheetMatrixProfile(data) {
|
|
2667
|
+
return data ? spreadsheetMatrixProfiles.get(data) : void 0;
|
|
2668
|
+
}
|
|
2669
|
+
function attachSpreadsheetShownCommentCells(data, cells) {
|
|
2670
|
+
Object.defineProperty(data, SPREADSHEET_SHOWN_COMMENT_CELLS_PROPERTY, {
|
|
2671
|
+
configurable: false,
|
|
2672
|
+
enumerable: false,
|
|
2673
|
+
value: cells,
|
|
2674
|
+
writable: false
|
|
2675
|
+
});
|
|
2676
|
+
}
|
|
2677
|
+
function registerSpreadsheetMatrixProfile(data, options, history) {
|
|
2678
|
+
const initialHistoryState = Object.freeze({});
|
|
2679
|
+
const profile = Object.freeze({
|
|
2680
|
+
columnCount: options.columnCount,
|
|
2681
|
+
formulaCells: Object.freeze(options.formulaCells.map((cell)=>Object.freeze({
|
|
2682
|
+
...cell
|
|
2683
|
+
}))),
|
|
2684
|
+
fortuneReady: options.fortuneReady,
|
|
2685
|
+
historyRoot: history?.historyRoot ?? initialHistoryState,
|
|
2686
|
+
historyState: history?.historyState ?? initialHistoryState,
|
|
2687
|
+
populatedCellCount: options.populatedCellCount,
|
|
2688
|
+
protectionCellKey: options.protectionCellKey,
|
|
2689
|
+
rowCount: options.rowCount,
|
|
2690
|
+
shownCommentCells: Object.freeze(options.shownCommentCells.map((cell)=>Object.freeze({
|
|
2691
|
+
...cell
|
|
2692
|
+
})))
|
|
2693
|
+
});
|
|
2694
|
+
attachSpreadsheetShownCommentCells(data, profile.shownCommentCells);
|
|
2695
|
+
Object.freeze(data);
|
|
2696
|
+
spreadsheetMatrixProfiles.set(data, profile);
|
|
2697
|
+
}
|
|
2698
|
+
function spreadsheetProtectionCells(value) {
|
|
2699
|
+
const cells = new Map();
|
|
2700
|
+
for (const entry of value.split(',')){
|
|
2701
|
+
if (!entry) continue;
|
|
2702
|
+
const separator = entry.indexOf(':');
|
|
2703
|
+
if (!(separator <= 0)) cells.set(entry.slice(0, separator), entry.slice(separator + 1));
|
|
2704
|
+
}
|
|
2705
|
+
return cells;
|
|
2706
|
+
}
|
|
2707
|
+
function spreadsheetProtectionSignature(cell) {
|
|
2708
|
+
const hidden = cell?.hi;
|
|
2709
|
+
if (cell?.lo === void 0 && void 0 === hidden) return null;
|
|
2710
|
+
return `${cell?.lo ?? ''}:${hidden ?? ''}`;
|
|
2711
|
+
}
|
|
2712
|
+
function spreadsheetCoordinateKey(row, column) {
|
|
2713
|
+
return `${row}_${column}`;
|
|
2714
|
+
}
|
|
2715
|
+
function compareSpreadsheetCoordinates(left, right) {
|
|
2716
|
+
const [leftRow = 0, leftColumn = 0] = left.split('_').map(Number);
|
|
2717
|
+
const [rightRow = 0, rightColumn = 0] = right.split('_').map(Number);
|
|
2718
|
+
return leftRow - rightRow || leftColumn - rightColumn;
|
|
2719
|
+
}
|
|
2720
|
+
function compareSpreadsheetCells(left, right) {
|
|
2721
|
+
return left.row - right.row || left.column - right.column;
|
|
2722
|
+
}
|
|
2723
|
+
function freezeObject(value) {
|
|
2724
|
+
if (value && 'object' == typeof value) Object.freeze(value);
|
|
2725
|
+
}
|
|
2726
|
+
const DEFAULT_PROTECTION_HINT = '此工作表已受保护。若要更改锁定的单元格,请先取消工作表保护。';
|
|
2727
|
+
function defaultSheetProtectionAuthority(enabled = false) {
|
|
2728
|
+
return {
|
|
2729
|
+
sheet: enabled ? 1 : 0,
|
|
2730
|
+
selectLockedCells: 1,
|
|
2731
|
+
selectunLockedCells: 1,
|
|
2732
|
+
formatCells: 0,
|
|
2733
|
+
formatColumns: 0,
|
|
2734
|
+
formatRows: 0,
|
|
2735
|
+
insertColumns: 0,
|
|
2736
|
+
insertRows: 0,
|
|
2737
|
+
insertHyperlinks: 0,
|
|
2738
|
+
deleteColumns: 0,
|
|
2739
|
+
deleteRows: 0,
|
|
2740
|
+
sort: 0,
|
|
2741
|
+
filter: 0,
|
|
2742
|
+
usePivotTablereports: 0,
|
|
2743
|
+
editObjects: 0,
|
|
2744
|
+
editScenarios: 0,
|
|
2745
|
+
hintText: '',
|
|
2746
|
+
defaultSheetHintText: DEFAULT_PROTECTION_HINT,
|
|
2747
|
+
allowRangeList: [],
|
|
2748
|
+
cellProtectionRanges: []
|
|
2567
2749
|
};
|
|
2568
2750
|
}
|
|
2569
|
-
function
|
|
2570
|
-
return
|
|
2571
|
-
...cell,
|
|
2572
|
-
a3sXlsxStyleOrigin: origin
|
|
2573
|
-
} : cell;
|
|
2751
|
+
function sheetProtectionAuthority(sheet) {
|
|
2752
|
+
return normalizeSheetProtectionAuthority(sheet.config?.authority);
|
|
2574
2753
|
}
|
|
2575
|
-
function
|
|
2576
|
-
const
|
|
2577
|
-
if (!
|
|
2578
|
-
const
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2754
|
+
function normalizeSheetProtectionAuthority(source) {
|
|
2755
|
+
const defaults = defaultSheetProtectionAuthority();
|
|
2756
|
+
if (!source || 'object' != typeof source) return defaults;
|
|
2757
|
+
const authority = source;
|
|
2758
|
+
return {
|
|
2759
|
+
sheet: flag(authority.sheet, defaults.sheet),
|
|
2760
|
+
selectLockedCells: flag(authority.selectLockedCells, defaults.selectLockedCells),
|
|
2761
|
+
selectunLockedCells: flag(authority.selectunLockedCells, defaults.selectunLockedCells),
|
|
2762
|
+
formatCells: flag(authority.formatCells, defaults.formatCells),
|
|
2763
|
+
formatColumns: flag(authority.formatColumns, defaults.formatColumns),
|
|
2764
|
+
formatRows: flag(authority.formatRows, defaults.formatRows),
|
|
2765
|
+
insertColumns: flag(authority.insertColumns, defaults.insertColumns),
|
|
2766
|
+
insertRows: flag(authority.insertRows, defaults.insertRows),
|
|
2767
|
+
insertHyperlinks: flag(authority.insertHyperlinks, defaults.insertHyperlinks),
|
|
2768
|
+
deleteColumns: flag(authority.deleteColumns, defaults.deleteColumns),
|
|
2769
|
+
deleteRows: flag(authority.deleteRows, defaults.deleteRows),
|
|
2770
|
+
sort: flag(authority.sort, defaults.sort),
|
|
2771
|
+
filter: flag(authority.filter, defaults.filter),
|
|
2772
|
+
usePivotTablereports: flag(authority.usePivotTablereports, defaults.usePivotTablereports),
|
|
2773
|
+
editObjects: flag(authority.editObjects, defaults.editObjects),
|
|
2774
|
+
editScenarios: flag(authority.editScenarios, defaults.editScenarios),
|
|
2775
|
+
hintText: stringValue(authority.hintText),
|
|
2776
|
+
defaultSheetHintText: stringValue(authority.defaultSheetHintText) || DEFAULT_PROTECTION_HINT,
|
|
2777
|
+
allowRangeList: editableRangeList(authority.allowRangeList),
|
|
2778
|
+
cellProtectionRanges: cellProtectionRangeList(authority.cellProtectionRanges),
|
|
2779
|
+
xlsxAttributes: stringRecord(authority.xlsxAttributes)
|
|
2591
2780
|
};
|
|
2592
|
-
return xlsxCellStyleOriginHasValues(origin) ? origin : void 0;
|
|
2593
2781
|
}
|
|
2594
|
-
function
|
|
2595
|
-
|
|
2782
|
+
function importedSheetProtectionAuthority(authority, cellProtectionRanges) {
|
|
2783
|
+
if (!authority && !cellProtectionRanges.length) return;
|
|
2784
|
+
const normalized = normalizeSheetProtectionAuthority(authority);
|
|
2785
|
+
normalized.cellProtectionRanges = [
|
|
2786
|
+
...cellProtectionRanges,
|
|
2787
|
+
...normalized.allowRangeList.filter((range)=>!editableRangeRequiresCredentials(range)).flatMap((range)=>work_spreadsheet_ranges_parseSpreadsheetCellRanges(range.sqref) ?? []).map((range)=>({
|
|
2788
|
+
range,
|
|
2789
|
+
locked: false,
|
|
2790
|
+
hidden: false
|
|
2791
|
+
}))
|
|
2792
|
+
];
|
|
2793
|
+
return normalized;
|
|
2596
2794
|
}
|
|
2597
|
-
function
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
} else if ('indexed' === origin.kind) {
|
|
2602
|
-
if (attribute(element, 'indexed') !== String(origin.index)) return false;
|
|
2603
|
-
} else if (!xlsxBooleanAttribute(element, 'auto')) return false;
|
|
2604
|
-
const tint = boundedTint(attribute(element, 'tint'));
|
|
2605
|
-
return tint === (origin.tint ?? null);
|
|
2795
|
+
function withSheetProtection(sheet, enabled) {
|
|
2796
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2797
|
+
authority.sheet = enabled ? 1 : 0;
|
|
2798
|
+
return withAuthority(sheet, authority);
|
|
2606
2799
|
}
|
|
2607
|
-
function
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
'auto',
|
|
2613
|
-
'tint'
|
|
2614
|
-
])element.removeAttribute(name);
|
|
2615
|
-
if ('theme' === origin.kind) element.setAttribute('theme', String(origin.index));
|
|
2616
|
-
else if ('indexed' === origin.kind) element.setAttribute('indexed', String(origin.index));
|
|
2617
|
-
else element.setAttribute('auto', '1');
|
|
2618
|
-
if (void 0 !== origin.tint) element.setAttribute('tint', String(origin.tint));
|
|
2800
|
+
function withSheetSelectionPermissions(sheet, permissions) {
|
|
2801
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2802
|
+
if (void 0 !== permissions.selectLockedCells) authority.selectLockedCells = permissions.selectLockedCells ? 1 : 0;
|
|
2803
|
+
if (void 0 !== permissions.selectUnlockedCells) authority.selectunLockedCells = permissions.selectUnlockedCells ? 1 : 0;
|
|
2804
|
+
return withAuthority(sheet, authority);
|
|
2619
2805
|
}
|
|
2620
|
-
function
|
|
2621
|
-
|
|
2806
|
+
function withEditableRange(sheet, index, editableRange) {
|
|
2807
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2808
|
+
const nextRange = {
|
|
2809
|
+
name: editableRange.name.trim(),
|
|
2810
|
+
sqref: canonicalRangeReference(editableRange.sqref),
|
|
2811
|
+
hintText: editableRange.hintText?.trim() || void 0,
|
|
2812
|
+
xlsxAttributes: editableRange.xlsxAttributes
|
|
2813
|
+
};
|
|
2814
|
+
if (null !== index && authority.allowRangeList[index]) authority.allowRangeList[index] = nextRange;
|
|
2815
|
+
else authority.allowRangeList.push(nextRange);
|
|
2816
|
+
const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(nextRange.sqref) ?? [];
|
|
2817
|
+
const next = withCellProtection(sheet, ranges, false);
|
|
2818
|
+
const nextAuthority = sheetProtectionAuthority(next);
|
|
2819
|
+
nextAuthority.allowRangeList = authority.allowRangeList;
|
|
2820
|
+
return withAuthority(next, nextAuthority);
|
|
2622
2821
|
}
|
|
2623
|
-
function
|
|
2624
|
-
|
|
2625
|
-
|
|
2822
|
+
function withoutEditableRange(sheet, index) {
|
|
2823
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2824
|
+
const removed = authority.allowRangeList[index];
|
|
2825
|
+
if (!removed) return sheet;
|
|
2826
|
+
authority.allowRangeList.splice(index, 1);
|
|
2827
|
+
const removedRanges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(removed.sqref) ?? [];
|
|
2828
|
+
let next = withCellProtection(sheet, removedRanges, true);
|
|
2829
|
+
for (const editableRange of authority.allowRangeList)if (!editableRangeRequiresCredentials(editableRange)) next = withCellProtection(next, work_spreadsheet_ranges_parseSpreadsheetCellRanges(editableRange.sqref) ?? [], false);
|
|
2830
|
+
const nextAuthority = sheetProtectionAuthority(next);
|
|
2831
|
+
nextAuthority.allowRangeList = authority.allowRangeList;
|
|
2832
|
+
return withAuthority(next, nextAuthority);
|
|
2626
2833
|
}
|
|
2627
|
-
function
|
|
2628
|
-
|
|
2629
|
-
const
|
|
2630
|
-
let
|
|
2631
|
-
|
|
2632
|
-
for (const
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
if (
|
|
2636
|
-
|
|
2637
|
-
|
|
2834
|
+
function withCellProtection(sheet, ranges, locked, hidden = false) {
|
|
2835
|
+
if (!ranges.length) return sheet;
|
|
2836
|
+
const data = cloneSparseMatrix(sheet.data);
|
|
2837
|
+
let rowCount = Math.max(sheet.row ?? 0, data.length);
|
|
2838
|
+
let columnCount = Math.max(sheet.column ?? 0, sparseMatrixColumnCount(data));
|
|
2839
|
+
for (const range of ranges){
|
|
2840
|
+
rowCount = Math.max(rowCount, range.row[1] + 1);
|
|
2841
|
+
columnCount = Math.max(columnCount, range.column[1] + 1);
|
|
2842
|
+
for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(data))if (!(row < range.row[0]) && !(row > range.row[1])) for (const [column, source] of spreadsheet_sparse_sparseArrayEntries(values)){
|
|
2843
|
+
if (column < range.column[0] || column > range.column[1]) continue;
|
|
2844
|
+
const cell = {
|
|
2845
|
+
...source ?? {}
|
|
2846
|
+
};
|
|
2847
|
+
cell.lo = locked ? 1 : 0;
|
|
2848
|
+
if (hidden) cell.hi = 1;
|
|
2849
|
+
else if (void 0 !== cell.hi) delete cell.hi;
|
|
2850
|
+
data[row][column] = cell;
|
|
2638
2851
|
}
|
|
2639
2852
|
}
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2853
|
+
normalizeMatrix(data, rowCount, columnCount);
|
|
2854
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2855
|
+
authority.cellProtectionRanges.push(...ranges.map((range)=>({
|
|
2856
|
+
range,
|
|
2857
|
+
locked,
|
|
2858
|
+
hidden
|
|
2859
|
+
})));
|
|
2860
|
+
return withAuthority({
|
|
2861
|
+
...sheet,
|
|
2862
|
+
row: rowCount,
|
|
2863
|
+
column: columnCount,
|
|
2864
|
+
data
|
|
2865
|
+
}, authority);
|
|
2866
|
+
}
|
|
2867
|
+
function editableRangeRequiresCredentials(range) {
|
|
2868
|
+
const attributes = range.xlsxAttributes ?? {};
|
|
2869
|
+
return Boolean(attributes.password || attributes.hashValue || attributes.saltValue || attributes.securityDescriptor || attributes.securitydescriptor);
|
|
2870
|
+
}
|
|
2871
|
+
function sheetHasProtectionState(sheet) {
|
|
2872
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2873
|
+
if (1 === authority.sheet || authority.allowRangeList.length || Object.keys(authority.xlsxAttributes ?? {}).length) return true;
|
|
2874
|
+
return (sheet.data ?? []).some((row)=>row.some((cell)=>cell?.lo !== void 0 || cell?.hi !== void 0));
|
|
2875
|
+
}
|
|
2876
|
+
function protectedSheetCount(sheets) {
|
|
2877
|
+
return sheets.filter((sheet)=>1 === sheetProtectionAuthority(sheet).sheet).length;
|
|
2878
|
+
}
|
|
2879
|
+
function unlockedCellCount(sheet) {
|
|
2880
|
+
return (sheet.data ?? []).reduce((total, row)=>total + row.reduce((rowTotal, cell)=>rowTotal + (cell?.lo === 0 ? 1 : 0), 0), 0);
|
|
2881
|
+
}
|
|
2882
|
+
function spreadsheetProtectionKey(sheets) {
|
|
2883
|
+
return sheets.map((sheet)=>{
|
|
2884
|
+
const authority = sheetProtectionAuthority(sheet);
|
|
2885
|
+
const profile = spreadsheetMatrixProfile(sheet.data);
|
|
2886
|
+
let protectionCellKey = profile?.protectionCellKey;
|
|
2887
|
+
if (void 0 === protectionCellKey) {
|
|
2888
|
+
const cells = [];
|
|
2889
|
+
for (const [row, values] of spreadsheet_sparse_sparseArrayEntries(sheet.data))for (const [column, cell] of spreadsheet_sparse_sparseArrayEntries(values)){
|
|
2890
|
+
const hidden = cell?.hi;
|
|
2891
|
+
if (cell?.lo !== void 0 || void 0 !== hidden) cells.push(`${row}_${column}:${cell?.lo ?? ''}:${hidden ?? ''}`);
|
|
2671
2892
|
}
|
|
2893
|
+
protectionCellKey = cells.join(',');
|
|
2672
2894
|
}
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
palette: {
|
|
2676
|
-
indexed: supportedIndexed,
|
|
2677
|
-
theme: supportedTheme
|
|
2678
|
-
},
|
|
2679
|
-
stylesChanged,
|
|
2680
|
-
themeChanged
|
|
2681
|
-
};
|
|
2895
|
+
return `${sheet.id ?? sheet.name}:${JSON.stringify(authority)}:${protectionCellKey}`;
|
|
2896
|
+
}).join('|');
|
|
2682
2897
|
}
|
|
2683
|
-
function
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
const indexedConflicts = new Set();
|
|
2688
|
-
for (const origin of origins)for (const color of xlsxCellStyleOriginColors(origin)){
|
|
2689
|
-
if ('automatic' === color.kind) continue;
|
|
2690
|
-
const target = 'theme' === color.kind ? theme : indexed;
|
|
2691
|
-
const conflicts = 'theme' === color.kind ? themeConflicts : indexedConflicts;
|
|
2692
|
-
const current = target.get(color.index);
|
|
2693
|
-
if (current && current.toLowerCase() !== color.baseColor.toLowerCase()) conflicts.add(color.index);
|
|
2694
|
-
else if (!current) target.set(color.index, color.baseColor);
|
|
2695
|
-
}
|
|
2696
|
-
for (const index of themeConflicts)theme.delete(index);
|
|
2697
|
-
for (const index of indexedConflicts)indexed.delete(index);
|
|
2898
|
+
function editableRangeCellCount(ranges) {
|
|
2899
|
+
return ranges.reduce((total, range)=>total + (range.row[1] - range.row[0] + 1) * (range.column[1] - range.column[0] + 1), 0);
|
|
2900
|
+
}
|
|
2901
|
+
function withAuthority(sheet, authority) {
|
|
2698
2902
|
return {
|
|
2699
|
-
|
|
2700
|
-
|
|
2903
|
+
...sheet,
|
|
2904
|
+
config: {
|
|
2905
|
+
...sheet.config ?? {},
|
|
2906
|
+
authority
|
|
2907
|
+
}
|
|
2701
2908
|
};
|
|
2702
2909
|
}
|
|
2703
|
-
function
|
|
2704
|
-
return [
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2910
|
+
function editableRangeList(value) {
|
|
2911
|
+
if (!Array.isArray(value)) return [];
|
|
2912
|
+
return value.flatMap((item, index)=>{
|
|
2913
|
+
if (!item || 'object' != typeof item) return [];
|
|
2914
|
+
const range = item;
|
|
2915
|
+
const sqref = stringValue(range.sqref);
|
|
2916
|
+
if (!sqref || !work_spreadsheet_ranges_parseSpreadsheetCellRanges(sqref)) return [];
|
|
2917
|
+
return [
|
|
2918
|
+
{
|
|
2919
|
+
name: stringValue(range.name) || `Range ${index + 1}`,
|
|
2920
|
+
sqref: canonicalRangeReference(sqref),
|
|
2921
|
+
hintText: stringValue(range.hintText) || void 0,
|
|
2922
|
+
xlsxAttributes: stringRecord(range.xlsxAttributes)
|
|
2923
|
+
}
|
|
2924
|
+
];
|
|
2925
|
+
});
|
|
2709
2926
|
}
|
|
2710
|
-
function
|
|
2711
|
-
const
|
|
2712
|
-
|
|
2713
|
-
for (const child of directChildren(entry))child.remove();
|
|
2714
|
-
const qualifiedName = entry.prefix ? `${entry.prefix}:srgbClr` : 'srgbClr';
|
|
2715
|
-
const replacement = entry.ownerDocument.createElementNS(entry.namespaceURI, qualifiedName);
|
|
2716
|
-
replacement.setAttribute('val', color.slice(1).toUpperCase());
|
|
2717
|
-
entry.append(replacement);
|
|
2718
|
-
return true;
|
|
2927
|
+
function canonicalRangeReference(value) {
|
|
2928
|
+
const ranges = work_spreadsheet_ranges_parseSpreadsheetCellRanges(value);
|
|
2929
|
+
return ranges ? formatSpreadsheetCellRanges(ranges) : value.trim();
|
|
2719
2930
|
}
|
|
2720
|
-
function
|
|
2721
|
-
|
|
2722
|
-
const
|
|
2723
|
-
for (const side of [
|
|
2724
|
-
'bottom',
|
|
2725
|
-
'diagonal',
|
|
2726
|
-
'left',
|
|
2727
|
-
'right',
|
|
2728
|
-
'top'
|
|
2729
|
-
]){
|
|
2730
|
-
const color = normalizeXlsxSemanticColorOrigin(value[side]);
|
|
2731
|
-
if (color) result[side] = color;
|
|
2732
|
-
}
|
|
2733
|
-
return Object.keys(result).length ? result : void 0;
|
|
2931
|
+
function normalizeMatrix(data, rows, columns) {
|
|
2932
|
+
data.length = Math.max(data.length, rows);
|
|
2933
|
+
for (const [, row] of spreadsheet_sparse_sparseArrayEntries(data))row.length = Math.max(row.length, columns);
|
|
2734
2934
|
}
|
|
2735
|
-
function
|
|
2736
|
-
if (!
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2935
|
+
function cellProtectionRangeList(value) {
|
|
2936
|
+
if (!Array.isArray(value)) return [];
|
|
2937
|
+
return value.flatMap((item)=>{
|
|
2938
|
+
if (!item || 'object' != typeof item) return [];
|
|
2939
|
+
const candidate = item;
|
|
2940
|
+
const range = candidate.range;
|
|
2941
|
+
if (!range || !Array.isArray(range.row) || !Array.isArray(range.column) || range.row.length < 2 || range.column.length < 2 || ![
|
|
2942
|
+
...range.row,
|
|
2943
|
+
...range.column
|
|
2944
|
+
].every((index)=>Number.isSafeInteger(index) && index >= 0)) return [];
|
|
2945
|
+
return [
|
|
2946
|
+
{
|
|
2947
|
+
range: {
|
|
2948
|
+
row: [
|
|
2949
|
+
Math.min(range.row[0], range.row[1]),
|
|
2950
|
+
Math.max(range.row[0], range.row[1])
|
|
2951
|
+
],
|
|
2952
|
+
column: [
|
|
2953
|
+
Math.min(range.column[0], range.column[1]),
|
|
2954
|
+
Math.max(range.column[0], range.column[1])
|
|
2955
|
+
]
|
|
2956
|
+
},
|
|
2957
|
+
locked: false !== candidate.locked,
|
|
2958
|
+
hidden: true === candidate.hidden
|
|
2959
|
+
}
|
|
2960
|
+
];
|
|
2961
|
+
});
|
|
2761
2962
|
}
|
|
2762
|
-
function
|
|
2763
|
-
|
|
2963
|
+
function flag(value, fallback) {
|
|
2964
|
+
if (1 === value || true === value || '1' === value) return 1;
|
|
2965
|
+
if (0 === value || false === value || '0' === value) return 0;
|
|
2966
|
+
return fallback;
|
|
2764
2967
|
}
|
|
2765
|
-
function
|
|
2766
|
-
|
|
2767
|
-
return rgb ? `#${rgb.slice(-6).toLowerCase()}` : null;
|
|
2968
|
+
function stringValue(value) {
|
|
2969
|
+
return 'string' == typeof value ? value : '';
|
|
2768
2970
|
}
|
|
2769
|
-
function
|
|
2770
|
-
if (
|
|
2771
|
-
|
|
2971
|
+
function stringRecord(value) {
|
|
2972
|
+
if (!value || 'object' != typeof value || Array.isArray(value)) return;
|
|
2973
|
+
const entries = Object.entries(value).filter((entry)=>'string' == typeof entry[1]);
|
|
2974
|
+
return entries.length ? Object.fromEntries(entries) : void 0;
|
|
2772
2975
|
}
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
const
|
|
2776
|
-
|
|
2976
|
+
const MILLISECONDS_PER_DAY = 86400000;
|
|
2977
|
+
function normalizeSpreadsheetDateValidationBoundary(value, uses1904DateSystem = false) {
|
|
2978
|
+
const trimmed = value.trim().replace(/^=/, '');
|
|
2979
|
+
const iso = normalizeIsoDate(trimmed);
|
|
2980
|
+
if (iso) return iso;
|
|
2981
|
+
const formula = /^DATE\((\d{4}),\s*(\d{1,2}),\s*(\d{1,2})\)$/i.exec(trimmed);
|
|
2982
|
+
if (formula) return normalizeIsoDate(`${formula[1]}-${String(formula[2]).padStart(2, '0')}-${String(formula[3]).padStart(2, '0')}`);
|
|
2983
|
+
const serial = Number(trimmed);
|
|
2984
|
+
if (!Number.isInteger(serial) || serial < 0) return null;
|
|
2985
|
+
if (!uses1904DateSystem && (0 === serial || 60 === serial)) return null;
|
|
2986
|
+
const adjustedSerial = uses1904DateSystem ? serial : serial > 60 ? serial - 1 : serial;
|
|
2987
|
+
const epoch = uses1904DateSystem ? Date.UTC(1904, 0, 1) : Date.UTC(1899, 11, 31);
|
|
2988
|
+
return isoDateFromTimestamp(epoch + adjustedSerial * MILLISECONDS_PER_DAY);
|
|
2777
2989
|
}
|
|
2778
|
-
function
|
|
2779
|
-
|
|
2780
|
-
return
|
|
2990
|
+
function spreadsheetDateValidationFormula(value) {
|
|
2991
|
+
const normalized = normalizeIsoDate(value.trim());
|
|
2992
|
+
if (!normalized) return value.trim().replace(/^=/, '');
|
|
2993
|
+
const [year, month, day] = normalized.split('-');
|
|
2994
|
+
return `DATE(${year},${Number(month)},${Number(day)})`;
|
|
2781
2995
|
}
|
|
2782
|
-
function
|
|
2783
|
-
|
|
2996
|
+
function normalizeIsoDate(value) {
|
|
2997
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
2998
|
+
if (!match) return null;
|
|
2999
|
+
const timestamp = Date.UTC(Number(match[1]), Number(match[2]) - 1, Number(match[3]));
|
|
3000
|
+
const normalized = isoDateFromTimestamp(timestamp);
|
|
3001
|
+
return normalized === value ? normalized : null;
|
|
2784
3002
|
}
|
|
2785
|
-
function
|
|
2786
|
-
const
|
|
2787
|
-
|
|
3003
|
+
function isoDateFromTimestamp(timestamp) {
|
|
3004
|
+
const date = new Date(timestamp);
|
|
3005
|
+
const year = date.getUTCFullYear();
|
|
3006
|
+
if (!Number.isFinite(timestamp) || year < 1900 || year > 9999) return null;
|
|
3007
|
+
return `${String(year).padStart(4, '0')}-${String(date.getUTCMonth() + 1).padStart(2, '0')}-${String(date.getUTCDate()).padStart(2, '0')}`;
|
|
2788
3008
|
}
|
|
2789
|
-
|
|
2790
|
-
|
|
3009
|
+
const A3S_DIAGONAL_BORDER_KEY = 'a3sDiagonal';
|
|
3010
|
+
function spreadsheetDiagonalBorderFromCellValue(value) {
|
|
3011
|
+
if (!work_spreadsheet_diagonal_borders_isRecord(value)) return;
|
|
3012
|
+
const metadata = value[A3S_DIAGONAL_BORDER_KEY];
|
|
3013
|
+
if (work_spreadsheet_diagonal_borders_isRecord(metadata)) {
|
|
3014
|
+
const up = metadata.up;
|
|
3015
|
+
const down = metadata.down;
|
|
3016
|
+
const line = spreadsheetDiagonalBorderLine(metadata.line);
|
|
3017
|
+
if ('boolean' == typeof up && 'boolean' == typeof down) {
|
|
3018
|
+
if (!up && !down) return null;
|
|
3019
|
+
if (line) return {
|
|
3020
|
+
down,
|
|
3021
|
+
line,
|
|
3022
|
+
up
|
|
3023
|
+
};
|
|
3024
|
+
}
|
|
3025
|
+
}
|
|
3026
|
+
if (null === value.s) return null;
|
|
3027
|
+
const legacyLine = spreadsheetDiagonalBorderLine(value.s);
|
|
3028
|
+
return legacyLine ? {
|
|
3029
|
+
down: true,
|
|
3030
|
+
line: legacyLine,
|
|
3031
|
+
up: false
|
|
3032
|
+
} : void 0;
|
|
3033
|
+
}
|
|
3034
|
+
function spreadsheetCellValueWithDiagonalBorder(value, border) {
|
|
3035
|
+
const next = {
|
|
3036
|
+
...value
|
|
3037
|
+
};
|
|
3038
|
+
delete next.s;
|
|
3039
|
+
delete next[A3S_DIAGONAL_BORDER_KEY];
|
|
3040
|
+
if (!border) return next;
|
|
3041
|
+
const line = {
|
|
3042
|
+
...border.line
|
|
3043
|
+
};
|
|
3044
|
+
next[A3S_DIAGONAL_BORDER_KEY] = {
|
|
3045
|
+
down: border.down,
|
|
3046
|
+
line,
|
|
3047
|
+
up: border.up
|
|
3048
|
+
};
|
|
3049
|
+
if (border.down) next.s = line;
|
|
3050
|
+
return next;
|
|
3051
|
+
}
|
|
3052
|
+
function spreadsheetDiagonalBorderLine(value) {
|
|
3053
|
+
if (!work_spreadsheet_diagonal_borders_isRecord(value)) return null;
|
|
3054
|
+
return 'string' == typeof value.color && 'string' == typeof value.style ? {
|
|
3055
|
+
color: value.color,
|
|
3056
|
+
style: value.style
|
|
3057
|
+
} : null;
|
|
3058
|
+
}
|
|
3059
|
+
function work_spreadsheet_diagonal_borders_isRecord(value) {
|
|
3060
|
+
return Boolean(value && 'object' == typeof value && !Array.isArray(value));
|
|
2791
3061
|
}
|
|
2792
3062
|
const spreadsheetTextOrientationIds = [
|
|
2793
3063
|
'horizontal',
|
|
@@ -3037,6 +3307,34 @@ function nonNegativeInteger(value) {
|
|
|
3037
3307
|
const parsed = Number(value);
|
|
3038
3308
|
return Number.isSafeInteger(parsed) ? parsed : null;
|
|
3039
3309
|
}
|
|
3310
|
+
const xlsxNativeFillCellKeys = [
|
|
3311
|
+
XLSX_PATTERN_FILL_CELL_KEY,
|
|
3312
|
+
XLSX_GRADIENT_FILL_CELL_KEY
|
|
3313
|
+
];
|
|
3314
|
+
function activeXlsxNativeFill(cell) {
|
|
3315
|
+
const gradient = activeXlsxGradientFill(cell);
|
|
3316
|
+
const pattern = activeXlsxPatternFill(cell);
|
|
3317
|
+
if (Boolean(gradient) === Boolean(pattern)) return;
|
|
3318
|
+
return gradient ? {
|
|
3319
|
+
kind: 'gradient',
|
|
3320
|
+
value: gradient
|
|
3321
|
+
} : {
|
|
3322
|
+
kind: 'pattern',
|
|
3323
|
+
value: pattern
|
|
3324
|
+
};
|
|
3325
|
+
}
|
|
3326
|
+
function deleteXlsxNativeFills(cell) {
|
|
3327
|
+
deleteXlsxGradientFill(cell);
|
|
3328
|
+
deleteXlsxPatternFill(cell);
|
|
3329
|
+
}
|
|
3330
|
+
function xlsxNativeFillSemanticColors(fill) {
|
|
3331
|
+
if (!fill) return [];
|
|
3332
|
+
return 'gradient' === fill.kind ? xlsxGradientFillSemanticColors(fill.value) : xlsxPatternFillSemanticColors(fill.value);
|
|
3333
|
+
}
|
|
3334
|
+
function xlsxNativeFillKey(fill) {
|
|
3335
|
+
if (!fill) return '';
|
|
3336
|
+
return 'gradient' === fill.kind ? `gradient:${xlsxGradientFillKey(fill.value)}` : `pattern:${xlsxPatternFillKey(fill.value)}`;
|
|
3337
|
+
}
|
|
3040
3338
|
const SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS = [
|
|
3041
3339
|
'greaterThan',
|
|
3042
3340
|
'greaterThanOrEqual',
|
|
@@ -3834,7 +4132,7 @@ function readRichTextRun(element, value, colors) {
|
|
|
3834
4132
|
if (work_xlsx_rich_text_xlsxToggleEnabled(directChild(properties, 'b'))) run.bl = 1;
|
|
3835
4133
|
if (work_xlsx_rich_text_xlsxToggleEnabled(directChild(properties, 'i'))) run.it = 1;
|
|
3836
4134
|
if (work_xlsx_rich_text_xlsxToggleEnabled(directChild(properties, 'strike'))) run.cl = 1;
|
|
3837
|
-
const size =
|
|
4135
|
+
const size = work_xlsx_rich_text_finiteNumber(attribute(directChild(properties, 'sz') ?? properties, 'val'));
|
|
3838
4136
|
if (null !== size && size >= 1 && size <= 409) run.fs = size;
|
|
3839
4137
|
const underline = directChild(properties, 'u');
|
|
3840
4138
|
if (underline) {
|
|
@@ -3906,7 +4204,7 @@ function work_xlsx_rich_text_xlsxToggleEnabled(element) {
|
|
|
3906
4204
|
const value = attribute(element, 'val')?.trim().toLowerCase();
|
|
3907
4205
|
return '0' !== value && 'false' !== value && 'off' !== value;
|
|
3908
4206
|
}
|
|
3909
|
-
function
|
|
4207
|
+
function work_xlsx_rich_text_finiteNumber(value) {
|
|
3910
4208
|
if (null === value || !value.trim()) return null;
|
|
3911
4209
|
const parsed = Number(value);
|
|
3912
4210
|
return Number.isFinite(parsed) ? parsed : null;
|
|
@@ -3919,4 +4217,4 @@ function work_xlsx_rich_text_nonNegativeInteger(value) {
|
|
|
3919
4217
|
function work_xlsx_rich_text_isRecord(value) {
|
|
3920
4218
|
return 'object' == typeof value && null !== value && !Array.isArray(value);
|
|
3921
4219
|
}
|
|
3922
|
-
export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, activeXlsxSemanticColorOrigin, applyImportedXlsxRichText, applyXlsxSemanticColorOrigin, attachSpreadsheetShownCommentCells, coalesceXlsxRichTextRuns, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, createXlsxColorResolver, createXlsxRichTextReadContext, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, defaultXlsxBorder, defaultXlsxFill, directXlsxAlignment, directXlsxFontStyle, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, ensureXlsxStyleCollection, freezeImportedSpreadsheetCell, hasXlsxDirectFontStyle, importedSheetProtectionAuthority, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isHighSurrogate, isLowSurrogate, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, normalizeXlsxRichTextCell, normalizeXlsxRichTextColor, normalizeXlsxRichTextEditSource, normalizeXlsxRichTextRun, normalizeXlsxSemanticColorOrigin, patchSpreadsheetRichTextFontRuns, prepareXlsxSemanticPalette, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, readXlsxRichTextCells, readXlsxSemanticColorOrigin, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, resolveXlsxColor, sameSpreadsheetHistoryValue, sameXlsxRichTextRunStyle, setXlsxBorderLine, setXlsxColorChild, setXlsxToggleChild, setXlsxUnderlineChild, setXlsxValueChild, sheetHasProtectionState, sheetHasXlsxRichTextCells, sheetProtectionAuthority, spreadsheetCellValueWithDiagonalBorder, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetDiagonalBorderFromCellValue, spreadsheetExplicitTextOrientationFromCell, spreadsheetMatrixProfile, spreadsheetProtectionKey, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, unlockedCellCount, validXlsxRichText, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withXlsxCellStyleOrigin, withoutEditableRange, work_xlsx_cell_style_values_xlsxBooleanAttribute, writeXlsxAlignment, writeXlsxRichTextCells, xlsxAlignmentMatches, xlsxBorderLineMatches, xlsxCellStyleOrigin, xlsxColorElementMatchesOrigin, xlsxColorMatches, xlsxRgbColor, xlsxRichTextCellText, xlsxRichTextStyleOrigins, xlsxSemanticColorMatchesValue, xlsxSemanticColorOriginKey, xlsxStyleCollectionIndex, xlsxToggleEnabled, xlsxUnderlineStyle, xlsxWorksheetCellEntries };
|
|
4220
|
+
export { DEFAULT_PROTECTION_HINT, SPREADSHEET_CONDITIONAL_COMPARISON_OPERATORS, SPREADSHEET_CONDITIONAL_ICON_SETS, activeXlsxNativeFill, activeXlsxSemanticColorOrigin, applyImportedXlsxRichText, applyXlsxSemanticColorOrigin, attachSpreadsheetShownCommentCells, coalesceXlsxRichTextRuns, createWorkOfficeSpreadsheetCollaborationBinding as createOfficeSpreadsheetCollaborationBinding, createXlsxColorResolver, createXlsxRichTextReadContext, defaultSpreadsheetColorScaleThresholds, defaultSpreadsheetConditionalIconThresholds, defaultSpreadsheetDataBarOptions, defaultXlsxBorder, defaultXlsxFill, deleteXlsxNativeFills, directXlsxAlignment, directXlsxFontStyle, drawSpreadsheetConditionalIcon, editableRangeCellCount, editableRangeRequiresCredentials, effectiveSpreadsheetPageSetup, ensureXlsxStyleCollection, freezeImportedSpreadsheetCell, hasXlsxDirectFontStyle, importedSheetProtectionAuthority, initializeWorkOfficeSpreadsheetCollaboration as initializeOfficeSpreadsheetCollaboration, isHighSurrogate, isLowSurrogate, isSpreadsheetConditionalComparisonOperator, isSpreadsheetConditionalIconSetName, isSpreadsheetTextOrientationId, isSpreadsheetUnderlineStyle, normalizeSheetProtectionAuthority, normalizeSpreadsheetConditionalIconSetFormat, normalizeSpreadsheetConditionalVisualOptions, normalizeSpreadsheetDateValidationBoundary, normalizeSpreadsheetPaperSize, normalizeXlsxGradientFill, normalizeXlsxPatternFill, normalizeXlsxRichTextCell, normalizeXlsxRichTextColor, normalizeXlsxRichTextEditSource, normalizeXlsxRichTextRun, normalizeXlsxSemanticColorOrigin, patchSpreadsheetRichTextFontRuns, prepareXlsxSemanticPalette, protectedSheetCount, readWorkOfficeSpreadsheetCollaboration as readOfficeSpreadsheetCollaboration, readXlsxGradientFill, readXlsxPatternFill, readXlsxRichTextCells, readXlsxSemanticColorOrigin, registerDerivedSpreadsheetMatrix, registerImportedSpreadsheetMatrix, replaceWorkOfficeSpreadsheetCollaboration as replaceOfficeSpreadsheetCollaboration, resolveXlsxColor, sameSpreadsheetHistoryValue, sameXlsxRichTextRunStyle, setXlsxBorderLine, setXlsxColorChild, setXlsxToggleChild, setXlsxUnderlineChild, setXlsxValueChild, sheetHasProtectionState, sheetHasXlsxRichTextCells, sheetProtectionAuthority, spreadsheetCellValueWithDiagonalBorder, spreadsheetConditionalComparisonNeedsUpperValue, spreadsheetConditionalIconForValue, spreadsheetConditionalIconSetCount, spreadsheetConditionalThresholdValue, spreadsheetConditionalThresholdsEqual, spreadsheetDateValidationFormula, spreadsheetDiagonalBorderFromCellValue, spreadsheetExplicitTextOrientationFromCell, spreadsheetMatrixProfile, spreadsheetProtectionKey, spreadsheetTextOrientationCellStyle, spreadsheetTextOrientationChoiceFromCell, spreadsheetTextOrientationFromAngle, spreadsheetTextOrientationFromCell, spreadsheetTextOrientationFromChoice, spreadsheetTextOrientationFromXlsx, spreadsheetUnderlineCellValue, spreadsheetUnderlineCellValueFromSheetJs, spreadsheetUnderlineCellValueFromXlsx, spreadsheetUnderlineStyle, spreadsheetVisibleTextRotationFromCell, unlockedCellCount, validXlsxRichText, withEditableRange, withSheetProtection, withSheetSelectionPermissions, withXlsxCellStyleOrigin, withXlsxGradientFill, withXlsxPatternFill, withoutEditableRange, work_xlsx_cell_style_values_xlsxBooleanAttribute, writeXlsxAlignment, writeXlsxRichTextCells, xlsxAlignmentMatches, xlsxBorderLineMatches, xlsxCellStyleOrigin, xlsxCellStyleOriginSemanticColors, xlsxColorElementMatchesOrigin, xlsxColorMatches, xlsxGradientFillFallbackColor, xlsxGradientFillKey, xlsxNativeFillCellKeys, xlsxNativeFillKey, xlsxNativeFillSemanticColors, xlsxPatternFillTypes, xlsxRgbColor, xlsxRichTextCellText, xlsxRichTextStyleOrigins, xlsxSemanticColorMatchesValue, xlsxSemanticColorOriginKey, xlsxStyleCollectionIndex, xlsxToggleEnabled, xlsxUnderlineStyle, xlsxWorksheetCellEntries };
|