Skip to content

Let the core render the raw files it has learned to render - #564

Merged
andiwand merged 3 commits into
mainfrom
retire-most-of-the-raw-loader
Aug 2, 2026
Merged

Let the core render the raw files it has learned to render#564
andiwand merged 3 commits into
mainfrom
retire-most-of-the-raw-loader

Conversation

@andiwand

@andiwand andiwand commented Aug 2, 2026

Copy link
Copy Markdown
Member

RawLoader was written when odrcore could only turn office documents into html. Everything else — text, csv, images, audio, video, zip — got a viewer of its own out of assets/: PhotoSwipe, Plyr, JSZip, csv-to-html-table.

odrcore 6.2, which we already ship, renders all of them. Verified against OpenDocument.core at the v6.2.0 tag: translate_html is set for text, csv, zip and cfb, nine image formats (webp, tiff, heic and avif joined the original five), fonts, and all five audio and five video types. html.cpp dispatches them to a line-numbered text view, an <img> page, an archive listing and a real <audio controls> / <video controls playsinline> player.

Most of this was already dead code

LoaderService.onSuccess routes METADATA → CORE unconditionally and FileLoader.loadAsync has no isSupported guard — isSupported only informs routing. RawLoader was reached from exactly one place: LoaderService.onError, when the core threw. Since the core stopped throwing for those formats, those branches stopped running.

Confirmed empirically rather than by reading: I built main in a scratch worktree and ran the same corpus through both. On main a .csv already renders as the core's plain text — the table viewer had quietly died with the 6.2 upgrade.

Deleting the four assets removes 916KB of vendored javascript.

What stays

  • csv, because the core renders it line by line where text-prefix.html builds a real table. Bringing it back is a deliberate feature change, not preservation. It is excluded from CORE_FILE_TYPES and asked for before the core, which otherwise succeeds and RawLoader never gets a turn.
  • svg, which odrcore has no file type for.
  • xml and whatever else reaches the generic branch.

Claim vs render

SupportedDocumentTypes answers two questions now. What the app claims (CLAIMED_FILE_TYPES) is unchanged, so AndroidManifest.xml does not move and we stay out of the share sheet for an mp3. What CoreLoader renders (CORE_FILE_TYPES) is now every translateHtml format whatever its category — so an mp3 handed to us still plays.

Two bugs fixed on the way

  • OnlineLoader used CoreLoader.isSupported to mean "is an office document". That stops being true the moment the core loader claims images and media, so a png would have gone to the LibreOffice converter and the Microsoft viewer. It asks SupportedDocumentTypes.isDocument now — which also makes .xlsb convertible, correctly: the converter is not odrcore.
  • svg never reached RawLoader at all. MetadataLoader asks Odr.mimetype first and the core content-detects an svg as text/plain, so the image/svg+xml a provider volunteered never reached routing — and MimeTypeResolver.resolve then rewrites the extension to txt, losing the name too. Routing on the original filename fixes it. An svg renders as an image for the first time, rather than as a line-numbered text dump.

The "open it in another app" hint follows the core's file category now rather than "the raw loader ran" — which meant the same thing only while everything non-document went to RawLoader.

RawLoaderTest moves to androidTest: the csv spellings come from a table in libodr_jni.

Verification

spotlessCheck, lintProDebug, testProDebugUnitTest and 55 instrumented tests pass on a Pixel 6 Pro emulator.

Same corpus through a build of main and this branch, comparing which loader and which view each file got:

file main this branch
png core image.html unchanged
wav core audio.html unchanged
txt, zip, odt core unchanged
csv core plain text RawLoader table (sortable, search)
svg core text dump RawLoader image
xml core text dump RawLoader

Screenshots confirm the csv table and the svg drawing.

One judgement call worth a look

A failed RawLoader load now falls through to the core rather than erroring — DocumentFragment.onUnsupported has no RAW branch and would otherwise show a blank screen. Easy to change if you would rather it report the error.

🤖 Generated with Claude Code

odrcore 6.2 turns text, images, zip and cfb, fonts, audio and video into html
itself, so the viewers RawLoader kept in assets/ - PhotoSwipe, Plyr, JSZip -
had nothing left to do. They were in fact already unreachable: LoaderService
routes METADATA -> CORE unconditionally and only falls back to RawLoader when
the core *throws*, which it stopped doing for those formats. Deleting them
takes 916KB of vendored javascript with them.

What is left in RawLoader has a reason to be:

- csv, because the core files it as text and renders it line by line where
  text-prefix.html builds a real table. This one is a restoration: on main a
  .csv already showed as plain text, the table viewer having quietly died with
  the 6.2 upgrade. It is excluded from CORE_FILE_TYPES and asked for first,
  since the core would otherwise succeed and RawLoader would never get a turn.
- svg, which odrcore has no file type for at all.
- xml and whatever else reaches the generic branch.

SupportedDocumentTypes now answers two questions instead of one. What the app
*claims* (CLAIMED_FILE_TYPES) is unchanged, so AndroidManifest.xml does not
move and the app still stays out of the share sheet for an mp3; what CoreLoader
*renders* (CORE_FILE_TYPES) is now every translateHtml format whatever its
category, so an mp3 handed to us still plays.

Two bugs fixed on the way:

- OnlineLoader used CoreLoader.isSupported to mean "is an office document",
  which stops being true once the core loader claims images and media - a png
  would have been sent to the libreoffice converter and the microsoft viewer.
  It asks SupportedDocumentTypes.isDocument now, which also makes .xlsb
  convertible: the converter is not odrcore and can manage one.
- svg never reached RawLoader at all. MetadataLoader asks Odr.mimetype first
  and the core content-detects an svg as text/plain, so the image/svg+xml a
  provider volunteered never reached routing - and MimeTypeResolver.resolve
  then rewrites the extension to "txt", losing the name too. Routing on the
  original filename fixes it, and an svg renders as an image for the first
  time rather than as a line-numbered text dump.

The "open it in another app" hint follows the core's file category now rather
than "the raw loader ran", which said the same thing only while everything
that was not a document went to RawLoader.

RawLoaderTest moves to androidTest: the csv spellings come from the core's
table, which lives in libodr_jni.

Verified on an emulator against a build of main over the same corpus: png, wav,
txt, zip and odt route identically, and only csv, svg and xml change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019PhqfvUDxKNH7b9ueC5iuE

@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: 20c2e05e0c

ℹ️ 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".

andiwand and others added 2 commits August 2, 2026 23:22
Routing svg and xml by their filename, which the previous commit added because
the core content-detects both as text/plain, was too eager: it also took a file
the core *had* identified. An odt called report.csv went to RawLoader on the
strength of its name, which base64'd the zip into the table viewer and reported
success - and success leaves no fallback, so the document was simply gone.

The name only gets a say now where the detection has none to give: the core
recognized nothing, or recognized plain text. Anything it identified as a
format of its own keeps that identity.

Reported by codex on #564, reproduced on an emulator (report.csv holding an odt
opened blank, now renders as a document again) and covered by a test.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019PhqfvUDxKNH7b9ueC5iuE
Cut the KDoc and inline comments added by this branch to roughly half. The
originals restated what the code said next to them; what is left is the part a
reader could not reconstruct.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019PhqfvUDxKNH7b9ueC5iuE
@andiwand
andiwand merged commit 977f15f into main Aug 2, 2026
2 checks passed
@andiwand
andiwand deleted the retire-most-of-the-raw-loader branch August 2, 2026 21:28
andiwand added a commit that referenced this pull request Aug 3, 2026
The store listing has carried the same three release notes since 2024 -
137.txt, 93.txt and 82.txt all say "Fix potential crash while saving
changes for a document" - so every release since has gone out with
whatever the console last had, and there is nowhere in the tree that says
what a user got.

One file per release under fastlane/metadata, named by version code,
which is what `fastlane supply` uploads as the Play Console release
notes. The codes jump: 4.6, 4.7 and 4.8.0 were counted by hand (202-204)
and everything from 4.9.0 on is derived from the tag (40900 and up). All
of them are inside Play's 500 character limit.

CHANGELOG.md is the same history at more length, for the repo and for
github releases.

Three of the eight releases say "maintenance release, no visible
changes", because that is what they were: 4.6 was CI cleanup and a
submodule bump of renovate commits, 4.8.0 was the release workflow and
the instrumented test flakiness, and 4.12.0 was moving odrcore from a
conan build to the maven central AAR.

Core changes are folded into the release that absorbed them rather than
listed on their own, since a user has no way to tell where a change came
from. That puts almost everything in 4.7, which took odrcore 5.2.0 ->
5.7.1 in one go: the whole PDF renderer, the built-in doc/xls/ppt
implementations, and the drop of the pdf2htmlEX and wvWare backends.

Nothing about formats that disappeared and came back - the csv table
viewer that died with the 6.2 upgrade and returned in #564 reads only as
"text, images, archives and media are shown by the engine", and the lite
review prompt that had been dead since 4.2 is not described as broken.

Play-facing wording says "our own engine" rather than naming odrcore,
which store readers have no reason to know.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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