Split the debug hook into one file per topic (#215)
debugHook.ts had grown to 1097 lines of unrelated test hooks. They now live in seven files under src/editor/debug/, grouped by topic. debugHook.ts only assembles them and is down to 86 lines. - The shape of window.__gm is unchanged for tools/. Measured in the browser before and after: 120 top-level keys and 313 leaves with their arity, byte-identical JSON. - The Text import is explicit in the helpers. Without it the name fell back to the DOM type and instanceof would never have matched. Findings: - The comment for vectorArt sat above pixelArt. It is back in place. - An orphaned duplicate comment on assetRow is gone. Tests: - ./check.sh: 145 files, 2192 tests, CHECK EXIT 0 (unchanged) - e2e 1-16,37,39-43,47,48: ALL PASSED, 734 checks - The shape probe turns red against a deliberately misnested hook. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b830f9c747
commit
ed29b2f3dc
9 files changed
+1114
-1031
No files matched your search
@@ -0,0 +1,80 @@
|
||||
import { findAsset } from '../../core/model/Project';
|
||||
import { currentGradientBar, currentShapeList } from '../inspector/shapeSection';
|
||||
import { centreOf, snapButton, type HookContext } from './hookHelpers';
|
||||
|
||||
/** The Vector art tab (#129). */
|
||||
export function vectorArtHooks({ state, editor }: HookContext) {
|
||||
const { vectorArtEditor } = editor;
|
||||
return {
|
||||
/** The Vector art tab (#129, stage 3): where a canvas pixel is, and which tool a press uses. */
|
||||
vectorArt: {
|
||||
current: () => vectorArtEditor.currentAssetId,
|
||||
info: () => vectorArtEditor.shownInfo,
|
||||
pointAt: (x: number, y: number) => vectorArtEditor.canvasToScreen(x, y),
|
||||
rect: () => vectorArtEditor.canvasRect(),
|
||||
tool: () => vectorArtEditor.canvas.currentTool,
|
||||
snapping: () => vectorArtEditor.canvas.snapping,
|
||||
snapButton: () => snapButton(vectorArtEditor.snap),
|
||||
/** Whether the pen has a line open that the next click would add a point to. */
|
||||
drawing: () => vectorArtEditor.canvas.drawing,
|
||||
/** The header's point type (#195): where to click it, what it says, and the type it reads. */
|
||||
pointButton: () => ({
|
||||
...centreOf(vectorArtEditor.pointButton),
|
||||
text: vectorArtEditor.pointButton.text,
|
||||
enabled: vectorArtEditor.pointButton.enabled,
|
||||
kind: vectorArtEditor.canvas.pickedKind,
|
||||
}),
|
||||
/** The shapes as the model holds them, so a check can read points and handles exactly. */
|
||||
shapes: (assetId: string) => {
|
||||
const asset = findAsset(state.project, assetId);
|
||||
if (!asset || asset.type !== 'vectorart') return null;
|
||||
return asset.shapes.map((shape) => ({
|
||||
id: shape.id,
|
||||
name: shape.name,
|
||||
fill: shape.fill,
|
||||
opacity: shape.opacity,
|
||||
stroke: shape.stroke ? (JSON.parse(JSON.stringify(shape.stroke)) as unknown) : null,
|
||||
paint: shape.paint ? (JSON.parse(JSON.stringify(shape.paint)) as unknown) : null,
|
||||
rings: shape.rings.map((ring) => ({
|
||||
closed: ring.closed,
|
||||
points: ring.points.map((point) => ({
|
||||
x: point.x,
|
||||
y: point.y,
|
||||
in: point.in ? { ...point.in } : null,
|
||||
out: point.out ? { ...point.out } : null,
|
||||
mode: point.mode ?? null,
|
||||
})),
|
||||
})),
|
||||
}));
|
||||
},
|
||||
selected: () => (state.selection?.kind === 'shape' ? state.selection.shapeId : ''),
|
||||
selectedIds: () => state.selectedShapeIds,
|
||||
/**
|
||||
* The shape list in the inspector (#129, stage 4): the order it shows, top first, and where a
|
||||
* row sits. A row carries a name that also stands in the tab, so a check cannot click it by text.
|
||||
*/
|
||||
shapeRows: () => currentShapeList()?.shownIds ?? null,
|
||||
shapeRowAt: (shapeId: string) => currentShapeList()?.rowGlobal(shapeId) ?? null,
|
||||
/** The cross on a shape's row. */
|
||||
shapeRemoveAt: (shapeId: string) => currentShapeList()?.removeGlobal(shapeId) ?? null,
|
||||
/** The duplicate mark on a shape's row, and where a double-click edits its name. */
|
||||
shapeDuplicateAt: (shapeId: string) => currentShapeList()?.duplicateGlobal(shapeId) ?? null,
|
||||
shapeNameAt: (shapeId: string) => currentShapeList()?.nameGlobal(shapeId) ?? null,
|
||||
/** The field a shape's name is being edited in, with what it holds; null while none is. */
|
||||
shapeRenaming: () => {
|
||||
const field = currentShapeList()?.renameField;
|
||||
return field ? { ...centreOf(field), value: field.value } : null;
|
||||
},
|
||||
/** The Paint tool (#186): its button, the "Handles" menu, and which part it shows. */
|
||||
paintButton: () => centreOf(vectorArtEditor.paintButton),
|
||||
paintTarget: () => ({
|
||||
...centreOf(vectorArtEditor.paintTargetButton),
|
||||
text: vectorArtEditor.paintTargetButton.text,
|
||||
target: vectorArtEditor.canvas.paintTarget,
|
||||
}),
|
||||
/** A colour stop's marker, or the bar at an offset, in the inspector's fill or outline bar. */
|
||||
stopAt: (part: 'fill' | 'stroke', index: number) => currentGradientBar(part)?.stopGlobal(index) ?? null,
|
||||
barAt: (part: 'fill' | 'stroke', offset: number) => currentGradientBar(part)?.barGlobal(offset) ?? null,
|
||||
},
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user