Adds a widget destroy method (#9097)

* feat: widget destroy method

* fix: revert to original implementation

* Invoke onDestroy method during widget destruction

Add custom cleanup method call in destroy process

* Update documentation for destroy method options

* Fix formatting in widget.js comments

* Refactor destroyChildren method for formatting

* Fix indentation in findNextSiblingDomNode method

* docs: added changenote

* chore: lint

* fix: remove deprecated utils method
This commit is contained in:
Saq Imtiaz 2026-02-05 17:03:40 +01:00 committed by GitHub
parent 33b2f514fb
commit d376ada241
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 67 additions and 15 deletions

View file

@ -787,9 +787,9 @@ Widget.prototype.findNextSiblingDomNode = function(startIndex) {
// Refer to this widget by its index within its parents children
var parent = this.parentWidget,
index = startIndex !== undefined ? startIndex : parent.children.indexOf(this);
if(index === -1) {
throw "node not found in parents children";
}
if(index === -1) {
throw "node not found in parents children";
}
// Look for a DOM node in the later siblings
while(++index < parent.children.length) {
var domNode = parent.children[index].findFirstDomNode();
@ -827,21 +827,60 @@ Widget.prototype.findFirstDomNode = function() {
};
/*
Remove any DOM nodes created by this widget or its children
Entry into destroy procedure
options include:
removeDOMNodes: boolean (default true)
*/
Widget.prototype.destroyChildren = function(options) {
$tw.utils.each(this.children,function(childWidget) {
childWidget.destroy(options);
});
};
/*
Legacy entry into destroy procedure
*/
Widget.prototype.removeChildDomNodes = function() {
// If this widget has directly created DOM nodes, delete them and exit. This assumes that any child widgets are contained within the created DOM nodes, which would normally be the case
if(this.domNodes.length > 0) {
$tw.utils.each(this.domNodes,function(domNode) {
domNode.parentNode.removeChild(domNode);
});
this.domNodes = [];
} else {
// Otherwise, ask the child widgets to delete their DOM nodes
$tw.utils.each(this.children,function(childWidget) {
childWidget.removeChildDomNodes();
});
this.destroy({removeDOMNodes: true});
};
/*
Default destroy
options include:
- removeDOMNodes: boolean (default true)
*/
Widget.prototype.destroy = function(options) {
const { removeDOMNodes = true } = options || {};
let removeChildDOMNodes = removeDOMNodes;
if(removeDOMNodes && this.domNodes.length > 0) {
// If this widget will remove its own DOM nodes, children should not remove theirs
removeChildDOMNodes = false;
}
// Destroy children first
this.destroyChildren({removeDOMNodes: removeChildDOMNodes});
this.children = [];
// Call custom cleanup method if implemented
if(typeof this.onDestroy === "function") {
this.onDestroy();
}
// Remove our DOM nodes if needed
if(removeDOMNodes) {
this.removeLocalDomNodes();
}
};
/*
Remove any DOM nodes created by this widget
*/
Widget.prototype.removeLocalDomNodes = function() {
for(const domNode of this.domNodes) {
if(domNode.parentNode) {
domNode.parentNode.removeChild(domNode);
}
}
this.domNodes = [];
};
/*

View file

@ -0,0 +1,13 @@
change-category: internal
change-type: enhancement
created: 20260120153052332
description: Adds a destroy method for widgets allowing for clean up of resources when a widget is removed.
github-contributors: saqimtiaz
github-links: https://github.com/TiddlyWiki/TiddlyWiki5/pull/9097
modified: 20260125212701672
release: 5.4.0
tags: $:/tags/ChangeNote
title: $:/changenotes/5.4.0/#9097
type: text/vnd.tiddlywiki
Adds a destroy method for widgets allowing for clean up of resources when a widget is removed.