parsejs 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+