Skip to content

Give every frame fragment a single content root - #97

Merged
ctgnz merged 5 commits into
masterfrom
feat/79-frame-content-root
Sep 24, 2026
Merged

ctgnz merged 5 commits into
masterfrom
feat/79-frame-content-root

Conversation

@ctgnz

@ctgnz ctgnz commented Sep 24, 2026

Copy link
Copy Markdown
Owner

Closes #79.

All 225 frame fragments now hold exactly one content element — 217 a <g id="frame">, and the eight overlays a <g id="frame_overlay">. Nothing else at the root.

The survey turned up more than the issue's ten, because it also looked at naming and at the construction guide the issue had silently discounted. Five commits, in the order they were worked out.

What was wrong

files fix
letter group beside #frame_overlay rather than inside it 2 folded in, matching overlays 5 and 7
frame content loose at the root (<path>, or an unnamed <g>) 3 moved into #frame
frame outline in an unnamed group, fill in #frame 5 outline moved in, matching 0_327_0
content root named frame_1_ / frame_2_ 10 renamed frame; two were a bare <polyline> and are now wrapped
<g id="octagon"> construction guide 14 removed

Most of these had a sibling that already showed the intended shape — 0_160_0c, 0_060_0c, 0_327_0, overlays 5 and 7 — so the target was rarely a judgement call.

The octagon guide is the bounding octagon, its mod1/mod2 guide lines and the outFrame outline: scaffolding for positioning a main icon or sector modifier within the octagon. A frame is drawn around the octagon rather than within it, so it was never of any use in these files.

0_060_0 is the only file that loses anything. Its unnamed group held a second copy of the cloverleaf #frame already drew, alongside the bump. Identical d, fill and stroke, and opaque, so drawing it twice and drawing it once come out the same — and 0_060_0c has the bump in #frame with no duplicate, which is what it now matches.

Why the normaliser had not already caught the names

FragmentNormaliser's generated-id test is an SVG element name followed by digits. frame is not an element name, so frame_1_ reads as a name worth keeping. It is a name — just not a useful one.

Verification

SvgFingerprint cannot guard this, for the same reason it could not guard #78: it records structure, so moving an element between groups changes it by design. Instead, every drawing element compared before and after with its ancestors' attributes folded in and display:none subtrees left out — so a move between groups carrying nothing but an id is invisible to the comparison, and so is the removal of a hidden guide.

  • 27 files changed, 26 draw identically; the one difference is 0_060_0's duplicate, 3 drawn → 2.
  • FragmentMeasurer re-run: frame bounds identical, which also confirms foxglove was already honouring the guide's display, rather than it quietly counting towards a frame's extent.
  • Normaliser clean, mvn verify green.

Next

This makes frames the second family with a settled shape, after the free canvas fragments in #78. Once #80 gives the remaining fragments their canonical ids, FragmentShapeChecker can cover all three rather than just free canvas.

The matching changes to jmsfx-hallux are in the hallux working tree, uncommitted.

🤖 Generated with Claude Code

ctgnz and others added 5 commits September 25, 2026 08:29
Overlay 6 and 8 each carried their letter in a group sitting beside
#frame_overlay rather than inside it, where 5 and 7 - the same two overlays with
a different letter - put theirs. The suffixes those groups carry, -3 and -5, are
what an editor adds when a group is duplicated, so this was one overlay copied
rather than two drawn differently.

Nothing is drawn differently. The group was the last thing in the document and
becomes the last thing in #frame_overlay, which is itself last, so paint order
holds; and #frame_overlay carries no attributes beyond its id, so nothing new is
inherited. Checked by comparing every drawing element before and after with its
ancestors' attributes folded in - 14 each, identical.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CTG's changes. Three fragments drew part of the frame outside the group that
names it: 0_160_0 and 0_560_0 left the right-hand bump as a loose <path>, and
0_060_0 held it in an unnamed group alongside a second copy of the cloverleaf
that #frame already drew.

Both have a counterpart that shows the intended shape - 0_160_0c and 0_060_0c,
the same frames in the other identity colour - and both keep everything inside
#frame, with no duplicate.

0_160_0 and 0_560_0 draw exactly what they drew. 0_060_0 loses one of its three
paths, which is the duplicated cloverleaf: identical d, fill and stroke to the one
kept, and opaque, so drawing it twice and drawing it once come out the same.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
CTG's changes. Five fragments split the frame in two: the filled polygon inside
#frame, and the stroked outline of the same polygon in an unnamed group beside
it. 0_327_0 - the same frame, undashed - already held both inside #frame, so it
is what the other five now look like.

Nothing is drawn differently: the outline was already painting after the fill and
still does, and the group it came out of carried no attributes to inherit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Ten fragments called their content root frame_1_ or frame_2_ - the suffix an
editor adds when a group is duplicated, rather than a name anything chose - and
two of those, 0_435_0 and 0_435_0c, put it on a bare <polyline> with no group at
all, so there was nothing for a consumer to take hold of. Those two are now
wrapped in a <g id="frame"> like the rest; the other eight are renamed.

The normaliser leaves these alone by design: its generated-id test is an SVG
element name followed by digits, and "frame" is not an element name, so frame_1_
reads as a name worth keeping. It is a name, just not a useful one.

An id is not part of SvgFingerprint and nothing in the tree references one of
these, so nothing is drawn differently.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Fourteen frames carried a <g id="octagon"> - the bounding octagon, its mod1 and
mod2 guide lines, and the outFrame outline. That is drawing scaffolding for
positioning a main icon or a sector modifier within the octagon, and a frame is
the thing drawn around the octagon rather than within it, so it was never of any
use here.

It was display="none" throughout, so nothing is drawn differently, and the
measured frame bounds come back identical - which also confirms foxglove was
already honouring the display, rather than the group having quietly counted
towards a frame's extent all this time.

With this, all 225 frame fragments hold exactly one content element: 217 a
<g id="frame">, and the eight overlays a <g id="frame_overlay">.

Closes #79

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ctgnz
ctgnz merged commit a3bd613 into master Sep 24, 2026
1 check passed
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.

Frame fragments: give each a single content root

1 participant