Skip to content

Fit a document to the screen, as Android does - #157

Merged
andiwand merged 2 commits into
mainfrom
viewer-html-config
Aug 15, 2026
Merged

Fit a document to the screen, as Android does#157
andiwand merged 2 commits into
mainfrom
viewer-html-config

Conversation

@andiwand

@andiwand andiwand commented Aug 15, 2026

Copy link
Copy Markdown
Member

Stacked on #156, which is stacked on #155 — this branch adds only its own commit.

What the two apps actually send odrcore

CoreLoader.kt and CoreWrapper.swift, side by side:

OpenDocument.droid here, before here, now
embedImages false false false
embedShippedResources true unset (default true) true
relativeResourcePaths false false false
textDocumentMargin the pagination setting, default true true true
editable editable editable editable
viewport unsetautomatic unsetautomatic unsetautomatic

So the config was already the same in effect, on the same odrcore (6.6.0) — embedShippedResources is the one line that was left implicit, and it is spelled out now. Android's textDocumentMargin follows a user setting we have no equivalent for; its default is true, which is what we pass.

The HTML that comes back is therefore identical. I checked what odrcore emits for each fixture:

fixture viewport meta
test.odt width=device-width,user-scalable=yes
test.odp width=device-width,user-scalable=yes
test.ods width=device-width,initial-scale=1.0,user-scalable=yes
test.csv width=device-width,initial-scale=1.0,user-scalable=yes

Paged content leaves the scale out on purpose; reflowing content names it.

Where the two readers part

Leaving the scale out only means "fit the width" to a web view in overview mode. PageView.kt sets loadWithOverviewMode = true and useWideViewPort = true, so Android zooms a page out until its full width is on screen. WKWebView has no such setting and reads width=device-width literally: lay out at screen width, let the rest overflow. A letter-wide page ran off the right edge of every iPhone — the clipped text is visible in the screenshots on #155.

A script at document end gives the viewport meta the width the page actually needs, which is overview mode by the only means iOS has. A page that names its own scale is left alone, so spreadsheets and csvs still open at 100% exactly as they do on Android.

Checked in the simulator

iPhone 17 Pro on iOS 26.0 and iPhone 16 Pro on iOS 18.4:

  • test.odt — the page now fits the screen with odrcore's gutter around it, and full lines are readable instead of being cut off mid-sentence. Pinch to zoom still works.
  • test.ods — unchanged, opens at actual size.

Unit tests pass and scripts/format.sh --check is clean.

🤖 Generated with Claude Code

@andiwand
andiwand force-pushed the viewer-toolbar-buttons branch from e12c25c to d3f663e Compare August 15, 2026 17:01

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5cd1b9f733

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread OpenDocumentReader/DocumentViewController.swift Outdated
Base automatically changed from viewer-toolbar-buttons to main August 15, 2026 17:01
@andiwand
andiwand force-pushed the viewer-html-config branch from 5cd1b9f to 7f95adc Compare August 15, 2026 17:01
andiwand and others added 2 commits August 15, 2026 19:03
OpenDocument.droid gives odrcore the same five answers we do, and gets the
same HTML out: a text document or a presentation carries
`width=device-width` and no scale of its own, a spreadsheet or a csv names
`initial-scale=1.0`. Only `embedShippedResources` was left to odrcore's
default here, so it is spelled out now next to the rest.

What differed is the reader. A web view in Android's overview mode zooms a
page out until its full width is on screen, which is what odrcore means by
leaving the scale out; WKWebView has no such setting, so a letter-wide page
was laid out at 100% and ran off the right edge of every phone. A script at
document end gives the viewport meta the width the page actually needs,
which is the same thing by the only means iOS has. A page that names its own
scale means it, and is left alone.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Q1T4UTUxDqjCGUn3Uiyhkj
The script was registered once for the web view, which shows more than
odrcore's pages: the formats odrcore does not handle are loaded from a
file, and a link in a document is followed in the same view. Their
viewport is their author's to write - a fixed-width page would have been
shrunk, and `user-scalable=no`, a maximum scale or a `viewport-fit`
thrown away with the rest of what it said.

It is installed per load now, only for a URL `isServedURL` recognises,
and the script checks the origin it was installed for before it touches
anything - the fallback to a file happens after the page it replaces was
already asked for.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Q1T4UTUxDqjCGUn3Uiyhkj
@andiwand
andiwand force-pushed the viewer-html-config branch from 7f95adc to c5408f1 Compare August 15, 2026 17:08
@andiwand
andiwand merged commit f97959a into main Aug 15, 2026
4 checks passed
@andiwand
andiwand deleted the viewer-html-config branch August 15, 2026 17:09
andiwand added a commit that referenced this pull request Aug 15, 2026
Everything under Unreleased is in: the tool bar sitting on the status bar
(#155), the chevron and the pencil (#156), and a document fitted to the
screen (#157). That is a version, so the heading is cut to 1.40 and the
store copy for it written.

No date and no compare link on the heading: v1.40 is written when the
drafted release is published, and this file says to wait for the tag. The
Unreleased link stays on v1.39...HEAD for the same reason.

Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
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