1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-23 18:17:20 +00:00

Feat: destroy() method for widgets to do custom cleanup (#6699)

* feat: inform child widget to do some custom cleanup

* fix: type

* refactor: restore old removeChildDomNodes

* refactor: make destroy() a separate method

* refactor: make destroy call removeChildDomNodes

* refactor: call destroy instead of removeChildDomNodes in each core widgets

* fix: refreshSelf does not mean destroy

* refactor: use old var insteadof const

* docs: about subclass
This commit is contained in:
lin onetwo 2023-05-06 19:19:11 +08:00 committed by GitHub
parent 2b95daf59b
commit 474b73bdbe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 37 additions and 14 deletions

View File

@ -80,7 +80,7 @@ ClassicStoryView.prototype.remove = function(widget) {
if(duration) { if(duration) {
var targetElement = widget.findFirstDomNode(), var targetElement = widget.findFirstDomNode(),
removeElement = function() { removeElement = function() {
widget.removeChildDomNodes(); widget.destroy();
}; };
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {
@ -112,7 +112,7 @@ ClassicStoryView.prototype.remove = function(widget) {
{opacity: "0.0"} {opacity: "0.0"}
]); ]);
} else { } else {
widget.removeChildDomNodes(); widget.destroy();
} }
}; };

View File

@ -73,7 +73,7 @@ PopStoryView.prototype.remove = function(widget) {
duration = $tw.utils.getAnimationDuration(), duration = $tw.utils.getAnimationDuration(),
removeElement = function() { removeElement = function() {
if(targetElement && targetElement.parentNode) { if(targetElement && targetElement.parentNode) {
widget.removeChildDomNodes(); widget.destroy();
} }
}; };
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)

View File

@ -154,7 +154,7 @@ ZoominListView.prototype.remove = function(widget) {
var targetElement = widget.findFirstDomNode(), var targetElement = widget.findFirstDomNode(),
duration = $tw.utils.getAnimationDuration(), duration = $tw.utils.getAnimationDuration(),
removeElement = function() { removeElement = function() {
widget.removeChildDomNodes(); widget.destroy();
}; };
// Abandon if the list entry isn't a DOM element (it might be a text node) // Abandon if the list entry isn't a DOM element (it might be a text node)
if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) { if(!targetElement || targetElement.nodeType === Node.TEXT_NODE) {

View File

@ -122,7 +122,7 @@ ImportVariablesWidget.prototype.refresh = function(changedTiddlers) {
} }
if(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) { if(changedAttributes.filter || !$tw.utils.isArrayEqual(this.tiddlerList,tiddlerList) || haveListedTiddlersChanged()) {
// Compute the filter // Compute the filter
this.removeChildDomNodes(); this.destroy();
this.execute(tiddlerList); this.execute(tiddlerList);
this.renderChildren(this.parentDomNode,this.findNextSiblingDomNode()); this.renderChildren(this.parentDomNode,this.findNextSiblingDomNode());
return true; return true;

View File

@ -219,7 +219,7 @@ ListWidget.prototype.handleListChanges = function(changedTiddlers) {
} else { } else {
// If the list was empty then we need to remove the empty message // If the list was empty then we need to remove the empty message
if(prevList.length === 0) { if(prevList.length === 0) {
this.removeChildDomNodes(); this.destroy();
this.children = []; this.children = [];
} }
// If we are providing an counter variable then we must refresh the items, otherwise we can rearrange them // If we are providing an counter variable then we must refresh the items, otherwise we can rearrange them
@ -312,7 +312,7 @@ ListWidget.prototype.removeListItem = function(index) {
if(this.storyview && this.storyview.remove) { if(this.storyview && this.storyview.remove) {
this.storyview.remove(widget); this.storyview.remove(widget);
} else { } else {
widget.removeChildDomNodes(); widget.destroy();
} }
// Remove the child widget // Remove the child widget
this.children.splice(index,1); this.children.splice(index,1);

View File

@ -688,7 +688,7 @@ Rebuild a previously rendered widget
*/ */
Widget.prototype.refreshSelf = function() { Widget.prototype.refreshSelf = function() {
var nextSibling = this.findNextSiblingDomNode(); var nextSibling = this.findNextSiblingDomNode();
this.removeChildDomNodes(); this.removeChildDomNodes({ recursive: true });
this.render(this.parentDomNode,nextSibling); this.render(this.parentDomNode,nextSibling);
}; };
@ -753,19 +753,42 @@ Widget.prototype.findFirstDomNode = function() {
/* /*
Remove any DOM nodes created by this widget or its children Remove any DOM nodes created by this widget or its children
*/ */
Widget.prototype.removeChildDomNodes = function() { Widget.prototype.removeChildDomNodes = function(options) {
// 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 var recursive = options && options.recursive;
/**
* 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) { if(this.domNodes.length > 0) {
$tw.utils.each(this.domNodes,function(domNode) { $tw.utils.each(this.domNodes,function(domNode) {
domNode.parentNode.removeChild(domNode); domNode.parentNode.removeChild(domNode);
}); });
this.domNodes = []; this.domNodes = [];
} else { return true;
} else if(recursive) {
// Otherwise, ask the child widgets to delete their DOM nodes // Otherwise, ask the child widgets to delete their DOM nodes
$tw.utils.each(this.children,function(childWidget) { $tw.utils.each(this.children,function(childWidget) {
childWidget.removeChildDomNodes(); childWidget.removeChildDomNodes(options);
}); });
} }
return false
};
/*
Inform widget subclass that extends this widget and children widgets of this widget. Let them know this widget tree is about to destroy, and dom nodes are being unmounted from the document.
*/
Widget.prototype.destroy = function(options) {
// removeDom by default
var removeDom = (options && options.removeDom) || true;
if (removeDom) {
// prepare options for children, if we have removed the dom, child don't need to remove their dom
removeDom = !this.removeChildDomNodes();
}
// nothing need to do, as dom is already removed in the removeChildDomNodes
// we just need to inform the children
$tw.utils.each(this.children,function(childWidget) {
childWidget.destroy({ removeDom: removeDom });
});
}; };
/* /*

View File

@ -62,7 +62,7 @@ CecilyStoryView.prototype.remove = function(widget) {
duration = $tw.utils.getAnimationDuration(); duration = $tw.utils.getAnimationDuration();
// Remove the widget at the end of the transition // Remove the widget at the end of the transition
setTimeout(function() { setTimeout(function() {
widget.removeChildDomNodes(); widget.destroy();
},duration); },duration);
// Animate the closure // Animate the closure
$tw.utils.setStyle(targetElement,[ $tw.utils.setStyle(targetElement,[

View File

@ -80,7 +80,7 @@ StackedListView.prototype.insert = function(widget) {
}; };
StackedListView.prototype.remove = function(widget) { StackedListView.prototype.remove = function(widget) {
widget.removeChildDomNodes(); widget.destroy();
}; };
exports.stacked = StackedListView; exports.stacked = StackedListView;