Outcome
Audit and complete the browser-to-host file workflow rather than claiming it works because Blob exists. Required for imported sources, portable/reference projects, PNG, SRT/EDL and movie downloads. Playback depends on #54; persistence integration depends on #56; PNG pixels remain owned by #34.
Specification and implementation
- Audit File/Blob constructors and methods used by the app (size/type/name, text, arrayBuffer, slice), FileReader.readAsDataURL and load/error/abort ordering, URL.createObjectURL/revokeObjectURL, fetch(blob URL), and input[type=file]/FileList/change plus file drag/drop/DataTransfer. Implement missing pieces using immutable/shared byte ownership with cancellation and origin checks.
- Integrate native picker and download host services with user activation/host policy. Support multiple selection, accept filtering as a picker hint, cancellation and file names; do not silently read arbitrary local paths from script.
- Implement anchor.download + click for Blob URLs through a real save operation; propagate host cancellation/errors observably and sanitize suggested names. Never declare export successful merely because a URL was created.
- Support Frameforge portable .frameforge projects (base64-embedded imported files, app limit 250 MiB media / 360 MiB project JSON), reference projects/relinking, still import, SRT import/export and EDL downloads. Preserve original app validation and content; document memory costs and avoid redundant whole-file copies when possible.
- Blob URL revocation prevents new access while acquired readers/decoders retain valid leases until completion. Ensure navigation, download cancellation and source disposal reclaim storage; add MIME/range support where media consumes Blob resources.
Tests and verification
Round-trip binary files with non-ASCII names, empty/large files and typed-array slices; revoke during decode/download; cross-origin denial; picker/drop cancellation and multiple selection; missing/relinked sources; corrupt portable project and boundary-size failures. Verify saved bytes on disk independently, reload exported project and compare project/media contents. Exercise Native AOT picker callbacks without trimming failures.
Acceptance
References
File API and HTML download handling.
Original application references
Shared delivery requirements
Parent: #53. Baseline: PR #43 / ce56d49; sample experiments/WebScene.Frameforge.
Reference application: https://github.com/wieslawsoltes/Frameforge (pin f414cd44896b659a5c6da2e4fc596a2ded055f2a, includes demo media and THIRD_PARTY_NOTICES.md).
Implement in WebScene, leaving original application JavaScript/WGSL unchanged. No fake capability objects, synthetic successful events or swallowed errors. Keep public contracts cross-platform with isolated backend implementations; qualify macOS arm64 first and explicitly track Windows/Linux follow-up. Production Avalonia 11 must remain supported; only samples opt into Avalonia 12. Native AOT/trim safety is mandatory.
Add focused native/managed regression coverage and a pinned WPT subset or clearly labeled project-owned contract for non-WebGPU behavior. Applicable WebGPU CTS cases belong with GPU work. Record exact revisions, test commands, negative cases and reproducible evidence in the implementation PR. Unsupported functionality cannot be marked passed; distinguish app coverage from standards conformance. Review existing implementation before adding overlapping infrastructure.
Native application file integration — clarified requirement
WebScene hosts a native application. Browser file APIs are compatibility entry points into native host services; the user-facing action is Open/Import or Save/Save As, not a browser download. This requirement supersedes any browser-download terminology above.
Backend contract
- Define a backend-neutral asynchronous file interaction service for selecting existing files and selecting/writing a save destination. Supply filename suggestions, allowed file types, multiple-selection intent and owning window; return selected file handles/streams or explicit cancellation. Avoid assuming every provider exposes a local filesystem path.
- Wire Avalonia to its native storage/file picker integration (StorageProvider OpenFilePickerAsync/SaveFilePickerAsync or the applicable supported API), and Uno to its platform file open/save picker APIs. Resolve picker ownership from the actual hosting window; handle UI-thread dispatch, modal ownership and platform lifecycle requirements in the backend. Inspect existing host abstractions first and extend them rather than adding a sample-only dialog implementation.
- HTML input[type=file], programmatic activation under the host interaction policy, and supported web picker entry points invoke the native Open dialog. Native file drops feed the same file abstraction and browser File/FileList compatibility objects. Preserve filtering, multiselect and cancellation semantics.
- Blob + anchor.download/click and supported save-picker APIs invoke the host Save workflow. The compatibility property
download supplies a suggested filename; it must not create a browser download shelf, silently choose Downloads, or launch a browser. Use the host-selected destination and normal platform overwrite handling.
- Write actual exported bytes to the selected native file/stream with bounded asynchronous I/O, proper close/flush and safe replacement where supported. Report write failures through host diagnostics/user feedback and web API promises/events where those APIs define them; do not invent a promise for anchor.click. Cancellation is normal and must not be presented as a saved file.
- Host configuration may supply an application-specific save destination/workflow, but it must be explicit. Do not silently bypass the native picker or route to a fixed directory. Respect sandbox/security-scoped access and provider lifetime without exposing unrelated filesystem access to JavaScript.
- Native user-facing wording should say Open, Import, Save or Export. Preserve original Frameforge JavaScript; implement the bridge in WebScene/backend integration. Original web UI text may remain where supplied by the app, but host chrome must behave as native file operations.
Required acceptance on both backends
Outcome
Audit and complete the browser-to-host file workflow rather than claiming it works because Blob exists. Required for imported sources, portable/reference projects, PNG, SRT/EDL and movie downloads. Playback depends on #54; persistence integration depends on #56; PNG pixels remain owned by #34.
Specification and implementation
Tests and verification
Round-trip binary files with non-ASCII names, empty/large files and typed-array slices; revoke during decode/download; cross-origin denial; picker/drop cancellation and multiple selection; missing/relinked sources; corrupt portable project and boundary-size failures. Verify saved bytes on disk independently, reload exported project and compare project/media contents. Exercise Native AOT picker callbacks without trimming failures.
Acceptance
References
File API and HTML download handling.
Original application references
Shared delivery requirements
Parent: #53. Baseline: PR #43 / ce56d49; sample
experiments/WebScene.Frameforge.Reference application: https://github.com/wieslawsoltes/Frameforge (pin f414cd44896b659a5c6da2e4fc596a2ded055f2a, includes demo media and THIRD_PARTY_NOTICES.md).
Implement in WebScene, leaving original application JavaScript/WGSL unchanged. No fake capability objects, synthetic successful events or swallowed errors. Keep public contracts cross-platform with isolated backend implementations; qualify macOS arm64 first and explicitly track Windows/Linux follow-up. Production Avalonia 11 must remain supported; only samples opt into Avalonia 12. Native AOT/trim safety is mandatory.
Add focused native/managed regression coverage and a pinned WPT subset or clearly labeled project-owned contract for non-WebGPU behavior. Applicable WebGPU CTS cases belong with GPU work. Record exact revisions, test commands, negative cases and reproducible evidence in the implementation PR. Unsupported functionality cannot be marked passed; distinguish app coverage from standards conformance. Review existing implementation before adding overlapping infrastructure.
Native application file integration — clarified requirement
WebScene hosts a native application. Browser file APIs are compatibility entry points into native host services; the user-facing action is Open/Import or Save/Save As, not a browser download. This requirement supersedes any browser-download terminology above.
Backend contract
downloadsupplies a suggested filename; it must not create a browser download shelf, silently choose Downloads, or launch a browser. Use the host-selected destination and normal platform overwrite handling.Required acceptance on both backends