fix: stop guessing a kind for composite Divi attribute paths
Review fix round 1 on the lit/divi-catalog task:
- AttrPathIndex::collectKinds() no longer records a kind from a
component.type === "group" node (a composite of several sub-kinds,
e.g. button.innerContent = text + link + target), and kinds() now
drops any attrName with more than one distinct candidate kind
instead of last-write-wins (e.g. imageIcon.innerContent had onoff +
icon + image sub-fields sharing one attrName). Both previously
produced a wrong-but-present kind, which is more dangerous for 2b's
sanitization routing than "unknown". Verified against the committed
blurb/button/fullwidth-header fixture entries and live against the
full 100-module catalog.
- AttrPathIndex::fromDefaults() now builds on AttrMap::flatten()
instead of a parallel walker.
- ModuleCatalog::shortName() replaces the duplicated
substr($name, strlen('divi/')) in DiviCatalogAbility.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01At3V6SjwbMe6eMzVGW3Hs7
This commit is contained in:
@@ -136,12 +136,13 @@ final class ModuleCatalogTest extends TestCase
|
||||
self::assertSame('richtext', $catalog->pathKind('divi/text', 'content.innerContent'));
|
||||
self::assertSame('text', $catalog->pathKind('divi/heading', 'title.innerContent'));
|
||||
self::assertSame('code', $catalog->pathKind('divi/code', 'content.innerContent'));
|
||||
self::assertSame('url', $catalog->pathKind('divi/button', 'button.innerContent'));
|
||||
self::assertSame('text', $catalog->pathKind('divi/button', 'module.meta.adminLabel'));
|
||||
// Structural/style groups (fonts, backgrounds, …) carry no single scalar component in
|
||||
// Divi's metadata; 2b falls back to key-name routing for them (spec §5.6, ruling R3).
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/button', 'button.decoration.background'));
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/button', 'no.such.path'));
|
||||
// divi/image has no explicit attrName for its innerContent sub-fields at all.
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/image', 'image.innerContent'));
|
||||
|
||||
// Every kind in the module's kinds() map is a string, keyed by a known attribute path.
|
||||
$paths = $catalog->paths('divi/heading');
|
||||
@@ -150,4 +151,20 @@ final class ModuleCatalogTest extends TestCase
|
||||
self::assertContains($path, $paths);
|
||||
}
|
||||
}
|
||||
|
||||
public function testLeavesCompositeAttributePathsUnknownRatherThanGuessing(): void
|
||||
{
|
||||
$catalog = self::sampleCatalog();
|
||||
|
||||
// button.innerContent's only attrName-annotated node is the "link" sub-group itself
|
||||
// (component.type "group": link text + linkUrl + linkTarget) – not a single scalar kind.
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/button', 'button.innerContent'));
|
||||
|
||||
// imageIcon.innerContent carries three "field" components under the same attrName with
|
||||
// different kinds (useIcon: onoff, icon: icon, src: image) – a genuine conflict.
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/blurb', 'imageIcon.innerContent'));
|
||||
|
||||
// fullwidth-header's scrollDown.decoration.icon is the same pattern (onoff/icon/color/number).
|
||||
self::assertSame('unknown', $catalog->pathKind('divi/fullwidth-header', 'scrollDown.decoration.icon'));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user