ooxml-ui 1.8.4 → 1.9.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/dist/{chunk-CTPXTRDT.js → chunk-PH7IBZOZ.js} +1 -1
- package/dist/docx/columns-dialog.d.ts +1 -1
- package/dist/docx/editor-core.d.ts +2 -0
- package/dist/docx/page-controller.d.ts +3 -2
- package/dist/docx/print-drag-scroll.d.ts +7 -0
- package/dist/docx/print-editing-geometry.d.ts +2 -0
- package/dist/docx/print-editing-index.d.ts +30 -0
- package/dist/docx/print-editing.d.ts +12 -0
- package/dist/docx/print-keyboard-navigation.d.ts +18 -0
- package/dist/docx/print-layout-view.d.ts +6 -10
- package/dist/docx/print-layout.d.ts +2 -2
- package/dist/docx/print-picture.d.ts +1 -0
- package/dist/docx.js +677 -20
- package/dist/index.js +2 -2
- package/dist/pptx/{chunk-KMNNTEGF.cjs → chunk-BFZDO2DY.cjs} +429 -194
- package/dist/pptx/{chunk-VRFNAF3Q.mjs → chunk-F7BBPOVJ.mjs} +9 -0
- package/dist/pptx/{chunk-STXGHV25.cjs → chunk-HWW2UVUP.cjs} +161 -4
- package/dist/pptx/{chunk-GHFJ46NS.mjs → chunk-KBCKCW5M.mjs} +371 -161
- package/dist/pptx/{chunk-NVYVHNPD.mjs → chunk-MKVKISFW.mjs} +1 -1
- package/dist/pptx/{chunk-NKHPE4PS.cjs → chunk-PKDISDDZ.cjs} +2 -2
- package/dist/pptx/{chunk-SM3CWDIQ.cjs → chunk-QVYJB7G2.cjs} +9 -0
- package/dist/pptx/chunk-SABFKDRM.mjs +286 -0
- package/dist/pptx/dom/elements/image.d.ts.map +1 -1
- package/dist/pptx/dom/index.cjs +221 -213
- package/dist/pptx/dom/index.mjs +24 -16
- package/dist/pptx/i18n/index.cjs +6 -6
- package/dist/pptx/i18n/index.mjs +1 -1
- package/dist/pptx/i18n/translations-en.d.ts.map +1 -1
- package/dist/pptx/index.cjs +2834 -2766
- package/dist/pptx/index.mjs +4 -4
- package/dist/pptx/render/find-replace.d.ts +1 -1
- package/dist/pptx/render/find-replace.d.ts.map +1 -1
- package/dist/pptx/render/format-painter.cjs +5 -5
- package/dist/pptx/render/format-painter.mjs +2 -2
- package/dist/pptx/render/index.d.ts +3 -0
- package/dist/pptx/render/index.d.ts.map +1 -1
- package/dist/pptx/render/inspector-helpers.cjs +12 -12
- package/dist/pptx/render/inspector-helpers.d.ts.map +1 -1
- package/dist/pptx/render/inspector-helpers.mjs +1 -1
- package/dist/pptx/render/inspector-number.d.ts +15 -0
- package/dist/pptx/render/inspector-number.d.ts.map +1 -0
- package/dist/pptx/render/picture-frame.d.ts +52 -0
- package/dist/pptx/render/picture-frame.d.ts.map +1 -0
- package/dist/pptx/render/ribbon-home-commands.d.ts +11 -2
- package/dist/pptx/render/ribbon-home-commands.d.ts.map +1 -1
- package/dist/pptx/render/share-session.d.ts.map +1 -1
- package/dist/pptx/render/slide-operations.d.ts +2 -1
- package/dist/pptx/render/slide-operations.d.ts.map +1 -1
- package/dist/pptx/render/slide-package-clipboard.d.ts +31 -0
- package/dist/pptx/render/slide-package-clipboard.d.ts.map +1 -0
- package/dist/pptx/render/slide-sorter-context-menu.d.ts +3 -5
- package/dist/pptx/render/slide-sorter-context-menu.d.ts.map +1 -1
- package/dist/pptx/render/slide-sorter-state.d.ts +8 -1
- package/dist/pptx/render/slide-sorter-state.d.ts.map +1 -1
- package/dist/pptx/render/text-advanced.d.ts.map +1 -1
- package/dist/pptx/render/text-style-scope.d.ts +41 -1
- package/dist/pptx/render/text-style-scope.d.ts.map +1 -1
- package/dist/pptx/render/text-style-update.d.ts.map +1 -1
- package/dist/pptx/web-components/index.d.ts +2 -0
- package/dist/pptx/web-components/index.d.ts.map +1 -1
- package/dist/pptx/web-components/slide-clipboard.d.ts +14 -0
- package/dist/pptx/web-components/slide-clipboard.d.ts.map +1 -0
- package/dist/teams.js +1 -1
- package/dist/visio/format-pane-fields.d.ts +2 -0
- package/dist/visio/page-setup-action.d.ts +1 -1
- package/dist/visio/page-setup-dialog-form.d.ts +1 -1
- package/dist/visio/ribbon-action.d.ts +1 -1
- package/dist/visio/viewer-accessibility.d.ts +17 -0
- package/dist/visio/viewer-insert-dialog.d.ts +2 -1
- package/dist/visio/viewer-review.d.ts +2 -0
- package/dist/visio.js +304 -14
- package/dist/xlsx/commands/pivots.d.ts +2 -0
- package/dist/xlsx/commands/sparklines.d.ts +2 -0
- package/dist/xlsx/dialogs/help-dialogs.d.ts +2 -2
- package/dist/xlsx/dialogs/page-header.d.ts +4 -0
- package/dist/xlsx/dialogs/page-setup-tabs.d.ts +6 -1
- package/dist/xlsx/dialogs/pivots.d.ts +2 -0
- package/dist/xlsx/dialogs/print-preview.d.ts +2 -0
- package/dist/xlsx/dialogs/sparklines.d.ts +4 -0
- package/dist/xlsx/print-cell.d.ts +4 -0
- package/dist/xlsx/print-header.d.ts +7 -0
- package/dist/xlsx/print-pages.d.ts +4 -0
- package/dist/xlsx/print.d.ts +4 -12
- package/dist/xlsx.js +1078 -287
- package/package.json +3 -3
- package/dist/pptx/chunk-VD7HRMTA.mjs +0 -137
- /package/dist/{chunk-SUHT5S2P.js → chunk-SKYBYVYH.js} +0 -0
package/dist/xlsx.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import './chunk-
|
|
1
|
+
import './chunk-PH7IBZOZ.js';
|
|
2
2
|
import { syncRibbonAddIns } from './chunk-W6AV3GHC.js';
|
|
3
3
|
export { RIBBON_ADD_IN_EVENT } from './chunk-W6AV3GHC.js';
|
|
4
4
|
import { defineSmartArt } from './chunk-PXIYHFZ5.js';
|
|
5
|
-
import { withExtension, saveExtension, downloadBytes, emit, emitEvent, blobFor, announceFileCommand, pickFile } from './chunk-
|
|
6
|
-
export { XLSX_EDITOR_EVENTS } from './chunk-
|
|
5
|
+
import { withExtension, saveExtension, downloadBytes, emit, emitEvent, blobFor, announceFileCommand, pickFile } from './chunk-SKYBYVYH.js';
|
|
6
|
+
export { XLSX_EDITOR_EVENTS } from './chunk-SKYBYVYH.js';
|
|
7
7
|
import './chunk-SNV6YKPC.js';
|
|
8
8
|
import { shadcnBridge } from './chunk-S6ZXU442.js';
|
|
9
9
|
import { range_control_default, createRibbonOverflow, defineBackstage, defineRibbon, defineRibbonActions, defineTitleBar, defineStatusBar, defineZoomSlider, rangeControl, defineDialog, runKeyTips, assignKeyTips, defineCheckbox, defineGallery, defineColorGrid, defineContextMenu, defineCommentsPane, parseSvgPreview } from './chunk-O7APCA5N.js';
|
|
@@ -11,9 +11,9 @@ import { getIcon, registerIcon } from './chunk-M6GF5ED2.js';
|
|
|
11
11
|
import { definePresence } from './chunk-L7JV5FVE.js';
|
|
12
12
|
import { withTokens } from './chunk-OGNNNTKI.js';
|
|
13
13
|
import './chunk-SPNWHKSR.js';
|
|
14
|
-
import { SPECIAL_CODES, FRACTION_CODES, AUTOSUM_FUNCTIONS, themeToCssVars, lightTheme, darkTheme, ICON_ACCENTS, ICON_PATHS, normalizeThemeMode, applyThemeColors, parseSelectionRef, selectionRef, normalizeEditorLocale, DirtyState, createCommandRegistry, createDialogRegistry, activeRef, createSelectionModel, SheetSelections, translator, initialSelection, sheetBaseName, historyOf, onRibbonTabsChange, activeChart, editChart, ribbonTabs, isTabHidden, selectTab, setTabHidden, tabButton, searchCommands, formatNumber, TEMPLATES, createTemplateWorkbook, isMenuSeparator, registerRibbonTabs, installFormatPainter, SHEET_ICONS, clipboardCommands, fontCommands, alignmentCommands, numberCommands, cellCommands, editingCommands, pageLayoutCommands, formulaCommands, dataCommands, contextualCommands, reviewTab, viewTab, helpTab, editBridge, CellViewCache, QUADRANTS, columnHeaderHeight, rowHeaderWidth, GridGeometry, cellRange, scrollToReveal, buildItems, fitNumber, cssFont, clampAddress, selectCell, movingEnd, extendSelection, moveWithinSelection, rowsRange, colsRange, ALL_RANGE, tabMenu, editing, icon, DATA_BAR_COLORS, dataBarRule, COLOR_SCALES, colorScaleRule, iconSetRule, target, tableAt, viewing, activeTable, numberFormatOptions, FONT_NAMES, FONT_SIZES, BORDER_PRESETS, ORIENTATIONS, ACCOUNTING_FORMATS, themePaletteItems, MARGIN_PRESETS, PAPER_SIZES, FUNCTION_MENUS, MORE_FUNCTION_CATEGORIES, functionsIn, isSingleCell, spanRange, selectionCellCount, addRange, activeStyle, selectSpecial, insertFunctionCall, guessHeader, regionOf, HIGHLIGHT_STYLES, ICON_SETS, TABLE_STYLES, tableStylePreview, resolveNameBox, absoluteReference, nameForRange, fillPaint, iconSvg, colSelected, rowSelected, rowHeaderMenu, columnHeaderMenu, cellMenu, recentFunctions, evaluateRef, buildChart, detectCategory, CATEGORIES, TIME_CODES, DATE_CODES, DEFAULT_OPTIONS, cellStyleItems, textDecoration, justify, alignItems, textAlign, hasBorders, edgeCss, diagonalSvg, SYMBOLS, buildCode, UNSET, dxfCss, negativeCodes, iconCount, iconThresholds, rowsOf, colsOf } from 'ooxml-core/xlsx/ui';
|
|
14
|
+
import { SPECIAL_CODES, FRACTION_CODES, AUTOSUM_FUNCTIONS, themeToCssVars, lightTheme, darkTheme, ICON_ACCENTS, ICON_PATHS, normalizeThemeMode, applyThemeColors, parseSelectionRef, selectionRef, normalizeEditorLocale, DirtyState, createCommandRegistry, createDialogRegistry, activeRef, createSelectionModel, SheetSelections, translator, initialSelection, sheetBaseName, historyOf, onRibbonTabsChange, activeChart, editChart, ribbonTabs, isTabHidden, selectTab, setTabHidden, tabButton, searchCommands, formatNumber, TEMPLATES, createTemplateWorkbook, isMenuSeparator, registerRibbonTabs, installFormatPainter, SHEET_ICONS, clipboardCommands, fontCommands, alignmentCommands, numberCommands, cellCommands, editingCommands, pageLayoutCommands, pageBreakCommands, formulaCommands, dataCommands, contextualCommands, reviewTab, viewTab, helpTab, editBridge, CellViewCache, QUADRANTS, columnHeaderHeight, rowHeaderWidth, GridGeometry, cellRange, scrollToReveal, buildItems, fitNumber, cssFont, clampAddress, selectCell, movingEnd, extendSelection, moveWithinSelection, rowsRange, colsRange, ALL_RANGE, tabMenu, editing, icon, DATA_BAR_COLORS, dataBarRule, COLOR_SCALES, colorScaleRule, iconSetRule, target, tableAt, viewing, activeTable, numberFormatOptions, FONT_NAMES, FONT_SIZES, BORDER_PRESETS, ORIENTATIONS, ACCOUNTING_FORMATS, themePaletteItems, MARGIN_PRESETS, PAPER_SIZES, FUNCTION_MENUS, MORE_FUNCTION_CATEGORIES, functionsIn, isSingleCell, spanRange, selectionCellCount, addRange, activeStyle, selectSpecial, insertFunctionCall, guessHeader, regionOf, HIGHLIGHT_STYLES, ICON_SETS, TABLE_STYLES, tableStylePreview, resolveNameBox, absoluteReference, nameForRange, fillPaint, iconSvg, colSelected, rowSelected, rowHeaderMenu, columnHeaderMenu, cellMenu, recentFunctions, evaluateRef, buildChart, detectCategory, CATEGORIES, TIME_CODES, DATE_CODES, DEFAULT_OPTIONS, cellStyleItems, textDecoration, justify, alignItems, textAlign, hasBorders, edgeCss, diagonalSvg, SYMBOLS, buildCode, UNSET, dxfCss, negativeCodes, iconCount, iconThresholds, rowsOf, colsOf } from 'ooxml-core/xlsx/ui';
|
|
15
15
|
export { EDITOR_LOCALES, THEME_KEYS, normalizeEditorLocale, registerRibbonTabs, themeToCssVars, darkTheme as xlsxDarkTheme, lightTheme as xlsxLightTheme } from 'ooxml-core/xlsx/ui';
|
|
16
|
-
import { createWorksheet, createEditSession, approximateMeasure, createWorkbook, MAX_ROW, MAX_COL, chartView, createRefEvaluator, chartBarSpacing, CHART_FILL_PARTS, selectionStats, formatSelectionStat, formatRange, chartSeriesTransparencyPatch, chartSeriesTransparency, chartSeriesGradientPatch, chartSeriesSolidFillPatch, chartSeriesFillPatch, chartWithElementFills, chartElementTransparencyPatch, chartElementTransparency, chartElementGradientPatch, chartElementSolidFillPatch, chartElementFillPatch, chartElementFill,
|
|
16
|
+
import { createWorksheet, createEditSession, approximateMeasure, createWorkbook, MAX_ROW, MAX_COL, chartView, createRefEvaluator, chartBarSpacing, CHART_FILL_PARTS, selectionStats, formatSelectionStat, printRange, formatRange, chartSeriesTransparencyPatch, chartSeriesTransparency, chartSeriesGradientPatch, chartSeriesSolidFillPatch, chartSeriesFillPatch, chartWithElementFills, chartElementTransparencyPatch, chartElementTransparency, chartElementGradientPatch, chartElementSolidFillPatch, chartElementFillPatch, chartElementFill, chartGradientStopTransparency, paginateWorksheet, resolveColor, DEFAULT_THEME, pageHeaderFooter, createGridMetrics, createPrintMergeIndex, formatAddress, cellView, renderHeaderFooterRuns, nextSheetName, FUNCTION_CATALOG, mergeAt, visibleCells, getCell, cellInputText, closeParens, isFormulaText, parseCellInput, referenceTarget, navigate, anchorToPixelBox, renderChartSvg, pixelBoxToAnchor, listValidationOptions, validationAt, getValue, resolvePasteOptions, DEFAULT_COL_WIDTH, nameAtCaret, functionMatches, callAtCaret, splice, acceptsReference, translateFormula, isCellError, layoutRemoteSelections, parseHtmlTable, toggleAbsolute, rangeContains, formatValue, isDateFormat, pictureAnchorAt, selectedSparklineGroups, pivotTableAt, validateDefinedName, usedRange, parseAddress, parseRange, styleAt, rangesIntersect, chartColorScheme, coloredReferences, syntaxParams, activeParam, columnLabel, THEME_SLOTS, normalizeRange, currentRegion, autoFitColumnWidth, validateSheetName, dateToSerial, IMAGE_EXTENSIONS, verifySheetPassword, verifyWorkbookPassword, sheetByName, quoteSheetName, pivotSourceData, printTitles, formatPrintTitleSpan, parsePrintTitleSpan, serialToDate, BUILTIN_NUMBER_FORMATS, pixelsToColumnWidth, validateTableName } from 'ooxml-core/xlsx';
|
|
17
17
|
import { hyperlinkPolicy } from 'ooxml-core/opc';
|
|
18
18
|
import { resolveChartGradient, sortGradientStops, withChartGradientDirection, buildChartGradientDef, chartGradientMarkup, CHART_COLOR_PALETTES, chartPaletteColors } from 'ooxml-core/chart';
|
|
19
19
|
import { render } from 'lit';
|
|
@@ -69,35 +69,35 @@ var DEFAULT_AUTHOR_NAME = "Author";
|
|
|
69
69
|
function isXlsxEditorAttribute(name) {
|
|
70
70
|
return XLSX_EDITOR_ATTRIBUTES.includes(name);
|
|
71
71
|
}
|
|
72
|
-
function applyAttribute(
|
|
72
|
+
function applyAttribute(target29, name, value) {
|
|
73
73
|
switch (name) {
|
|
74
74
|
case "locale":
|
|
75
|
-
if (normalizeEditorLocale(value ?? "en") !==
|
|
75
|
+
if (normalizeEditorLocale(value ?? "en") !== target29.locale) target29.locale = value ?? "en";
|
|
76
76
|
return;
|
|
77
77
|
case "read-only":
|
|
78
|
-
if ((value !== null && value !== "false") !==
|
|
79
|
-
|
|
78
|
+
if ((value !== null && value !== "false") !== target29.readOnly)
|
|
79
|
+
target29.readOnly = value !== null && value !== "false";
|
|
80
80
|
return;
|
|
81
81
|
case "file-name": {
|
|
82
82
|
const next = value || DEFAULT_FILE_NAME;
|
|
83
|
-
if (next !==
|
|
83
|
+
if (next !== target29.fileName) target29.fileName = next;
|
|
84
84
|
return;
|
|
85
85
|
}
|
|
86
86
|
case "author-name": {
|
|
87
87
|
const next = value || DEFAULT_AUTHOR_NAME;
|
|
88
|
-
if (next !==
|
|
88
|
+
if (next !== target29.authorName) target29.authorName = next;
|
|
89
89
|
return;
|
|
90
90
|
}
|
|
91
91
|
case "theme": {
|
|
92
92
|
const next = normalizeThemeMode(value);
|
|
93
|
-
if (next !==
|
|
93
|
+
if (next !== target29.theme) target29.theme = next;
|
|
94
94
|
return;
|
|
95
95
|
}
|
|
96
96
|
case "show-toolbar":
|
|
97
|
-
if (value !== "false" !==
|
|
97
|
+
if (value !== "false" !== target29.showToolbar) target29.showToolbar = value !== "false";
|
|
98
98
|
return;
|
|
99
99
|
case "show-formula-bar":
|
|
100
|
-
if (value !== "false" !==
|
|
100
|
+
if (value !== "false" !== target29.showFormulaBar) target29.showFormulaBar = value !== "false";
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
function reflectAttribute(element, name, value) {
|
|
@@ -365,7 +365,7 @@ function renderInfo(page) {
|
|
|
365
365
|
paragraph(
|
|
366
366
|
page,
|
|
367
367
|
t(
|
|
368
|
-
"Charts
|
|
368
|
+
"Charts, sparklines and worksheet-range PivotTables support editing. Advanced PivotTables, macros and other unsupported parts are preserved."
|
|
369
369
|
),
|
|
370
370
|
"xve-backstage-muted"
|
|
371
371
|
)
|
|
@@ -426,6 +426,8 @@ function renderInfo(page) {
|
|
|
426
426
|
layout.append(left, right);
|
|
427
427
|
content.replaceChildren(heading(page, t("Info")), layout);
|
|
428
428
|
}
|
|
429
|
+
|
|
430
|
+
// src/xlsx/print-cell.ts
|
|
429
431
|
var escapeHtml = (text3) => text3.replace(/[&<>"']/g, (ch) => `&#${ch.charCodeAt(0)};`);
|
|
430
432
|
var edge = (view) => view ? `${view.style === "double" ? 3 : view.widthPx}px ${view.style} ${view.color}` : "none";
|
|
431
433
|
function cellCss(view) {
|
|
@@ -455,55 +457,89 @@ function cellCss(view) {
|
|
|
455
457
|
else if (fill && "pattern" in fill) parts.push(`background:${fill.fg}`);
|
|
456
458
|
return parts.join(";");
|
|
457
459
|
}
|
|
458
|
-
function
|
|
460
|
+
function printPageHeaders(workbook, sheetIndex, layout, page, title, options) {
|
|
459
461
|
const sheet = workbook.sheets[sheetIndex];
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
462
|
+
const setup = sheet.pageSetup ?? {};
|
|
463
|
+
const number = (setup.firstPageNumber ?? 1) + page - 1;
|
|
464
|
+
const text3 = pageHeaderFooter(setup, page, number);
|
|
465
|
+
const context = {
|
|
466
|
+
page: number,
|
|
467
|
+
pages: layout.pages.length,
|
|
468
|
+
sheet: sheet.name,
|
|
469
|
+
file: (options.fileName ?? title).split(/[\\/]/).at(-1),
|
|
470
|
+
...options.date ? { date: options.date } : {},
|
|
471
|
+
...options.locale ? { locale: options.locale } : {}
|
|
472
|
+
};
|
|
473
|
+
const left = (setup.alignWithMargins === false ? 0.7 : layout.margins.left) * 96;
|
|
474
|
+
const right = (setup.alignWithMargins === false ? 0.7 : layout.margins.right) * 96;
|
|
475
|
+
const size = 11 * 96 / 72 * (setup.scaleWithDoc === false ? 1 : layout.scale);
|
|
476
|
+
const band2 = (kind, value) => {
|
|
477
|
+
if (!value) return "";
|
|
478
|
+
const sections = renderHeaderFooterRuns(value, context).sections;
|
|
479
|
+
const runs = (section) => sections[section].map(({ text: text4, style }) => {
|
|
480
|
+
const css = [
|
|
481
|
+
style.font ? `font-family:${style.font.replace(/["\\;<>]/g, "")}` : "",
|
|
482
|
+
style.size ? `font-size:${style.size / 11 * size}px` : "",
|
|
483
|
+
style.color ? `color:${style.color}` : "",
|
|
484
|
+
`font-weight:${style.bold ? 700 : 400}`,
|
|
485
|
+
`font-style:${style.italic ? "italic" : "normal"}`,
|
|
486
|
+
`text-decoration:${[style.underline ? "underline" : "", style.strike ? "line-through" : ""].filter(Boolean).join(" ") || "none"}`
|
|
487
|
+
].filter(Boolean).join(";");
|
|
488
|
+
return `<span style="${escapeHtml(css)}">${escapeHtml(text4)}</span>`;
|
|
489
|
+
}).join("");
|
|
490
|
+
return `<div class="xve-print-${kind}" style="position:absolute;${kind === "header" ? "top" : "bottom"}:${layout.margins[kind] * 96}px;left:${left}px;right:${right}px;font-size:${size}px;display:flex;line-height:1.2">${["left", "center", "right"].map((section) => `<span style="width:33.333%;white-space:pre-wrap;text-align:${section};overflow:hidden">${runs(section)}</span>`).join("")}</div>`;
|
|
491
|
+
};
|
|
492
|
+
return band2("header", text3.header) + band2("footer", text3.footer);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// src/xlsx/print-pages.ts
|
|
496
|
+
function pageTable(workbook, sheetIndex, page) {
|
|
473
497
|
const sheet = workbook.sheets[sheetIndex];
|
|
474
|
-
const range2 = printRange(workbook, sheetIndex);
|
|
475
|
-
const head = `<!doctype html><html><head><meta charset="utf-8"><title>${escapeHtml(title)}</title><style>
|
|
476
|
-
@page{margin:12mm}body{margin:0;font-family:Calibri,sans-serif}table{border-collapse:collapse;table-layout:fixed}
|
|
477
|
-
td{overflow:hidden;padding:0 3px;box-sizing:border-box;line-height:1.2}</style></head><body>`;
|
|
478
|
-
if (!sheet || !range2) return `${head}</body></html>`;
|
|
479
498
|
const metrics = createGridMetrics(sheet, { zoom: 100 });
|
|
480
|
-
const
|
|
481
|
-
|
|
482
|
-
const
|
|
483
|
-
const
|
|
484
|
-
const rows =
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
for (
|
|
499
|
-
if (!
|
|
500
|
-
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
}
|
|
504
|
-
|
|
505
|
-
}
|
|
506
|
-
return
|
|
499
|
+
const headings = !!sheet.printOptions?.headings;
|
|
500
|
+
const merges = createPrintMergeIndex(sheet.merges, page.rows, page.columns);
|
|
501
|
+
const columns = `${headings ? '<col style="width:24px">' : ""}${page.columns.map((col) => `<col style="width:${metrics.colWidth(col)}px">`).join("")}`;
|
|
502
|
+
const header = headings ? `<tr style="height:24px"><th></th>${page.columns.map((col) => `<th>${formatAddress({ row: 0, col }).replace(/\d+$/, "")}</th>`).join("")}</tr>` : "";
|
|
503
|
+
const rows = page.rows.map((row2) => {
|
|
504
|
+
const cells = page.columns.map((col) => {
|
|
505
|
+
const merge = merges.at(row2, col);
|
|
506
|
+
if (merge && (row2 !== merge.row || col !== merge.col)) return "";
|
|
507
|
+
const view = cellView(
|
|
508
|
+
workbook,
|
|
509
|
+
sheetIndex,
|
|
510
|
+
merge?.range.start.row ?? row2,
|
|
511
|
+
merge?.range.start.col ?? col,
|
|
512
|
+
void 0,
|
|
513
|
+
{ merged: !!merge }
|
|
514
|
+
);
|
|
515
|
+
let css = cellCss(view);
|
|
516
|
+
if (sheet.printOptions?.gridLines) {
|
|
517
|
+
for (const side of ["top", "right", "bottom", "left"])
|
|
518
|
+
if (!view.borders[side]) css += `;border-${side}:1px solid #d9d9d9`;
|
|
519
|
+
}
|
|
520
|
+
const span = `${merge && merge.colspan > 1 ? ` colspan="${merge.colspan}"` : ""}${merge && merge.rowspan > 1 ? ` rowspan="${merge.rowspan}"` : ""}`;
|
|
521
|
+
return `<td${span} style="${escapeHtml(css)}">${escapeHtml(view.text)}</td>`;
|
|
522
|
+
}).join("");
|
|
523
|
+
return `<tr style="height:${metrics.rowHeight(row2)}px">${headings ? `<th>${row2 + 1}</th>` : ""}${cells}</tr>`;
|
|
524
|
+
}).join("");
|
|
525
|
+
return `<table style="width:${page.width + (headings ? 24 : 0)}px"><colgroup>${columns}</colgroup><tbody>${header}${rows}</tbody></table>`;
|
|
526
|
+
}
|
|
527
|
+
function buildPrintHtml(workbook, sheetIndex, title, options = {}) {
|
|
528
|
+
const headerOptions = { date: /* @__PURE__ */ new Date(), ...options };
|
|
529
|
+
const layout = paginateWorksheet(workbook, sheetIndex);
|
|
530
|
+
const sheet = workbook.sheets[sheetIndex];
|
|
531
|
+
const pages = layout.pages.map((page) => {
|
|
532
|
+
const headings = sheet.printOptions?.headings ? 24 : 0;
|
|
533
|
+
const left = sheet.printOptions?.horizontalCentered ? Math.max(0, (layout.contentWidth - (page.width + headings) * layout.scale) / 2) : 0;
|
|
534
|
+
const top = sheet.printOptions?.verticalCentered ? Math.max(0, (layout.contentHeight - (page.height + headings) * layout.scale) / 2) : 0;
|
|
535
|
+
return `<section class="xve-print-page" data-page="${page.number}" style="position:relative;width:${layout.paperWidth}px;height:${layout.paperHeight}px;padding:${layout.margins.top}in ${layout.margins.right}in ${layout.margins.bottom}in ${layout.margins.left}in">${printPageHeaders(workbook, sheetIndex, layout, page.number, title, headerOptions)}<div class="xve-print-content" style="width:${layout.contentWidth}px;height:${layout.contentHeight}px"><div style="position:absolute;left:${left}px;top:${top}px;transform:scale(${layout.scale});transform-origin:top left">${pageTable(workbook, sheetIndex, page)}</div></div></section>`;
|
|
536
|
+
}).join("");
|
|
537
|
+
return `<!doctype html><html><head><meta charset="utf-8"><title>${escapeHtml(title)}</title><style>
|
|
538
|
+
@page{size:${layout.paperWidth / 96}in ${layout.paperHeight / 96}in;margin:0}
|
|
539
|
+
body{margin:0;background:#e8eaed;font-family:Calibri,sans-serif}.xve-print-page{box-sizing:border-box;background:white;margin:16px auto;box-shadow:0 1px 5px #0003;overflow:hidden;break-after:page}.xve-print-content{position:relative;overflow:hidden}
|
|
540
|
+
table{border-collapse:collapse;table-layout:fixed}td{overflow:hidden;padding:0 3px;box-sizing:border-box;line-height:1.2}th{box-sizing:border-box;font-size:12px;font-weight:400;color:#444;border:1px solid #ccc;overflow:hidden}
|
|
541
|
+
@media print{body{background:white}.xve-print-page{margin:0;box-shadow:none}.xve-print-page:last-child{break-after:auto}}
|
|
542
|
+
</style></head><body>${pages}</body></html>`;
|
|
507
543
|
}
|
|
508
544
|
var PRINT_FRAME_TIMEOUT_MS = 6e4;
|
|
509
545
|
var pendingFrames = /* @__PURE__ */ new WeakMap();
|
|
@@ -514,9 +550,9 @@ function printHtml(doc, html) {
|
|
|
514
550
|
frame.tabIndex = -1;
|
|
515
551
|
frame.style.cssText = "position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden";
|
|
516
552
|
doc.body.append(frame);
|
|
517
|
-
const
|
|
553
|
+
const target29 = frame.contentWindow;
|
|
518
554
|
const frameDoc = frame.contentDocument;
|
|
519
|
-
if (!
|
|
555
|
+
if (!target29 || !frameDoc) {
|
|
520
556
|
frame.remove();
|
|
521
557
|
return;
|
|
522
558
|
}
|
|
@@ -526,18 +562,18 @@ function printHtml(doc, html) {
|
|
|
526
562
|
let safety;
|
|
527
563
|
const cleanup = () => {
|
|
528
564
|
if (safety !== void 0) clearTimeout(safety);
|
|
529
|
-
|
|
565
|
+
target29.removeEventListener("afterprint", cleanup);
|
|
530
566
|
frame.remove();
|
|
531
567
|
if (pendingFrames.get(doc) === cleanup) pendingFrames.delete(doc);
|
|
532
568
|
};
|
|
533
569
|
pendingFrames.set(doc, cleanup);
|
|
534
|
-
|
|
570
|
+
target29.addEventListener("afterprint", cleanup);
|
|
535
571
|
safety = setTimeout(cleanup, PRINT_FRAME_TIMEOUT_MS);
|
|
536
572
|
setTimeout(() => {
|
|
537
573
|
if (!frame.isConnected) return;
|
|
538
574
|
try {
|
|
539
|
-
|
|
540
|
-
|
|
575
|
+
target29.focus();
|
|
576
|
+
target29.print();
|
|
541
577
|
} catch (error) {
|
|
542
578
|
cleanup();
|
|
543
579
|
console.error("xlsx-editor: printing failed", error);
|
|
@@ -647,7 +683,7 @@ function renderPrint(page) {
|
|
|
647
683
|
paragraph(
|
|
648
684
|
page,
|
|
649
685
|
t(
|
|
650
|
-
"
|
|
686
|
+
"Browser printing includes page setup, manual breaks, leading print titles and header/footer fields. Drawings and unsupported formatting are preserved but not rendered."
|
|
651
687
|
),
|
|
652
688
|
"xve-backstage-muted"
|
|
653
689
|
)
|
|
@@ -1169,10 +1205,10 @@ function listBox(ctx, label, onChange, onActivate) {
|
|
|
1169
1205
|
box.setAttribute("role", "listbox");
|
|
1170
1206
|
box.setAttribute("aria-label", ctx.t(label));
|
|
1171
1207
|
box.tabIndex = 0;
|
|
1172
|
-
let
|
|
1208
|
+
let selected2;
|
|
1173
1209
|
const options = () => [...box.querySelectorAll('[role="option"]')];
|
|
1174
1210
|
const choose = (value, notify = true) => {
|
|
1175
|
-
|
|
1211
|
+
selected2 = value;
|
|
1176
1212
|
for (const option of options()) {
|
|
1177
1213
|
const on = option.dataset.value === value;
|
|
1178
1214
|
option.setAttribute("aria-selected", String(on));
|
|
@@ -1185,7 +1221,7 @@ function listBox(ctx, label, onChange, onActivate) {
|
|
|
1185
1221
|
};
|
|
1186
1222
|
box.addEventListener("keydown", (event) => {
|
|
1187
1223
|
const list = options();
|
|
1188
|
-
const index = list.findIndex((o) => o.dataset.value ===
|
|
1224
|
+
const index = list.findIndex((o) => o.dataset.value === selected2);
|
|
1189
1225
|
const move = (to) => {
|
|
1190
1226
|
const next = list[Math.max(0, Math.min(list.length - 1, to))];
|
|
1191
1227
|
if (next?.dataset.value !== void 0) choose(next.dataset.value);
|
|
@@ -1194,7 +1230,7 @@ function listBox(ctx, label, onChange, onActivate) {
|
|
|
1194
1230
|
else if (event.key === "ArrowUp") move(index - 1);
|
|
1195
1231
|
else if (event.key === "Home") move(0);
|
|
1196
1232
|
else if (event.key === "End") move(list.length - 1);
|
|
1197
|
-
else if (event.key === "Enter" &&
|
|
1233
|
+
else if (event.key === "Enter" && selected2 !== void 0 && onActivate) onActivate(selected2);
|
|
1198
1234
|
else return;
|
|
1199
1235
|
event.preventDefault();
|
|
1200
1236
|
event.stopPropagation();
|
|
@@ -1214,10 +1250,10 @@ function listBox(ctx, label, onChange, onActivate) {
|
|
|
1214
1250
|
return option;
|
|
1215
1251
|
})
|
|
1216
1252
|
);
|
|
1217
|
-
if (
|
|
1218
|
-
else
|
|
1253
|
+
if (selected2 !== void 0 && items2.some(([v]) => v === selected2)) choose(selected2, false);
|
|
1254
|
+
else selected2 = void 0;
|
|
1219
1255
|
},
|
|
1220
|
-
value: () =>
|
|
1256
|
+
value: () => selected2,
|
|
1221
1257
|
select: (value) => choose(value)
|
|
1222
1258
|
};
|
|
1223
1259
|
}
|
|
@@ -1369,6 +1405,7 @@ function showDialog(ctx, spec, handle) {
|
|
|
1369
1405
|
defineDialog(ctx.host.ownerDocument.defaultView?.customElements);
|
|
1370
1406
|
ensureStyles(ctx);
|
|
1371
1407
|
const doc = ctx.host.ownerDocument;
|
|
1408
|
+
const opener = ctx.root.activeElement ?? doc.activeElement;
|
|
1372
1409
|
const dialog = doc.createElement("office-ui-dialog");
|
|
1373
1410
|
dialog.setAttribute("heading", ctx.t(spec.heading));
|
|
1374
1411
|
dialog.dataset.dialog = spec.name;
|
|
@@ -1390,6 +1427,9 @@ function showDialog(ctx, spec, handle) {
|
|
|
1390
1427
|
done = true;
|
|
1391
1428
|
dialog.removeAttribute("open");
|
|
1392
1429
|
dialog.remove();
|
|
1430
|
+
if (ctx.grid()) ctx.grid()?.focus();
|
|
1431
|
+
else if (opener instanceof doc.defaultView.HTMLElement && opener.isConnected)
|
|
1432
|
+
opener.focus({ preventScroll: true });
|
|
1393
1433
|
resolve(result);
|
|
1394
1434
|
};
|
|
1395
1435
|
let submitting = false;
|
|
@@ -1762,10 +1802,10 @@ function findShortcut(event, mac) {
|
|
|
1762
1802
|
return SHORTCUTS.find((shortcut) => shortcut.keys.some((spec) => matchesKeys(event, spec, mac)));
|
|
1763
1803
|
}
|
|
1764
1804
|
function inTextField(event) {
|
|
1765
|
-
const
|
|
1766
|
-
if (!(
|
|
1767
|
-
if (
|
|
1768
|
-
return
|
|
1805
|
+
const target29 = event.composedPath()[0];
|
|
1806
|
+
if (!(target29 instanceof Element)) return false;
|
|
1807
|
+
if (target29.closest(".xve-grid-host")) return false;
|
|
1808
|
+
return target29.matches(
|
|
1769
1809
|
'input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), textarea, select, [contenteditable=""], [contenteditable="true"]'
|
|
1770
1810
|
);
|
|
1771
1811
|
}
|
|
@@ -1935,11 +1975,11 @@ function alignmentTab(init) {
|
|
|
1935
1975
|
const alignment = patch();
|
|
1936
1976
|
return Object.keys(alignment).length ? { alignment } : {};
|
|
1937
1977
|
},
|
|
1938
|
-
apply: (
|
|
1978
|
+
apply: (target29) => {
|
|
1939
1979
|
if (!changed.has("merge") || merge.input.checked === merged) return;
|
|
1940
|
-
for (const range2 of
|
|
1941
|
-
if (merge.input.checked)
|
|
1942
|
-
else
|
|
1980
|
+
for (const range2 of target29.ranges)
|
|
1981
|
+
if (merge.input.checked) target29.session.merge(target29.sheet, range2, "merge");
|
|
1982
|
+
else target29.session.unmerge(target29.sheet, range2);
|
|
1943
1983
|
},
|
|
1944
1984
|
focus: () => horizontal.focus()
|
|
1945
1985
|
};
|
|
@@ -1981,11 +2021,14 @@ function mountPopover(anchor, pop, expanded = anchor, onClose) {
|
|
|
1981
2021
|
doc.addEventListener("pointerdown", outside, true);
|
|
1982
2022
|
doc.addEventListener("keydown", escape, true);
|
|
1983
2023
|
closeOpen = () => {
|
|
2024
|
+
const active2 = root instanceof ShadowRoot ? root.activeElement : doc.activeElement;
|
|
2025
|
+
const restoreFocus = active2 !== null && pop.contains(active2);
|
|
1984
2026
|
doc.removeEventListener("pointerdown", outside, true);
|
|
1985
2027
|
doc.removeEventListener("keydown", escape, true);
|
|
1986
2028
|
pop.remove();
|
|
1987
2029
|
expanded.setAttribute("aria-expanded", "false");
|
|
1988
2030
|
closeOpen = void 0;
|
|
2031
|
+
if (restoreFocus && anchor.isConnected) anchor.focus({ preventScroll: true });
|
|
1989
2032
|
};
|
|
1990
2033
|
return true;
|
|
1991
2034
|
}
|
|
@@ -2020,12 +2063,12 @@ function openMenu(anchor, entries, label = "") {
|
|
|
2020
2063
|
item.setAttribute("role", entry.checked === void 0 ? "menuitem" : "menuitemcheckbox");
|
|
2021
2064
|
if (entry.checked !== void 0) item.setAttribute("aria-checked", String(entry.checked));
|
|
2022
2065
|
item.disabled = entry.disabled ?? false;
|
|
2023
|
-
const
|
|
2024
|
-
|
|
2025
|
-
if (entry.icon)
|
|
2066
|
+
const icon9 = doc.createElement("span");
|
|
2067
|
+
icon9.className = "ribbon-menu-icon";
|
|
2068
|
+
if (entry.icon) icon9.append(ribbonIcon(doc, entry.icon, 16));
|
|
2026
2069
|
const text3 = doc.createElement("span");
|
|
2027
2070
|
text3.textContent = entry.label;
|
|
2028
|
-
item.append(
|
|
2071
|
+
item.append(icon9, text3);
|
|
2029
2072
|
if (entry.shortcut) {
|
|
2030
2073
|
const keys = doc.createElement("span");
|
|
2031
2074
|
keys.className = "ribbon-menu-shortcut";
|
|
@@ -2065,9 +2108,9 @@ function openList(anchor, items2, current, choose, options = {}) {
|
|
|
2065
2108
|
}
|
|
2066
2109
|
arrowNavigation(pop, '[role="option"]');
|
|
2067
2110
|
if (!mountPopover(anchor, pop, options.expanded ?? anchor)) return;
|
|
2068
|
-
const
|
|
2069
|
-
|
|
2070
|
-
|
|
2111
|
+
const selected2 = pop.querySelector('[aria-selected="true"]') ?? pop.querySelector('[role="option"]');
|
|
2112
|
+
selected2?.scrollIntoView?.({ block: "center" });
|
|
2113
|
+
selected2?.focus({ preventScroll: true });
|
|
2071
2114
|
}
|
|
2072
2115
|
|
|
2073
2116
|
// src/xlsx/ribbon/color-grid.ts
|
|
@@ -3044,9 +3087,9 @@ function openGoTo(ctx) {
|
|
|
3044
3087
|
buttons: [special],
|
|
3045
3088
|
opened: () => reference.focus(),
|
|
3046
3089
|
submit: () => {
|
|
3047
|
-
const
|
|
3048
|
-
if (!
|
|
3049
|
-
selectOn(ctx,
|
|
3090
|
+
const target29 = resolveReference(ctx, reference.value);
|
|
3091
|
+
if (!target29) return invalid(ctx, reference, "Reference is not valid.");
|
|
3092
|
+
selectOn(ctx, target29.sheet, target29.range);
|
|
3050
3093
|
return reference.value.trim();
|
|
3051
3094
|
}
|
|
3052
3095
|
},
|
|
@@ -3828,7 +3871,14 @@ function menuEntries(scope, items2) {
|
|
|
3828
3871
|
...command.shortcut ? { shortcut: command.shortcut } : {},
|
|
3829
3872
|
...checked === void 0 ? {} : { checked },
|
|
3830
3873
|
disabled: !ctx.commands.isEnabled(command.id),
|
|
3831
|
-
run: () =>
|
|
3874
|
+
run: () => {
|
|
3875
|
+
const origin = ctx.root.activeElement;
|
|
3876
|
+
void Promise.resolve(ctx.commands.run(command.id, item.arg)).then(() => {
|
|
3877
|
+
const active2 = ctx.root.activeElement;
|
|
3878
|
+
if (active2 === origin && active2?.closest('[part~="ribbon"]') || !active2 && ctx.host.ownerDocument.activeElement === ctx.host.ownerDocument.body)
|
|
3879
|
+
ctx.grid()?.focus();
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3832
3882
|
});
|
|
3833
3883
|
}
|
|
3834
3884
|
while (entries.length && "separator" in entries[entries.length - 1]) entries.pop();
|
|
@@ -4098,6 +4148,8 @@ var SUPPORTED_FEATURES = [
|
|
|
4098
4148
|
"Conditional formatting display",
|
|
4099
4149
|
"Tables",
|
|
4100
4150
|
"Charts (display and basic editing)",
|
|
4151
|
+
"Sparklines (create, format and clear)",
|
|
4152
|
+
"Worksheet-range PivotTables (one row field, optional column field and one value field)",
|
|
4101
4153
|
"Comments and notes",
|
|
4102
4154
|
"Hyperlinks",
|
|
4103
4155
|
"Data validation",
|
|
@@ -4105,8 +4157,7 @@ var SUPPORTED_FEATURES = [
|
|
|
4105
4157
|
"Freeze panes"
|
|
4106
4158
|
];
|
|
4107
4159
|
var UNSUPPORTED_FEATURES = [
|
|
4108
|
-
"
|
|
4109
|
-
"Creating or editing sparklines (existing ones are shown)",
|
|
4160
|
+
"Advanced PivotTable layouts, grouping and external data sources (preserved)",
|
|
4110
4161
|
"Show Formulas",
|
|
4111
4162
|
"Manual calculation",
|
|
4112
4163
|
"Outline (grouping) for columns",
|
|
@@ -4275,9 +4326,9 @@ function openNameManager(ctx) {
|
|
|
4275
4326
|
const newButton = button(ctx, "New...");
|
|
4276
4327
|
const editButton = button(ctx, "Edit...");
|
|
4277
4328
|
const deleteButton = button(ctx, "Delete");
|
|
4278
|
-
let
|
|
4329
|
+
let selected2;
|
|
4279
4330
|
const sync = () => {
|
|
4280
|
-
const editable = !!
|
|
4331
|
+
const editable = !!selected2 && !ctx.readOnly();
|
|
4281
4332
|
editButton.disabled = !editable;
|
|
4282
4333
|
deleteButton.disabled = !editable;
|
|
4283
4334
|
newButton.disabled = ctx.readOnly();
|
|
@@ -4294,7 +4345,7 @@ function openNameManager(ctx) {
|
|
|
4294
4345
|
}
|
|
4295
4346
|
const body = table.createTBody();
|
|
4296
4347
|
const names2 = visibleNames(workbook?.definedNames ?? []);
|
|
4297
|
-
if (
|
|
4348
|
+
if (selected2 && !names2.includes(selected2)) selected2 = void 0;
|
|
4298
4349
|
for (const name of names2) {
|
|
4299
4350
|
const value = nameValue(ctx, name);
|
|
4300
4351
|
const kind = filter.value;
|
|
@@ -4305,12 +4356,12 @@ function openNameManager(ctx) {
|
|
|
4305
4356
|
const tr = body.insertRow();
|
|
4306
4357
|
tr.tabIndex = 0;
|
|
4307
4358
|
tr.dataset.name = name.name;
|
|
4308
|
-
if (name ===
|
|
4359
|
+
if (name === selected2) tr.setAttribute("aria-selected", "true");
|
|
4309
4360
|
const scope = name.localSheet === void 0 ? ctx.t("Workbook") : workbook?.sheets[name.localSheet]?.name ?? "";
|
|
4310
4361
|
for (const text3 of [name.name, value.text, `=${name.formula}`, scope, name.comment ?? ""])
|
|
4311
4362
|
tr.insertCell().textContent = text3;
|
|
4312
4363
|
const pick = () => {
|
|
4313
|
-
|
|
4364
|
+
selected2 = name;
|
|
4314
4365
|
for (const other of body.rows) other.removeAttribute("aria-selected");
|
|
4315
4366
|
tr.setAttribute("aria-selected", "true");
|
|
4316
4367
|
sync();
|
|
@@ -4334,17 +4385,17 @@ function openNameManager(ctx) {
|
|
|
4334
4385
|
render3();
|
|
4335
4386
|
});
|
|
4336
4387
|
editButton.addEventListener("click", async () => {
|
|
4337
|
-
if (!
|
|
4338
|
-
const props2 = { name:
|
|
4339
|
-
if (
|
|
4388
|
+
if (!selected2) return;
|
|
4389
|
+
const props2 = { name: selected2.name };
|
|
4390
|
+
if (selected2.localSheet !== void 0) props2.localSheet = selected2.localSheet;
|
|
4340
4391
|
await ctx.dialogs.open("define-name", props2);
|
|
4341
4392
|
render3();
|
|
4342
4393
|
});
|
|
4343
4394
|
deleteButton.addEventListener("click", () => {
|
|
4344
4395
|
const session = ctx.session();
|
|
4345
|
-
if (!
|
|
4346
|
-
session.deleteDefinedName(
|
|
4347
|
-
|
|
4396
|
+
if (!selected2 || !session || ctx.readOnly()) return;
|
|
4397
|
+
session.deleteDefinedName(selected2.name, selected2.localSheet);
|
|
4398
|
+
selected2 = void 0;
|
|
4348
4399
|
render3();
|
|
4349
4400
|
});
|
|
4350
4401
|
render3();
|
|
@@ -5160,7 +5211,7 @@ function cfManagerDialog(ctx) {
|
|
|
5160
5211
|
const t = target(ctx);
|
|
5161
5212
|
if (!t) return Promise.resolve(void 0);
|
|
5162
5213
|
let entries = stageRules(t.ws.conditionalFormats);
|
|
5163
|
-
let
|
|
5214
|
+
let selected2 = entries.length ? 0 : -1;
|
|
5164
5215
|
const scope = select(
|
|
5165
5216
|
ctx,
|
|
5166
5217
|
[
|
|
@@ -5191,15 +5242,15 @@ function cfManagerDialog(ctx) {
|
|
|
5191
5242
|
const entry = entries[i];
|
|
5192
5243
|
const tr = el(ctx, "tr");
|
|
5193
5244
|
tr.dataset.index = String(i);
|
|
5194
|
-
tr.setAttribute("aria-selected", String(i ===
|
|
5245
|
+
tr.setAttribute("aria-selected", String(i === selected2));
|
|
5195
5246
|
tr.addEventListener("click", (event) => {
|
|
5196
|
-
if (
|
|
5197
|
-
|
|
5247
|
+
if (selected2 === i || event.target.tagName === "INPUT") {
|
|
5248
|
+
selected2 = i;
|
|
5198
5249
|
for (const other of table.querySelectorAll("tr[data-index]"))
|
|
5199
5250
|
other.setAttribute("aria-selected", String(other === tr));
|
|
5200
5251
|
return;
|
|
5201
5252
|
}
|
|
5202
|
-
|
|
5253
|
+
selected2 = i;
|
|
5203
5254
|
render3();
|
|
5204
5255
|
});
|
|
5205
5256
|
const desc = el(ctx, "td");
|
|
@@ -5250,11 +5301,11 @@ function cfManagerDialog(ctx) {
|
|
|
5250
5301
|
};
|
|
5251
5302
|
const move = (delta) => {
|
|
5252
5303
|
if (!commitRanges()) return;
|
|
5253
|
-
const to =
|
|
5254
|
-
if (
|
|
5255
|
-
const [entry] = entries.splice(
|
|
5304
|
+
const to = selected2 + delta;
|
|
5305
|
+
if (selected2 < 0 || to < 0 || to >= entries.length) return;
|
|
5306
|
+
const [entry] = entries.splice(selected2, 1);
|
|
5256
5307
|
if (entry) entries.splice(to, 0, entry);
|
|
5257
|
-
|
|
5308
|
+
selected2 = to;
|
|
5258
5309
|
render3();
|
|
5259
5310
|
};
|
|
5260
5311
|
const newRule = button(ctx, "New Rule...");
|
|
@@ -5268,28 +5319,28 @@ function cfManagerDialog(ctx) {
|
|
|
5268
5319
|
const result = await editRuleDialog(ctx);
|
|
5269
5320
|
if (!result) return;
|
|
5270
5321
|
entries.unshift(result);
|
|
5271
|
-
|
|
5322
|
+
selected2 = 0;
|
|
5272
5323
|
render3();
|
|
5273
5324
|
});
|
|
5274
5325
|
editRule.addEventListener("click", async () => {
|
|
5275
5326
|
if (!commitRanges()) return;
|
|
5276
|
-
const entry = entries[
|
|
5327
|
+
const entry = entries[selected2];
|
|
5277
5328
|
if (!entry) return;
|
|
5278
5329
|
const result = await editRuleDialog(ctx, entry);
|
|
5279
|
-
if (result) entries[
|
|
5330
|
+
if (result) entries[selected2] = result;
|
|
5280
5331
|
render3();
|
|
5281
5332
|
});
|
|
5282
5333
|
deleteRule.addEventListener("click", () => {
|
|
5283
|
-
if (
|
|
5284
|
-
entries.splice(
|
|
5285
|
-
|
|
5334
|
+
if (selected2 < 0) return;
|
|
5335
|
+
entries.splice(selected2, 1);
|
|
5336
|
+
selected2 = Math.min(selected2, entries.length - 1);
|
|
5286
5337
|
render3();
|
|
5287
5338
|
});
|
|
5288
5339
|
duplicate.addEventListener("click", () => {
|
|
5289
5340
|
if (!commitRanges()) return;
|
|
5290
|
-
const entry = entries[
|
|
5341
|
+
const entry = entries[selected2];
|
|
5291
5342
|
if (!entry) return;
|
|
5292
|
-
entries.splice(
|
|
5343
|
+
entries.splice(selected2, 0, structuredClone(entry));
|
|
5293
5344
|
render3();
|
|
5294
5345
|
});
|
|
5295
5346
|
up.addEventListener("click", () => move(-1));
|
|
@@ -5297,11 +5348,11 @@ function cfManagerDialog(ctx) {
|
|
|
5297
5348
|
table.addEventListener("keydown", (event) => {
|
|
5298
5349
|
if (event.target !== table) return;
|
|
5299
5350
|
const list = visible();
|
|
5300
|
-
const at = list.indexOf(
|
|
5351
|
+
const at = list.indexOf(selected2);
|
|
5301
5352
|
const next = event.key === "ArrowDown" ? list[at + 1] : event.key === "ArrowUp" ? list[at - 1] : void 0;
|
|
5302
5353
|
if (next === void 0) return;
|
|
5303
5354
|
event.preventDefault();
|
|
5304
|
-
|
|
5355
|
+
selected2 = next;
|
|
5305
5356
|
render3();
|
|
5306
5357
|
});
|
|
5307
5358
|
scope.addEventListener("change", render3);
|
|
@@ -5852,7 +5903,7 @@ function sortDialog(ctx) {
|
|
|
5852
5903
|
const header = checkbox(ctx, "My data has headers", guessHeader(t.ws, region));
|
|
5853
5904
|
const levels = [];
|
|
5854
5905
|
const list = el(ctx, "div", "xve-sort-levels");
|
|
5855
|
-
let
|
|
5906
|
+
let selected2 = 0;
|
|
5856
5907
|
const columnOptions = () => {
|
|
5857
5908
|
const out = [];
|
|
5858
5909
|
for (let col = region.start.col; col <= region.end.col; col++) {
|
|
@@ -5865,7 +5916,7 @@ function sortDialog(ctx) {
|
|
|
5865
5916
|
const render3 = () => {
|
|
5866
5917
|
list.replaceChildren(
|
|
5867
5918
|
...levels.map((level, i) => {
|
|
5868
|
-
level.element.setAttribute("aria-selected", String(i ===
|
|
5919
|
+
level.element.setAttribute("aria-selected", String(i === selected2));
|
|
5869
5920
|
const caption = level.element.querySelector(".xve-sort-caption");
|
|
5870
5921
|
if (caption) caption.textContent = ctx.t(i === 0 ? "Sort by" : "Then by");
|
|
5871
5922
|
return level.element;
|
|
@@ -5890,11 +5941,11 @@ function sortDialog(ctx) {
|
|
|
5890
5941
|
const element = row(ctx, caption, column, on, order);
|
|
5891
5942
|
const level = { element, column, order };
|
|
5892
5943
|
element.addEventListener("focusin", () => {
|
|
5893
|
-
|
|
5944
|
+
selected2 = levels.indexOf(level);
|
|
5894
5945
|
render3();
|
|
5895
5946
|
});
|
|
5896
5947
|
levels.splice(at, 0, level);
|
|
5897
|
-
|
|
5948
|
+
selected2 = at;
|
|
5898
5949
|
render3();
|
|
5899
5950
|
};
|
|
5900
5951
|
addLevel(
|
|
@@ -5922,20 +5973,20 @@ function sortDialog(ctx) {
|
|
|
5922
5973
|
});
|
|
5923
5974
|
remove.addEventListener("click", () => {
|
|
5924
5975
|
if (levels.length <= 1) return;
|
|
5925
|
-
levels.splice(
|
|
5926
|
-
|
|
5976
|
+
levels.splice(selected2, 1);
|
|
5977
|
+
selected2 = Math.max(0, Math.min(selected2, levels.length - 1));
|
|
5927
5978
|
render3();
|
|
5928
5979
|
});
|
|
5929
5980
|
copy.addEventListener("click", () => {
|
|
5930
|
-
const level = levels[
|
|
5931
|
-
if (level) addLevel(Number(level.column.value), level.order.value === "desc",
|
|
5981
|
+
const level = levels[selected2];
|
|
5982
|
+
if (level) addLevel(Number(level.column.value), level.order.value === "desc", selected2 + 1);
|
|
5932
5983
|
});
|
|
5933
5984
|
const move = (delta) => {
|
|
5934
|
-
const to =
|
|
5985
|
+
const to = selected2 + delta;
|
|
5935
5986
|
if (to < 0 || to >= levels.length) return;
|
|
5936
|
-
const [level] = levels.splice(
|
|
5987
|
+
const [level] = levels.splice(selected2, 1);
|
|
5937
5988
|
if (level) levels.splice(to, 0, level);
|
|
5938
|
-
|
|
5989
|
+
selected2 = to;
|
|
5939
5990
|
render3();
|
|
5940
5991
|
};
|
|
5941
5992
|
up.addEventListener("click", () => move(-1));
|
|
@@ -6730,6 +6781,115 @@ function openMoveCopySheet(ctx) {
|
|
|
6730
6781
|
}
|
|
6731
6782
|
});
|
|
6732
6783
|
}
|
|
6784
|
+
|
|
6785
|
+
// src/xlsx/dialogs/page-header.ts
|
|
6786
|
+
function headerTab(ctx, setup) {
|
|
6787
|
+
const changes = /* @__PURE__ */ new Map();
|
|
6788
|
+
const fields = [
|
|
6789
|
+
["header", "Header:"],
|
|
6790
|
+
["footer", "Footer:"],
|
|
6791
|
+
["firstHeader", "First Page Header:"],
|
|
6792
|
+
["firstFooter", "First Page Footer:"],
|
|
6793
|
+
["evenHeader", "Even Page Header:"],
|
|
6794
|
+
["evenFooter", "Even Page Footer:"]
|
|
6795
|
+
];
|
|
6796
|
+
let active2;
|
|
6797
|
+
const inputs = fields.map(([key, label]) => {
|
|
6798
|
+
const original = setup[key] ?? "";
|
|
6799
|
+
const shown2 = original.startsWith("&C") && !/&[LR]/.test(original.slice(2)) ? original.slice(2) : original;
|
|
6800
|
+
const input = textArea(ctx, shown2, 2);
|
|
6801
|
+
const read = () => input.value ? /&[LCR]/.test(input.value) ? input.value : `&C${input.value}` : void 0;
|
|
6802
|
+
input.addEventListener("input", () => changes.set(key, read));
|
|
6803
|
+
input.addEventListener("change", () => changes.set(key, read));
|
|
6804
|
+
input.addEventListener("focus", () => {
|
|
6805
|
+
active2 = input;
|
|
6806
|
+
});
|
|
6807
|
+
return { key, input, field: field(ctx, label, input) };
|
|
6808
|
+
});
|
|
6809
|
+
active2 = inputs[0].input;
|
|
6810
|
+
const flags = [
|
|
6811
|
+
["differentFirst", "Different first page", false],
|
|
6812
|
+
["differentOddEven", "Different odd and even pages", false],
|
|
6813
|
+
["scaleWithDoc", "Scale header and footer with document", true],
|
|
6814
|
+
["alignWithMargins", "Align header and footer with margins", true]
|
|
6815
|
+
];
|
|
6816
|
+
const checks = flags.map(([key, label, fallback]) => {
|
|
6817
|
+
const check = checkbox(ctx, label, setup[key] ?? fallback);
|
|
6818
|
+
check.input.addEventListener("change", () => {
|
|
6819
|
+
changes.set(key, () => check.input.checked);
|
|
6820
|
+
update();
|
|
6821
|
+
});
|
|
6822
|
+
return { key, ...check };
|
|
6823
|
+
});
|
|
6824
|
+
const update = () => {
|
|
6825
|
+
for (const input of inputs)
|
|
6826
|
+
if (input.key.startsWith("first") || input.key.startsWith("even"))
|
|
6827
|
+
input.input.disabled = !checks.find(
|
|
6828
|
+
(check) => check.key === (input.key.startsWith("first") ? "differentFirst" : "differentOddEven")
|
|
6829
|
+
).input.checked;
|
|
6830
|
+
};
|
|
6831
|
+
update();
|
|
6832
|
+
const insert = select(
|
|
6833
|
+
ctx,
|
|
6834
|
+
[
|
|
6835
|
+
["", "Insert Field"],
|
|
6836
|
+
["&P", "Page Number"],
|
|
6837
|
+
["&N", "Total Pages"],
|
|
6838
|
+
["&A", "Sheet Name"],
|
|
6839
|
+
["&F", "File Name"],
|
|
6840
|
+
["&D", "Date"],
|
|
6841
|
+
["&T", "Time"]
|
|
6842
|
+
],
|
|
6843
|
+
""
|
|
6844
|
+
);
|
|
6845
|
+
const insertCode = (control, wrap = false) => {
|
|
6846
|
+
if (!control.value || active2.disabled) return;
|
|
6847
|
+
const start = active2.selectionStart;
|
|
6848
|
+
const selected2 = wrap ? active2.value.slice(start, active2.selectionEnd) : "";
|
|
6849
|
+
active2.setRangeText(
|
|
6850
|
+
control.value + selected2 + (selected2 ? control.value : ""),
|
|
6851
|
+
start,
|
|
6852
|
+
active2.selectionEnd,
|
|
6853
|
+
"end"
|
|
6854
|
+
);
|
|
6855
|
+
active2.dispatchEvent(new ctx.host.ownerDocument.defaultView.Event("input", { bubbles: true }));
|
|
6856
|
+
control.value = "";
|
|
6857
|
+
active2.focus();
|
|
6858
|
+
};
|
|
6859
|
+
insert.addEventListener("change", () => insertCode(insert));
|
|
6860
|
+
const formatting = select(
|
|
6861
|
+
ctx,
|
|
6862
|
+
[
|
|
6863
|
+
["", "Insert Formatting"],
|
|
6864
|
+
["&B", "Bold"],
|
|
6865
|
+
["&I", "Italic"],
|
|
6866
|
+
["&U", "Underline"],
|
|
6867
|
+
["&S", "Strikethrough"]
|
|
6868
|
+
],
|
|
6869
|
+
""
|
|
6870
|
+
);
|
|
6871
|
+
formatting.addEventListener("change", () => insertCode(formatting, true));
|
|
6872
|
+
return {
|
|
6873
|
+
panel: panel(
|
|
6874
|
+
ctx,
|
|
6875
|
+
row(ctx, field(ctx, "Insert Field", insert)),
|
|
6876
|
+
row(ctx, field(ctx, "Insert Formatting", formatting)),
|
|
6877
|
+
text(
|
|
6878
|
+
ctx,
|
|
6879
|
+
'Formatting: &B bold, &I italic, &U underline, &S strike, &18 font size, &KFF0000 RGB color, &"Arial,Regular" font.'
|
|
6880
|
+
),
|
|
6881
|
+
...checks.map((check) => check.wrapper),
|
|
6882
|
+
text(
|
|
6883
|
+
ctx,
|
|
6884
|
+
"Use &L, &C and &R for sections. Fields: &P page, &N total pages, &A sheet, &F file, &D date, &T time. Use && for an ampersand. Unsupported formatting codes are preserved."
|
|
6885
|
+
),
|
|
6886
|
+
...inputs.map((input) => input.field)
|
|
6887
|
+
),
|
|
6888
|
+
read: () => Object.fromEntries([...changes].map(([key, read]) => [key, read()]))
|
|
6889
|
+
};
|
|
6890
|
+
}
|
|
6891
|
+
|
|
6892
|
+
// src/xlsx/dialogs/page-setup-tabs.ts
|
|
6733
6893
|
var DEFAULT_MARGINS = {
|
|
6734
6894
|
top: 0.75,
|
|
6735
6895
|
bottom: 0.75,
|
|
@@ -6738,8 +6898,13 @@ var DEFAULT_MARGINS = {
|
|
|
6738
6898
|
header: 0.3,
|
|
6739
6899
|
footer: 0.3
|
|
6740
6900
|
};
|
|
6741
|
-
var plainHeader = (value) => (value ?? "").replace(/&[LCR]/g, "");
|
|
6742
6901
|
function pageTab(ctx, setup) {
|
|
6902
|
+
const firstNumber = numberInput(ctx, setup.firstPageNumber ?? 1, 0, 32767);
|
|
6903
|
+
const useFirstNumber = checkbox(
|
|
6904
|
+
ctx,
|
|
6905
|
+
"Use first page number",
|
|
6906
|
+
setup.firstPageNumber !== void 0
|
|
6907
|
+
);
|
|
6743
6908
|
const orientation = radios(
|
|
6744
6909
|
ctx,
|
|
6745
6910
|
"Orientation",
|
|
@@ -6778,13 +6943,18 @@ function pageTab(ctx, setup) {
|
|
|
6778
6943
|
field(ctx, "Pages wide", wide),
|
|
6779
6944
|
field(ctx, "Pages tall", tall)
|
|
6780
6945
|
),
|
|
6781
|
-
field(ctx, "Paper size", paper)
|
|
6946
|
+
field(ctx, "Paper size", paper),
|
|
6947
|
+
useFirstNumber.wrapper,
|
|
6948
|
+
field(ctx, "First page number", firstNumber)
|
|
6782
6949
|
),
|
|
6783
6950
|
read() {
|
|
6784
6951
|
const out = {
|
|
6952
|
+
firstPageNumber: useFirstNumber.input.checked ? Number(firstNumber.value) : void 0,
|
|
6785
6953
|
orientation: orientation.get(),
|
|
6786
6954
|
paperSize: Number(paper.value)
|
|
6787
6955
|
};
|
|
6956
|
+
if (useFirstNumber.input.checked && (!Number.isInteger(out.firstPageNumber) || out.firstPageNumber < 0 || out.firstPageNumber > 32767))
|
|
6957
|
+
return "Enter a first page number between 0 and 32767.";
|
|
6788
6958
|
if (scaling.get() === "fit") {
|
|
6789
6959
|
const w = Number(wide.value);
|
|
6790
6960
|
const h2 = Number(tall.value);
|
|
@@ -6845,26 +7015,33 @@ function marginsTab(ctx, setup, ws) {
|
|
|
6845
7015
|
}
|
|
6846
7016
|
};
|
|
6847
7017
|
}
|
|
6848
|
-
function headerTab(ctx, setup) {
|
|
6849
|
-
const header = textInput(ctx, plainHeader(setup.header));
|
|
6850
|
-
const footer = textInput(ctx, plainHeader(setup.footer));
|
|
6851
|
-
return {
|
|
6852
|
-
panel: panel(
|
|
6853
|
-
ctx,
|
|
6854
|
-
field(ctx, "Header:", header),
|
|
6855
|
-
field(ctx, "Footer:", footer),
|
|
6856
|
-
text(
|
|
6857
|
-
ctx,
|
|
6858
|
-
"The text is centered; left and right sections, fields and fonts are not supported yet."
|
|
6859
|
-
)
|
|
6860
|
-
),
|
|
6861
|
-
read: () => ({
|
|
6862
|
-
header: header.value ? `&C${header.value}` : void 0,
|
|
6863
|
-
footer: footer.value ? `&C${footer.value}` : void 0
|
|
6864
|
-
})
|
|
6865
|
-
};
|
|
6866
|
-
}
|
|
6867
7018
|
function sheetTab(ctx, setup, ws) {
|
|
7019
|
+
const existingTitles = printTitles(ctx.workbook(), ctx.activeSheet());
|
|
7020
|
+
const repeatRows = textInput(
|
|
7021
|
+
ctx,
|
|
7022
|
+
existingTitles.rows ? formatPrintTitleSpan(existingTitles.rows, "row") : ""
|
|
7023
|
+
);
|
|
7024
|
+
const repeatColumns = textInput(
|
|
7025
|
+
ctx,
|
|
7026
|
+
existingTitles.columns ? formatPrintTitleSpan(existingTitles.columns, "col") : ""
|
|
7027
|
+
);
|
|
7028
|
+
let titlesChanged = false;
|
|
7029
|
+
for (const input of [repeatRows, repeatColumns]) {
|
|
7030
|
+
input.addEventListener("input", () => {
|
|
7031
|
+
titlesChanged = true;
|
|
7032
|
+
});
|
|
7033
|
+
input.addEventListener("change", () => {
|
|
7034
|
+
titlesChanged = true;
|
|
7035
|
+
});
|
|
7036
|
+
}
|
|
7037
|
+
const order = select(
|
|
7038
|
+
ctx,
|
|
7039
|
+
[
|
|
7040
|
+
["downThenOver", "Down, then over"],
|
|
7041
|
+
["overThenDown", "Over, then down"]
|
|
7042
|
+
],
|
|
7043
|
+
setup.pageOrder ?? "downThenOver"
|
|
7044
|
+
);
|
|
6868
7045
|
const area = textInput(ctx, setup.printArea ? formatRange(setup.printArea) : "");
|
|
6869
7046
|
const gridlines = checkbox(ctx, "Gridlines", !!ws.printOptions?.gridLines);
|
|
6870
7047
|
const headings = checkbox(ctx, "Row and column headings", !!ws.printOptions?.headings);
|
|
@@ -6872,16 +7049,40 @@ function sheetTab(ctx, setup, ws) {
|
|
|
6872
7049
|
panel: panel(
|
|
6873
7050
|
ctx,
|
|
6874
7051
|
field(ctx, "Print area", area),
|
|
7052
|
+
field(ctx, "Rows to repeat at top", repeatRows),
|
|
7053
|
+
field(ctx, "Columns to repeat at left", repeatColumns),
|
|
7054
|
+
...existingTitles.unsupported ? [
|
|
7055
|
+
text(
|
|
7056
|
+
ctx,
|
|
7057
|
+
"Existing print titles are unsupported. Changing a title range replaces them; leaving the fields unchanged preserves them."
|
|
7058
|
+
)
|
|
7059
|
+
] : [],
|
|
7060
|
+
field(ctx, "Page order", order),
|
|
6875
7061
|
fieldset(ctx, "Print", gridlines.wrapper, headings.wrapper)
|
|
6876
7062
|
),
|
|
6877
7063
|
gridlines: () => gridlines.input.checked,
|
|
7064
|
+
titles: () => {
|
|
7065
|
+
if (!titlesChanged) return void 0;
|
|
7066
|
+
try {
|
|
7067
|
+
return {
|
|
7068
|
+
rows: parsePrintTitleSpan(repeatRows.value, "row"),
|
|
7069
|
+
columns: parsePrintTitleSpan(repeatColumns.value, "col")
|
|
7070
|
+
};
|
|
7071
|
+
} catch {
|
|
7072
|
+
return "Print titles must be whole rows or whole columns.";
|
|
7073
|
+
}
|
|
7074
|
+
},
|
|
6878
7075
|
headings: () => headings.input.checked,
|
|
6879
7076
|
read() {
|
|
6880
7077
|
const value = area.value.trim().replace(/^=/, "").replace(/^.*!/, "").replace(/\$/g, "");
|
|
6881
|
-
if (!value)
|
|
7078
|
+
if (!value)
|
|
7079
|
+
return {
|
|
7080
|
+
printArea: void 0,
|
|
7081
|
+
pageOrder: order.value
|
|
7082
|
+
};
|
|
6882
7083
|
const range2 = parseRange(value);
|
|
6883
7084
|
if (!range2) return "The reference is not valid.";
|
|
6884
|
-
return { printArea: range2 };
|
|
7085
|
+
return { printArea: range2, pageOrder: order.value };
|
|
6885
7086
|
}
|
|
6886
7087
|
};
|
|
6887
7088
|
}
|
|
@@ -6927,7 +7128,14 @@ function openPageSetup(ctx, props2 = {}) {
|
|
|
6927
7128
|
}
|
|
6928
7129
|
Object.assign(patch, result);
|
|
6929
7130
|
}
|
|
7131
|
+
const titles = sheet.titles();
|
|
7132
|
+
if (typeof titles === "string") {
|
|
7133
|
+
view.show("sheet");
|
|
7134
|
+
ctx.toast(ctx.t(titles), "warning");
|
|
7135
|
+
return void 0;
|
|
7136
|
+
}
|
|
6930
7137
|
t.session.batch("Page Setup", () => {
|
|
7138
|
+
if (titles) t.session.setPrintTitles(t.sheet, titles);
|
|
6931
7139
|
t.session.setPageSetup(t.sheet, patch);
|
|
6932
7140
|
const named = t.workbook.definedNames.some(
|
|
6933
7141
|
(n) => n.name === "_xlnm.Print_Area" && n.localSheet === t.sheet
|
|
@@ -7726,11 +7934,446 @@ function openZoom(ctx) {
|
|
|
7726
7934
|
}
|
|
7727
7935
|
});
|
|
7728
7936
|
}
|
|
7937
|
+
var TYPES3 = [
|
|
7938
|
+
["line", "Line"],
|
|
7939
|
+
["column", "Column"],
|
|
7940
|
+
["stacked", "Win/Loss"]
|
|
7941
|
+
];
|
|
7942
|
+
function openCreateSparklines(ctx, type = "line") {
|
|
7943
|
+
const t = target(ctx);
|
|
7944
|
+
if (!t) return Promise.resolve(void 0);
|
|
7945
|
+
const data = textInput(ctx);
|
|
7946
|
+
const locations = textInput(ctx, formatRange(t.range));
|
|
7947
|
+
const kind = select(ctx, TYPES3, type);
|
|
7948
|
+
const dates = textInput(ctx);
|
|
7949
|
+
return showDialog(ctx, {
|
|
7950
|
+
name: "create-sparklines",
|
|
7951
|
+
heading: "Create Sparklines",
|
|
7952
|
+
body: [
|
|
7953
|
+
field(ctx, "Data Range:", data),
|
|
7954
|
+
field(ctx, "Location Range:", locations),
|
|
7955
|
+
field(ctx, "Sparkline Type:", kind),
|
|
7956
|
+
field(ctx, "Date Range (optional):", dates)
|
|
7957
|
+
],
|
|
7958
|
+
opened: () => data.focus(),
|
|
7959
|
+
submit: () => {
|
|
7960
|
+
const range2 = parseRange(locations.value.trim().replace(/^=/, "").replaceAll("$", ""));
|
|
7961
|
+
if (!range2) throw new Error("The reference is not valid.");
|
|
7962
|
+
t.session.batch("Create sparklines", () => {
|
|
7963
|
+
t.session.createSparklineGroup(t.sheet, data.value, range2, {
|
|
7964
|
+
type: kind.value
|
|
7965
|
+
});
|
|
7966
|
+
if (dates.value.trim()) t.session.setSparklineDateRange(t.sheet, [range2], dates.value);
|
|
7967
|
+
});
|
|
7968
|
+
ctx.selection.set({ ranges: [range2], active: range2.start, anchor: range2.start });
|
|
7969
|
+
return true;
|
|
7970
|
+
}
|
|
7971
|
+
});
|
|
7972
|
+
}
|
|
7973
|
+
function openSparklineSettings(ctx) {
|
|
7974
|
+
const t = target(ctx);
|
|
7975
|
+
const groups = t ? selectedSparklineGroups(t.ws, t.ranges) : [];
|
|
7976
|
+
const group = groups[0];
|
|
7977
|
+
if (!t || !group) return Promise.resolve(void 0);
|
|
7978
|
+
const dates = textInput(ctx, group.dateAxis ? group.dateFormula ?? "" : "");
|
|
7979
|
+
if (groups.some(
|
|
7980
|
+
(entry) => entry.dateAxis !== group.dateAxis || entry.dateFormula !== group.dateFormula
|
|
7981
|
+
)) {
|
|
7982
|
+
dates.value = "";
|
|
7983
|
+
dates.placeholder = ctx.t("Mixed");
|
|
7984
|
+
}
|
|
7985
|
+
let datesChanged = false;
|
|
7986
|
+
dates.addEventListener("input", () => {
|
|
7987
|
+
datesChanged = true;
|
|
7988
|
+
});
|
|
7989
|
+
dates.addEventListener("change", () => {
|
|
7990
|
+
datesChanged = true;
|
|
7991
|
+
});
|
|
7992
|
+
const changes = /* @__PURE__ */ new Map();
|
|
7993
|
+
const track = (input, key, read) => {
|
|
7994
|
+
const changed = () => {
|
|
7995
|
+
if (input.dataset.mixed && input.value === "") changes.delete(key);
|
|
7996
|
+
else changes.set(key, read);
|
|
7997
|
+
};
|
|
7998
|
+
input.addEventListener("input", changed);
|
|
7999
|
+
input.addEventListener("change", changed);
|
|
8000
|
+
};
|
|
8001
|
+
const mixed = (input, key) => {
|
|
8002
|
+
if (!groups.some((entry) => entry[key] !== group[key])) return;
|
|
8003
|
+
input.dataset.mixed = "true";
|
|
8004
|
+
if (input instanceof ctx.host.ownerDocument.defaultView.HTMLSelectElement) {
|
|
8005
|
+
const option = ctx.host.ownerDocument.createElement("option");
|
|
8006
|
+
option.value = "";
|
|
8007
|
+
option.textContent = ctx.t("Mixed");
|
|
8008
|
+
input.prepend(option);
|
|
8009
|
+
input.value = "";
|
|
8010
|
+
} else if (input.type === "checkbox") {
|
|
8011
|
+
input.indeterminate = true;
|
|
8012
|
+
input.checked = false;
|
|
8013
|
+
} else {
|
|
8014
|
+
input.value = "";
|
|
8015
|
+
input.placeholder = ctx.t("Mixed");
|
|
8016
|
+
}
|
|
8017
|
+
};
|
|
8018
|
+
const kind = select(ctx, TYPES3, group.type);
|
|
8019
|
+
const width = numberInput(ctx, group.lineWeight, 0, 1584, 0.25);
|
|
8020
|
+
const empty = select(
|
|
8021
|
+
ctx,
|
|
8022
|
+
[
|
|
8023
|
+
["gap", "Gaps"],
|
|
8024
|
+
["zero", "Zero"],
|
|
8025
|
+
["span", "Connect data points"]
|
|
8026
|
+
],
|
|
8027
|
+
group.displayEmptyCellsAs
|
|
8028
|
+
);
|
|
8029
|
+
const markers = [
|
|
8030
|
+
["markers", "Markers"],
|
|
8031
|
+
["high", "High Point"],
|
|
8032
|
+
["low", "Low Point"],
|
|
8033
|
+
["first", "First Point"],
|
|
8034
|
+
["last", "Last Point"],
|
|
8035
|
+
["negative", "Negative Points"]
|
|
8036
|
+
];
|
|
8037
|
+
const checks = markers.map(([key, label]) => ({ key, ...checkbox(ctx, label, group[key]) }));
|
|
8038
|
+
const hidden = checkbox(ctx, "Show data in hidden rows and columns", group.displayHidden);
|
|
8039
|
+
const axis = checkbox(ctx, "Show horizontal axis", group.displayXAxis);
|
|
8040
|
+
const rtl = checkbox(ctx, "Plot right to left", group.rightToLeft);
|
|
8041
|
+
const scales = [
|
|
8042
|
+
["individual", "Individual"],
|
|
8043
|
+
["group", "Same for all sparklines"],
|
|
8044
|
+
["custom", "Custom"]
|
|
8045
|
+
];
|
|
8046
|
+
const minType = select(ctx, scales, group.minAxisType);
|
|
8047
|
+
const maxType = select(ctx, scales, group.maxAxisType);
|
|
8048
|
+
const min = numberInput(ctx, group.manualMin ?? 0, -1e308, 1e308, 0.1);
|
|
8049
|
+
const max = numberInput(ctx, group.manualMax ?? 1, -1e308, 1e308, 0.1);
|
|
8050
|
+
const updateLimits = () => {
|
|
8051
|
+
min.disabled = minType.value !== "custom";
|
|
8052
|
+
max.disabled = maxType.value !== "custom";
|
|
8053
|
+
};
|
|
8054
|
+
minType.addEventListener("change", updateLimits);
|
|
8055
|
+
maxType.addEventListener("change", updateLimits);
|
|
8056
|
+
updateLimits();
|
|
8057
|
+
const color = textInput(ctx, resolveColor(group.colorSeries, t.workbook.theme));
|
|
8058
|
+
color.type = "color";
|
|
8059
|
+
const negative = textInput(ctx, resolveColor(group.colorNegative, t.workbook.theme));
|
|
8060
|
+
negative.type = "color";
|
|
8061
|
+
const mixedColors = groups.some(
|
|
8062
|
+
(entry) => (resolveColor(entry.colorSeries, t.workbook.theme) ?? "#000000").toLowerCase() !== color.value.toLowerCase() || (resolveColor(entry.colorNegative, t.workbook.theme) ?? "#000000").toLowerCase() !== negative.value.toLowerCase()
|
|
8063
|
+
);
|
|
8064
|
+
for (const [input, key] of [
|
|
8065
|
+
[kind, "type"],
|
|
8066
|
+
[width, "lineWeight"],
|
|
8067
|
+
[empty, "displayEmptyCellsAs"],
|
|
8068
|
+
[hidden.input, "displayHidden"],
|
|
8069
|
+
[axis.input, "displayXAxis"],
|
|
8070
|
+
[rtl.input, "rightToLeft"],
|
|
8071
|
+
[minType, "minAxisType"],
|
|
8072
|
+
[maxType, "maxAxisType"],
|
|
8073
|
+
[min, "manualMin"],
|
|
8074
|
+
[max, "manualMax"]
|
|
8075
|
+
])
|
|
8076
|
+
mixed(input, key);
|
|
8077
|
+
for (const check of checks) {
|
|
8078
|
+
mixed(check.input, check.key);
|
|
8079
|
+
track(check.input, check.key, () => ({ [check.key]: check.input.checked }));
|
|
8080
|
+
}
|
|
8081
|
+
track(kind, "type", () => ({ type: kind.value }));
|
|
8082
|
+
track(width, "lineWeight", () => ({ lineWeight: Number(width.value) }));
|
|
8083
|
+
track(empty, "displayEmptyCellsAs", () => ({
|
|
8084
|
+
displayEmptyCellsAs: empty.value
|
|
8085
|
+
}));
|
|
8086
|
+
track(hidden.input, "displayHidden", () => ({ displayHidden: hidden.input.checked }));
|
|
8087
|
+
track(axis.input, "displayXAxis", () => ({ displayXAxis: axis.input.checked }));
|
|
8088
|
+
track(rtl.input, "rightToLeft", () => ({ rightToLeft: rtl.input.checked }));
|
|
8089
|
+
track(minType, "minAxisType", () => ({
|
|
8090
|
+
minAxisType: minType.value,
|
|
8091
|
+
...minType.value === "custom" ? { manualMin: Number(min.value) } : {}
|
|
8092
|
+
}));
|
|
8093
|
+
track(maxType, "maxAxisType", () => ({
|
|
8094
|
+
maxAxisType: maxType.value,
|
|
8095
|
+
...maxType.value === "custom" ? { manualMax: Number(max.value) } : {}
|
|
8096
|
+
}));
|
|
8097
|
+
track(min, "manualMin", () => ({ manualMin: Number(min.value) }));
|
|
8098
|
+
track(max, "manualMax", () => ({ manualMax: Number(max.value) }));
|
|
8099
|
+
track(color, "colorSeries", () => ({ colorSeries: { rgb: color.value.slice(1) } }));
|
|
8100
|
+
track(negative, "colorNegative", () => ({ colorNegative: { rgb: negative.value.slice(1) } }));
|
|
8101
|
+
updateLimits();
|
|
8102
|
+
return showDialog(ctx, {
|
|
8103
|
+
name: "sparkline-settings",
|
|
8104
|
+
heading: "Sparkline Settings",
|
|
8105
|
+
wide: true,
|
|
8106
|
+
body: [
|
|
8107
|
+
text(ctx, "Changes apply to the entire selected sparkline groups."),
|
|
8108
|
+
text(ctx, "Only changed settings are applied."),
|
|
8109
|
+
field(ctx, "Sparkline Type:", kind),
|
|
8110
|
+
field(ctx, "Line Weight:", width),
|
|
8111
|
+
field(ctx, "Date Range (optional):", dates),
|
|
8112
|
+
text(ctx, "Leave the date range empty for a general axis."),
|
|
8113
|
+
fieldset(ctx, "Show", ...checks.map((check) => check.wrapper)),
|
|
8114
|
+
fieldset(
|
|
8115
|
+
ctx,
|
|
8116
|
+
"Colors",
|
|
8117
|
+
field(ctx, "Sparkline Color:", color),
|
|
8118
|
+
field(ctx, "Negative Color:", negative),
|
|
8119
|
+
...mixedColors ? [text(ctx, "Colors vary between selected groups.")] : []
|
|
8120
|
+
),
|
|
8121
|
+
fieldset(
|
|
8122
|
+
ctx,
|
|
8123
|
+
"Axis",
|
|
8124
|
+
field(ctx, "Minimum Axis:", minType),
|
|
8125
|
+
field(ctx, "Minimum Value:", min),
|
|
8126
|
+
field(ctx, "Maximum Axis:", maxType),
|
|
8127
|
+
field(ctx, "Maximum Value:", max),
|
|
8128
|
+
axis.wrapper,
|
|
8129
|
+
rtl.wrapper
|
|
8130
|
+
),
|
|
8131
|
+
field(ctx, "Empty Cells:", empty),
|
|
8132
|
+
hidden.wrapper
|
|
8133
|
+
],
|
|
8134
|
+
submit: () => {
|
|
8135
|
+
const patch = {};
|
|
8136
|
+
for (const read of changes.values()) Object.assign(patch, read());
|
|
8137
|
+
if (minType.value !== "custom") delete patch.manualMin;
|
|
8138
|
+
if (maxType.value !== "custom") delete patch.manualMax;
|
|
8139
|
+
if (patch.minAxisType === "custom" && !min.value.trim() || patch.maxAxisType === "custom" && !max.value.trim())
|
|
8140
|
+
throw new Error("The sparkline axis limits are not valid.");
|
|
8141
|
+
t.session.batch("Format sparklines", () => {
|
|
8142
|
+
if (datesChanged) t.session.setSparklineDateRange(t.sheet, t.ranges, dates.value);
|
|
8143
|
+
if (Object.keys(patch).length) t.session.setSparklineGroups(t.sheet, t.ranges, patch);
|
|
8144
|
+
});
|
|
8145
|
+
return true;
|
|
8146
|
+
}
|
|
8147
|
+
});
|
|
8148
|
+
}
|
|
8149
|
+
var AGGREGATES = [
|
|
8150
|
+
["sum", "Sum"],
|
|
8151
|
+
["count", "Count"],
|
|
8152
|
+
["average", "Average"],
|
|
8153
|
+
["min", "Min"],
|
|
8154
|
+
["max", "Max"]
|
|
8155
|
+
];
|
|
8156
|
+
function openPivotTable(ctx, settings = false) {
|
|
8157
|
+
const t = target(ctx);
|
|
8158
|
+
if (!t) return Promise.resolve(void 0);
|
|
8159
|
+
const pivot = settings ? pivotTableAt(t.ws, t.range.start) : void 0;
|
|
8160
|
+
if (settings && !pivot) return Promise.resolve(void 0);
|
|
8161
|
+
const source = textInput(ctx, pivot?.source ?? formatRange(t.range));
|
|
8162
|
+
const destination = textInput(
|
|
8163
|
+
ctx,
|
|
8164
|
+
formatAddress(pivot?.location.start ?? { row: t.range.start.row, col: t.range.end.col + 2 })
|
|
8165
|
+
);
|
|
8166
|
+
source.disabled = settings;
|
|
8167
|
+
destination.disabled = settings;
|
|
8168
|
+
const row2 = select(ctx, [], "");
|
|
8169
|
+
const second = select(ctx, [["", "(None)"]], "");
|
|
8170
|
+
const layout = select(
|
|
8171
|
+
ctx,
|
|
8172
|
+
[
|
|
8173
|
+
["compact", "Compact Form"],
|
|
8174
|
+
["outline", "Outline Form"],
|
|
8175
|
+
["tabular", "Tabular Form"]
|
|
8176
|
+
],
|
|
8177
|
+
pivot ? pivot.layout ?? "tabular" : "compact"
|
|
8178
|
+
);
|
|
8179
|
+
const position = select(
|
|
8180
|
+
ctx,
|
|
8181
|
+
[
|
|
8182
|
+
["top", "Above each group"],
|
|
8183
|
+
["bottom", "Below each group"]
|
|
8184
|
+
],
|
|
8185
|
+
pivot?.subtotalPosition ?? (pivot ? "bottom" : "top")
|
|
8186
|
+
);
|
|
8187
|
+
const subtotals = checkbox(ctx, "Show subtotals", pivot?.subtotals !== false);
|
|
8188
|
+
const tabularNotice = text(ctx, "Tabular layout displays subtotals below groups.");
|
|
8189
|
+
const repeat = checkbox(ctx, "Repeat row labels", pivot?.repeatLabels ?? false);
|
|
8190
|
+
const column = select(ctx, [["", "(None)"]], "");
|
|
8191
|
+
const value = select(ctx, [], "");
|
|
8192
|
+
const aggregate = select(ctx, AGGREGATES, pivot?.aggregate ?? "sum");
|
|
8193
|
+
const loadFields = () => {
|
|
8194
|
+
let fields;
|
|
8195
|
+
try {
|
|
8196
|
+
fields = pivotSourceData(ctx.workbook(), t.sheet, source.value).fields;
|
|
8197
|
+
} catch {
|
|
8198
|
+
fields = [];
|
|
8199
|
+
}
|
|
8200
|
+
for (const [control, chosen, optional] of [
|
|
8201
|
+
[row2, pivot?.rowField, false],
|
|
8202
|
+
[second, pivot?.secondRowField, true],
|
|
8203
|
+
[column, pivot?.columnField, true],
|
|
8204
|
+
[value, pivot?.valueField, false]
|
|
8205
|
+
]) {
|
|
8206
|
+
const previous = chosen ?? control.value;
|
|
8207
|
+
control.replaceChildren();
|
|
8208
|
+
for (const name of [...optional ? [""] : [], ...fields]) {
|
|
8209
|
+
const option = ctx.host.ownerDocument.createElement("option");
|
|
8210
|
+
option.value = name;
|
|
8211
|
+
option.textContent = name || ctx.t("(None)");
|
|
8212
|
+
control.append(option);
|
|
8213
|
+
}
|
|
8214
|
+
if (fields.includes(previous ?? "") || optional && !previous)
|
|
8215
|
+
control.value = previous ?? "";
|
|
8216
|
+
else if (control === value) control.value = fields.at(-1) ?? "";
|
|
8217
|
+
}
|
|
8218
|
+
};
|
|
8219
|
+
source.addEventListener("change", loadFields);
|
|
8220
|
+
loadFields();
|
|
8221
|
+
const updateRows = () => {
|
|
8222
|
+
subtotals.input.disabled = !second.value;
|
|
8223
|
+
repeat.input.disabled = !second.value || layout.value === "compact";
|
|
8224
|
+
position.disabled = !second.value || !subtotals.input.checked || layout.value === "tabular";
|
|
8225
|
+
tabularNotice.hidden = !second.value || !subtotals.input.checked || layout.value !== "tabular";
|
|
8226
|
+
};
|
|
8227
|
+
layout.addEventListener("change", updateRows);
|
|
8228
|
+
subtotals.input.addEventListener("change", updateRows);
|
|
8229
|
+
second.addEventListener("change", updateRows);
|
|
8230
|
+
source.addEventListener("change", updateRows);
|
|
8231
|
+
updateRows();
|
|
8232
|
+
return showDialog(ctx, {
|
|
8233
|
+
name: settings ? "pivot-settings" : "create-pivot-table",
|
|
8234
|
+
heading: settings ? "PivotTable Settings" : "Create PivotTable",
|
|
8235
|
+
body: [
|
|
8236
|
+
field(ctx, "Source Range:", source),
|
|
8237
|
+
field(ctx, "Destination Cell:", destination),
|
|
8238
|
+
field(ctx, "Row Field:", row2),
|
|
8239
|
+
field(ctx, "Second Row Field:", second),
|
|
8240
|
+
field(ctx, "Report Layout:", layout),
|
|
8241
|
+
subtotals.wrapper,
|
|
8242
|
+
field(ctx, "Subtotal Position:", position),
|
|
8243
|
+
tabularNotice,
|
|
8244
|
+
repeat.wrapper,
|
|
8245
|
+
field(ctx, "Column Field:", column),
|
|
8246
|
+
field(ctx, "Value Field:", value),
|
|
8247
|
+
field(ctx, "Summarize Values By:", aggregate)
|
|
8248
|
+
],
|
|
8249
|
+
opened: () => (settings ? row2 : source).focus(),
|
|
8250
|
+
submit: () => {
|
|
8251
|
+
const options = {
|
|
8252
|
+
rowField: row2.value,
|
|
8253
|
+
layout: layout.value,
|
|
8254
|
+
subtotalPosition: position.value,
|
|
8255
|
+
secondRowField: second.value,
|
|
8256
|
+
subtotals: subtotals.input.checked,
|
|
8257
|
+
repeatLabels: repeat.input.checked,
|
|
8258
|
+
columnField: column.value,
|
|
8259
|
+
valueField: value.value,
|
|
8260
|
+
aggregate: aggregate.value
|
|
8261
|
+
};
|
|
8262
|
+
if (pivot) {
|
|
8263
|
+
if (pivot.rowField !== options.rowField || (pivot.layout ?? "tabular") !== options.layout || (pivot.subtotalPosition ?? "bottom") !== options.subtotalPosition || (pivot.secondRowField ?? "") !== options.secondRowField || pivot.subtotals !== false !== options.subtotals || (pivot.repeatLabels ?? false) !== options.repeatLabels || (pivot.columnField ?? "") !== options.columnField || pivot.valueField !== options.valueField || pivot.aggregate !== options.aggregate)
|
|
8264
|
+
t.session.refreshPivotTable(t.sheet, pivot.name, options);
|
|
8265
|
+
} else {
|
|
8266
|
+
const at = parseAddress(destination.value.trim().replaceAll("$", ""));
|
|
8267
|
+
if (!at) throw new Error("The reference is not valid.");
|
|
8268
|
+
t.session.createPivotTable(t.sheet, at, { ...options, source: source.value });
|
|
8269
|
+
ctx.selection.set({ ranges: [{ start: at, end: at }], active: at, anchor: at });
|
|
8270
|
+
}
|
|
8271
|
+
return true;
|
|
8272
|
+
}
|
|
8273
|
+
});
|
|
8274
|
+
}
|
|
8275
|
+
function openPrintPreview(ctx) {
|
|
8276
|
+
const t = target(ctx);
|
|
8277
|
+
if (!t) return Promise.resolve(void 0);
|
|
8278
|
+
const layout = paginateWorksheet(t.workbook, t.sheet);
|
|
8279
|
+
const fileName = ctx.host.fileName ?? t.ws.name;
|
|
8280
|
+
const html = buildPrintHtml(t.workbook, t.sheet, fileName, { locale: ctx.locale() });
|
|
8281
|
+
const frame = ctx.host.ownerDocument.createElement("iframe");
|
|
8282
|
+
frame.title = ctx.t("Print Preview");
|
|
8283
|
+
frame.srcdoc = html;
|
|
8284
|
+
frame.style.cssText = "width:100%;height:60vh;border:1px solid var(--xve-border,#ccc)";
|
|
8285
|
+
let page = 1;
|
|
8286
|
+
let actualSize = false;
|
|
8287
|
+
const previous = button(ctx, "Previous Page");
|
|
8288
|
+
const next = button(ctx, "Next Page");
|
|
8289
|
+
const zoom = button(ctx, "Actual Size");
|
|
8290
|
+
const count = text(ctx, "Page {page} of {count}", "xve-note", {
|
|
8291
|
+
page,
|
|
8292
|
+
count: layout.pages.length
|
|
8293
|
+
});
|
|
8294
|
+
const controls = ctx.host.ownerDocument.createElement("div");
|
|
8295
|
+
controls.style.cssText = "display:flex;align-items:center;gap:8px;flex-wrap:wrap";
|
|
8296
|
+
controls.append(previous, next, count, zoom);
|
|
8297
|
+
const update = () => {
|
|
8298
|
+
previous.disabled = page <= 1;
|
|
8299
|
+
next.disabled = page >= layout.pages.length;
|
|
8300
|
+
zoom.disabled = !layout.pages.length;
|
|
8301
|
+
count.textContent = ctx.t("Page {page} of {count}", {
|
|
8302
|
+
page: layout.pages.length ? page : 0,
|
|
8303
|
+
count: layout.pages.length
|
|
8304
|
+
});
|
|
8305
|
+
zoom.textContent = ctx.t(actualSize ? "Fit Page" : "Actual Size");
|
|
8306
|
+
const doc = frame.contentDocument;
|
|
8307
|
+
if (!doc) return;
|
|
8308
|
+
let style = doc.getElementById("preview-controls");
|
|
8309
|
+
if (!style) {
|
|
8310
|
+
style = doc.createElement("style");
|
|
8311
|
+
style.id = "preview-controls";
|
|
8312
|
+
style.setAttribute("media", "screen");
|
|
8313
|
+
doc.head.append(style);
|
|
8314
|
+
}
|
|
8315
|
+
const factor = actualSize ? 1 : Math.max(
|
|
8316
|
+
0.05,
|
|
8317
|
+
Math.min(
|
|
8318
|
+
1,
|
|
8319
|
+
(frame.clientWidth - 32) / layout.paperWidth,
|
|
8320
|
+
(frame.clientHeight - 32) / layout.paperHeight
|
|
8321
|
+
)
|
|
8322
|
+
);
|
|
8323
|
+
style.textContent = `.xve-print-page{display:none;zoom:${factor}}.xve-print-page[data-page="${page}"]{display:block}`;
|
|
8324
|
+
};
|
|
8325
|
+
previous.addEventListener("click", () => {
|
|
8326
|
+
page--;
|
|
8327
|
+
update();
|
|
8328
|
+
});
|
|
8329
|
+
next.addEventListener("click", () => {
|
|
8330
|
+
page++;
|
|
8331
|
+
update();
|
|
8332
|
+
});
|
|
8333
|
+
zoom.addEventListener("click", () => {
|
|
8334
|
+
actualSize = !actualSize;
|
|
8335
|
+
update();
|
|
8336
|
+
});
|
|
8337
|
+
frame.addEventListener("load", update);
|
|
8338
|
+
update();
|
|
8339
|
+
const print = button(ctx, "Print", true);
|
|
8340
|
+
print.disabled = !layout.pages.length;
|
|
8341
|
+
print.addEventListener("click", () => printHtml(ctx.host.ownerDocument, html));
|
|
8342
|
+
return showDialog(ctx, {
|
|
8343
|
+
name: "print-preview",
|
|
8344
|
+
heading: "Print Preview",
|
|
8345
|
+
wide: true,
|
|
8346
|
+
okLabel: null,
|
|
8347
|
+
cancelLabel: "Close",
|
|
8348
|
+
buttons: [print],
|
|
8349
|
+
body: [
|
|
8350
|
+
text(ctx, "Pages: {count} | Scale: {scale}%", "xve-note", {
|
|
8351
|
+
count: layout.pages.length,
|
|
8352
|
+
scale: Math.round(layout.scale * 100)
|
|
8353
|
+
}),
|
|
8354
|
+
text(
|
|
8355
|
+
ctx,
|
|
8356
|
+
"Preview uses worksheet dimensions. Fonts and printer margins may change pagination in Excel."
|
|
8357
|
+
),
|
|
8358
|
+
...layout.warnings.map((warning) => text(ctx, warning)),
|
|
8359
|
+
controls,
|
|
8360
|
+
frame
|
|
8361
|
+
]
|
|
8362
|
+
});
|
|
8363
|
+
}
|
|
7729
8364
|
|
|
7730
8365
|
// src/xlsx/dialogs/register-tools.ts
|
|
7731
8366
|
var props = (value) => value && typeof value === "object" ? value : {};
|
|
7732
8367
|
function registerToolDialogs(ctx) {
|
|
7733
8368
|
const d = ctx.dialogs;
|
|
8369
|
+
d.register("print-preview", (c) => openPrintPreview(c));
|
|
8370
|
+
d.register("create-pivot-table", (c) => openPivotTable(c));
|
|
8371
|
+
d.register("pivot-settings", (c) => openPivotTable(c, true));
|
|
8372
|
+
d.register(
|
|
8373
|
+
"create-sparklines",
|
|
8374
|
+
(c, p) => openCreateSparklines(c, props(p).type)
|
|
8375
|
+
);
|
|
8376
|
+
d.register("sparkline-settings", (c) => openSparklineSettings(c));
|
|
7734
8377
|
d.register("insert-chart", (c, p) => openInsertChart(c, props(p)));
|
|
7735
8378
|
d.register("paste-special", (c) => openPasteSpecial(c));
|
|
7736
8379
|
d.register("page-setup", (c, p) => openPageSetup(c, props(p)));
|
|
@@ -7919,7 +8562,7 @@ function chartColorGallerySections(ctx) {
|
|
|
7919
8562
|
const selectedChart = activeChart(ctx);
|
|
7920
8563
|
if (!workbook || !selectedChart) return [];
|
|
7921
8564
|
const scheme = chartColorScheme(workbook.theme);
|
|
7922
|
-
const
|
|
8565
|
+
const selected2 = selectedChart.chart.colorPalette ?? 10;
|
|
7923
8566
|
return ["colorful", "monochromatic"].map((group) => ({
|
|
7924
8567
|
title: ctx.t(group === "colorful" ? "Colorful" : "Monochromatic"),
|
|
7925
8568
|
columns: 1,
|
|
@@ -7931,7 +8574,7 @@ function chartColorGallerySections(ctx) {
|
|
|
7931
8574
|
n: palette.index
|
|
7932
8575
|
}),
|
|
7933
8576
|
preview: swatchStripSvg(chartPaletteColors(palette, 6, scheme), { width: 96, height: 14 }),
|
|
7934
|
-
applied:
|
|
8577
|
+
applied: selected2 === palette.id
|
|
7935
8578
|
}))
|
|
7936
8579
|
}));
|
|
7937
8580
|
}
|
|
@@ -8518,7 +9161,19 @@ function insertTab() {
|
|
|
8518
9161
|
{
|
|
8519
9162
|
id: "tables",
|
|
8520
9163
|
label: "Tables",
|
|
8521
|
-
controls: [
|
|
9164
|
+
controls: [
|
|
9165
|
+
{ kind: "button", command: "insert.table", size: "large" },
|
|
9166
|
+
{ kind: "button", command: "insert.pivot-table", size: "large" },
|
|
9167
|
+
{
|
|
9168
|
+
kind: "menu",
|
|
9169
|
+
label: "PivotTable",
|
|
9170
|
+
items: [
|
|
9171
|
+
{ command: "pivot.settings" },
|
|
9172
|
+
{ command: "pivot.refresh" },
|
|
9173
|
+
{ command: "pivot.delete" }
|
|
9174
|
+
]
|
|
9175
|
+
}
|
|
9176
|
+
]
|
|
8522
9177
|
},
|
|
8523
9178
|
{
|
|
8524
9179
|
id: "illustrations",
|
|
@@ -8552,6 +9207,30 @@ function insertTab() {
|
|
|
8552
9207
|
label: "Links",
|
|
8553
9208
|
controls: [{ kind: "button", command: "insert.link", size: "large" }]
|
|
8554
9209
|
},
|
|
9210
|
+
{
|
|
9211
|
+
id: "sparklines",
|
|
9212
|
+
label: "Sparklines",
|
|
9213
|
+
launcher: "sparkline.settings",
|
|
9214
|
+
controls: [
|
|
9215
|
+
{ kind: "button", command: "insert.sparkline-line", size: "large" },
|
|
9216
|
+
{ kind: "button", command: "insert.sparkline-column", size: "large" },
|
|
9217
|
+
{ kind: "button", command: "insert.sparkline-stacked", size: "large" },
|
|
9218
|
+
{
|
|
9219
|
+
kind: "stack",
|
|
9220
|
+
controls: [
|
|
9221
|
+
{ kind: "button", command: "sparkline.settings" },
|
|
9222
|
+
{
|
|
9223
|
+
kind: "menu",
|
|
9224
|
+
label: "Clear Sparklines",
|
|
9225
|
+
items: [
|
|
9226
|
+
{ command: "sparkline.clear-selected" },
|
|
9227
|
+
{ command: "sparkline.clear-groups" }
|
|
9228
|
+
]
|
|
9229
|
+
}
|
|
9230
|
+
]
|
|
9231
|
+
}
|
|
9232
|
+
]
|
|
9233
|
+
},
|
|
8555
9234
|
{
|
|
8556
9235
|
id: "comments",
|
|
8557
9236
|
label: "Comments",
|
|
@@ -8618,7 +9297,23 @@ function pageLayoutTab() {
|
|
|
8618
9297
|
icon: "xl-printArea",
|
|
8619
9298
|
size: "large",
|
|
8620
9299
|
items: [{ command: "page.print-area-set" }, { command: "page.print-area-clear" }]
|
|
8621
|
-
}
|
|
9300
|
+
},
|
|
9301
|
+
{
|
|
9302
|
+
kind: "menu",
|
|
9303
|
+
label: "Breaks",
|
|
9304
|
+
icon: "xl-printArea",
|
|
9305
|
+
size: "large",
|
|
9306
|
+
items: [
|
|
9307
|
+
{ command: "page.break-row-insert" },
|
|
9308
|
+
{ command: "page.break-col-insert" },
|
|
9309
|
+
sep2,
|
|
9310
|
+
{ command: "page.break-row-remove" },
|
|
9311
|
+
{ command: "page.break-col-remove" },
|
|
9312
|
+
sep2,
|
|
9313
|
+
{ command: "page.breaks-reset" }
|
|
9314
|
+
]
|
|
9315
|
+
},
|
|
9316
|
+
{ kind: "button", command: "page.preview", size: "large" }
|
|
8622
9317
|
]
|
|
8623
9318
|
},
|
|
8624
9319
|
{
|
|
@@ -8665,6 +9360,99 @@ function registerSheetIcons() {
|
|
|
8665
9360
|
registered = true;
|
|
8666
9361
|
for (const [name, d] of Object.entries(SHEET_ICONS)) registerIcon(`xl-${name}`, d);
|
|
8667
9362
|
}
|
|
9363
|
+
function hasSparklines(ctx) {
|
|
9364
|
+
const t = target(ctx);
|
|
9365
|
+
return !!t && selectedSparklineGroups(t.ws, t.ranges).length > 0;
|
|
9366
|
+
}
|
|
9367
|
+
function sparklineCommands() {
|
|
9368
|
+
return [
|
|
9369
|
+
...[
|
|
9370
|
+
["line", "Line Sparkline", "chartLine"],
|
|
9371
|
+
["column", "Column Sparkline", "chartColumn"],
|
|
9372
|
+
["stacked", "Win/Loss Sparkline", "chartColumn"]
|
|
9373
|
+
].map(
|
|
9374
|
+
([type, label, glyph]) => editing({
|
|
9375
|
+
id: `insert.sparkline-${type}`,
|
|
9376
|
+
label,
|
|
9377
|
+
icon: icon(glyph),
|
|
9378
|
+
lock: "objects",
|
|
9379
|
+
run: (ctx) => void ctx.dialogs.open("create-sparklines", { type })
|
|
9380
|
+
})
|
|
9381
|
+
),
|
|
9382
|
+
editing({
|
|
9383
|
+
id: "sparkline.settings",
|
|
9384
|
+
label: "Sparkline Settings",
|
|
9385
|
+
icon: icon("chartLine"),
|
|
9386
|
+
lock: "objects",
|
|
9387
|
+
enabled: hasSparklines,
|
|
9388
|
+
run: (ctx) => void ctx.dialogs.open("sparkline-settings")
|
|
9389
|
+
}),
|
|
9390
|
+
...[
|
|
9391
|
+
["selected", false, "Clear Selected Sparklines"],
|
|
9392
|
+
["groups", true, "Clear Sparkline Groups"]
|
|
9393
|
+
].map(
|
|
9394
|
+
([id, whole, label]) => editing({
|
|
9395
|
+
id: `sparkline.clear-${id}`,
|
|
9396
|
+
label,
|
|
9397
|
+
icon: icon("clear"),
|
|
9398
|
+
lock: "objects",
|
|
9399
|
+
enabled: hasSparklines,
|
|
9400
|
+
run: (ctx) => {
|
|
9401
|
+
const t = target(ctx);
|
|
9402
|
+
if (t) t.session.deleteSparklines(t.sheet, t.ranges, whole);
|
|
9403
|
+
}
|
|
9404
|
+
})
|
|
9405
|
+
)
|
|
9406
|
+
];
|
|
9407
|
+
}
|
|
9408
|
+
function selected(ctx) {
|
|
9409
|
+
const t = target(ctx);
|
|
9410
|
+
const pivot = t ? pivotTableAt(t.ws, t.range.start) : void 0;
|
|
9411
|
+
return t && pivot ? { t, pivot } : void 0;
|
|
9412
|
+
}
|
|
9413
|
+
function pivotCommands() {
|
|
9414
|
+
return [
|
|
9415
|
+
editing({
|
|
9416
|
+
id: "insert.pivot-table",
|
|
9417
|
+
label: "PivotTable",
|
|
9418
|
+
icon: icon("table"),
|
|
9419
|
+
lock: "objects",
|
|
9420
|
+
run: (ctx) => void ctx.dialogs.open("create-pivot-table")
|
|
9421
|
+
}),
|
|
9422
|
+
editing({
|
|
9423
|
+
id: "pivot.settings",
|
|
9424
|
+
label: "PivotTable Settings",
|
|
9425
|
+
icon: icon("table"),
|
|
9426
|
+
lock: "objects",
|
|
9427
|
+
enabled: (ctx) => !!selected(ctx),
|
|
9428
|
+
run: (ctx) => void ctx.dialogs.open("pivot-settings")
|
|
9429
|
+
}),
|
|
9430
|
+
editing({
|
|
9431
|
+
id: "pivot.refresh",
|
|
9432
|
+
label: "Refresh PivotTable",
|
|
9433
|
+
icon: icon("table"),
|
|
9434
|
+
lock: "objects",
|
|
9435
|
+
enabled: (ctx) => !!selected(ctx),
|
|
9436
|
+
run: (ctx) => {
|
|
9437
|
+
const selection = selected(ctx);
|
|
9438
|
+
if (selection)
|
|
9439
|
+
selection.t.session.refreshPivotTable(selection.t.sheet, selection.pivot.name);
|
|
9440
|
+
}
|
|
9441
|
+
}),
|
|
9442
|
+
editing({
|
|
9443
|
+
id: "pivot.delete",
|
|
9444
|
+
label: "Delete PivotTable",
|
|
9445
|
+
icon: icon("clear"),
|
|
9446
|
+
lock: "objects",
|
|
9447
|
+
enabled: (ctx) => !!selected(ctx),
|
|
9448
|
+
run: (ctx) => {
|
|
9449
|
+
const selection = selected(ctx);
|
|
9450
|
+
if (selection)
|
|
9451
|
+
selection.t.session.deletePivotTable(selection.t.sheet, selection.pivot.name);
|
|
9452
|
+
}
|
|
9453
|
+
})
|
|
9454
|
+
];
|
|
9455
|
+
}
|
|
8668
9456
|
var ordered = (ctx) => [...target(ctx)?.ws.comments ?? []].sort(
|
|
8669
9457
|
(a, b) => a.address.row - b.address.row || a.address.col - b.address.col
|
|
8670
9458
|
);
|
|
@@ -8774,35 +9562,35 @@ function reviewCommands() {
|
|
|
8774
9562
|
})
|
|
8775
9563
|
];
|
|
8776
9564
|
}
|
|
8777
|
-
function seriesFillBinding(
|
|
9565
|
+
function seriesFillBinding(selected2) {
|
|
8778
9566
|
return {
|
|
8779
9567
|
commandId: "chart.format-series",
|
|
8780
|
-
key:
|
|
8781
|
-
fill: (chart) => chart.series[
|
|
8782
|
-
gradient: (view) => view.series[
|
|
8783
|
-
paint: (view) => view.series[
|
|
9568
|
+
key: selected2,
|
|
9569
|
+
fill: (chart) => chart.series[selected2()]?.fill,
|
|
9570
|
+
gradient: (view) => view.series[selected2()]?.gradient,
|
|
9571
|
+
paint: (view) => view.series[selected2()]?.color,
|
|
8784
9572
|
rectangular: (chart) => chart.chartType === "bar" || chart.chartType === "column",
|
|
8785
|
-
color: (chart, color) => chartSeriesFillPatch(chart,
|
|
8786
|
-
solid: (chart) => chartSeriesSolidFillPatch(chart,
|
|
8787
|
-
edit: (chart, edit) => chartSeriesGradientPatch(chart,
|
|
8788
|
-
transparency: (chart) => chartSeriesTransparency(chart,
|
|
8789
|
-
setTransparency: (chart, value) => chartSeriesTransparencyPatch(chart,
|
|
9573
|
+
color: (chart, color) => chartSeriesFillPatch(chart, selected2(), color),
|
|
9574
|
+
solid: (chart) => chartSeriesSolidFillPatch(chart, selected2()),
|
|
9575
|
+
edit: (chart, edit) => chartSeriesGradientPatch(chart, selected2(), edit),
|
|
9576
|
+
transparency: (chart) => chartSeriesTransparency(chart, selected2()),
|
|
9577
|
+
setTransparency: (chart, value) => chartSeriesTransparencyPatch(chart, selected2(), value),
|
|
8790
9578
|
preview: (chart, patch) => ({ ...chart, ...patch })
|
|
8791
9579
|
};
|
|
8792
9580
|
}
|
|
8793
|
-
function backgroundFillBinding(
|
|
9581
|
+
function backgroundFillBinding(selected2) {
|
|
8794
9582
|
return {
|
|
8795
9583
|
commandId: "chart.format-area",
|
|
8796
|
-
key:
|
|
8797
|
-
fill: (chart) => chartElementFill(chart,
|
|
8798
|
-
gradient: (view) => view.appearance?.[
|
|
8799
|
-
paint: (view) => view.appearance?.[
|
|
9584
|
+
key: selected2,
|
|
9585
|
+
fill: (chart) => chartElementFill(chart, selected2()),
|
|
9586
|
+
gradient: (view) => view.appearance?.[selected2()]?.gradient,
|
|
9587
|
+
paint: (view) => view.appearance?.[selected2()]?.fillColor ?? (selected2() === "chartArea" ? "#FFFFFF" : "none"),
|
|
8800
9588
|
rectangular: () => true,
|
|
8801
|
-
color: (chart, color) => chartElementFillPatch(chart,
|
|
8802
|
-
solid: (chart) => chartElementSolidFillPatch(chart,
|
|
8803
|
-
edit: (chart, edit) => chartElementGradientPatch(chart,
|
|
8804
|
-
transparency: (chart) => chartElementTransparency(chart,
|
|
8805
|
-
setTransparency: (chart, value) => chartElementTransparencyPatch(chart,
|
|
9589
|
+
color: (chart, color) => chartElementFillPatch(chart, selected2(), color),
|
|
9590
|
+
solid: (chart) => chartElementSolidFillPatch(chart, selected2()),
|
|
9591
|
+
edit: (chart, edit) => chartElementGradientPatch(chart, selected2(), edit),
|
|
9592
|
+
transparency: (chart) => chartElementTransparency(chart, selected2()),
|
|
9593
|
+
setTransparency: (chart, value) => chartElementTransparencyPatch(chart, selected2(), value),
|
|
8806
9594
|
preview: (chart, patch) => chartWithElementFills(chart, patch.elementFills ?? {})
|
|
8807
9595
|
};
|
|
8808
9596
|
}
|
|
@@ -8864,7 +9652,7 @@ function createNumberRange(input, options) {
|
|
|
8864
9652
|
}
|
|
8865
9653
|
|
|
8866
9654
|
// src/xlsx/chart-series-transparency.ts
|
|
8867
|
-
function createSeriesTransparency(ctx,
|
|
9655
|
+
function createSeriesTransparency(ctx, selected2, binding = seriesFillBinding(selected2)) {
|
|
8868
9656
|
const element = el(ctx, "div");
|
|
8869
9657
|
const input = numberInput(ctx, 0, 0, 100);
|
|
8870
9658
|
const row2 = field(ctx, "Transparency", input);
|
|
@@ -8959,9 +9747,9 @@ function createGradientStopTrack(doc) {
|
|
|
8959
9747
|
const next = event.key === "ArrowRight" ? index + 1 : event.key === "ArrowLeft" ? index - 1 : void 0;
|
|
8960
9748
|
if (next === void 0 || current.disabled) return;
|
|
8961
9749
|
event.preventDefault();
|
|
8962
|
-
const
|
|
8963
|
-
current.onSelect(
|
|
8964
|
-
element.querySelectorAll("button")[
|
|
9750
|
+
const selected2 = Math.max(0, Math.min(current.stops.length - 1, next));
|
|
9751
|
+
current.onSelect(selected2);
|
|
9752
|
+
element.querySelectorAll("button")[selected2]?.focus();
|
|
8965
9753
|
});
|
|
8966
9754
|
return button2;
|
|
8967
9755
|
})
|
|
@@ -9138,7 +9926,7 @@ function createGradientPresetGallery(doc) {
|
|
|
9138
9926
|
update(options) {
|
|
9139
9927
|
current = options;
|
|
9140
9928
|
if (options.disabled) element.open = false;
|
|
9141
|
-
const
|
|
9929
|
+
const selected2 = officeGradientPresetId(options.fill);
|
|
9142
9930
|
element.state = {
|
|
9143
9931
|
id: "gradient-presets",
|
|
9144
9932
|
label: options.label,
|
|
@@ -9152,7 +9940,7 @@ function createGradientPresetGallery(doc) {
|
|
|
9152
9940
|
items: OFFICE_GRADIENT_PRESETS.map((preset) => ({
|
|
9153
9941
|
id: String(preset.id),
|
|
9154
9942
|
label: options.translate(preset.label),
|
|
9155
|
-
applied: preset.id ===
|
|
9943
|
+
applied: preset.id === selected2,
|
|
9156
9944
|
preview: gradientGalleryPreview(
|
|
9157
9945
|
`${prefix}-${preset.id}`,
|
|
9158
9946
|
resolveChartGradient(
|
|
@@ -9206,10 +9994,10 @@ function createGradientTypeField(ctx, onPick) {
|
|
|
9206
9994
|
};
|
|
9207
9995
|
}
|
|
9208
9996
|
function createChartGradientPreview(root, drawing, series, gradient) {
|
|
9209
|
-
const
|
|
9997
|
+
const target29 = typeof series === "number" ? `s${series}` : series;
|
|
9210
9998
|
const nodes = Array.from(
|
|
9211
9999
|
root.querySelectorAll(
|
|
9212
|
-
`.xg-obj[data-index="${drawing}"] :is(linearGradient,radialGradient,pattern)[id$="-${
|
|
10000
|
+
`.xg-obj[data-index="${drawing}"] :is(linearGradient,radialGradient,pattern)[id$="-${target29}"]`
|
|
9213
10001
|
)
|
|
9214
10002
|
);
|
|
9215
10003
|
const originals = nodes.map((node) => ({
|
|
@@ -9299,7 +10087,7 @@ function seriesRangePreview(ctx, chart, view, series, stop, drawing, track, colo
|
|
|
9299
10087
|
}
|
|
9300
10088
|
|
|
9301
10089
|
// src/xlsx/chart-series-gradient.ts
|
|
9302
|
-
function createSeriesGradient(ctx,
|
|
10090
|
+
function createSeriesGradient(ctx, selected2, binding = seriesFillBinding(selected2)) {
|
|
9303
10091
|
const element = el(ctx, "div", "xve-chart-series-gradient");
|
|
9304
10092
|
const angle = numberInput(ctx, 90, 0, 360);
|
|
9305
10093
|
const position = numberInput(ctx, 0, 0, 100);
|
|
@@ -9551,7 +10339,7 @@ function createSeriesGradient(ctx, selected, binding = seriesFillBinding(selecte
|
|
|
9551
10339
|
}
|
|
9552
10340
|
|
|
9553
10341
|
// src/xlsx/chart-series-fill.ts
|
|
9554
|
-
function createSeriesFill(ctx,
|
|
10342
|
+
function createSeriesFill(ctx, selected2, binding = seriesFillBinding(selected2)) {
|
|
9555
10343
|
const element = el(ctx, "div", "xve-chart-series-fill");
|
|
9556
10344
|
const heading2 = el(ctx, "h3");
|
|
9557
10345
|
const kind = select(ctx, []);
|
|
@@ -9559,8 +10347,8 @@ function createSeriesFill(ctx, selected, binding = seriesFillBinding(selected))
|
|
|
9559
10347
|
const color = el(ctx, "button", "xve-input xve-chart-series-color");
|
|
9560
10348
|
color.type = "button";
|
|
9561
10349
|
const colorField = field(ctx, "Color", color);
|
|
9562
|
-
const transparency = createSeriesTransparency(ctx,
|
|
9563
|
-
const gradient = createSeriesGradient(ctx,
|
|
10350
|
+
const transparency = createSeriesTransparency(ctx, selected2, binding);
|
|
10351
|
+
const gradient = createSeriesGradient(ctx, selected2, binding);
|
|
9564
10352
|
element.append(heading2, kindField, colorField, transparency.element, gradient.element);
|
|
9565
10353
|
let current;
|
|
9566
10354
|
const apply = (value) => {
|
|
@@ -9665,15 +10453,15 @@ function createChartSeriesPane(ctx, onOpen) {
|
|
|
9665
10453
|
};
|
|
9666
10454
|
closeButton.addEventListener("click", close);
|
|
9667
10455
|
const body = el(ctx, "div", "xve-chart-series-body");
|
|
9668
|
-
let
|
|
10456
|
+
let selected2 = 0;
|
|
9669
10457
|
let shownWorkbook;
|
|
9670
10458
|
let shownSheet = -1;
|
|
9671
10459
|
let shownChart = -1;
|
|
9672
10460
|
const seriesSelect = select(ctx, []);
|
|
9673
10461
|
const seriesField = field(ctx, "Series", seriesSelect);
|
|
9674
|
-
const fills = createSeriesFill(ctx, () =>
|
|
10462
|
+
const fills = createSeriesFill(ctx, () => selected2);
|
|
9675
10463
|
seriesSelect.addEventListener("change", () => {
|
|
9676
|
-
|
|
10464
|
+
selected2 = Number(seriesSelect.value);
|
|
9677
10465
|
refresh();
|
|
9678
10466
|
});
|
|
9679
10467
|
const section = el(ctx, "h3");
|
|
@@ -9746,11 +10534,11 @@ function createChartSeriesPane(ctx, onOpen) {
|
|
|
9746
10534
|
const chart = found?.chart;
|
|
9747
10535
|
const workbook = ctx.workbook();
|
|
9748
10536
|
if (workbook !== shownWorkbook || shownSheet !== ctx.activeSheet() || shownChart !== found?.index)
|
|
9749
|
-
|
|
10537
|
+
selected2 = 0;
|
|
9750
10538
|
shownWorkbook = workbook;
|
|
9751
10539
|
shownSheet = ctx.activeSheet();
|
|
9752
10540
|
shownChart = found?.index ?? -1;
|
|
9753
|
-
if (!chart?.series[
|
|
10541
|
+
if (!chart?.series[selected2]) selected2 = 0;
|
|
9754
10542
|
const model = workbook && chart ? chartView(
|
|
9755
10543
|
workbook,
|
|
9756
10544
|
ctx.activeSheet(),
|
|
@@ -9765,7 +10553,7 @@ function createChartSeriesPane(ctx, onOpen) {
|
|
|
9765
10553
|
return option;
|
|
9766
10554
|
})
|
|
9767
10555
|
);
|
|
9768
|
-
seriesSelect.value = String(
|
|
10556
|
+
seriesSelect.value = String(selected2);
|
|
9769
10557
|
seriesSelect.disabled = !chart?.series.length || !ctx.commands.isEnabled("chart.format-series");
|
|
9770
10558
|
fills.refresh(chart, model);
|
|
9771
10559
|
const supported = chart?.chartType === "bar" || chart?.chartType === "column";
|
|
@@ -9804,7 +10592,7 @@ function createChartSeriesPane(ctx, onOpen) {
|
|
|
9804
10592
|
element.hidden = false;
|
|
9805
10593
|
refresh();
|
|
9806
10594
|
if (typeof props2 === "number" && Number.isInteger(props2) && activeChart(ctx)?.chart.series[props2]) {
|
|
9807
|
-
|
|
10595
|
+
selected2 = props2;
|
|
9808
10596
|
refresh();
|
|
9809
10597
|
}
|
|
9810
10598
|
overlap.focus();
|
|
@@ -9837,13 +10625,13 @@ function createChartAreaPane(ctx, onOpen) {
|
|
|
9837
10625
|
closeButton.type = "button";
|
|
9838
10626
|
closeButton.textContent = "\xD7";
|
|
9839
10627
|
const body = el(ctx, "div", "xve-chart-series-body");
|
|
9840
|
-
let
|
|
9841
|
-
const
|
|
9842
|
-
const targetField = field(ctx, "Chart element",
|
|
10628
|
+
let selected2 = "chartArea";
|
|
10629
|
+
const target29 = select(ctx, []);
|
|
10630
|
+
const targetField = field(ctx, "Chart element", target29);
|
|
9843
10631
|
const fills = createSeriesFill(
|
|
9844
10632
|
ctx,
|
|
9845
10633
|
() => 0,
|
|
9846
|
-
backgroundFillBinding(() =>
|
|
10634
|
+
backgroundFillBinding(() => selected2)
|
|
9847
10635
|
);
|
|
9848
10636
|
const close = () => {
|
|
9849
10637
|
fills.refresh(void 0, void 0);
|
|
@@ -9869,13 +10657,13 @@ function createChartAreaPane(ctx, onOpen) {
|
|
|
9869
10657
|
return;
|
|
9870
10658
|
}
|
|
9871
10659
|
const available = (part) => part === "title" ? !!found.chart.title : part === "legend" ? found.chart.showLegend : true;
|
|
9872
|
-
for (const option of
|
|
10660
|
+
for (const option of target29.options)
|
|
9873
10661
|
option.disabled = !available(option.value);
|
|
9874
|
-
if (!available(
|
|
9875
|
-
title.textContent = ctx.t(names[
|
|
10662
|
+
if (!available(selected2)) selected2 = "chartArea";
|
|
10663
|
+
title.textContent = ctx.t(names[selected2][1]);
|
|
9876
10664
|
element.setAttribute("aria-label", title.textContent);
|
|
9877
|
-
|
|
9878
|
-
|
|
10665
|
+
target29.value = selected2;
|
|
10666
|
+
target29.disabled = !ctx.commands.isEnabled("chart.format-area");
|
|
9879
10667
|
fills.refresh(
|
|
9880
10668
|
found.chart,
|
|
9881
10669
|
chartView(
|
|
@@ -9889,8 +10677,8 @@ function createChartAreaPane(ctx, onOpen) {
|
|
|
9889
10677
|
const relocalize = () => {
|
|
9890
10678
|
closeButton.setAttribute("aria-label", ctx.t("Close"));
|
|
9891
10679
|
targetField.querySelector("span").textContent = ctx.t("Chart element");
|
|
9892
|
-
|
|
9893
|
-
|
|
10680
|
+
target29.setAttribute("aria-label", ctx.t("Chart element"));
|
|
10681
|
+
target29.replaceChildren(
|
|
9894
10682
|
...CHART_FILL_PARTS.map((part) => {
|
|
9895
10683
|
const option = el(ctx, "option");
|
|
9896
10684
|
option.value = part;
|
|
@@ -9900,18 +10688,18 @@ function createChartAreaPane(ctx, onOpen) {
|
|
|
9900
10688
|
);
|
|
9901
10689
|
refresh();
|
|
9902
10690
|
};
|
|
9903
|
-
|
|
9904
|
-
if (!
|
|
9905
|
-
|
|
10691
|
+
target29.addEventListener("change", () => {
|
|
10692
|
+
if (!target29.disabled && CHART_FILL_PARTS.includes(target29.value))
|
|
10693
|
+
selected2 = target29.value;
|
|
9906
10694
|
refresh();
|
|
9907
10695
|
});
|
|
9908
10696
|
ctx.dialogs.register("format-chart-area", async (_ctx, part) => {
|
|
9909
10697
|
if (!ctx.commands.isEnabled("chart.format-area")) return;
|
|
9910
10698
|
onOpen();
|
|
9911
|
-
|
|
10699
|
+
selected2 = CHART_FILL_PARTS.includes(part) ? part : "chartArea";
|
|
9912
10700
|
element.hidden = false;
|
|
9913
10701
|
refresh();
|
|
9914
|
-
|
|
10702
|
+
target29.focus();
|
|
9915
10703
|
});
|
|
9916
10704
|
relocalize();
|
|
9917
10705
|
return { element, refresh, relocalize, close };
|
|
@@ -9929,7 +10717,10 @@ function allCommands() {
|
|
|
9929
10717
|
...editingCommands(),
|
|
9930
10718
|
...insertNowCommands(),
|
|
9931
10719
|
...insertCommands(),
|
|
10720
|
+
...sparklineCommands(),
|
|
10721
|
+
...pivotCommands(),
|
|
9932
10722
|
...pageLayoutCommands(),
|
|
10723
|
+
...pageBreakCommands(),
|
|
9933
10724
|
...formulaCommands(),
|
|
9934
10725
|
...dataCommands(),
|
|
9935
10726
|
...reviewCommands(),
|
|
@@ -10270,7 +11061,7 @@ function createFunctionAssist(doc, container, t, catalog = FUNCTION_CATALOG) {
|
|
|
10270
11061
|
const tip = h(doc, "div", "xg-assist-tip", { role: "tooltip" });
|
|
10271
11062
|
container.append(root);
|
|
10272
11063
|
let matches = [];
|
|
10273
|
-
let
|
|
11064
|
+
let selected2 = 0;
|
|
10274
11065
|
let token;
|
|
10275
11066
|
let lastField;
|
|
10276
11067
|
const close = () => {
|
|
@@ -10284,20 +11075,20 @@ function createFunctionAssist(doc, container, t, catalog = FUNCTION_CATALOG) {
|
|
|
10284
11075
|
matches.forEach((info, index) => {
|
|
10285
11076
|
const option = h(doc, "li", "xg-assist-option", {
|
|
10286
11077
|
role: "option",
|
|
10287
|
-
"aria-selected": String(index ===
|
|
11078
|
+
"aria-selected": String(index === selected2)
|
|
10288
11079
|
});
|
|
10289
11080
|
option.dataset.name = info.name;
|
|
10290
11081
|
option.textContent = info.name;
|
|
10291
11082
|
option.addEventListener("mousedown", (event) => {
|
|
10292
11083
|
event.preventDefault();
|
|
10293
|
-
|
|
11084
|
+
selected2 = index;
|
|
10294
11085
|
if (lastField) accept(lastField);
|
|
10295
11086
|
});
|
|
10296
11087
|
list.append(option);
|
|
10297
11088
|
});
|
|
10298
|
-
desc.textContent = matches[
|
|
11089
|
+
desc.textContent = matches[selected2]?.description ?? "";
|
|
10299
11090
|
root.replaceChildren(list, desc);
|
|
10300
|
-
list.children[
|
|
11091
|
+
list.children[selected2]?.scrollIntoView?.({ block: "nearest" });
|
|
10301
11092
|
};
|
|
10302
11093
|
const renderTip = (info, argIndex) => {
|
|
10303
11094
|
const { name, params } = syntaxParams(info.syntax);
|
|
@@ -10320,7 +11111,7 @@ function createFunctionAssist(doc, container, t, catalog = FUNCTION_CATALOG) {
|
|
|
10320
11111
|
root.replaceChildren(tip);
|
|
10321
11112
|
};
|
|
10322
11113
|
const accept = (field2) => {
|
|
10323
|
-
const info = matches[
|
|
11114
|
+
const info = matches[selected2];
|
|
10324
11115
|
if (!info || !token) return;
|
|
10325
11116
|
const next = splice(
|
|
10326
11117
|
field2.input.value,
|
|
@@ -10342,10 +11133,10 @@ function createFunctionAssist(doc, container, t, catalog = FUNCTION_CATALOG) {
|
|
|
10342
11133
|
token = nameAtCaret(text3, caret);
|
|
10343
11134
|
const found = token ? functionMatches(token.prefix, 12, catalog) : [];
|
|
10344
11135
|
if (found.length) {
|
|
10345
|
-
const previous = matches[
|
|
11136
|
+
const previous = matches[selected2]?.name;
|
|
10346
11137
|
matches = found;
|
|
10347
11138
|
const keep = previous ? found.findIndex((m) => m.name === previous) : -1;
|
|
10348
|
-
|
|
11139
|
+
selected2 = keep >= 0 ? keep : 0;
|
|
10349
11140
|
root.hidden = false;
|
|
10350
11141
|
renderList();
|
|
10351
11142
|
return;
|
|
@@ -10371,7 +11162,7 @@ function createFunctionAssist(doc, container, t, catalog = FUNCTION_CATALOG) {
|
|
|
10371
11162
|
}
|
|
10372
11163
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
10373
11164
|
const step2 = event.key === "ArrowDown" ? 1 : -1;
|
|
10374
|
-
|
|
11165
|
+
selected2 = (selected2 + step2 + matches.length) % matches.length;
|
|
10375
11166
|
renderList();
|
|
10376
11167
|
} else if (event.key === "Tab" || event.key === "Enter" && !event.altKey) {
|
|
10377
11168
|
accept(field2);
|
|
@@ -10626,11 +11417,11 @@ var CellEditor = class {
|
|
|
10626
11417
|
}
|
|
10627
11418
|
const refs = [];
|
|
10628
11419
|
for (const ref of this.field.references()) {
|
|
10629
|
-
const
|
|
10630
|
-
if (!
|
|
10631
|
-
if (
|
|
11420
|
+
const target29 = referenceTarget(ref.text);
|
|
11421
|
+
if (!target29) continue;
|
|
11422
|
+
if (target29.sheet !== void 0 && target29.sheet.toLowerCase() !== sheet.name.toLowerCase())
|
|
10632
11423
|
continue;
|
|
10633
|
-
refs.push({ range:
|
|
11424
|
+
refs.push({ range: target29.range, color: ref.color });
|
|
10634
11425
|
}
|
|
10635
11426
|
view.overlay.references = refs.length ? refs : void 0;
|
|
10636
11427
|
view.schedule();
|
|
@@ -10900,9 +11691,9 @@ var DrawingLayer = class {
|
|
|
10900
11691
|
}
|
|
10901
11692
|
}
|
|
10902
11693
|
#selection(node, index) {
|
|
10903
|
-
const
|
|
10904
|
-
node.classList.toggle("xg-obj-sel",
|
|
10905
|
-
if (!
|
|
11694
|
+
const selected2 = this.#selected === index;
|
|
11695
|
+
node.classList.toggle("xg-obj-sel", selected2);
|
|
11696
|
+
if (!selected2) {
|
|
10906
11697
|
for (const grip of node.querySelectorAll(".xg-grip")) grip.remove();
|
|
10907
11698
|
} else if (!node.querySelector(".xg-grip")) {
|
|
10908
11699
|
for (const pos of ["nw", "ne", "sw", "se"]) {
|
|
@@ -11021,9 +11812,9 @@ var GridA11y = class {
|
|
|
11021
11812
|
}
|
|
11022
11813
|
input;
|
|
11023
11814
|
/** Updates the sink label and announces (debounced) after a selection change. */
|
|
11024
|
-
update(selection,
|
|
11815
|
+
update(selection, editing9) {
|
|
11025
11816
|
const text3 = describeSelection(this.#view, selection);
|
|
11026
|
-
if (!
|
|
11817
|
+
if (!editing9) this.input.setAttribute("aria-label", text3);
|
|
11027
11818
|
if (this.#timer) clearTimeout(this.#timer);
|
|
11028
11819
|
this.#timer = setTimeout(() => {
|
|
11029
11820
|
this.live.textContent = text3;
|
|
@@ -11509,8 +12300,8 @@ function openMenuAtActive(view, refocus) {
|
|
|
11509
12300
|
}
|
|
11510
12301
|
function wireMenus(view, refocus) {
|
|
11511
12302
|
const onMenu = (event) => {
|
|
11512
|
-
const
|
|
11513
|
-
if (
|
|
12303
|
+
const target29 = event.target;
|
|
12304
|
+
if (target29.closest(".xg-editor-host.xg-editing, .xg-popup")) return;
|
|
11514
12305
|
event.preventDefault();
|
|
11515
12306
|
const hit = view.hitClient(event.clientX, event.clientY);
|
|
11516
12307
|
const kind = hit.area === "row-header" ? "row" : hit.area === "col-header" ? "col" : "cell";
|
|
@@ -11571,8 +12362,8 @@ function startHeaderResize(view, axis, index, event) {
|
|
|
11571
12362
|
}
|
|
11572
12363
|
};
|
|
11573
12364
|
draw();
|
|
11574
|
-
const
|
|
11575
|
-
|
|
12365
|
+
const target29 = view.view;
|
|
12366
|
+
target29.setPointerCapture?.(event.pointerId);
|
|
11576
12367
|
const move = (e) => {
|
|
11577
12368
|
const { x, y } = view.clientToView(e.clientX, e.clientY);
|
|
11578
12369
|
size = Math.max(0, Math.round((axis === "col" ? x : y) - start));
|
|
@@ -11580,9 +12371,9 @@ function startHeaderResize(view, axis, index, event) {
|
|
|
11580
12371
|
guide.title = String(toFileSize(view, axis, size));
|
|
11581
12372
|
};
|
|
11582
12373
|
const up = (e) => {
|
|
11583
|
-
|
|
11584
|
-
|
|
11585
|
-
|
|
12374
|
+
target29.removeEventListener("pointermove", move, true);
|
|
12375
|
+
target29.removeEventListener("pointerup", up, true);
|
|
12376
|
+
target29.releasePointerCapture?.(e.pointerId);
|
|
11586
12377
|
guide.remove();
|
|
11587
12378
|
const indices = resizeTargets(view, axis, index);
|
|
11588
12379
|
const sheet = view.sheetIndex();
|
|
@@ -11590,8 +12381,8 @@ function startHeaderResize(view, axis, index, event) {
|
|
|
11590
12381
|
else if (axis === "col") session.setColumnWidth(sheet, indices, toFileSize(view, "col", size));
|
|
11591
12382
|
else session.setRowHeight(sheet, indices, toFileSize(view, "row", size));
|
|
11592
12383
|
};
|
|
11593
|
-
|
|
11594
|
-
|
|
12384
|
+
target29.addEventListener("pointermove", move, true);
|
|
12385
|
+
target29.addEventListener("pointerup", up, true);
|
|
11595
12386
|
}
|
|
11596
12387
|
function autoFit(view, axis, index) {
|
|
11597
12388
|
const session = view.ctx.session();
|
|
@@ -11681,8 +12472,8 @@ function wirePointer(host) {
|
|
|
11681
12472
|
}, 40);
|
|
11682
12473
|
};
|
|
11683
12474
|
const onDown = (event) => {
|
|
11684
|
-
const
|
|
11685
|
-
if (
|
|
12475
|
+
const target29 = event.target;
|
|
12476
|
+
if (target29.closest(".xg-editor-host, .xg-obj, .xg-dd, .xg-popup, .xg-assist")) return;
|
|
11686
12477
|
const { x, y } = view.clientToView(event.clientX, event.clientY);
|
|
11687
12478
|
const g = view.geometry;
|
|
11688
12479
|
const hit = g.hit(x, y);
|
|
@@ -11699,7 +12490,7 @@ function wirePointer(host) {
|
|
|
11699
12490
|
event.preventDefault();
|
|
11700
12491
|
const sheet = view.sheet();
|
|
11701
12492
|
const editable = !view.ctx.readOnly();
|
|
11702
|
-
if (
|
|
12493
|
+
if (target29.closest('[data-handle="fill"]') && editable) {
|
|
11703
12494
|
drag = { kind: "fill", anchor: selection.get().active, pointer: event.pointerId, x, y };
|
|
11704
12495
|
el3.setPointerCapture?.(event.pointerId);
|
|
11705
12496
|
return;
|
|
@@ -11785,17 +12576,17 @@ function wirePointer(host) {
|
|
|
11785
12576
|
drag = void 0;
|
|
11786
12577
|
el3.releasePointerCapture?.(event.pointerId);
|
|
11787
12578
|
if (finished.kind === "fill") {
|
|
11788
|
-
const
|
|
12579
|
+
const target29 = view.overlay.fillPreview;
|
|
11789
12580
|
view.overlay.fillPreview = void 0;
|
|
11790
12581
|
const source = selection.get().ranges[selection.get().ranges.length - 1];
|
|
11791
|
-
if (
|
|
12582
|
+
if (target29 && source) host.fill(source, target29);
|
|
11792
12583
|
view.schedule();
|
|
11793
12584
|
}
|
|
11794
12585
|
if (finished.kind === "point") editor.focus();
|
|
11795
12586
|
};
|
|
11796
12587
|
const onDblClick = (event) => {
|
|
11797
|
-
const
|
|
11798
|
-
if (
|
|
12588
|
+
const target29 = event.target;
|
|
12589
|
+
if (target29.closest(".xg-editor-host, .xg-obj, .xg-popup")) return;
|
|
11799
12590
|
const { x, y } = view.clientToView(event.clientX, event.clientY);
|
|
11800
12591
|
const g = view.geometry;
|
|
11801
12592
|
const hit = g.hit(x, y);
|
|
@@ -12146,12 +12937,12 @@ function paintCell(doc, node, item, zoom) {
|
|
|
12146
12937
|
}
|
|
12147
12938
|
}
|
|
12148
12939
|
if (view.icon) {
|
|
12149
|
-
const
|
|
12940
|
+
const icon9 = svgNode(
|
|
12150
12941
|
doc,
|
|
12151
12942
|
iconSvg(view.icon.set, view.icon.index, Math.round(16 * (zoom / 100)))
|
|
12152
12943
|
);
|
|
12153
|
-
|
|
12154
|
-
node.append(
|
|
12944
|
+
icon9.setAttribute("class", "xg-ic");
|
|
12945
|
+
node.append(icon9);
|
|
12155
12946
|
}
|
|
12156
12947
|
if (item.text) {
|
|
12157
12948
|
const box = h(doc, "div", "xg-t");
|
|
@@ -12779,8 +13570,8 @@ function wireTooltips(view) {
|
|
|
12779
13570
|
tip.append(who, view.doc.createTextNode(reply.text));
|
|
12780
13571
|
}
|
|
12781
13572
|
} else if (link) {
|
|
12782
|
-
const
|
|
12783
|
-
tip.textContent = `${link.tooltip ??
|
|
13573
|
+
const target29 = link.target ?? link.location ?? "";
|
|
13574
|
+
tip.textContent = `${link.tooltip ?? target29}
|
|
12784
13575
|
${view.ctx.t("Ctrl+click to follow the link.")}`;
|
|
12785
13576
|
}
|
|
12786
13577
|
const g = view.geometry;
|
|
@@ -12815,8 +13606,8 @@ ${view.ctx.t("Ctrl+click to follow the link.")}`;
|
|
|
12815
13606
|
tip.remove();
|
|
12816
13607
|
};
|
|
12817
13608
|
}
|
|
12818
|
-
function workbookLocation(
|
|
12819
|
-
const value =
|
|
13609
|
+
function workbookLocation(target29) {
|
|
13610
|
+
const value = target29.trim();
|
|
12820
13611
|
if (value.startsWith("#")) return value.slice(1);
|
|
12821
13612
|
return /^[a-z][a-z0-9+.-]+:/i.test(value) || /[\\/]/.test(value) ? void 0 : value;
|
|
12822
13613
|
}
|
|
@@ -12846,13 +13637,13 @@ function goTo(view, selection, location) {
|
|
|
12846
13637
|
if (!workbook) return false;
|
|
12847
13638
|
const text3 = location.replace(/^#/, "");
|
|
12848
13639
|
const name = workbook.definedNames.find((n) => n.name.toLowerCase() === text3.toLowerCase());
|
|
12849
|
-
const
|
|
12850
|
-
if (!
|
|
12851
|
-
const sheetIndex =
|
|
13640
|
+
const target29 = referenceTarget(name ? name.formula : text3);
|
|
13641
|
+
if (!target29) return false;
|
|
13642
|
+
const sheetIndex = target29.sheet ? workbook.sheets.indexOf(sheetByName(workbook, target29.sheet)) : view.sheetIndex();
|
|
12852
13643
|
if (sheetIndex < 0) return false;
|
|
12853
13644
|
if (sheetIndex !== view.sheetIndex()) view.ctx.setActiveSheet(sheetIndex);
|
|
12854
|
-
const next = selectCell(sheetIndex, workbook.sheets[sheetIndex],
|
|
12855
|
-
selection.set({ ...next, ranges: [
|
|
13645
|
+
const next = selectCell(sheetIndex, workbook.sheets[sheetIndex], target29.range.start);
|
|
13646
|
+
selection.set({ ...next, ranges: [target29.range] }, target29.range.start);
|
|
12856
13647
|
return true;
|
|
12857
13648
|
}
|
|
12858
13649
|
|
|
@@ -13224,9 +14015,9 @@ function mountGrid(ctx, container) {
|
|
|
13224
14015
|
selection,
|
|
13225
14016
|
editor,
|
|
13226
14017
|
followLink: (row2, col) => followLink(view, selection, row2, col),
|
|
13227
|
-
fill(source,
|
|
13228
|
-
ctx.session()?.fill(view.sheetIndex(), source,
|
|
13229
|
-
selection.set({ ...selection.get(), ranges: [
|
|
14018
|
+
fill(source, target29) {
|
|
14019
|
+
ctx.session()?.fill(view.sheetIndex(), source, target29);
|
|
14020
|
+
selection.set({ ...selection.get(), ranges: [target29] });
|
|
13230
14021
|
}
|
|
13231
14022
|
}),
|
|
13232
14023
|
wireTooltips(view),
|
|
@@ -13415,10 +14206,10 @@ function createFormulaInput(ctx, doc, bar) {
|
|
|
13415
14206
|
const onKey = (event) => {
|
|
13416
14207
|
event.stopPropagation();
|
|
13417
14208
|
if (assist.handleKey(event, field2)) return;
|
|
13418
|
-
const
|
|
14209
|
+
const editing9 = bridge.state().editing;
|
|
13419
14210
|
if (event.key === "Escape") {
|
|
13420
14211
|
event.preventDefault();
|
|
13421
|
-
if (
|
|
14212
|
+
if (editing9) bridge.cancel();
|
|
13422
14213
|
else showCell();
|
|
13423
14214
|
ctx.grid()?.focus();
|
|
13424
14215
|
return;
|
|
@@ -13431,7 +14222,7 @@ function createFormulaInput(ctx, doc, bar) {
|
|
|
13431
14222
|
onInput();
|
|
13432
14223
|
return;
|
|
13433
14224
|
}
|
|
13434
|
-
if (!
|
|
14225
|
+
if (!editing9) return;
|
|
13435
14226
|
if (event.key === "Enter") {
|
|
13436
14227
|
event.preventDefault();
|
|
13437
14228
|
if (event.ctrlKey || event.metaKey) bridge.commit("none", true);
|
|
@@ -14099,13 +14890,13 @@ function mountSheetTabs(ctx, container) {
|
|
|
14099
14890
|
const visible = visibleSheetIndices(workbook);
|
|
14100
14891
|
const at = visible.indexOf(sheet);
|
|
14101
14892
|
const focusAt = (i) => {
|
|
14102
|
-
const
|
|
14103
|
-
if (
|
|
14104
|
-
focusable =
|
|
14893
|
+
const target30 = visible[Math.max(0, Math.min(visible.length - 1, i))];
|
|
14894
|
+
if (target30 === void 0) return;
|
|
14895
|
+
focusable = target30;
|
|
14105
14896
|
for (const tab of strip.querySelectorAll(".xst-tab"))
|
|
14106
|
-
tab.tabIndex = tab.dataset.sheet === String(
|
|
14107
|
-
scrollIntoView(
|
|
14108
|
-
tabFor(strip,
|
|
14897
|
+
tab.tabIndex = tab.dataset.sheet === String(target30) ? 0 : -1;
|
|
14898
|
+
scrollIntoView(target30);
|
|
14899
|
+
tabFor(strip, target30)?.focus();
|
|
14109
14900
|
};
|
|
14110
14901
|
const moves = {
|
|
14111
14902
|
ArrowLeft: at - 1,
|
|
@@ -14113,12 +14904,12 @@ function mountSheetTabs(ctx, container) {
|
|
|
14113
14904
|
Home: 0,
|
|
14114
14905
|
End: visible.length - 1
|
|
14115
14906
|
};
|
|
14116
|
-
const
|
|
14907
|
+
const target29 = moves[event.key];
|
|
14117
14908
|
const menuKey = event.key === "ContextMenu" || event.key === "F10" && event.shiftKey;
|
|
14118
|
-
if (
|
|
14909
|
+
if (target29 === void 0 && !menuKey && !["Enter", " ", "F2"].includes(event.key)) return;
|
|
14119
14910
|
event.preventDefault();
|
|
14120
14911
|
event.stopPropagation();
|
|
14121
|
-
if (
|
|
14912
|
+
if (target29 !== void 0) focusAt(target29);
|
|
14122
14913
|
else if (event.key === "F2") rename(sheet);
|
|
14123
14914
|
else if (menuKey) {
|
|
14124
14915
|
const box = event.target.getBoundingClientRect();
|
|
@@ -14311,7 +15102,7 @@ function collectKeyTips(panel3) {
|
|
|
14311
15102
|
};
|
|
14312
15103
|
targets.push({ key: COMMAND_KEYS[labelOf(control)] ?? "", element: control, activate });
|
|
14313
15104
|
}
|
|
14314
|
-
assignKeyTips(targets, (
|
|
15105
|
+
assignKeyTips(targets, (target29) => target29.element.getAttribute("aria-label") ?? "");
|
|
14315
15106
|
return targets;
|
|
14316
15107
|
}
|
|
14317
15108
|
var runTips = (root, targets, onDone) => (
|
|
@@ -14329,7 +15120,7 @@ function showTabKeyTips(root, select2) {
|
|
|
14329
15120
|
const id = panel3.dataset.tab ?? "";
|
|
14330
15121
|
const tab = tabButton(root, id);
|
|
14331
15122
|
if (!tab || isTabHidden(panel3)) continue;
|
|
14332
|
-
const used = targets.map((
|
|
15123
|
+
const used = targets.map((target29) => target29.key);
|
|
14333
15124
|
let key = TAB_KEYS[id] ?? "";
|
|
14334
15125
|
if (!key || used.includes(key))
|
|
14335
15126
|
key = [...(tab.textContent ?? id).toUpperCase().replace(/[^A-Z]/g, "")].find(
|
|
@@ -14603,10 +15394,10 @@ function adjacentSheet(ctx, step2) {
|
|
|
14603
15394
|
return void 0;
|
|
14604
15395
|
}
|
|
14605
15396
|
function shellCommands(handlers) {
|
|
14606
|
-
const file = (id, label, command,
|
|
15397
|
+
const file = (id, label, command, icon9, shortcut) => ({
|
|
14607
15398
|
id,
|
|
14608
15399
|
label,
|
|
14609
|
-
icon:
|
|
15400
|
+
icon: icon9,
|
|
14610
15401
|
...shortcut ? { shortcut } : {},
|
|
14611
15402
|
enabled: (ctx) => command === "new" || command === "open" || hasWorkbook(ctx),
|
|
14612
15403
|
run: () => handlers.fileCommand(command)
|
|
@@ -15164,9 +15955,9 @@ function buildShell(core) {
|
|
|
15164
15955
|
if (action === "help") return help.open();
|
|
15165
15956
|
if (action === "keytips") return ribbon.showKeyTips();
|
|
15166
15957
|
if (action === "context-menu") {
|
|
15167
|
-
const
|
|
15168
|
-
const box =
|
|
15169
|
-
|
|
15958
|
+
const target29 = root.activeElement ?? gridHost;
|
|
15959
|
+
const box = target29.getBoundingClientRect();
|
|
15960
|
+
target29.dispatchEvent(
|
|
15170
15961
|
new MouseEvent("contextmenu", {
|
|
15171
15962
|
bubbles: true,
|
|
15172
15963
|
composed: true,
|