Skip to content

feat(html): the sheet editor formats a selection of cells - #938

Merged
andiwand merged 3 commits into
mainfrom
feat/sheet-format-editor
Sep 28, 2026
Merged

andiwand merged 3 commits into
mainfrom
feat/sheet-format-editor

Conversation

@andiwand

@andiwand andiwand commented Sep 28, 2026 •

Copy link
Copy Markdown
Member

🤖 Generated with Claude Code

Step 4 of the cell-formatting plan (#934): the browser side.

Change

  • Selection. spreadsheet.js owns a rectangle that the pin is one corner of. A shift click, a shift arrow and a mouse drag (in the editing mode only) move the other corner. A column or row header selects its column or row across the rendered extent. odr.sheet adds selection(), select(position) and selectedCells(), and a merge answers once, at its anchor. A wider selection gets a wash of its own in both schemes.
  • Formatting. odr.editing.format(style) and toggle(property) act on every selected cell, with fill (#rrggbb or null) and align (left, center, right) beside the text keys of the document editor. A lock refuses a value, not a style, so a formula cell takes a style.
  • Paint. The editor patches the td and the x-p/x-s inside it with the declarations that the renderer writes. A fill also sets --odr-dark-fill, computed with a JavaScript copy of html::dark_fill, so a fill made in the dark scheme shows. In the dark scheme the renderer now also writes the light fill as --odr-fill, so the editor can read a cell's fill back.
  • Host events. onSelectionChange reports the keys that the selected cells agree on. Ctrl or Cmd with B, I and U toggle, where the config gives the scripts the shortcuts.
  • Log. One gesture is one undo step. The log holds one setCellStyle op per cell, the style keys of one cell merge with the later keys winning, and style ops do not mark formula cells stale.

Proof

  • New test/browser/sheet/formatting.html: 57 checks, 0 failed, headless Chrome. It covers the selection gestures, a fill and its dark colour, the text keys over a direct-text cell and a styled run, alignment, undo and redo, op merging, value plus style on one cell, a formula cell, refusals, an empty style, and the chords, which leave a key typed into a field alone.
  • The dark colours are pinned on both sides: html_common.a_dark_fill_is_what_the_sheet_editor_computes in C++, and the same five values in formatting.html.
  • All sheet check pages pass: tests 14, positions 22, sorting 8, editing 78, keyboard 10, formatting 57.
  • End to end: a real render of Senza nome 1.ods (translate CLI, editable) was formatted through odr.editing in Chrome: a 3×2 range filled and made bold, a cell italic/underlined/red/left, a cell struck at 16pt, and fills set and taken away. The op log (10 ops) was replayed with Document::edit and saved. LibreOffice renders the saved file as the page showed it.
  • The full suite passes (1895 tests).

Reference output

Only resources/ changes: the three scripts and the two sheet stylesheets. Pins: public c063f3c, private a4713fd.

The last commit changes sheet-editing.js and spreadsheet.js again, so resources/ at these pins still holds the scripts before it. No page changes. A fresh run differs from the pins in those two files only, in both repositories. One more output commit and pin advance brings them in line.

@andiwand
andiwand force-pushed the feat/xlsx-cell-style branch from eea7d7a to 197bec9 Compare September 28, 2026 19:08
Base automatically changed from feat/xlsx-cell-style to main September 28, 2026 19:28
andiwand and others added 3 commits September 28, 2026 21:28
A selection is a rectangle that the pin is one corner of. A shift click, a
shift arrow and a mouse drag in the editing mode move the other corner, and
a header click selects its row or column. odr.sheet answers selection(),
select(position) and selectedCells().

odr.editing.format and toggle act on every selected cell: fill, align and
the text keys of the document editor. The editor patches the cell and the
text in it with the declarations that the renderer writes. A fill also sets
--odr-dark-fill with the mapping of html::dark_fill, so a fill made in the
dark scheme shows. The renderer writes --odr-fill beside it, so the editor
reads the fill back in the dark scheme. onSelectionChange reports the keys
that the selected cells agree on, Ctrl or Cmd with B, I and U toggle, and
one gesture is one undo step. The log holds one setCellStyle op per cell,
and the keys of one cell merge.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NXnz6EZY8YpyiyyE1GpsWy
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NXnz6EZY8YpyiyyE1GpsWy
The formatting chords of the sheet editor did not check where the key
came from, so ctrl+b in a text field made the selected cells bold and
the field never saw the key. The chords now skip a field, as the arrow
keys do. An empty style refuses and logs no op. A drag that stays on one
cell no longer repaints the selection and reports it again on every
mouse move.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tigcf9he3w1aHfNPJoEGsd
@andiwand
andiwand force-pushed the feat/sheet-format-editor branch from 5531ba5 to 716e5cf Compare September 28, 2026 19:35
@andiwand
andiwand merged commit b0c02f6 into main Sep 28, 2026
27 checks passed
@andiwand
andiwand deleted the feat/sheet-format-editor branch September 28, 2026 19:40
andiwand added a commit to opendocument-app/OpenDocument.test.output that referenced this pull request Sep 28, 2026
The sheet editor ignores a formatting chord typed into a field, refuses
an empty style, and reports a selection only when its focus moves.
opendocument-app/OpenDocument.core#938
andiwand added a commit that referenced this pull request Sep 28, 2026
The review of #938 changed `sheet-editing.js` and `spreadsheet.js`, so
`resources/` in both output repositories now holds the new scripts. No
page changes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Tigcf9he3w1aHfNPJoEGsd
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant