fix #8056 - more refinements to checking data
[g.raphael] / seed / rSet.js
1
2 importz = imports['seed/importz.js'].importz;
3 Element = importz('Element');
4 Roo = importz('Roo');
5
6
7 var has = "hasOwnProperty";  
8
9 function rSet (items) {
10     this.items = [];
11     this.length = 0;
12     this.type = "set";
13     if (items) {
14         for (var i = 0, ii = items.length; i < ii; i++) {
15             //if (items[i] && (items[i].constructor == Element.prototype.constructor || items[i].constructor == Set)) {
16                 this[this.items.length] = this.items[this.items.length] = items[i];
17                 this.length++;
18             //}
19         }
20     }
21 }
22
23
24 rSet.prototype = {
25     
26     push : function () {
27         var item,
28             len;
29         for (var i = 0, ii = arguments.length; i < ii; i++) {
30             item = arguments[i];
31             
32             //print(item.constructor);
33             
34             //if (item && (item.constructor == Element.prototype.constructor || item.constructor == Set)) {
35                 len = this.items.length;
36                 this[len] = this.items[len] = item;
37                 this.length++;
38             //}
39         }
40         return this;
41     },
42
43     pop : function () {
44         this.length && delete this[this.length--];
45         return this.items.pop();
46     },
47     
48     forEach : function (callback, thisArg) {
49         for (var i = 0, ii = this.items.length; i < ii; i++) {
50             if (callback.call(thisArg, this.items[i], i) === false) {
51                 return this;
52             }
53         }
54         return this;
55     },
56     
57     attr : function (name, value) {
58         if (name && R.is(name, array) && R.is(name[0], "object")) {
59             for (var j = 0, jj = name.length; j < jj; j++) {
60                 this.items[j].attr(name[j]);
61             }
62         } else {
63             for (var i = 0, ii = this.items.length; i < ii; i++) {
64                 this.items[i].attr(name, value);
65             }
66         }
67         return this;
68     },
69     
70     clear : function () {
71         while (this.length) {
72             this.pop();
73         }
74     },
75     
76     splice : function (index, count, insertion) {
77         index = index < 0 ? mmax(this.length + index, 0) : index;
78         count = mmax(0, mmin(this.length - index, count));
79         var tail = [],
80             todel = [],
81             args = [],
82             i;
83         for (i = 2; i < arguments.length; i++) {
84             args.push(arguments[i]);
85         }
86         for (i = 0; i < count; i++) {
87             todel.push(this[index + i]);
88         }
89         for (; i < this.length - index; i++) {
90             tail.push(this[index + i]);
91         }
92         var arglen = args.length;
93         for (i = 0; i < arglen + tail.length; i++) {
94             this.items[index + i] = this[index + i] = i < arglen ? args[i] : tail[i - arglen];
95         }
96         i = this.items.length = this.length -= count - arglen;
97         while (this[i]) {
98             delete this[i++];
99         }
100         return new rSet(todel);
101     },
102     
103     exclude : function (el) {
104         for (var i = 0, ii = this.length; i < ii; i++) if (this[i] == el) {
105             this.splice(i, 1);
106             return true;
107         }
108         return false;
109     },
110     animate : function (params, ms, easing, callback) {
111         (R.is(easing, "function") || !easing) && (callback = easing || null);
112         var len = this.items.length,
113             i = len,
114             item,
115             set = this,
116             collector;
117         if (!len) {
118             return this;
119         }
120         callback && (collector = function () {
121             !--len && callback.call(set);
122         });
123         easing = R.is(easing, string) ? easing : collector;
124         var anim = R.animation(params, ms, easing, collector);
125         item = this.items[--i].animate(anim);
126         while (i--) {
127             this.items[i] && !this.items[i].removed && this.items[i].animateWith(item, anim);
128         }
129         return this;
130     },
131     insertAfter : function (el) {
132         var i = this.items.length;
133         while (i--) {
134             this.items[i].insertAfter(el);
135         }
136         return this;
137     },
138     getBBox : function () {
139         //Roo.log("SET : getBBox");
140         var x = [],
141             y = [],
142             w = [],
143             h = [];
144         for (var i = this.items.length; i--;) if (!this.items[i].removed) {
145             var box = this.items[i].getBBox();
146             //Roo.log(['box of set item: ' ,JSON.stringify(box)]);
147             x.push(box.x);
148             y.push(box.y);
149             w.push(box.x + box.width);
150             h.push(box.y + box.height);
151         }
152         x = Math.min.apply(0, x);
153         y = Math.min.apply(0, y);
154         //Roo.log(['set bbox return :', x,y,Math.max.apply(0, w) - x,Math.max.apply(0, h) - y]);
155         
156         return {
157             x: x,
158             y: y,
159             width: Math.max.apply(0, w) - x,
160             height: Math.max.apply(0, h) - y
161         };
162     },
163     clone : function (s) {
164         s = new rSet;
165         for (var i = 0, ii = this.items.length; i < ii; i++) {
166             s.push(this.items[i].clone());
167         }
168         return s;
169     },
170     toString : function () {
171         return "Rapha\xebl\u2018s set";
172     },
173 }
174
175 // seems an odd way to copy prototypes...    
176 for (var method in Element.prototype) {
177     if (!Element.prototype[has](method)) {
178         continue;
179     }
180     if (rSet.prototype[has](method)) {
181         continue;
182     }
183     rSet.prototype[method] = (function (methodname) {
184         return function () {
185             var arg = arguments;
186             return this.forEach(function (el) {
187                 el[methodname].apply(el, arg);
188             });
189         };
190     })(method);
191 }
192