You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Refactor the rerender() method in Toggle class (BootstrapToggle.ts) to reinitialize the component internally without destroying the current instance. Currently, rerender() calls this.destroy() followed by new Toggle(...), which creates a completely new instance and breaks reference continuity. The new implementation will reuse the existing instance, restoring properties, unbinding listeners, rebuilding DOM, and reinitializing state.
Simpler mental model: Rerender now means "rebuild internal structures" not "kill and respawn"
Acceptance Criteria
rerender() no longer calls this.destroy() or creates new Toggle instances
rerender() follows the exact sequence defined above
this.element.bsToggle remains unchanged (still references the same this instance)
No try/catch blocks added for error handling (errors propagate naturally)
No suppressExternalSync guard added (keeps current behavior)
Return type remains void (no chaining support)
Method works regardless of current lifecycle state (lifecycle not yet implemented)
Existing destroy() method remains unchanged and functional
No new events emitted (no toggle:rerendered)
Method is NOT async (synchronous execution)
All existing tests pass; no regressions introduced
Documentation
Sequence Diagram of New rerender() Flow
sequenceDiagram
participant T as Toggle Instance
participant E as HTMLInputElement
participant L as Event Listeners
participant D as DOMBuilder
participant O as OptionResolver
participant S as StateReducer
Note over T: rerender() called
T->>E: restoreInputProperties()
Note over E: Restores original getters/setters
T->>L: unbindEventListeners()
Note over L: Removes pointer/keyboard/label/form listeners
T->>D: domBuilder.destroy()
Note over D: Removes toggle DOM<br/>Restores original checkbox<br/>Disconnects ResizeObserver
T->>O: options = OptionResolver.resolve(element, userOptions)
Note over O: Re-reads from element attributes
T->>S: stateReducer = new StateReducer(element, tristate)
Note over S: Creates fresh state (resets to initial)
T->>D: domBuilder = new DOMBuilder(options, state)
Note over D: Builds new toggle DOM structure
T->>L: bindEventListeners()
Note over L: Re-attaches all event listeners
T->>E: interceptInputProperties()
Note over E: Re-intercepts getters/setters
Note over T: Instance rebuilt (same object reference)
Loading
Key Differences from Current Implementation
Aspect
Current
New
Instance identity
Changes (new object)
Preserved (same object)
element.bsToggle reference
Reassigned to new instance
Unchanged (still references same instance)
External references
Break (point to destroyed instance)
Remain valid
Memory allocation
New instance + GC of old
No new instance
State initialization
From constructor options
From re-resolved options (same result)
Error handling
Errors in new constructor propagate
Errors propagate (no catch)
Why This Order Matters
Restore properties first: Ensures element returns to vanilla state before any cleanup
Unbind listeners second: Prevents stale event handlers from firing during teardown
Destroy DOM third: Removes visual elements while preserving original checkbox
Re-resolve options fourth: Captures any HTML attribute changes since construction
Create fresh state fifth: Resets toggle to initial state (matches current behavior)
Rebuild DOM sixth: Creates new toggle structure with current options/state
Rebind listeners seventh: Attaches fresh handlers to new DOM
Re-intercept properties last: Restores change detection on the rebuilt element
consttoggle=newToggle(element);constoldListenersCount=getListenerCount(element);toggle.rerender();// Verify no listener leaks (count same as after initial construction)
State reset verification:
consttoggle=newToggle(element);toggle.on();// Change state to ONtoggle.rerender();// Verify toggle returns to initial (off/on based on options)
Additional Comments
Relationship to Lifecycle Migration Feature
This refactor is a mandatory prerequisite for the #317. The lifecycle migration will:
Require rerender() to work without destroying the instance (this refactor provides that)
Replace manual destroy() calls with super.destroy() + lifecycle hooks
Short Description of the Feature
Refactor the
rerender()method inToggleclass (BootstrapToggle.ts) to reinitialize the component internally without destroying the current instance. Currently,rerender()callsthis.destroy()followed bynew Toggle(...), which creates a completely new instance and breaks reference continuity. The new implementation will reuse the existing instance, restoring properties, unbinding listeners, rebuilding DOM, and reinitializing state.Current behavior:
Target behavior:
Expected Benefits
this.element.bsTogglecontinues to reference the same instance (no reassignment needed)rerender()that works withoutdestroy()+ recreationAcceptance Criteria
rerender()no longer callsthis.destroy()or creates newToggleinstancesrerender()follows the exact sequence defined abovethis.element.bsToggleremains unchanged (still references the samethisinstance)try/catchblocks added for error handling (errors propagate naturally)suppressExternalSyncguard added (keeps current behavior)void(no chaining support)destroy()method remains unchanged and functionaltoggle:rerendered)async(synchronous execution)Documentation
Sequence Diagram of New rerender() Flow
sequenceDiagram participant T as Toggle Instance participant E as HTMLInputElement participant L as Event Listeners participant D as DOMBuilder participant O as OptionResolver participant S as StateReducer Note over T: rerender() called T->>E: restoreInputProperties() Note over E: Restores original getters/setters T->>L: unbindEventListeners() Note over L: Removes pointer/keyboard/label/form listeners T->>D: domBuilder.destroy() Note over D: Removes toggle DOM<br/>Restores original checkbox<br/>Disconnects ResizeObserver T->>O: options = OptionResolver.resolve(element, userOptions) Note over O: Re-reads from element attributes T->>S: stateReducer = new StateReducer(element, tristate) Note over S: Creates fresh state (resets to initial) T->>D: domBuilder = new DOMBuilder(options, state) Note over D: Builds new toggle DOM structure T->>L: bindEventListeners() Note over L: Re-attaches all event listeners T->>E: interceptInputProperties() Note over E: Re-intercepts getters/setters Note over T: Instance rebuilt (same object reference)Key Differences from Current Implementation
element.bsTogglereferenceWhy This Order Matters
Testing Recommendations
Unit test scenarios to add/update:
Instance identity preservation:
Option re-resolution:
Error propagation:
Event listener cleanup verification:
State reset verification:
Additional Comments
Relationship to Lifecycle Migration Feature
This refactor is a mandatory prerequisite for the #317. The lifecycle migration will:
rerender()to work without destroying the instance (this refactor provides that)destroy()calls withsuper.destroy()+ lifecycle hooksdoInit(),doAttach(),doDispose(),doDestroy()hooksWithout this refactor, the lifecycle migration would be impossible because
rerender()would bypass the state machine entirely.Risk Assessment
unbindEventListeners()covers all listeners (already validated)rerender()changes instance identityDependencies
Out of Scope
rerender()returnthisfor chainingtoggle:rerenderedeventsrerender()asyncdestroy(),toggle(),on(), etc.)Feature Request Checklist