UNPKG

dijit

Version:

Dijit provides a complete collection of user interface controls based on Dojo, giving you the power to create web applications that are highly optimized for usability, performance, internationalization, accessibility, but above all deliver an incredible u

84 lines (74 loc) 2.87 kB
define([ "dojo/_base/array", // array.forEach array.map "dojo/aspect", "dojo/_base/declare" ], function(array, aspect, declare){ // module: // dijit/Destroyable return declare("dijit.Destroyable", null, { // summary: // Mixin to track handles and release them when instance is destroyed. // description: // Call this.own(...) on list of handles (returned from dojo/aspect, dojo/on, // dojo/Stateful::watch, or any class (including widgets) with a destroyRecursive() or destroy() method. // Then call destroy() later to destroy this instance and release the resources. destroy: function(/*Boolean*/ preserveDom){ // summary: // Destroy this class, releasing any resources registered via own(). this._destroyed = true; }, own: function(){ // summary: // Track specified handles and remove/destroy them when this instance is destroyed, unless they were // already removed/destroyed manually. // tags: // protected // returns: // The array of specified handles, so you can do for example: // | var handle = this.own(on(...))[0]; var cleanupMethods = [ "destroyRecursive", "destroy", "remove" ]; array.forEach(arguments, function(handle){ // When this.destroy() is called, destroy handle. Since I'm using aspect.before(), // the handle will be destroyed before a subclass's destroy() method starts running, before it calls // this.inherited() or even if it doesn't call this.inherited() at all. If that's an issue, make an // onDestroy() method and connect to that instead. var destroyMethodName; var odh = aspect.before(this, "destroy", function (preserveDom){ handle[destroyMethodName](preserveDom); }); // Callback for when handle is manually destroyed. var hdhs = []; function onManualDestroy(){ odh.remove(); array.forEach(hdhs, function(hdh){ hdh.remove(); }); } // Setup listeners for manual destroy of handle. // Also computes destroyMethodName, used in listener above. if(handle.then){ // Special path for Promises. Detect when Promise is resolved, rejected, or // canceled (nb: cancelling a Promise causes it to be rejected). destroyMethodName = "cancel"; handle.then(onManualDestroy, onManualDestroy); }else{ // Path for other handles. Just use AOP to detect when handle is manually destroyed. array.forEach(cleanupMethods, function(cleanupMethod){ if(typeof handle[cleanupMethod] === "function"){ if(!destroyMethodName){ // Use first matching method name in above listener (prefer destroyRecursive() to destroy()) destroyMethodName = cleanupMethod; } hdhs.push(aspect.after(handle, cleanupMethod, onManualDestroy, true)); } }); } }, this); return arguments; // handle } }); });