- Replace JSON.parse() with repairJSON() in desktop.js and mobile.js
to handle malformed JSON from infoBox/userStats data
- Add defensive initialization in renderEquipment(): ensure showEquipment
defaults to true and equipment data structure exists
- Add explicit renderEquipment() call during initialization
- Add clearDomCache() for jQuery object cache invalidation on panel rebuild
- Track all event handlers in on()/once() for complete cleanup by unregisterAllEvents()
- Migrate direct eventSource.on() calls to tracked onEvent() in index.js, injector.js, sillyTavernExpressions.js
- Add clearDebugLogs() called on CHAT_CHANGED to prevent memory accumulation
- Add trackJQueryHandler()/cleanupJQueryEvents() infrastructure for jQuery event cleanup
- Add comprehensive memory management tests (14 new tests, all passing)
- Pre-compile all regex patterns as module-level constants in parser.js and jsonRepair.js
- Add format detection caching (lastDetectedFormat, formatCacheHits) to skip redundant checks
- Add clearFormatCache() export for cache invalidation
- Add comprehensive test suite (33 tests) for parser and jsonRepair modules
- Fix regex escaping in dynamic patterns (statRegex, fieldRegex)
- Improve toFieldKey() regex specificity
Fixes critical bug identified by Zephyre_Review: event handlers used
global jQuery selectors instead of container-scoped selectors, causing
potential event handler leaks and scope mismatches.
- requestAnimationFrame batching: rerenderRpgState() now batches all
render calls into a single animation frame, reducing reflow/repaint costs
- Lightweight change detection: Render functions use updateIfChanged() to
skip DOM updates when content hasn't changed, and only re-bind event
handlers when the DOM was actually updated
- CSS content-visibility: Added content-visibility: auto with
contain-intrinsic-size to inventory and equipment containers, deferring
rendering of off-screen content
New file: src/systems/rendering/renderUtils.js (rendering utilities module)
Updated: All render modules + sillytavern.js integration + style.css
- setupPlotButtons requires handlePlotClick and handleEncounterClick callbacks
- Pass sendPlotProgression and openEncounterModal as arguments
- removeAlternatePresentCharactersPanel is already correctly imported
- Update HTML input max attribute from 20 to 99 in generateStatCheckboxes()
- Update JS clamping logic Math.min(20, val) to Math.min(99, val) in saveEquipmentItem()
Add a new Equipment tab to manage player gear and stat bonuses.
Features:
- 19 equipment slots across 8 categories (helmet, necklace, body armor, gloves, pants, shoes, rings, accessories)
- Type-to-slot validation: each type has max equipped limits (1 helmet, 10 rings, 3 accessories, etc.)
- Auto-slot assignment: equipping a ring fills the first available ring slot
- Stat bonuses from equipped items display on RPG attributes (e.g. STR 10 +2)
- Create/edit modal with stat checkboxes per RPG attribute
- Inventory list for unequipped items
Architecture:
- Shared constants in src/systems/equipment/constants.js
- Category-based types (Ring, Accessory) with auto-slot assignment
- v7 migration converts legacy slot-specific types to generic categories
- Full i18n support for all UI strings
Files:
- New: src/systems/equipment/constants.js
- New: src/systems/interaction/equipmentActions.js
- New: src/systems/rendering/equipment.js
- Modified: state.js, persistence.js, template.html, index.js
- Modified: userStats.js, desktop.js, mobile.js, layout.js, modals.js
- Modified: apiClient.js, sillytavern.js, style.css, en.json