parsejs 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +5 -0
- data/README.markdown +85 -0
- data/Rakefile +15 -0
- data/lib/parsejs.rb +14 -0
- data/lib/parsejs/ast.rb +84 -0
- data/lib/parsejs/docs.rb +237 -0
- data/lib/parsejs/grammar.kpeg +575 -0
- data/lib/parsejs/grammar.kpeg.rb +9460 -0
- data/lib/parsejs/scope.rb +183 -0
- data/lib/parsejs/stringifier.rb +450 -0
- data/lib/parsejs/version.rb +3 -0
- data/lib/parsejs/visitor.rb +257 -0
- data/parsejs.gemspec +24 -0
- data/spec/fixtures/jquery-1.6.js +8982 -0
- data/spec/fixtures/jquery-1.7.js +9289 -0
- data/spec/fixtures/jquery-ajax.js +1000 -0
- data/spec/fixtures/jquery-attributes.js +650 -0
- data/spec/fixtures/jquery-traversing.js +330 -0
- data/spec/fixtures/metamorph.js +324 -0
- data/spec/fixtures/sizzle.js +1442 -0
- data/spec/fixtures/sproutcore-core.js +195 -0
- data/spec/fixtures/sproutcore-each-proxy.js +218 -0
- data/spec/fixtures/sproutcore-native-array.js +139 -0
- data/spec/fixtures/sproutcore.js +14319 -0
- data/spec/scope_spec.rb +111 -0
- data/spec/stringify_spec.rb +587 -0
- data/test.rb +76 -0
- metadata +145 -0
@@ -0,0 +1,195 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore Runtime
|
3
|
+
// Copyright: ©2011 Strobe Inc. and contributors.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
// NOTE: this object should never be included directly. Instead use SC.
|
10
|
+
// SC.Object. We only define this separately so that SC.Set can depend on it
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
var rewatch = SC.rewatch;
|
15
|
+
var classToString = SC.Mixin.prototype.toString;
|
16
|
+
var set = SC.set, get = SC.get;
|
17
|
+
var o_create = SC.platform.create,
|
18
|
+
meta = SC.meta;
|
19
|
+
|
20
|
+
function makeCtor() {
|
21
|
+
|
22
|
+
// Note: avoid accessing any properties on the object since it makes the
|
23
|
+
// method a lot faster. This is glue code so we want it to be as fast as
|
24
|
+
// possible.
|
25
|
+
|
26
|
+
var isPrepared = false, initMixins, init = false, hasChains = false;
|
27
|
+
|
28
|
+
var Class = function() {
|
29
|
+
if (!isPrepared) { get(Class, 'proto'); } // prepare prototype...
|
30
|
+
if (initMixins) {
|
31
|
+
this.reopen.apply(this, initMixins);
|
32
|
+
initMixins = null;
|
33
|
+
rewatch(this); // ålways rewatch just in case
|
34
|
+
this.init.apply(this, arguments);
|
35
|
+
} else {
|
36
|
+
if (hasChains) {
|
37
|
+
rewatch(this);
|
38
|
+
} else {
|
39
|
+
this[SC.GUID_KEY] = undefined;
|
40
|
+
}
|
41
|
+
if (init===false) { init = this.init; } // cache for later instantiations
|
42
|
+
init.apply(this, arguments);
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
Class.toString = classToString;
|
47
|
+
Class._prototypeMixinDidChange = function() { isPrepared = false; };
|
48
|
+
Class._initMixins = function(args) { initMixins = args; };
|
49
|
+
|
50
|
+
SC.defineProperty(Class, 'proto', SC.computed(function() {
|
51
|
+
if (!isPrepared) {
|
52
|
+
isPrepared = true;
|
53
|
+
Class.PrototypeMixin.applyPartial(Class.prototype);
|
54
|
+
hasChains = !!meta(Class.prototype, false).chains; // avoid rewatch
|
55
|
+
}
|
56
|
+
return this.prototype;
|
57
|
+
}));
|
58
|
+
|
59
|
+
return Class;
|
60
|
+
|
61
|
+
}
|
62
|
+
|
63
|
+
var CoreObject = makeCtor();
|
64
|
+
|
65
|
+
CoreObject.PrototypeMixin = SC.Mixin.create({
|
66
|
+
|
67
|
+
reopen: function() {
|
68
|
+
SC.Mixin._apply(this, arguments, true);
|
69
|
+
return this;
|
70
|
+
},
|
71
|
+
|
72
|
+
isInstance: true,
|
73
|
+
|
74
|
+
init: function() {},
|
75
|
+
|
76
|
+
isDestroyed: false,
|
77
|
+
|
78
|
+
/**
|
79
|
+
Destroys an object by setting the isDestroyed flag and removing its
|
80
|
+
metadata, which effectively destroys observers and bindings.
|
81
|
+
|
82
|
+
If you try to set a property on a destroyed object, an exception will be
|
83
|
+
raised.
|
84
|
+
|
85
|
+
Note that destruction is scheduled for the end of the run loop and does not
|
86
|
+
happen immediately.
|
87
|
+
|
88
|
+
@returns {SC.Object} receiver
|
89
|
+
*/
|
90
|
+
destroy: function() {
|
91
|
+
set(this, 'isDestroyed', true);
|
92
|
+
SC.run.schedule('destroy', this, this._scheduledDestroy);
|
93
|
+
return this;
|
94
|
+
},
|
95
|
+
|
96
|
+
/**
|
97
|
+
Invoked by the run loop to actually destroy the object. This is
|
98
|
+
scheduled for execution by the `destroy` method.
|
99
|
+
|
100
|
+
@private
|
101
|
+
*/
|
102
|
+
_scheduledDestroy: function() {
|
103
|
+
this[SC.META_KEY] = null;
|
104
|
+
},
|
105
|
+
|
106
|
+
bind: function(to, from) {
|
107
|
+
if (!(from instanceof SC.Binding)) { from = SC.Binding.from(from); }
|
108
|
+
from.to(to).connect(this);
|
109
|
+
return from;
|
110
|
+
},
|
111
|
+
|
112
|
+
toString: function() {
|
113
|
+
return '<'+this.constructor.toString()+':'+SC.guidFor(this)+'>';
|
114
|
+
}
|
115
|
+
});
|
116
|
+
|
117
|
+
CoreObject.__super__ = null;
|
118
|
+
|
119
|
+
var ClassMixin = SC.Mixin.create({
|
120
|
+
|
121
|
+
ClassMixin: SC.required(),
|
122
|
+
|
123
|
+
PrototypeMixin: SC.required(),
|
124
|
+
|
125
|
+
isClass: true,
|
126
|
+
|
127
|
+
isMethod: false,
|
128
|
+
|
129
|
+
extend: function() {
|
130
|
+
var Class = makeCtor(), proto;
|
131
|
+
Class.ClassMixin = SC.Mixin.create(this.ClassMixin);
|
132
|
+
Class.PrototypeMixin = SC.Mixin.create(this.PrototypeMixin);
|
133
|
+
|
134
|
+
Class.ClassMixin.ownerConstructor = Class;
|
135
|
+
Class.PrototypeMixin.ownerConstructor = Class;
|
136
|
+
|
137
|
+
var PrototypeMixin = Class.PrototypeMixin;
|
138
|
+
PrototypeMixin.reopen.apply(PrototypeMixin, arguments);
|
139
|
+
|
140
|
+
Class.superclass = this;
|
141
|
+
Class.__super__ = this.prototype;
|
142
|
+
|
143
|
+
proto = Class.prototype = o_create(this.prototype);
|
144
|
+
proto.constructor = Class;
|
145
|
+
SC.generateGuid(proto, 'sc');
|
146
|
+
meta(proto).proto = proto; // this will disable observers on prototype
|
147
|
+
SC.rewatch(proto); // setup watch chains if needed.
|
148
|
+
|
149
|
+
|
150
|
+
Class.subclasses = SC.Set ? new SC.Set() : null;
|
151
|
+
if (this.subclasses) { this.subclasses.add(Class); }
|
152
|
+
|
153
|
+
Class.ClassMixin.apply(Class);
|
154
|
+
return Class;
|
155
|
+
},
|
156
|
+
|
157
|
+
create: function() {
|
158
|
+
var C = this;
|
159
|
+
if (arguments.length>0) { this._initMixins(arguments); }
|
160
|
+
return new C();
|
161
|
+
},
|
162
|
+
|
163
|
+
reopen: function() {
|
164
|
+
var PrototypeMixin = this.PrototypeMixin;
|
165
|
+
PrototypeMixin.reopen.apply(PrototypeMixin, arguments);
|
166
|
+
this._prototypeMixinDidChange();
|
167
|
+
return this;
|
168
|
+
},
|
169
|
+
|
170
|
+
reopenClass: function() {
|
171
|
+
var ClassMixin = this.ClassMixin;
|
172
|
+
ClassMixin.reopen.apply(ClassMixin, arguments);
|
173
|
+
SC.Mixin._apply(this, arguments, false);
|
174
|
+
return this;
|
175
|
+
},
|
176
|
+
|
177
|
+
detect: function(obj) {
|
178
|
+
if ('function' !== typeof obj) { return false; }
|
179
|
+
while(obj) {
|
180
|
+
if (obj===this) { return true; }
|
181
|
+
obj = obj.superclass;
|
182
|
+
}
|
183
|
+
return false;
|
184
|
+
}
|
185
|
+
|
186
|
+
});
|
187
|
+
|
188
|
+
CoreObject.ClassMixin = ClassMixin;
|
189
|
+
ClassMixin.apply(CoreObject);
|
190
|
+
|
191
|
+
SC.CoreObject = CoreObject;
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
|
@@ -0,0 +1,218 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore Runtime
|
3
|
+
// Copyright: ©2011 Strobe Inc. and contributors.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
|
7
|
+
require('sproutcore-runtime/system/object');
|
8
|
+
require('sproutcore-runtime/mixins/array');
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
var set = SC.set, get = SC.get, guidFor = SC.guidFor;
|
13
|
+
|
14
|
+
var EachArray = SC.Object.extend(SC.Array, {
|
15
|
+
|
16
|
+
init: function(content, keyName, owner) {
|
17
|
+
this._super();
|
18
|
+
this._keyName = keyName;
|
19
|
+
this._owner = owner;
|
20
|
+
this._content = content;
|
21
|
+
},
|
22
|
+
|
23
|
+
objectAt: function(idx) {
|
24
|
+
var item = this._content.objectAt(idx);
|
25
|
+
return item && get(item, this._keyName);
|
26
|
+
},
|
27
|
+
|
28
|
+
length: function() {
|
29
|
+
var content = this._content;
|
30
|
+
return content ? get(content, 'length') : 0;
|
31
|
+
}.property('[]').cacheable()
|
32
|
+
|
33
|
+
});
|
34
|
+
|
35
|
+
var IS_OBSERVER = /^.+:(before|change)$/;
|
36
|
+
|
37
|
+
function addObserverForContentKey(content, keyName, proxy, idx, loc) {
|
38
|
+
var objects = proxy._objects, guid;
|
39
|
+
if (!objects) objects = proxy._objects = {};
|
40
|
+
|
41
|
+
while(--loc>=idx) {
|
42
|
+
var item = content.objectAt(loc);
|
43
|
+
if (item) {
|
44
|
+
SC.addBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
|
45
|
+
SC.addObserver(item, keyName, proxy, 'contentKeyDidChange');
|
46
|
+
|
47
|
+
// keep track of the indicies each item was found at so we can map
|
48
|
+
// it back when the obj changes.
|
49
|
+
guid = guidFor(item);
|
50
|
+
if (!objects[guid]) objects[guid] = [];
|
51
|
+
objects[guid].push(loc);
|
52
|
+
}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
function removeObserverForContentKey(content, keyName, proxy, idx, loc) {
|
57
|
+
var objects = proxy._objects;
|
58
|
+
if (!objects) objects = proxy._objects = {};
|
59
|
+
var indicies, guid;
|
60
|
+
|
61
|
+
while(--loc>=idx) {
|
62
|
+
var item = content.objectAt(loc);
|
63
|
+
if (item) {
|
64
|
+
SC.removeBeforeObserver(item, keyName, proxy, 'contentKeyWillChange');
|
65
|
+
SC.removeObserver(item, keyName, proxy, 'contentKeyDidChange');
|
66
|
+
|
67
|
+
guid = guidFor(item);
|
68
|
+
indicies = objects[guid];
|
69
|
+
indicies[indicies.indexOf(loc)] = null;
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/**
|
75
|
+
@private
|
76
|
+
@class
|
77
|
+
|
78
|
+
This is the object instance returned when you get the @each property on an
|
79
|
+
array. It uses the unknownProperty handler to automatically create
|
80
|
+
EachArray instances for property names.
|
81
|
+
|
82
|
+
@extends SC.Object
|
83
|
+
*/
|
84
|
+
SC.EachProxy = SC.Object.extend({
|
85
|
+
|
86
|
+
init: function(content) {
|
87
|
+
this._super();
|
88
|
+
this._content = content;
|
89
|
+
content.addArrayObserver(this);
|
90
|
+
|
91
|
+
// in case someone is already observing some keys make sure they are
|
92
|
+
// added
|
93
|
+
SC.watchedEvents(this).forEach(function(eventName) {
|
94
|
+
this.didAddListener(eventName);
|
95
|
+
}, this);
|
96
|
+
},
|
97
|
+
|
98
|
+
/**
|
99
|
+
You can directly access mapped properties by simply requesting them.
|
100
|
+
The unknownProperty handler will generate an EachArray of each item.
|
101
|
+
*/
|
102
|
+
unknownProperty: function(keyName, value) {
|
103
|
+
var ret;
|
104
|
+
ret = new EachArray(this._content, keyName, this);
|
105
|
+
new SC.Descriptor().setup(this, keyName, ret);
|
106
|
+
this.beginObservingContentKey(keyName);
|
107
|
+
return ret;
|
108
|
+
},
|
109
|
+
|
110
|
+
// ..........................................................
|
111
|
+
// ARRAY CHANGES
|
112
|
+
// Invokes whenever the content array itself changes.
|
113
|
+
|
114
|
+
arrayWillChange: function(content, idx, removedCnt, addedCnt) {
|
115
|
+
var keys = this._keys, key, array, lim;
|
116
|
+
|
117
|
+
lim = removedCnt>0 ? idx+removedCnt : -1;
|
118
|
+
SC.beginPropertyChanges(this);
|
119
|
+
for(key in keys) {
|
120
|
+
if (!keys.hasOwnProperty(key)) continue;
|
121
|
+
|
122
|
+
if (lim>0) removeObserverForContentKey(content, key, this, idx, lim);
|
123
|
+
|
124
|
+
array = get(this, key);
|
125
|
+
SC.propertyWillChange(this, key);
|
126
|
+
if (array) array.arrayContentWillChange(idx, removedCnt, addedCnt);
|
127
|
+
}
|
128
|
+
|
129
|
+
SC.propertyWillChange(this._content, '@each');
|
130
|
+
SC.endPropertyChanges(this);
|
131
|
+
},
|
132
|
+
|
133
|
+
arrayDidChange: function(content, idx, removedCnt, addedCnt) {
|
134
|
+
var keys = this._keys, key, array, lim;
|
135
|
+
|
136
|
+
lim = addedCnt>0 ? idx+addedCnt : -1;
|
137
|
+
SC.beginPropertyChanges(this);
|
138
|
+
for(key in keys) {
|
139
|
+
if (!keys.hasOwnProperty(key)) continue;
|
140
|
+
|
141
|
+
if (lim>0) addObserverForContentKey(content, key, this, idx, lim);
|
142
|
+
|
143
|
+
array = get(this, key);
|
144
|
+
if (array) array.arrayContentDidChange(idx, removedCnt, addedCnt);
|
145
|
+
SC.propertyDidChange(this, key);
|
146
|
+
}
|
147
|
+
SC.propertyDidChange(this._content, '@each');
|
148
|
+
SC.endPropertyChanges(this);
|
149
|
+
},
|
150
|
+
|
151
|
+
// ..........................................................
|
152
|
+
// LISTEN FOR NEW OBSERVERS AND OTHER EVENT LISTENERS
|
153
|
+
// Start monitoring keys based on who is listening...
|
154
|
+
|
155
|
+
didAddListener: function(eventName) {
|
156
|
+
if (IS_OBSERVER.test(eventName)) {
|
157
|
+
this.beginObservingContentKey(eventName.slice(0, -7));
|
158
|
+
}
|
159
|
+
},
|
160
|
+
|
161
|
+
didRemoveListener: function(eventName) {
|
162
|
+
if (IS_OBSERVER.test(eventName)) {
|
163
|
+
this.stopObservingContentKey(eventName.slice(0, -7));
|
164
|
+
}
|
165
|
+
},
|
166
|
+
|
167
|
+
// ..........................................................
|
168
|
+
// CONTENT KEY OBSERVING
|
169
|
+
// Actual watch keys on the source content.
|
170
|
+
|
171
|
+
beginObservingContentKey: function(keyName) {
|
172
|
+
var keys = this._keys;
|
173
|
+
if (!keys) keys = this._keys = {};
|
174
|
+
if (!keys[keyName]) {
|
175
|
+
keys[keyName] = 1;
|
176
|
+
var content = this._content,
|
177
|
+
len = get(content, 'length');
|
178
|
+
addObserverForContentKey(content, keyName, this, 0, len);
|
179
|
+
} else {
|
180
|
+
keys[keyName]++;
|
181
|
+
}
|
182
|
+
},
|
183
|
+
|
184
|
+
stopObservingContentKey: function(keyName) {
|
185
|
+
var keys = this._keys;
|
186
|
+
if (keys && (keys[keyName]>0) && (--keys[keyName]<=0)) {
|
187
|
+
var content = this._content,
|
188
|
+
len = get(content, 'length');
|
189
|
+
removeObserverForContentKey(content, keyName, this, 0, len);
|
190
|
+
}
|
191
|
+
},
|
192
|
+
|
193
|
+
contentKeyWillChange: function(obj, keyName) {
|
194
|
+
// notify array.
|
195
|
+
var indexes = this._objects[guidFor(obj)],
|
196
|
+
array = get(this, keyName),
|
197
|
+
len = array && indexes ? indexes.length : 0, idx;
|
198
|
+
|
199
|
+
for(idx=0;idx<len;idx++) {
|
200
|
+
array.arrayContentWillChange(indexes[idx], 1, 1);
|
201
|
+
}
|
202
|
+
},
|
203
|
+
|
204
|
+
contentKeyDidChange: function(obj, keyName) {
|
205
|
+
// notify array.
|
206
|
+
var indexes = this._objects[guidFor(obj)],
|
207
|
+
array = get(this, keyName),
|
208
|
+
len = array && indexes ? indexes.length : 0, idx;
|
209
|
+
|
210
|
+
for(idx=0;idx<len;idx++) {
|
211
|
+
array.arrayContentDidChange(indexes[idx], 1, 1);
|
212
|
+
}
|
213
|
+
|
214
|
+
SC.propertyDidChange(this, keyName);
|
215
|
+
}
|
216
|
+
|
217
|
+
});
|
218
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
// ==========================================================================
|
2
|
+
// Project: SproutCore Runtime
|
3
|
+
// Copyright: ©2011 Strobe Inc. and contributors.
|
4
|
+
// License: Licensed under MIT license (see license.js)
|
5
|
+
// ==========================================================================
|
6
|
+
|
7
|
+
|
8
|
+
require('sproutcore-runtime/mixins/observable');
|
9
|
+
require('sproutcore-runtime/mixins/mutable_array');
|
10
|
+
require('sproutcore-runtime/mixins/copyable');
|
11
|
+
|
12
|
+
|
13
|
+
|
14
|
+
var get = SC.get, set = SC.set;
|
15
|
+
|
16
|
+
// Add SC.Array to Array.prototype. Remove methods with native
|
17
|
+
// implementations and supply some more optimized versions of generic methods
|
18
|
+
// because they are so common.
|
19
|
+
var NativeArray = SC.Mixin.create(SC.MutableArray, SC.Observable, SC.Copyable, {
|
20
|
+
|
21
|
+
// because length is a built-in property we need to know to just get the
|
22
|
+
// original property.
|
23
|
+
get: function(key) {
|
24
|
+
if (key==='length') return this.length;
|
25
|
+
else if ('number' === typeof key) return this[key];
|
26
|
+
else return this._super(key);
|
27
|
+
},
|
28
|
+
|
29
|
+
objectAt: function(idx) {
|
30
|
+
return this[idx];
|
31
|
+
},
|
32
|
+
|
33
|
+
// primitive for array support.
|
34
|
+
replace: function(idx, amt, objects) {
|
35
|
+
|
36
|
+
if (this.isFrozen) throw SC.FROZEN_ERROR ;
|
37
|
+
|
38
|
+
// if we replaced exactly the same number of items, then pass only the
|
39
|
+
// replaced range. Otherwise, pass the full remaining array length
|
40
|
+
// since everything has shifted
|
41
|
+
var len = objects ? get(objects, 'length') : 0;
|
42
|
+
if (this.isBilly) { debugger; }
|
43
|
+
this.arrayContentWillChange(idx, amt, len);
|
44
|
+
|
45
|
+
if (!objects || objects.length === 0) {
|
46
|
+
this.splice(idx, amt) ;
|
47
|
+
} else {
|
48
|
+
var args = [idx, amt].concat(objects) ;
|
49
|
+
this.splice.apply(this,args) ;
|
50
|
+
}
|
51
|
+
|
52
|
+
this.arrayContentDidChange(idx, amt, len);
|
53
|
+
return this ;
|
54
|
+
},
|
55
|
+
|
56
|
+
// If you ask for an unknown property, then try to collect the value
|
57
|
+
// from member items.
|
58
|
+
unknownProperty: function(key, value) {
|
59
|
+
var ret;// = this.reducedProperty(key, value) ;
|
60
|
+
if ((value !== undefined) && ret === undefined) {
|
61
|
+
ret = this[key] = value;
|
62
|
+
}
|
63
|
+
return ret ;
|
64
|
+
},
|
65
|
+
|
66
|
+
// If browser did not implement indexOf natively, then override with
|
67
|
+
// specialized version
|
68
|
+
indexOf: function(object, startAt) {
|
69
|
+
var idx, len = this.length;
|
70
|
+
|
71
|
+
if (startAt === undefined) startAt = 0;
|
72
|
+
else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
|
73
|
+
if (startAt < 0) startAt += len;
|
74
|
+
|
75
|
+
for(idx=startAt;idx<len;idx++) {
|
76
|
+
if (this[idx] === object) return idx ;
|
77
|
+
}
|
78
|
+
return -1;
|
79
|
+
},
|
80
|
+
|
81
|
+
lastIndexOf: function(object, startAt) {
|
82
|
+
var idx, len = this.length;
|
83
|
+
|
84
|
+
if (startAt === undefined) startAt = len-1;
|
85
|
+
else startAt = (startAt < 0) ? Math.ceil(startAt) : Math.floor(startAt);
|
86
|
+
if (startAt < 0) startAt += len;
|
87
|
+
|
88
|
+
for(idx=startAt;idx>=0;idx--) {
|
89
|
+
if (this[idx] === object) return idx ;
|
90
|
+
}
|
91
|
+
return -1;
|
92
|
+
},
|
93
|
+
|
94
|
+
copy: function() {
|
95
|
+
return this.slice();
|
96
|
+
}
|
97
|
+
});
|
98
|
+
|
99
|
+
// Remove any methods implemented natively so we don't override them
|
100
|
+
var ignore = ['length'];
|
101
|
+
NativeArray.keys().forEach(function(methodName) {
|
102
|
+
if (Array.prototype[methodName]) ignore.push(methodName);
|
103
|
+
});
|
104
|
+
|
105
|
+
if (ignore.length>0) {
|
106
|
+
NativeArray = NativeArray.without.apply(NativeArray, ignore);
|
107
|
+
}
|
108
|
+
|
109
|
+
/**
|
110
|
+
The NativeArray mixin contains the properties needed to to make the native
|
111
|
+
Array support SC.MutableArray and all of its dependent APIs. Unless you
|
112
|
+
have SC.EXTEND_PROTOTYPES set to false, this will be applied automatically.
|
113
|
+
Otherwise you can apply the mixin at anytime by calling
|
114
|
+
`SC.NativeArray.activate`.
|
115
|
+
|
116
|
+
@namespace
|
117
|
+
@extends SC.MutableArray
|
118
|
+
@extends SC.Array
|
119
|
+
@extends SC.Enumerable
|
120
|
+
@extends SC.MutableEnumerable
|
121
|
+
@extends SC.Copyable
|
122
|
+
@extends SC.Freezable
|
123
|
+
*/
|
124
|
+
SC.NativeArray = NativeArray;
|
125
|
+
|
126
|
+
/**
|
127
|
+
Activates the mixin on the Array.prototype if not already applied. Calling
|
128
|
+
this method more than once is safe.
|
129
|
+
|
130
|
+
@returns {void}
|
131
|
+
*/
|
132
|
+
SC.NativeArray.activate = function() {
|
133
|
+
NativeArray.apply(Array.prototype);
|
134
|
+
};
|
135
|
+
|
136
|
+
if (SC.EXTEND_PROTOTYPES) SC.NativeArray.activate();
|
137
|
+
|
138
|
+
|
139
|
+
|