Files
feuerwerk/src/editor/debug/documentHooks.ts
T
adminandClaude Opus 5.5 ed29b2f3dc 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>
2026-09-23 10:20:06 +02:00

90 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { findAsset, findAssetOf } from '../../core/model/Project';
import { previewObjectId } from '../../core/model/animationPreview';
import { currentFramesDialog } from '../animation/FramesDialog';
import { currentRowDialog } from '../animation/RowDialog';
import { centreOf, type HookContext } from './hookHelpers';
/** The Texture, Animation, Tile and List tabs. */
export function documentHooks({ state, editor }: HookContext) {
const { textureEditor } = editor;
return {
texture: {
current: () => textureEditor.currentAssetId,
/** Where an image pixel of the shown sheet sits on screen (frames are dragged in image coordinates). */
pointAt: (x: number, y: number) => textureEditor.imageToScreen(x, y),
rect: () => textureEditor.canvasRect(),
/** Whether a press edits the selected frame's collision outline (#141). */
collisionMode: () => textureEditor.canvas.collisionMode,
/** The open "Generate collision…" dialog (#161), or null. */
generateDialog: () => textureEditor.generateDialog.current()?.info ?? null,
},
animation: {
current: () => editor.animationEditor.currentAssetId,
info: () => editor.animationEditor.shownInfo,
rootPickerAt: () => centreOf(editor.animationEditor.rootPicker),
addRowAt: () => centreOf(editor.animationEditor.addRowButton),
playAt: () => ({
...centreOf(editor.animationEditor.playButton),
text: editor.animationEditor.playButton.text,
}),
/** Where a cell, a row's header and a frame on the ruler sit – no text names a cell. */
cellAt: (trackId: string, frame: number) => editor.animationEditor.canvas.cellGlobal(trackId, frame),
headerAt: (trackId: string) => editor.animationEditor.canvas.headerGlobal(trackId),
rulerAt: (frame: number) => editor.animationEditor.canvas.rulerGlobal(frame),
keys: () => editor.animationEditor.canvas.keysDrawn(),
rows: () => editor.animationEditor.canvas.rowsDrawn(),
view: () => editor.animationEditor.canvas.viewInfo(),
scrub: (frame: number) => editor.animationEditor.canvas.scrub(frame),
/** The open row dialog: what it offers and holds, and a way to pick without clicking through menus. */
rowDialog: () => currentRowDialog()?.debugInfo() ?? null,
rowDialogPick: (target: string, property: string) => currentRowDialog()?.pick(target, property),
/** Copy/paste and frames (#102): what the clipboard holds, and the open frames dialog. */
clipboard: () => structuredClone(state.keyClipboard),
framesDialog: () => currentFramesDialog()?.debugInfo() ?? null,
framesDialogCount: (count: number) => currentFramesDialog()?.setCount(count),
framesDialogConfirm: () => {
const dialog = currentFramesDialog();
if (!dialog) return null;
const g = dialog.confirm.getGlobalPosition();
return { x: g.x + dialog.confirm.w / 2, y: g.y + dialog.confirm.h / 2 };
},
/** The preview above the timeline (#99): where a row's target is drawn and with which values. */
preview: {
/** The id the preview draws a row's target under (`''` = the root itself). */
objectId: (target: string) => {
const asset = findAssetOf(state.project, editor.animationEditor.currentAssetId, 'animation');
return previewObjectId(asset && findAsset(state.project, asset.root), target);
},
rect: (objectId: string) => editor.animationEditor.preview.objectRect(objectId),
item: (objectId: string) => editor.animationEditor.preview.itemDrawn(objectId),
info: () => editor.animationEditor.preview.debugInfo(),
fitAt: () => centreOf(editor.animationEditor.fitButton),
},
},
tile: {
current: () => editor.tileEditor.currentAssetId,
info: () => editor.tileEditor.shownInfo,
/** What the board drew: tiles, the picture it is showing and what stands in the way. */
board: () => editor.tileEditor.canvas.debugInfo(),
pictures: () => editor.tileEditor.strip.debugInfo(),
/** A tile of the board: its quarters and where each of them is drawn. */
tile: (index: number) => editor.tileEditor.canvas.tileDrawn(index),
/** Which board tile a cell of the sample map became – `-1` when that cell is empty. */
sampleTile: (row: number, column: number) => editor.tileEditor.canvas.sampleTile(row, column),
kindPickerAt: () => centreOf(editor.tileEditor.kindPicker),
addPictureAt: () => centreOf(editor.tileEditor.strip.addButton),
removePictureAt: () => centreOf(editor.tileEditor.strip.removeButton),
pictureRowAt: (index: number) => editor.tileEditor.strip.list.rowGlobal(String(index)),
fitAt: () => centreOf(editor.tileEditor.fitButton),
},
list: {
info: () => editor.listEditor.debugInfo(),
/** Where an item's widget sits, so a check can click it – a number field has no findable text. */
fieldAt: (index: number, field = '') => editor.listEditor.fieldAt(index, field),
/** The kind mark of a row, or of one field of a struct item – both are pickers. */
markAt: (index: number, field = '') => editor.listEditor.markAt(index, field),
nameAt: (index: number, field: string) => editor.listEditor.nameAt(index, field),
},
};
}