A file placed from a path becomes a link immediately, with its size and
time as the fingerprint and its bytes kept resident. The background job
adds the content hash and proxy to the live document, undo history and
saved state without changing storage. Saves (file.save, saveACopy,
serialize, recovery snapshots) make the proxies still missing and write
links without a hash. An open hashes a no-hash link whose file matches by
size and time. embed:true placements hash while placing. The embed-until-
hashed path (settle_pending, settle_copy, keep_embedded) is gone.
Placing from files (file.place, place.load, table and media posters)
embeds each graphic with its link record and queues its content hash
and proxy on the link-check thread; the poll links it under the same
key, in the live document, the undo history and the saved state. A
save before then hashes the pending graphics from their bytes and
writes them embedded. crop_pdf checks the crop choice and mime before
reading, and place and relink pass the bytes they already hold.
- Open queues every linked file's lookup (stat, then hash) for the background
check instead of stating candidates on the UI thread.
- links.list, links.update and relinkFolder use the open's status only while
its check is still running; afterwards the file is looked at as it is now.
- Preflight tells Modified from size, time and the remembered hash checks
(the worker keeps them between passes) and the vector test from the mime
type; it never loads a linked original.
- A modification time of 0 never vouches for a file's bytes.
- Migration keeps an unsettled time as UNVERIFIED_MTIME; recovery snapshots
keep images not yet saved as links embedded.
- Links panel test fixture has real files, so its Embedded assertions hold.
IDML imports link the files they read through links::link_to_file, the
path File > Place takes, so a file read just after it was written keeps
an unverified fingerprint and its status comes from the hash instead of
reading as missing. File > Package and Links > Copy Links To point a
linked graphic's record (paths, unverified fingerprint) at its copy.
Regular-file metadata goes through io::file_metadata, which the file
guard accepts.
Save records each link's absolute path and its path relative to the
destination; linked assets write their record and proxy only, and Save a
Copy {embedLinks: true} copies every linked file in (failing on a missing
or changed one). On the web, links stay links with a warning.
Recovery snapshots record links as a save to the document's own file
would, never their originals; recovered documents resolve relative links
against the recorded document path.
Open (and Revert, Open Bytes, Recover) points each linked asset at its
file without reading it: a file with the recorded size and time is the
one; one with the recorded size and another time is hashed on a
cancellable background thread (native_links), absolute path first, and
the first hash match wins and keeps its new time. No match is Modified.
Status is kept on DocState::links for the Links panel; links.progress
applies results and gives the status-line notice once.
Documents saved before linked storage (embedded assets with a link and
no content hash), opened from a file, get a background byte comparison;
confirmed images get their hash and a proxy and save as links, and their
in-memory bytes become a link after that save. Changed or missing files
stay embedded.
Based on #1108 by ForestParks.
(cherry picked from commit 3a453b7f3752d255b6f74cfb55ea2459c5d9a074)