Skip to content
This repository was archived by the owner on Dec 9, 2021. It is now read-only.

Commit ddc904c

Browse files
committed
Create ObjectManager class to fix issue of destroy erroring when disabled is called
1 parent 7bdda6a commit ddc904c

File tree

12 files changed

+445
-248
lines changed

12 files changed

+445
-248
lines changed

src/BaseObject.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ define(function (require, exports, module) { // jshint ignore:line
5656
* @public
5757
* @example
5858
* ClassName.prototype.destroy = function() {
59-
* this._childInstance.destroy();
60-
*
61-
* _super.prototype.destroy.call(this);
62-
* }
59+
* this._childInstance.destroy();
60+
*
61+
* _super.prototype.destroy.call(this);
62+
* }
6363
*/
6464
BaseObject.prototype.destroy = function () {
6565
for (var key in this) {

src/ObjectManager.js

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
define(function (require, exports, module) { // jshint ignore:line
2+
'use strict';
3+
4+
var Extend = require('structurejs/util/Extend');
5+
var BaseObject = require('structurejs/BaseObject');
6+
7+
/**
8+
* The {{#crossLink "ObjectManager"}}{{/crossLink}} class is an abstract class that provides enabling and disabling functionality for most StructureJS classes.
9+
*
10+
* @class ObjectManager
11+
* @module StructureJS
12+
* @extends BaseObject
13+
* @submodule core
14+
* @constructor
15+
* @author Robert S. (www.codeBelt.com)
16+
*/
17+
var ObjectManager = (function () {
18+
19+
var _super = Extend(ObjectManager, BaseObject);
20+
21+
function ObjectManager() {
22+
_super.call(this);
23+
/**
24+
* The isEnabled property is used to keep track of the enabled state of the object.
25+
*
26+
* @property isEnabled
27+
* @type {boolean}
28+
* @default false
29+
* @protected
30+
*/
31+
this.isEnabled = false;
32+
}
33+
/**
34+
* The enable method is responsible for enabling event listeners and/or children of the containing objects.
35+
*
36+
* @method enable
37+
* @public
38+
* @chainable
39+
* @example
40+
* ClassName.prototype.enable = function() {
41+
* if (this.isEnabled === true) return this;
42+
*
43+
* this._childInstance.addEventListener(BaseEvent.CHANGE, this.handlerMethod, this);
44+
* this._childInstance.enable();
45+
*
46+
* return _super.prototype.enable.call(this);
47+
* }
48+
*/
49+
ObjectManager.prototype.enable = function () {
50+
if (this.isEnabled === true)
51+
return this;
52+
53+
this.isEnabled = true;
54+
return this;
55+
};
56+
57+
/**
58+
* The disable method is responsible for disabling event listeners and/or children of the containing objects.
59+
*
60+
* @method disable
61+
* @public
62+
* @chainable
63+
* @example
64+
* ClassName.prototype.disable = function() {
65+
* if (this.isEnabled === false) return this;
66+
*
67+
* this._childInstance.removeEventListener(BaseEvent.CHANGE, this.handlerMethod, this);
68+
* this._childInstance.disable();
69+
*
70+
* return _super.prototype.disable.call(this);
71+
* }
72+
*/
73+
ObjectManager.prototype.disable = function () {
74+
if (this.isEnabled === false)
75+
return this;
76+
77+
this.isEnabled = false;
78+
return this;
79+
};
80+
return ObjectManager;
81+
})();
82+
83+
module.exports = ObjectManager;
84+
85+
});
86+

src/display/DOMElement.js

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -216,24 +216,24 @@ define(function (require, exports, module) { // jshint ignore:line
216216
* @example
217217
* // EXAMPLE 1: By default your view class will be a div element:
218218
* ClassName.prototype.createChildren = function () {
219-
* _super.prototype.createChildren.call(this);
220-
*
221-
* this._childInstance = new DOMElement();
222-
* this.addChild(this._childInstance);
223-
* }
219+
* _super.prototype.createChildren.call(this);
220+
*
221+
* this._childInstance = new DOMElement();
222+
* this.addChild(this._childInstance);
223+
* }
224224
*
225225
* // EXAMPLE 2: But lets say you wanted the view to be a ul element your would do:
226226
* ClassName.prototype.createChildren = function () {
227-
* _super.prototype.createChildren.call(this, 'ul');
228-
* }
227+
* _super.prototype.createChildren.call(this, 'ul');
228+
* }
229229
*
230230
* // Then you could nest other elements inside this base view/element.
231231
* ClassName.prototype.createChildren = function () {
232-
* _super.prototype.createChildren.call(this, 'ul', {id: 'myId', 'class': 'myClass anotherClass'});
233-
*
234-
* var li = new DOMElement('li', {text: 'Robert is cool'});
235-
* this.addChild(li);
236-
* }
232+
* _super.prototype.createChildren.call(this, 'ul', {id: 'myId', 'class': 'myClass anotherClass'});
233+
*
234+
* var li = new DOMElement('li', {text: 'Robert is cool'});
235+
* this.addChild(li);
236+
* }
237237
*
238238
* // EXAMPLE 3: So that's cool but what if you wanted a block of html to be your view. Let's say you had the below
239239
* // inline Handlebar template in your html file.
@@ -249,17 +249,17 @@ define(function (require, exports, module) { // jshint ignore:line
249249
* // You would just pass in the id or class selector of the template which in this case is "#todoTemplate".
250250
* // There is a second optional argument where you can pass data for the Handlebar template to use.
251251
* ClassName.prototype.createChildren = function () {
252-
* _super.prototype.createChildren.call(this, '#todoTemplate', { data: this.viewData });
253-
*
254-
* }
252+
* _super.prototype.createChildren.call(this, '#todoTemplate', { data: this.viewData });
253+
*
254+
* }
255255
*
256256
* // EXAMPLE 4: One more way. Let's say you wanted to use th Handlebar plugin within RequireJS. You can pass the template into createChildren.
257257
* var HomeTemplate = require('hbs!templates/HomeTemplate');
258258
*
259259
* ClassName.prototype.createChildren = function () {
260-
* _super.prototype.createChildren.call(this, HomeTemplate, {data: "some data"});
261-
*
262-
* }
260+
* _super.prototype.createChildren.call(this, HomeTemplate, {data: "some data"});
261+
*
262+
* }
263263
*/
264264
DOMElement.prototype.createChildren = function (type, params) {
265265
if (typeof type === "undefined") { type = 'div'; }
@@ -497,8 +497,11 @@ define(function (require, exports, module) { // jshint ignore:line
497497
*/
498498
DOMElement.prototype.removeChild = function (child, destroy) {
499499
if (typeof destroy === "undefined") { destroy = true; }
500-
child.$element.unbind();
501-
child.$element.remove();
500+
// If destroy was called before removeChild so id doesn't error.
501+
if (child.$element != null) {
502+
child.$element.unbind();
503+
child.$element.remove();
504+
}
502505

503506
_super.prototype.removeChild.call(this, child, destroy);
504507

src/display/DisplayObjectContainer.js

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,7 @@ define(function (require, exports, module) { // jshint ignore:line
115115
* @chainable
116116
*/
117117
DisplayObjectContainer.prototype.createChildren = function () {
118-
// Meant to be overridden because the extended class should call the createChildren method.
119-
return this;
118+
throw new Error('[' + this.getQualifiedClassName() + '] Error: The createChildren method is meant to be overridden.');
120119
};
121120

122121
/**
@@ -135,7 +134,7 @@ define(function (require, exports, module) { // jshint ignore:line
135134
DisplayObjectContainer.prototype.addChild = function (child) {
136135
//If the child being passed in already has a parent then remove the reference from there.
137136
if (child.parent) {
138-
child.parent.removeChild(child);
137+
child.parent.removeChild(child, false);
139138
}
140139

141140
this.children.push(child);
@@ -161,7 +160,7 @@ define(function (require, exports, module) { // jshint ignore:line
161160
DisplayObjectContainer.prototype.addChildAt = function (child, index) {
162161
//If the child being passed in already has a parent then remove the reference from there.
163162
if (child.parent) {
164-
child.parent.removeChild(child);
163+
child.parent.removeChild(child, false);
165164
}
166165

167166
this.children.splice(index, 0, child);
@@ -172,6 +171,55 @@ define(function (require, exports, module) { // jshint ignore:line
172171
return this;
173172
};
174173

174+
/**
175+
* Removes the specified child object instance from the child list of the parent object instance.
176+
* The parent property of the removed child is set to null , and the object is garbage collected if no other references
177+
* to the child exist. The index positions of any objects above the child in the parent object are decreased by 1.
178+
*
179+
* @method removeChild
180+
* @param child {DisplayObjectContainer} The DisplayObjectContainer instance to remove.
181+
* @returns {DisplayObjectContainer} Returns an instance of itself.
182+
* @public
183+
* @chainable
184+
*/
185+
DisplayObjectContainer.prototype.removeChild = function (child, destroy) {
186+
var index = this.getChildIndex(child);
187+
if (index !== -1) {
188+
// Removes the child object from the parent.
189+
this.children.splice(index, 1);
190+
}
191+
192+
if (destroy === true) {
193+
child.destroy();
194+
} else {
195+
child.disable();
196+
}
197+
198+
child.parent = null;
199+
200+
this.numChildren = this.children.length;
201+
202+
return this;
203+
};
204+
205+
/**
206+
* Removes all child DisplayObjectContainer instances from the child list of the DisplayObjectContainerContainer instance.
207+
* The parent property of the removed children is set to null , and the objects are garbage collected if
208+
* no other references to the children exist.
209+
*
210+
* @method removeChildren
211+
* @returns {DisplayObjectContainer} Returns an instance of itself.
212+
* @public
213+
* @chainable
214+
*/
215+
DisplayObjectContainer.prototype.removeChildren = function (destroy) {
216+
while (this.children.length > 0) {
217+
this.removeChild(this.children.pop(), destroy);
218+
}
219+
220+
return this;
221+
};
222+
175223
/**
176224
* Swaps two DisplayObjectContainer's with each other.
177225
*
@@ -183,8 +231,7 @@ define(function (require, exports, module) { // jshint ignore:line
183231
* @chainable
184232
*/
185233
DisplayObjectContainer.prototype.swapChildren = function (child1, child2) {
186-
// Meant to be overridden because the extended class should call the addChildAt method.
187-
return this;
234+
throw new Error('[' + this.getQualifiedClassName() + '] Error: The swapChildren method is meant to be overridden.');
188235
};
189236

190237
/**
@@ -234,50 +281,6 @@ define(function (require, exports, module) { // jshint ignore:line
234281
return this.children.indexOf(child) >= 0;
235282
};
236283

237-
/**
238-
* Removes the specified child object instance from the child list of the parent object instance.
239-
* The parent property of the removed child is set to null , and the object is garbage collected if no other references
240-
* to the child exist. The index positions of any objects above the child in the parent object are decreased by 1.
241-
*
242-
* @method removeChild
243-
* @param child {DisplayObjectContainer} The DisplayObjectContainer instance to remove.
244-
* @returns {DisplayObjectContainer} Returns an instance of itself.
245-
* @public
246-
* @chainable
247-
*/
248-
DisplayObjectContainer.prototype.removeChild = function (child) {
249-
var index = this.getChildIndex(child);
250-
if (index !== -1) {
251-
this.children.splice(index, 1);
252-
}
253-
child.disable();
254-
child.parent = null;
255-
256-
this.numChildren = this.children.length;
257-
258-
return this;
259-
};
260-
261-
/**
262-
* Removes all child DisplayObjectContainer instances from the child list of the DisplayObjectContainerContainer instance.
263-
* The parent property of the removed children is set to null , and the objects are garbage collected if
264-
* no other references to the children exist.
265-
*
266-
* @method removeChildren
267-
* @returns {DisplayObjectContainer} Returns an instance of itself.
268-
* @public
269-
* @chainable
270-
*/
271-
DisplayObjectContainer.prototype.removeChildren = function () {
272-
while (this.children.length > 0) {
273-
this.removeChild(this.children.pop());
274-
}
275-
276-
this.numChildren = this.children.length;
277-
278-
return this;
279-
};
280-
281284
/**
282285
* Returns the child display object instance that exists at the specified index.
283286
*
@@ -339,6 +342,16 @@ define(function (require, exports, module) { // jshint ignore:line
339342
return this;
340343
};
341344

345+
/**
346+
* @overridden EventDispatcher.destroy
347+
*/
348+
DisplayObjectContainer.prototype.destroy = function () {
349+
_super.prototype.destroy.call(this);
350+
};
351+
return DisplayObjectContainer;ainer.prototype.layoutChildren = function () {
352+
return this;
353+
};
354+
342355
/**
343356
* @overridden EventDispatcher.destroy
344357
*/

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy