mirror of
https://github.com/ZSeven-W/openpencil.git
synced 2026-05-31 19:04:29 +07:00
isBadgeOverlayNode matched role:'badge'|'pill'|'tag' and pulled those children out of their parent's auto-layout, rendering them at (0,0) of the parent and stacking them on top of siblings. But in this repo badge/pill/tag are inline-component roles (see role-resolver NAME_EXACT_MAP and strip-redundant-section-fills PROTECTED_ROLES) — they're meant to flow in layout like any other child. Rename to isOverlayNode and narrow to role:'overlay'. Add matching "Layout-escape roles" guidance in role-definitions.md so generation prompts can reach the new opt-in. Inline roles now flow correctly; true floating decorations (notification dots, corner ribbons) still have a dedicated marker.
3.8 KiB
3.8 KiB
pen-core
Pure document tree operations, layout engine, variables, normalization, boolean ops, and merge utilities.
Structure
src/tree-utils.ts— Tree CRUD:findNodeInTree,findParentInTree,removeNodeFromTree,updateNodeInTree,flattenNodes,insertNodeInTree,isDescendantOf,getNodeBounds,findClearX,scaleChildrenInPlace,rotateChildrenInPlace,nodeTreeToSummary; page helpers:createEmptyDocument,getActivePage,getActivePageChildren,setActivePageChildren,getAllChildren,migrateToPages,ensureDocumentNodeIds; clone utilities:deepCloneNode,cloneNodeWithNewIds,cloneNodesWithNewIds; constants:DEFAULT_FRAME_ID,DEFAULT_PAGE_IDsrc/normalize.ts—normalizePenDocument: format-only normalization (fill type "color" to "solid", gradient stop position to offset, sizing strings, padding arrays). Preserves$variablerefssrc/boolean-ops.ts—canBooleanOp,executeBooleanOp(union/subtract/intersect via Paper.js headless)src/sync-lock.ts—isFabricSyncLocked,setFabricSyncLock: prevents circular document-store to canvas syncsrc/arc-path.ts—buildEllipseArcPath,isArcEllipse: SVG arc path generation for partial ellipsessrc/path-anchors.ts—anchorsToPathData,pathDataToAnchors,getPathBoundsFromAnchors,inferPathAnchorPointTypesrc/font-utils.ts—cssFontFamily: CSS font-family string buildersrc/node-helpers.ts—isOverlayNode(detectsrole: 'overlay'),sanitizeName(PascalCase conversion)src/design-md-parser.ts—parseDesignMd,generateDesignMd,designMdColorsToVariables,extractDesignMdFromDocumentsrc/constants.ts— Canvas rendering constants (zoom limits, colors, snap thresholds, pen tool sizes, guide styling)src/id.ts—generateId(nanoid wrapper)src/layout/engine.ts— Auto-layout computation:resolvePadding,getNodeWidth,getNodeHeight,computeLayoutPositions,inferLayout,fitContentWidth,fitContentHeight,isNodeVisible,setRootChildrenProvider,getRootFillWidthFallbacksrc/layout/text-measure.ts— Text measurement:estimateTextWidth,estimateTextWidthPrecise,estimateTextHeight,resolveTextContent,parseSizing,defaultLineHeight,hasCjkText,isCjkCodePoint,countWrappedLinesFallback,setWrappedLineCountersrc/layout/normalize-tree.ts—normalizeTreeLayout: infers missing layout mode on frames, strips child x/y in layout containerssrc/layout/unwrap-fake-phone-mockup.ts—unwrapFakePhoneMockups: repairs AI-generated fake phone mockup framessrc/layout/strip-redundant-section-fills.ts—stripRedundantSectionFills: removes redundant dark fills from section containerssrc/normalize/normalize-stroke-fill-schema.ts—normalizeStrokeFillSchema: repairs AI-generated stroke/fill schema violationssrc/variables/resolve.ts—isVariableRef,getDefaultTheme,resolveVariableRef,resolveColorRef,resolveNumericRef,resolveNodeForCanvassrc/variables/replace-refs.ts—replaceVariableRefsInTree: recursively rename/delete$variablerefs in node treessrc/merge/node-diff.ts—diffDocuments: one-direction diff producingNodePatch[](add/remove/modify/move)src/merge/node-merge.ts—mergeDocuments: pure 3-way merge of PenDocument trees, returnsMergeResultwith conflictssrc/merge/merge-helpers.ts— Shared helpers for diff/merge (node indexing, field comparison)
Key patterns
- All tree operations are pure functions returning new references (structural sharing)
$variablerefs are preserved in the document; resolution happens at render time viaresolveNodeForCanvas()- Layout engine resolves
fill_container/fit_contentsizing and computes absolute positions
Testing
bun --bun vitest run packages/pen-core/src/__tests__/