Frames on the page or in a section convert to sections (object.convertToSection) and sections back to frames (object.convertToFrame), in place, one undo step each, from the canvas context menu; nested frames, instances, main components and sections holding sections are refused.
The .fig export now writes a numbered list's start on each of its lines,
so a reader that takes it per line or per list counts the same. Bullets
no longer keep a start. The field is named start_offset (it holds the
offset: 1 shows "2."). get_node reports listStartOffsets. The parity doc
lists what's still not read from .fig lists.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Figma stores where a numbered list starts counting on each text line
(listStartOffset; a list shown as "2." has offset 1). The import dropped
it, so every list counted from 1.
A paragraph's list settings now carry a start number (written only when
set, so older files open and save unchanged). Numbering counts on from
it where a list starts; items that go on counting ignore it. The .fig
import reads it, the .fig export writes it on a list's first line, and
plain paragraphs drop it. Toggling a list off ignores differing starts.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A home-screen drop that carries only bytes queued file.open with data and name, which file.open rejected because it requires a path. file.open now also takes base64 data with a name and opens it as a new document without a save path.
Found while testing crates/engine/src/cmd/file.rs:1283
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Regression test for #586: with the colour picker open on a red rectangle or
pen path, duplicating it (edit.duplicate, or copy and paste) and recolouring
the copy leaves the original red. The cause was the picker staying bound to
the original after the selection moved to the copy, fixed by #523; without
that fix this test fails. The duplicated paint is already independent data.
- Files dragged over the window show a "Drop to open" (home screen) or
"Drop to import" (canvas) overlay.
- On the home screen each dropped file the app opens becomes a document of its
own; any other file is turned away with a toast.
- On the canvas dropped files import as before, at the drop point.
- A small card ("Opening as a new file", "Adding to {document}") is on screen
before a large file blocks the window; the files then open a frame later.
- A canvas import stays with the document and page that received the drop,
keeps its placement, restores the page and selection chosen meanwhile, and is
cancelled with a message if that document or page is gone.
- ui.inspect reports pendingOpens; every new string, including the cancel
messages, goes through tr() with en, de and es entries.
page.duplicate copies every layer with duplicate_all_into (navigation between
copied frames points at the copies) and builds the old-to-new list for flows
from that copy, instead of copying each layer separately.
Main's case-insensitive replace loop (from an earlier PR) took the place of the
loop this change edited, so the replacement text is normalised once, where
the parameter is read.
Czech counts take three integer forms: one (1), few (2-4) and other
(0 and 5+). Since #257 catalogs can supply `few`, so `plural()` gets a
Czech rule and the 38 plural entries in cs.toml now read naturally
("1 vrstva", "3 vrstvy", "5 vrstev") instead of the count-neutral
"Vrstvy: {n}" that #469 used for everything but 1.
Test czech_integer_plurals covers the rule (1; 2-4; 0, 5, 11, 12, 21,
22, 100, 1 000 000), a real key through counted(), and that every Czech
plural entry has one and few. Docs no longer say Czech has only one/other.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The control server answered a line that wasn't JSON with an error and read
on. A web page can make the browser send an HTTP request to the loopback
port; its request and header lines were skipped that way and the JSON lines
of its body ran as commands. The first line that isn't JSON now closes the
connection before anything after it is read. Clients that send JSON lines
(MCP --attach, scripts) are unaffected.