aboutsummaryrefslogtreecommitdiff
path: root/node_modules/montage/core/extras/array.js
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/montage/core/extras/array.js')
-rwxr-xr-xnode_modules/montage/core/extras/array.js292
1 files changed, 292 insertions, 0 deletions
diff --git a/node_modules/montage/core/extras/array.js b/node_modules/montage/core/extras/array.js
new file mode 100755
index 00000000..73e1bd87
--- /dev/null
+++ b/node_modules/montage/core/extras/array.js
@@ -0,0 +1,292 @@
1/* <copyright>
2 This file contains proprietary software owned by Motorola Mobility, Inc.<br/>
3 No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/>
4 (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved.
5 </copyright> */
6/**
7 Defines extensions to native Array object.
8 @see [Array class]{@link external:Array}
9 @module montage/core/shim/array
10*/
11/**
12 @external Array
13*/
14
15/**
16 @function external:Array#equals
17 @param {object} right The object to compare.
18 @returns {Boolean} true or false
19*/
20if (!Array.prototype.equals) {
21 Object.defineProperty(Array.prototype, "equals", {
22 value: function (right) {
23 var i = 0,
24 length = this.length,
25 lhs,
26 rhs;
27
28 if (this === right) {
29 return true;
30 }
31
32 if (!right || !Array.isArray(right)) {
33 return false;
34 }
35
36 if (length !== right.length) {
37 return false;
38 } else {
39 for (; i < length; ++i) {
40 if (i in this) {
41 lhs = this[i],
42 rhs = right[i];
43
44 if (lhs !== rhs && (lhs && rhs && !lhs.equals(rhs))) {
45 return false;
46 }
47 } else {
48 if (i in right) {
49 return false;
50 }
51 }
52 }
53 }
54 return true;
55 }
56 });
57}
58Object.defineProperty(Array, "isCanvasPixelArray", {
59 value: function(obj) {
60 return Object.prototype.toString.call(obj) === "[object CanvasPixelArray]";
61 }
62});
63
64/**
65Description
66@member external:Array#getProperty
67@function
68@param {Object} aPropertyPath
69@param {Property} unique
70@param {Property} preserve
71@param {Function} visitedComponentCallback
72@param {Array} currentIndex
73*/
74var _index_array_regexp = /^[0-9]+$/;
75Object.defineProperty(Array.prototype, "getProperty", {
76 value: function(aPropertyPath, unique, preserve, visitedComponentCallback, currentIndex) {
77
78 if (aPropertyPath == null) {
79 return;
80 }
81
82 currentIndex = currentIndex || 0;
83
84 var result,
85 propertyIsNumber = _index_array_regexp.test(aPropertyPath),//!isNaN(aPropertyPath),
86 parenthesisStartIndex = propertyIsNumber ? -1 : aPropertyPath.indexOf("(", currentIndex),
87 parenthesisEndIndex = propertyIsNumber ? -1 : aPropertyPath.lastIndexOf(")"),
88 currentPathComponentEndIndex = propertyIsNumber ? -1 : aPropertyPath.indexOf(".", currentIndex),
89 nextDelimiterIndex = -1,
90 itemResult,
91 index,
92 currentPathComponent,
93 functionName,
94 functionArgPropertyPath,
95 tmpResult,
96 uniques;
97
98 // PARSE: Determine the indices of the currentPathComponent we're concerned with
99
100 if (currentPathComponentEndIndex > -1 && parenthesisStartIndex > -1) {
101 // We have both a dot and an open parenthesis somewhere in the path, figure out the next path component
102 if (currentPathComponentEndIndex > parenthesisStartIndex) {
103 // The next dot was actually inside the function call; use the entire function call: foo.bar(a.b.c) -> bar(a.b.c)
104 nextDelimiterIndex = parenthesisEndIndex + 1;
105 functionName = aPropertyPath.substring(currentIndex, parenthesisStartIndex);
106 } else {
107 // The next dot comes before the start of the function parenthesis; use the dot: foo.bar(a.b.c) -> foo
108 nextDelimiterIndex = currentPathComponentEndIndex;
109 }
110 } else {
111 // We have either a dot, parenthesis, or neither
112 if (parenthesisStartIndex > -1) {
113 // we had a starting parenthesis; use the END parenthesis to include the entire function call
114 nextDelimiterIndex = parenthesisEndIndex + 1;
115 functionName = aPropertyPath.substring(currentIndex, parenthesisStartIndex);
116 } else {
117 nextDelimiterIndex = currentPathComponentEndIndex;
118 }
119 }
120
121 // Find the component of the propertyPath we want to deal with during this particular invocation of this function
122 currentPathComponent = propertyIsNumber ? aPropertyPath : aPropertyPath.substring(currentIndex, (nextDelimiterIndex === -1 ? aPropertyPath.length : nextDelimiterIndex));
123
124 // EVALUATE: Determine the value of the currentPathComponent
125
126 if (functionName) {
127 // We have a function to execute as part of this propertyPath; execute it assuming that it will know
128 // how to handle the property path being passed along
129
130 // TODO do we call this before or after finding the result (probably before to maintain the chain
131 // of one invocation's discovered value being the context of the next invocation
132 if (visitedComponentCallback) {
133 visitedComponentCallback(this, functionName + "()", null, null, null);
134 }
135
136 functionArgPropertyPath = aPropertyPath.substring(parenthesisStartIndex + 1, parenthesisEndIndex);
137 result = this[functionName](functionArgPropertyPath, visitedComponentCallback);
138
139
140 } else {
141
142 // TODO we don't provide any way to access properties that are actually accessible on the array itself
143 // we assume that by default, any property in a propertyPath after an array refers to a property
144 // you are interested in getting on each member of the array
145
146 if (isNaN(currentPathComponent)) {
147
148 if (visitedComponentCallback) {
149 //console.log("....", currentPathComponent, aPropertyPath , currentPathComponentEndIndex != -1 ? aPropertyPath.slice(currentPathComponentEndIndex + 1) : null);
150 //console.log(aPropertyPath.slice(currentIndex));
151 visitedComponentCallback(this, null, undefined, null, aPropertyPath.slice(currentIndex));
152 }
153
154 result = [];
155 index = 0;
156
157 // The currentPathComponent is some property not directly on this array, and not an index in the array
158 // so we'll be getting an array of resolving this currentPathComponent on each member in the array
159 if (preserve) {
160
161 while((itemResult = this[index]) != null) {
162 result[index] = itemResult.getProperty(aPropertyPath, unique, preserve, visitedComponentCallback, currentIndex);
163 index++;
164 }
165
166 } else {
167
168 // TODO in either case, why do we stop if we encounter null|undefined? there could be useful
169 // values after that in the collection. I already had to fix an issue here where a zero
170 // would short-circuit the loop
171 while((itemResult = this[index]) != null) {
172 tmpResult = itemResult.getProperty(aPropertyPath, unique, preserve, visitedComponentCallback, currentIndex);
173
174 if (Array.isArray(tmpResult)) {
175 result = result.concat(tmpResult);
176 } else {
177 result[index] = tmpResult;
178 }
179 index++;
180 }
181
182 if (unique) {
183 var uniques = {}; // TODO reuse this object if possible
184 // TODO don't recreate this filter function each time
185 result = result.filter(function(element) {
186 return uniques[element] ? false : (uniques[element] = true);
187 });
188 }
189
190 }
191
192 } else {
193
194 // The currentPathComponent is an index into this array
195 result = this[currentPathComponent];
196
197
198 if (visitedComponentCallback) {
199 visitedComponentCallback(this, currentPathComponent, result, null, currentPathComponentEndIndex != -1 ? aPropertyPath.slice(currentPathComponentEndIndex + 1) : null);
200 }
201
202 if (currentPathComponentEndIndex > 0) {
203 result = result ? result.getProperty(aPropertyPath, unique, preserve, visitedComponentCallback, currentPathComponentEndIndex + 1) : undefined;
204 } else if (visitedComponentCallback && currentPathComponentEndIndex === -1 && result) {
205 // If we're at the end of the path, but have a result, visit it
206 //visitedComponentCallback(result, null, null, null, null);
207 }
208 }
209 }
210
211 return result;
212 },
213 enumerable: false
214});
215
216/**
217@member external:Array#count
218@function
219@returns this.length
220*/
221Object.defineProperty(Array.prototype, "count", {
222 value: function() {
223 return this.length;
<