Created
February 16, 2010 22:18
-
-
Save erichocean/306005 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* @license | |
| ========================================================================== | |
| SproutCore Costello -- Property Observing Library | |
| Copyright ©2006-2009, Sprout Systems, Inc. and contributors. | |
| Portions copyright ©2008-2009 Apple Inc. All rights reserved. | |
| Permission is hereby granted, free of charge, to any person obtaining a | |
| copy of this software and associated documentation files (the "Software"), | |
| to deal in the Software without restriction, including without limitation | |
| the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| and/or sell copies of the Software, and to permit persons to whom the | |
| Software is furnished to do so, subject to the following conditions: | |
| The above copyright notice and this permission notice shall be included in | |
| all copies or substantial portions of the Software. | |
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| DEALINGS IN THE SOFTWARE. | |
| For more information about SproutCore, visit http://www.sproutcore.com | |
| ========================================================================== | |
| @license */ | |
| var sys = require("sys"); | |
| var exports = exports || {}; | |
| var SC = SC || exports; | |
| var SproutCore = SproutCore || SC; | |
| var YES = true, NO = false; | |
| var sc_require = sc_require || function() { }; | |
| var sc_resource = sc_resource || function sc_resource() {}; | |
| // set up console | |
| SC.console = { | |
| message: function(type, what) { | |
| sys.puts(type + ": " + sys.inspect(what)); | |
| }, | |
| log: function(what){ | |
| this.message("LOG", what); | |
| }, | |
| info: function(what){ | |
| this.message("INFO", what); | |
| }, | |
| error: function(what){ | |
| this.message("ERROR", what); | |
| }, | |
| warn: function(what){ | |
| this.message("WARN", what); | |
| } | |
| }; | |
| SC.root = GLOBAL; | |
| SC.mixin = function() { | |
| var e = arguments[0] || {}; | |
| var a = 1; | |
| var d = arguments.length; | |
| var b; | |
| if (d === 1) { | |
| e = this || {}; | |
| a = 0 | |
| } | |
| for (; a < d; a++) { | |
| if (! (b = arguments[a])) { | |
| continue | |
| } | |
| for (var c in b) { | |
| if (!b.hasOwnProperty(c)) { | |
| continue | |
| } | |
| var f = b[c]; | |
| if (e === f) { | |
| continue | |
| } | |
| if (f !== undefined) { | |
| e[c] = f | |
| } | |
| } | |
| } | |
| return e | |
| }; | |
| SC.supplement = function() { | |
| var e = arguments[0] || {}; | |
| var a = 1; | |
| var d = arguments.length; | |
| var b; | |
| if (d === 1) { | |
| e = this || {}; | |
| a = 0 | |
| } | |
| for (; a < d; a++) { | |
| if (! (b = arguments[a])) { | |
| continue | |
| } | |
| for (var c in b) { | |
| if (!b.hasOwnProperty(c)) { | |
| continue | |
| } | |
| var f = e[c]; | |
| var g = b[c]; | |
| if (e === g) { | |
| continue | |
| } | |
| if (g !== undefined && f === undefined) { | |
| e[c] = g | |
| } | |
| } | |
| } | |
| return e | |
| }; | |
| SC.extend = SC.mixin; | |
| SC.mixin({ | |
| T_ERROR: "error", | |
| T_OBJECT: "object", | |
| T_NULL: "null", | |
| T_CLASS: "class", | |
| T_HASH: "hash", | |
| T_FUNCTION: "function", | |
| T_UNDEFINED: "undefined", | |
| T_NUMBER: "number", | |
| T_BOOL: "boolean", | |
| T_ARRAY: "array", | |
| T_STRING: "string", | |
| typeOf: function(b) { | |
| if (b === undefined) { | |
| return SC.T_UNDEFINED | |
| } | |
| if (b === null) { | |
| return SC.T_NULL | |
| } | |
| var a = typeof(b); | |
| if (a == "object") { | |
| if (b instanceof Array) { | |
| a = SC.T_ARRAY | |
| } else { | |
| if (b instanceof Function) { | |
| a = b.isClass ? SC.T_CLASS: SC.T_FUNCTION | |
| } else { | |
| if (SC.Error && (b instanceof SC.Error)) { | |
| a = SC.T_ERROR | |
| } else { | |
| if (b.isObject === true) { | |
| a = SC.T_OBJECT | |
| } else { | |
| a = SC.T_HASH | |
| } | |
| } | |
| } | |
| } | |
| } else { | |
| if (a === SC.T_FUNCTION) { | |
| a = (b.isClass) ? SC.T_CLASS: SC.T_FUNCTION | |
| } | |
| } | |
| return a | |
| }, | |
| none: function(a) { | |
| return a === null || a === undefined | |
| }, | |
| empty: function(a) { | |
| return a === null || a === undefined || a === "" | |
| }, | |
| isArray: function(c) { | |
| if (c && c.objectAt) { | |
| return YES | |
| } | |
| var a = (c ? c.length: null), | |
| b = SC.typeOf(c); | |
| return ! (SC.none(a) || (b === SC.T_FUNCTION) || (b === SC.T_STRING) || c.setInterval) | |
| }, | |
| makeArray: function(a) { | |
| return SC.isArray(a) ? a: SC.A(a) | |
| }, | |
| A: function(c) { | |
| if (SC.none(c)) { | |
| return [] | |
| } | |
| if (c.slice instanceof Function) { | |
| if (typeof(c) === "string") { | |
| return [c] | |
| } else { | |
| return c.slice() | |
| } | |
| } | |
| if (c.toArray) { | |
| return c.toArray() | |
| } | |
| if (!SC.isArray(c)) { | |
| return [c] | |
| } | |
| var b = [], | |
| a = c.length; | |
| while (--a >= 0) { | |
| b[a] = c[a] | |
| } | |
| return b | |
| }, | |
| guidKey: "_sc_guid_" + new Date().getTime(), | |
| _nextGUID: 0, | |
| _numberGuids: [], | |
| _stringGuids: {}, | |
| _keyCache: {}, | |
| guidFor: function(b) { | |
| if (b === undefined) { | |
| return "(undefined)" | |
| } | |
| if (b === null) { | |
| return "(null)" | |
| } | |
| if (b === Object) { | |
| return "(Object)" | |
| } | |
| if (b === Array) { | |
| return "(Array)" | |
| } | |
| var a = this.guidKey; | |
| if (b[a]) { | |
| return b[a] | |
| } | |
| switch (typeof b) { | |
| case SC.T_NUMBER: | |
| return (this._numberGuids[b] = this._numberGuids[b] || ("nu" + b)); | |
| case SC.T_STRING: | |
| return (this._stringGuids[b] = this._stringGuids[b] || ("st" + b)); | |
| case SC.T_BOOL: | |
| return (b) ? "(true)": "(false)"; | |
| default: | |
| return SC.generateGuid(b) | |
| } | |
| }, | |
| keyFor: function(d, c) { | |
| var b, | |
| a = this._keyCache[d]; | |
| if (!a) { | |
| a = this._keyCache[d] = {} | |
| } | |
| b = a[c]; | |
| if (!b) { | |
| b = a[c] = d + "_" + c | |
| } | |
| return b | |
| }, | |
| generateGuid: function(b) { | |
| var a = ("sc" + (this._nextGUID++)); | |
| if (b) { | |
| b[this.guidKey] = a | |
| } | |
| return a | |
| }, | |
| hashFor: function(a) { | |
| return (a && a.hash && (typeof a.hash === SC.T_FUNCTION)) ? a.hash() : this.guidFor(a) | |
| }, | |
| isEqual: function(d, c) { | |
| if (d === null) { | |
| return c === null | |
| } else { | |
| if (d === undefined) { | |
| return c === undefined | |
| } else { | |
| return this.hashFor(d) === this.hashFor(c) | |
| } | |
| } | |
| }, | |
| compare: function(h, g) { | |
| var f = SC.typeOf(h); | |
| var d = SC.typeOf(g); | |
| var j = SC.ORDER_DEFINITION.indexOf(f); | |
| var b = SC.ORDER_DEFINITION.indexOf(d); | |
| if (j < b) { | |
| return - 1 | |
| } | |
| if (j > b) { | |
| return 1 | |
| } | |
| switch (f) { | |
| case SC.T_BOOL: | |
| case SC.T_NUMBER: | |
| if (h < g) { | |
| return - 1 | |
| } | |
| if (h > g) { | |
| return 1 | |
| } | |
| return 0; | |
| case SC.T_STRING: | |
| if (h.localeCompare(g) < 0) { | |
| return - 1 | |
| } | |
| if (h.localeCompare(g) > 0) { | |
| return 1 | |
| } | |
| return 0; | |
| case SC.T_ARRAY: | |
| var c = Math.min(h.length, g.length); | |
| var a = 0; | |
| var e = 0; | |
| while (a === 0 && e < c) { | |
| a = arguments.callee(h[e], g[e]); | |
| if (a !== 0) { | |
| return a | |
| } | |
| e++ | |
| } | |
| if (h.length < g.length) { | |
| return - 1 | |
| } | |
| if (h.length > g.length) { | |
| return 1 | |
| } | |
| return 0; | |
| case SC.T_OBJECT: | |
| if (h.constructor.isComparable === YES) { | |
| return h.constructor.compare(h, g) | |
| } | |
| return 0; | |
| default: | |
| return 0 | |
| } | |
| }, | |
| K: function() { | |
| return this | |
| }, | |
| EMPTY_ARRAY: [], | |
| EMPTY_HASH: {}, | |
| EMPTY_RANGE: { | |
| start: 0, | |
| length: 0 | |
| }, | |
| beget: function(c) { | |
| if (SC.none(c)) { | |
| return null | |
| } | |
| var a = SC.K; | |
| a.prototype = c; | |
| var b = new a(); | |
| a.prototype = null; | |
| if (SC.typeOf(c.didBeget) === SC.T_FUNCTION) { | |
| b = c.didBeget(b) | |
| } | |
| return b | |
| }, | |
| copy: function(b) { | |
| var a = b; | |
| if (b && b.isCopyable) { | |
| return b.copy() | |
| } | |
| switch (SC.typeOf(b)) { | |
| case SC.T_ARRAY: | |
| if (b.clone && SC.typeOf(b.clone) === SC.T_FUNCTION) { | |
| a = b.clone() | |
| } else { | |
| a = b.slice() | |
| } | |
| break; | |
| case SC.T_HASH: | |
| case SC.T_OBJECT: | |
| if (b.clone && SC.typeOf(b.clone) === SC.T_FUNCTION) { | |
| a = b.clone() | |
| } else { | |
| a = {}; | |
| for (var c in b) { | |
| a[c] = b[c] | |
| } | |
| } | |
| } | |
| return a | |
| }, | |
| merge: function() { | |
| var c = {}, | |
| b = arguments.length, | |
| a; | |
| for (a = 0; a < b; a++) { | |
| SC.mixin(c, arguments[a]) | |
| } | |
| return c | |
| }, | |
| keys: function(c) { | |
| var a = []; | |
| for (var b in c) { | |
| a.push(b) | |
| } | |
| return a | |
| }, | |
| inspect: function(d) { | |
| var a, | |
| b = []; | |
| for (var c in d) { | |
| a = d[c]; | |
| if (a === "toString") { | |
| continue | |
| } | |
| if (SC.typeOf(a) === SC.T_FUNCTION) { | |
| a = "function() { ... }" | |
| } | |
| b.push(c + ": " + a) | |
| } | |
| return "{" + b.join(" , ") + "}" | |
| }, | |
| tupleForPropertyPath: function(e, a) { | |
| if (SC.typeOf(e) === SC.T_ARRAY) { | |
| return e | |
| } | |
| var c; | |
| var b = e.indexOf("*"); | |
| if (b < 0) { | |
| b = e.lastIndexOf(".") | |
| } | |
| c = (b >= 0) ? e.slice(b + 1) : e; | |
| var d = this.objectForPropertyPath(e, a, b); | |
| return (d && c) ? [d, c] : null | |
| }, | |
| objectForPropertyPath: function(f, c, d) { | |
| var g, | |
| b, | |
| e, | |
| a; | |
| if (!c) { | |
| c = SC.root | |
| } | |
| if (SC.typeOf(f) === SC.T_STRING) { | |
| if (d === undefined) { | |
| d = f.length | |
| } | |
| g = 0; | |
| while ((c) && (g < d)) { | |
| b = f.indexOf(".", g); | |
| if ((b < 0) || (b > d)) { | |
| b = d | |
| } | |
| e = f.slice(g, b); | |
| c = c.get ? c.get(e) : c[e]; | |
| g = b + 1 | |
| } | |
| if (g < d) { | |
| c = undefined | |
| } | |
| } else { | |
| g = 0; | |
| a = f.length; | |
| e = null; | |
| while ((g < a) && c) { | |
| e = f[g++]; | |
| if (e) { | |
| c = (c.get) ? c.get(e) : c[e] | |
| } | |
| } | |
| if (g < a) { | |
| c = undefined | |
| } | |
| } | |
| return c | |
| }, | |
| STRINGS: {}, | |
| stringsFor: function(b, a) { | |
| SC.mixin(SC.STRINGS, a); | |
| return this | |
| } | |
| }); | |
| SC.clone = SC.copy; | |
| SC.$A = SC.A; | |
| SC.didLoad = SC.K; | |
| SC.ORDER_DEFINITION = [SC.T_ERROR, SC.T_UNDEFINED, SC.T_NULL, SC.T_BOOL, SC.T_NUMBER, SC.T_STRING, SC.T_ARRAY, SC.T_HASH, SC.T_OBJECT, SC.T_FUNCTION, SC.T_CLASS]; | |
| SC.mixin(Function.prototype, { | |
| property: function() { | |
| this.dependentKeys = SC.$A(arguments); | |
| var a = SC.guidFor(this); | |
| this.cacheKey = "__cache__" + a; | |
| this.lastSetValueKey = "__lastValue__" + a; | |
| this.isProperty = YES; | |
| return this | |
| }, | |
| cacheable: function(a) { | |
| this.isProperty = YES; | |
| if (!this.dependentKeys) { | |
| this.dependentKeys = [] | |
| } | |
| this.isCacheable = (a === undefined) ? YES: a; | |
| return this | |
| }, | |
| idempotent: function(a) { | |
| this.isProperty = YES; | |
| if (!this.dependentKeys) { | |
| this.dependentKeys = [] | |
| } | |
| this.isVolatile = (a === undefined) ? YES: a; | |
| return this | |
| }, | |
| observes: function(a) { | |
| var e = arguments.length, | |
| b = null, | |
| d = null; | |
| while (--e >= 0) { | |
| var c = arguments[e]; | |
| if ((c.indexOf(".") < 0) && (c.indexOf("*") < 0)) { | |
| if (!b) { | |
| b = this.localPropertyPaths = [] | |
| } | |
| b.push(c) | |
| } else { | |
| if (!d) { | |
| d = this.propertyPaths = [] | |
| } | |
| d.push(c) | |
| } | |
| } | |
| return this | |
| } | |
| }); | |
| String.prototype.fmt = function() { | |
| var b = arguments; | |
| var a = 0; | |
| return this.replace(/%@([0-9]+)?/g, | |
| function(c, d) { | |
| d = (d) ? parseInt(d, 0) - 1: a++; | |
| c = b[d]; | |
| return ((c === null) ? "(null)": (c === undefined) ? "": c).toString() | |
| }) | |
| }; | |
| String.prototype.loc = function() { | |
| var a = SC.STRINGS[this] || this; | |
| return a.fmt.apply(a, arguments) | |
| }; | |
| String.prototype.w = function() { | |
| var c = [], | |
| d = this.split(" "), | |
| b = d.length; | |
| for (var a = 0; a < b; ++a) { | |
| var e = d[a]; | |
| if (e.length !== 0) { | |
| c.push(e) | |
| } | |
| } | |
| return c | |
| }; | |
| SC.ObserverSet = { | |
| targets: 0, | |
| _membersCacheIsValid: NO, | |
| add: function(d, f, b) { | |
| var c = (d) ? SC.guidFor(d) : "__this__"; | |
| var a = this[c]; | |
| if (!a) { | |
| a = this[c] = SC.CoreSet.create(); | |
| a.target = d; | |
| a.isTargetSet = YES; | |
| this.targets++ | |
| } | |
| a.add(f); | |
| if (b !== undefined) { | |
| var e = a.contexts; | |
| if (!b) { | |
| e = {} | |
| } | |
| e[SC.guidFor(f)] = b | |
| } | |
| this._membersCacheIsValid = NO | |
| }, | |
| remove: function(c, d) { | |
| var b = (c) ? SC.guidFor(c) : "__this__"; | |
| var a = this[b]; | |
| if (!a) { | |
| return NO | |
| } | |
| a.remove(d); | |
| if (a.length <= 0) { | |
| a.target = null; | |
| a.isTargetSet = NO; | |
| a.contexts = null; | |
| delete this[b]; | |
| this.targets-- | |
| } else { | |
| if (a.contexts) { | |
| delete a.contexts[SC.guidFor(d)] | |
| } | |
| } | |
| this._membersCacheIsValid = NO; | |
| return YES | |
| }, | |
| invokeMethods: function() { | |
| for (var b in this) { | |
| if (!this.hasOwnProperty(b)) { | |
| continue | |
| } | |
| var c = this[b]; | |
| if (c && c.isTargetSet) { | |
| var a = c.length; | |
| var d = c.target; | |
| while (--a >= 0) { | |
| c[a].call(d) | |
| } | |
| } | |
| } | |
| }, | |
| getMembers: function() { | |
| if (this._membersCacheIsValid) { | |
| return this._members | |
| } | |
| if (!this._members) { | |
| this._members = [] | |
| } else { | |
| this._members.length = 0 | |
| } | |
| var b = this._members; | |
| for (var c in this) { | |
| if (!this.hasOwnProperty(c)) { | |
| continue | |
| } | |
| var d = this[c]; | |
| if (d && d.isTargetSet) { | |
| var a = d.length; | |
| var e = d.target; | |
| var g = d.contexts; | |
| if (g) { | |
| while (--a >= 0) { | |
| var f = d[a]; | |
| b.push([e, f, g[SC.guidFor(f)]]) | |
| } | |
| } else { | |
| while (--a >= 0) { | |
| b.push([e, d[a]]) | |
| } | |
| } | |
| } | |
| } | |
| this._membersCacheIsValid = YES; | |
| return b | |
| }, | |
| clone: function() { | |
| var b, | |
| d, | |
| c, | |
| a = SC.ObserverSet.create(); | |
| for (c in this) { | |
| if (!this.hasOwnProperty(c)) { | |
| continue | |
| } | |
| b = this[c]; | |
| if (b && b.isTargetSet) { | |
| d = b.clone(); | |
| d.target = b.target; | |
| if (b.contexts) { | |
| d.contexts = SC.clone(b.contexts) | |
| } | |
| a[c] = d | |
| } | |
| } | |
| a.targets = this.targets; | |
| a._membersCacheIsValid = NO; | |
| return a | |
| }, | |
| create: function() { | |
| return SC.beget(this) | |
| } | |
| }; | |
| SC.ObserverSet.slice = SC.ObserverSet.clone; | |
| sc_require("private/observer_set"); | |
| SC.LOG_OBSERVERS = NO; | |
| SC.Observable = { | |
| isObservable: YES, | |
| automaticallyNotifiesObserversFor: function(a) { | |
| return YES | |
| }, | |
| get: function(c) { | |
| var b = this[c], | |
| a; | |
| if (b === undefined) { | |
| return this.unknownProperty(c) | |
| } else { | |
| if (b && b.isProperty) { | |
| if (b.isCacheable) { | |
| a = this._kvo_cache; | |
| if (!a) { | |
| a = this._kvo_cache = {} | |
| } | |
| return (a[b.cacheKey] !== undefined) ? a[b.cacheKey] : (a[b.cacheKey] = b.call(this, c)) | |
| } else { | |
| return b.call(this, c) | |
| } | |
| } else { | |
| return b | |
| } | |
| } | |
| }, | |
| set: function(h, f) { | |
| var b = this[h], | |
| i = this.automaticallyNotifiesObserversFor(h), | |
| e = f, | |
| c, | |
| a, | |
| g, | |
| d; | |
| if (this._kvo_cacheable && (a = this._kvo_cache)) { | |
| c = this._kvo_cachedep; | |
| if (!c || (c = c[h]) === undefined) { | |
| c = this._kvo_computeCachedDependentsFor(h) | |
| } | |
| if (c) { | |
| g = c.length; | |
| while (--g >= 0) { | |
| d = c[g]; | |
| a[d.cacheKey] = a[d.lastSetValueKey] = undefined | |
| } | |
| } | |
| } | |
| if (b && b.isProperty) { | |
| a = this._kvo_cache; | |
| if (b.isVolatile || !a || (a[b.lastSetValueKey] !== f)) { | |
| if (!a) { | |
| a = this._kvo_cache = {} | |
| } | |
| a[b.lastSetValueKey] = f; | |
| if (i) { | |
| this.propertyWillChange(h) | |
| } | |
| e = b.call(this, h, f); | |
| if (b.isCacheable) { | |
| a[b.cacheKey] = e | |
| } | |
| if (i) { | |
| this.propertyDidChange(h, e, YES) | |
| } | |
| } | |
| } else { | |
| if (b === undefined) { | |
| if (i) { | |
| this.propertyWillChange(h) | |
| } | |
| this.unknownProperty(h, f); | |
| if (i) { | |
| this.propertyDidChange(h, e) | |
| } | |
| } else { | |
| if (this[h] !== f) { | |
| if (i) { | |
| this.propertyWillChange(h) | |
| } | |
| e = this[h] = f; | |
| if (i) { | |
| this.propertyDidChange(h, e) | |
| } | |
| } | |
| } | |
| } | |
| return this | |
| }, | |
| unknownProperty: function(a, b) { | |
| if (! (b === undefined)) { | |
| this[a] = b | |
| } | |
| return b | |
| }, | |
| beginPropertyChanges: function() { | |
| this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1; | |
| return this | |
| }, | |
| endPropertyChanges: function() { | |
| this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1; | |
| var b = this._kvo_changeLevel, | |
| a = this._kvo_changes; | |
| if ((b <= 0) && a && (a.length > 0) && !SC.Observers.isObservingSuspended) { | |
| this._notifyPropertyObservers() | |
| } | |
| return this | |
| }, | |
| propertyWillChange: function(a) { | |
| return this | |
| }, | |
| propertyDidChange: function(l, j, c) { | |
| this._kvo_revision = (this._kvo_revision || 0) + 1; | |
| var b = this._kvo_changeLevel || 0, | |
| g, | |
| k, | |
| h, | |
| a, | |
| d, | |
| f = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING === NO); | |
| if (this._kvo_cacheable && (a = this._kvo_cache)) { | |
| if (!c) { | |
| d = this[l]; | |
| if (d && d.isProperty) { | |
| a[d.cacheKey] = a[d.lastSetValueKey] = undefined | |
| } | |
| } | |
| g = this._kvo_cachedep; | |
| if (!g || (g = g[l]) === undefined) { | |
| g = this._kvo_computeCachedDependentsFor(l) | |
| } | |
| if (g) { | |
| k = g.length; | |
| while (--k >= 0) { | |
| h = g[k]; | |
| a[h.cacheKey] = a[h.lastSetValueKey] = undefined | |
| } | |
| } | |
| } | |
| var e = SC.Observers.isObservingSuspended; | |
| if ((b > 0) || e) { | |
| var i = this._kvo_changes; | |
| if (!i) { | |
| i = this._kvo_changes = SC.CoreSet.create() | |
| } | |
| i.add(l); | |
| if (e) { | |
| if (f) { | |
| console.log("%@%@: will not notify observers because observing is suspended".fmt(SC.KVO_SPACES, this)) | |
| } | |
| SC.Observers.objectHasPendingChanges(this) | |
| } | |
| } else { | |
| this._notifyPropertyObservers(l) | |
| } | |
| return this | |
| }, | |
| registerDependentKey: function(h, c) { | |
| var e = this._kvo_dependents, | |
| b = this[h], | |
| i, | |
| g, | |
| a, | |
| f, | |
| d; | |
| if (SC.typeOf(c) === SC.T_ARRAY) { | |
| i = c; | |
| a = 0 | |
| } else { | |
| i = arguments; | |
| a = 1 | |
| } | |
| g = i.length; | |
| if (!e) { | |
| this._kvo_dependents = e = {} | |
| } | |
| while (--g >= a) { | |
| f = i[g]; | |
| d = e[f]; | |
| if (!d) { | |
| d = e[f] = [] | |
| } | |
| d.push(h) | |
| } | |
| }, | |
| _kvo_addCachedDependents: function(b, f, h, c) { | |
| var a = f.length, | |
| e, | |
| d, | |
| g; | |
| while (--a >= 0) { | |
| d = f[a]; | |
| c.add(d); | |
| e = this[d]; | |
| if (e && (e instanceof Function) && e.isProperty) { | |
| if (e.isCacheable) { | |
| b.push(e) | |
| } | |
| if ((g = h[d]) && g.length > 0) { | |
| this._kvo_addCachedDependents(b, g, h, c) | |
| } | |
| } | |
| } | |
| }, | |
| _kvo_computeCachedDependentsFor: function(c) { | |
| var d = this._kvo_cachedep, | |
| f = this._kvo_dependents, | |
| e = f ? f[c] : null, | |
| a, | |
| b; | |
| if (!d) { | |
| d = this._kvo_cachedep = {} | |
| } | |
| if (!e || e.length === 0) { | |
| return d[c] = null | |
| } | |
| a = d[c] = []; | |
| b = SC._TMP_SEEN_SET = (SC._TMP_SEEN_SET || SC.CoreSet.create()); | |
| b.add(c); | |
| this._kvo_addCachedDependents(a, e, f, b); | |
| b.clear(); | |
| if (a.length === 0) { | |
| a = d[c] = null | |
| } | |
| return a | |
| }, | |
| _kvo_for: function(c, b) { | |
| var a = this[c]; | |
| if (!this._kvo_cloned) { | |
| this._kvo_cloned = {} | |
| } | |
| if (!a) { | |
| a = this[c] = (b === undefined) ? [] : b.create(); | |
| this._kvo_cloned[c] = YES | |
| } else { | |
| if (!this._kvo_cloned[c]) { | |
| a = this[c] = a.copy(); | |
| this._kvo_cloned[c] = YES | |
| } | |
| } | |
| return a | |
| }, | |
| addObserver: function(c, f, h, b) { | |
| var d, | |
| a, | |
| e, | |
| g; | |
| if (h === undefined) { | |
| h = f; | |
| f = this | |
| } | |
| if (!f) { | |
| f = this | |
| } | |
| if (SC.typeOf(h) === SC.T_STRING) { | |
| h = f[h] | |
| } | |
| if (!h) { | |
| throw "You must pass a method to addObserver()" | |
| } | |
| c = c.toString(); | |
| if (c.indexOf(".") >= 0) { | |
| a = SC._ChainObserver.createChain(this, c, f, h, b); | |
| a.masterTarget = f; | |
| a.masterMethod = h; | |
| this._kvo_for(SC.keyFor("_kvo_chains", c)).push(a) | |
| } else { | |
| if ((this[c] === undefined) && (c.indexOf("@") === 0)) { | |
| this.get(c) | |
| } | |
| if (f === this) { | |
| f = null | |
| } | |
| d = SC.keyFor("_kvo_observers", c); | |
| this._kvo_for(d, SC.ObserverSet).add(f, h, b); | |
| this._kvo_for("_kvo_observed_keys", SC.CoreSet).add(c) | |
| } | |
| if (this.didAddObserver) { | |
| this.didAddObserver(c, f, h) | |
| } | |
| return this | |
| }, | |
| removeObserver: function(c, f, h) { | |
| var d, | |
| e, | |
| b, | |
| g, | |
| a; | |
| if (h === undefined) { | |
| h = f; | |
| f = this | |
| } | |
| if (!f) { | |
| f = this | |
| } | |
| if (SC.typeOf(h) === SC.T_STRING) { | |
| h = f[h] | |
| } | |
| if (!h) { | |
| throw "You must pass a method to addObserver()" | |
| } | |
| c = c.toString(); | |
| if (c.indexOf(".") >= 0) { | |
| d = SC.keyFor("_kvo_chains", c); | |
| if (e = this[d]) { | |
| e = this._kvo_for(d); | |
| a = e.length; | |
| while (--a >= 0) { | |
| b = e[a]; | |
| if (b && (b.masterTarget === f) && (b.masterMethod === h)) { | |
| e[a] = b.destroyChain() | |
| } | |
| } | |
| } | |
| } else { | |
| if (f === this) { | |
| f = null | |
| } | |
| d = SC.keyFor("_kvo_observers", c); | |
| if (g = this[d]) { | |
| g = this._kvo_for(d); | |
| g.remove(f, h); | |
| if (g.targets <= 0) { | |
| this._kvo_for("_kvo_observed_keys", SC.CoreSet).remove(c) | |
| } | |
| } | |
| } | |
| if (this.didRemoveObserver) { | |
| this.didRemoveObserver(c, f, h) | |
| } | |
| return this | |
| }, | |
| hasObserverFor: function(b) { | |
| SC.Observers.flush(this); | |
| var d = this[SC.keyFor("_kvo_observers", b)], | |
| c = this[SC.keyFor("_kvo_local", b)], | |
| a; | |
| if (c && c.length > 0) { | |
| return YES | |
| } | |
| if (d && d.getMembers().length > 0) { | |
| return YES | |
| } | |
| return NO | |
| }, | |
| initObservable: function() { | |
| if (this._observableInited) { | |
| return | |
| } | |
| this._observableInited = YES; | |
| var e, | |
| l, | |
| j, | |
| i, | |
| g, | |
| d, | |
| k; | |
| if (l = this._observers) { | |
| var f = l.length; | |
| for (e = 0; e < f; e++) { | |
| j = l[e]; | |
| g = this[j]; | |
| d = g.propertyPaths; | |
| k = (d) ? d.length: 0; | |
| for (var b = 0; | |
| b < k; b++) { | |
| var m = d[b]; | |
| var a = m.indexOf("."); | |
| if (a < 0) { | |
| this.addObserver(m, this, g) | |
| } else { | |
| if (m.indexOf("*") === 0) { | |
| this.addObserver(m.slice(1), this, g) | |
| } else { | |
| var h = null; | |
| if (a === 0) { | |
| h = this; | |
| m = m.slice(1) | |
| } else { | |
| if (a === 4 && m.slice(0, 5) === "this.") { | |
| h = this; | |
| m = m.slice(5) | |
| } else { | |
| if (a < 0 && m.length === 4 && m === "this") { | |
| h = this; | |
| m = "" | |
| } | |
| } | |
| } | |
| SC.Observers.addObserver(m, this, g, h) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| this.bindings = []; | |
| if (l = this._bindings) { | |
| for (e = 0; e < l.length; e++) { | |
| j = l[e]; | |
| i = this[j]; | |
| var c = j.slice(0, -7); | |
| this[j] = this.bind(c, i) | |
| } | |
| } | |
| if (l = this._properties) { | |
| for (e = 0; e < l.length; | |
| e++) { | |
| j = l[e]; | |
| if (i = this[j]) { | |
| if (i.isCacheable) { | |
| this._kvo_cacheable = YES | |
| } | |
| if (i.dependentKeys && (i.dependentKeys.length > 0)) { | |
| this.registerDependentKey(j, i.dependentKeys) | |
| } | |
| } | |
| } | |
| } | |
| }, | |
| observersForKey: function(a) { | |
| var b = this._kvo_for("_kvo_observers", a); | |
| return b.getMembers() || [] | |
| }, | |
| _notifyPropertyObservers: function(t) { | |
| if (!this._observableInited) { | |
| this.initObservable() | |
| } | |
| SC.Observers.flush(this); | |
| var g = SC.LOG_OBSERVERS && !(this.LOG_OBSERVING === NO); | |
| var o, | |
| r, | |
| m, | |
| d, | |
| n, | |
| l, | |
| q; | |
| var p, | |
| j, | |
| a, | |
| f, | |
| s, | |
| c, | |
| i, | |
| e; | |
| var b, | |
| h, | |
| k; | |
| if (g) { | |
| h = SC.KVO_SPACES = (SC.KVO_SPACES || "") + " "; | |
| console.log('%@%@: notifying observers after change to key "%@"'.fmt(h, this, t)) | |
| } | |
| d = this["_kvo_observers_*"]; | |
| this._kvo_changeLevel = (this._kvo_changeLevel || 0) + 1; | |
| while (((r = this._kvo_changes) && (r.length > 0)) || t) { | |
| q = ++this.propertyRevision; | |
| if (!r) { | |
| r = SC.CoreSet.create() | |
| } | |
| this._kvo_changes = null; | |
| if (t === "*") { | |
| r.add("*"); | |
| r.addEach(this._kvo_for("_kvo_observed_keys", SC.CoreSet)) | |
| } else { | |
| if (t) { | |
| r.add(t) | |
| } | |
| } | |
| if (m = this._kvo_dependents) { | |
| for (n = 0; n < r.length; n++) { | |
| t = r[n]; | |
| l = m[t]; | |
| if (l && (i = l.length)) { | |
| if (g) { | |
| console.log("%@...including dependent keys for %@: %@".fmt(h, t, l)) | |
| } | |
| k = this._kvo_cache; | |
| if (!k) { | |
| k = this._kvo_cache = {} | |
| } | |
| while (--i >= 0) { | |
| r.add(t = l[i]); | |
| if (e = this[t]) { | |
| this[e.cacheKey] = undefined; | |
| k[e.cacheKey] = k[e.lastSetValueKey] = undefined | |
| } | |
| } | |
| } | |
| } | |
| } | |
| while (r.length > 0) { | |
| t = r.pop(); | |
| o = this[SC.keyFor("_kvo_observers", t)]; | |
| if (o) { | |
| p = o.getMembers(); | |
| j = p.length; | |
| for (f = 0; f < j; f++) { | |
| a = p[f]; | |
| if (a[3] === q) { | |
| continue | |
| } | |
| s = a[0] || this; | |
| c = a[1]; | |
| b = a[2]; | |
| a[3] = q; | |
| if (g) { | |
| console.log('%@...firing observer on %@ for key "%@"'.fmt(h, s, t)) | |
| } | |
| if (b !== undefined) { | |
| c.call(s, this, t, null, b, q) | |
| } else { | |
| c.call(s, this, t, null, q) | |
| } | |
| } | |
| } | |
| p = this[SC.keyFor("_kvo_local", t)]; | |
| if (p) { | |
| j = p.length; | |
| for (f = 0; f < j; f++) { | |
| a = p[f]; | |
| c = this[a]; | |
| if (c) { | |
| if (g) { | |
| console.log('%@...firing local observer %@.%@ for key "%@"'.fmt(h, this, a, t)) | |
| } | |
| c.call(this, this, t, null, q) | |
| } | |
| } | |
| } | |
| if (d && t !== "*") { | |
| p = d.getMembers(); | |
| j = p.length; | |
| for (f = 0; | |
| f < j; f++) { | |
| a = p[f]; | |
| s = a[0] || this; | |
| c = a[1]; | |
| b = a[2]; | |
| if (g) { | |
| console.log('%@...firing * observer on %@ for key "%@"'.fmt(h, s, t)) | |
| } | |
| if (b !== undefined) { | |
| c.call(s, this, t, null, b, q) | |
| } else { | |
| c.call(s, this, t, null, q) | |
| } | |
| } | |
| } | |
| if (this.propertyObserver) { | |
| if (g) { | |
| console.log('%@...firing %@.propertyObserver for key "%@"'.fmt(h, this, t)) | |
| } | |
| this.propertyObserver(this, t, null, q) | |
| } | |
| } | |
| if (r) { | |
| r.destroy() | |
| } | |
| t = null | |
| } | |
| this._kvo_changeLevel = (this._kvo_changeLevel || 1) - 1; | |
| if (g) { | |
| SC.KVO_SPACES = h.slice(0, -2) | |
| } | |
| return YES | |
| }, | |
| bind: function(a, c, e) { | |
| var d; | |
| if (e !== undefined) { | |
| c = [c, e] | |
| } | |
| var b = SC.typeOf(c); | |
| if (b === SC.T_STRING || b === SC.T_ARRAY) { | |
| d = this[a + "BindingDefault"] || SC.Binding; | |
| d = d.beget().from(c) | |
| } else { | |
| d = c | |
| } | |
| d = d.to(a, this).connect(); | |
| this.bindings.push(d); | |
| return d | |
| }, | |
| didChangeFor: function(a) { | |
| a = SC.hashFor(a); | |
| var b = this._kvo_didChange_valueCache; | |
| if (!b) { | |
| b = this._kvo_didChange_valueCache = {} | |
| } | |
| var f = this._kvo_didChange_revisionCache; | |
| if (!f) { | |
| f = this._kvo_didChange_revisionCache = {} | |
| } | |
| var e = b[a] || {}; | |
| var j = f[a] || {}; | |
| var d = false; | |
| var c = this._kvo_revision || 0; | |
| var h = arguments.length; | |
| while (--h >= 1) { | |
| var i = arguments[h]; | |
| if (j[i] != c) { | |
| var g = this.get(i); | |
| if (e[i] !== g) { | |
| d = true; | |
| e[i] = g | |
| } | |
| } | |
| j[i] = c | |
| } | |
| b[a] = e; | |
| f[a] = j; | |
| return d | |
| }, | |
| setIfChanged: function(a, b) { | |
| return (this.get(a) !== b) ? this.set(a, b) : this | |
| }, | |
| getPath: function(b) { | |
| var a = SC.tupleForPropertyPath(b, this); | |
| if (a === null || a[0] === null) { | |
| return undefined | |
| } | |
| return a[0].get(a[1]) | |
| }, | |
| setPath: function(c, b) { | |
| if (c.indexOf(".") >= 0) { | |
| var a = SC.tupleForPropertyPath(c, this); | |
| if (!a || !a[0]) { | |
| return null | |
| } | |
| a[0].set(a[1], b) | |
| } else { | |
| this.set(c, b) | |
| } | |
| return this | |
| }, | |
| setPathIfChanged: function(c, b) { | |
| if (c.indexOf(".") >= 0) { | |
| var a = SC.tupleForPropertyPath(c, this); | |
| if (!a || !a[0]) { | |
| return null | |
| } | |
| if (a[0].get(a[1]) !== b) { | |
| a[0].set(a[1], b) | |
| } | |
| } else { | |
| this.setIfChanged(c, b) | |
| } | |
| return this | |
| }, | |
| getEach: function() { | |
| var c = SC.A(arguments); | |
| var b = []; | |
| for (var a = 0; a < c.length; | |
| a++) { | |
| b[b.length] = this.getPath(c[a]) | |
| } | |
| return b | |
| }, | |
| incrementProperty: function(a) { | |
| this.set(a, (this.get(a) || 0) + 1); | |
| return this.get(a) | |
| }, | |
| decrementProperty: function(a) { | |
| this.set(a, (this.get(a) || 0) - 1); | |
| return this.get(a) | |
| }, | |
| toggleProperty: function(a, b, c) { | |
| if (b === undefined) { | |
| b = true | |
| } | |
| if (c === undefined) { | |
| c = false | |
| } | |
| b = (this.get(a) == b) ? c: b; | |
| this.set(a, b); | |
| return this.get(a) | |
| }, | |
| notifyPropertyChange: function(a, b) { | |
| this.propertyWillChange(a); | |
| this.propertyDidChange(a, b); | |
| return this | |
| }, | |
| allPropertiesDidChange: function() { | |
| this._kvo_cache = null; | |
| this._notifyPropertyObservers("*"); | |
| return this | |
| }, | |
| addProbe: function(a) { | |
| this.addObserver(a, SC.logChange) | |
| }, | |
| removeProbe: function(a) { | |
| this.removeObserver(a, SC.logChange) | |
| }, | |
| logProperty: function() { | |
| var b = SC.$A(arguments); | |
| for (var a = 0; a < b.length; a++) { | |
| var c = b[a]; | |
| console.log("%@:%@: ".fmt(SC.guidFor(this), c), this.get(c)) | |
| } | |
| }, | |
| propertyRevision: 1 | |
| }; | |
| SC.logChange = function logChange(c, a, b) { | |
| console.log("CHANGE: %@[%@] => %@".fmt(c, a, c.get(a))) | |
| }; | |
| SC.mixin(Array.prototype, SC.Observable); | |
| SC.Enumerator = function(a) { | |
| this.enumerable = a; | |
| this.reset(); | |
| return this | |
| }; | |
| SC.Enumerator.prototype = { | |
| nextObject: function() { | |
| var c = this._index; | |
| var a = this._length; | |
| if (c >= a) { | |
| return undefined | |
| } | |
| var b = this.enumerable.nextObject(c, this._previousObject, this._context); | |
| this._previousObject = b; | |
| this._index = c + 1; | |
| if (c >= a) { | |
| this._context = SC.Enumerator._pushContext(this._context) | |
| } | |
| return b | |
| }, | |
| reset: function() { | |
| var b = this.enumerable; | |
| if (!b) { | |
| throw SC.$error("Enumerator has been destroyed") | |
| } | |
| this._length = b.get ? b.get("length") : b.length; | |
| var a = this._length; | |
| this._index = 0; | |
| this._previousObject = null; | |
| this._context = (a > 0) ? SC.Enumerator._popContext() : null | |
| }, | |
| destroy: function() { | |
| this.enumerable = this._length = this._index = this._previousObject = this._context = null | |
| } | |
| }; | |
| SC.Enumerator.create = function(a) { | |
| return new SC.Enumerator(a) | |
| }; | |
| SC.Enumerator._popContext = function() { | |
| var a = this._contextCache ? this._contextCache.pop() : null; | |
| return a || {} | |
| }; | |
| SC.Enumerator._pushContext = function(b) { | |
| this._contextCache = this._contextCache || []; | |
| var a = this._contextCache; | |
| a.push(b); | |
| return null | |
| }; | |
| sc_require("core"); | |
| sc_require("system/enumerator"); | |
| SC.Enumerable = { | |
| isEnumerable: YES, | |
| nextObject: function(a, c, b) { | |
| return this.objectAt ? this.objectAt(a) : this[a] | |
| }, | |
| firstObject: function() { | |
| if (this.get("length") === 0) { | |
| return undefined | |
| } | |
| if (this.objectAt) { | |
| return this.objectAt(0) | |
| } | |
| var b = SC.Enumerator._popContext(), | |
| a; | |
| a = this.nextObject(0, null, b); | |
| b = SC.Enumerator._pushContext(b); | |
| return a | |
| }.property(), | |
| enumerator: function() { | |
| return SC.Enumerator.create(this) | |
| }, | |
| forEach: function(g, f) { | |
| if (typeof g !== "function") { | |
| throw new TypeError() | |
| } | |
| var b = this.get ? this.get("length") : this.length; | |
| if (f === undefined) { | |
| f = null | |
| } | |
| var e = null; | |
| var c = SC.Enumerator._popContext(); | |
| for (var a = 0; a < b; a++) { | |
| var d = this.nextObject(a, e, c); | |
| g.call(f, d, a, this); | |
| e = d | |
| } | |
| e = null; | |
| c = SC.Enumerator._pushContext(c); | |
| return this | |
| }, | |
| getEach: function(a) { | |
| return this.map(function(b) { | |
| return b ? (b.get ? b.get(a) : b[a]) : null | |
| }, | |
| this) | |
| }, | |
| setEach: function(a, b) { | |
| this.forEach(function(c) { | |
| if (c) { | |
| if (c.set) { | |
| c.set(a, b) | |
| } else { | |
| c[a] = b | |
| } | |
| } | |
| }, | |
| this); | |
| return this | |
| }, | |
| map: function(h, g) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var b = this.get ? this.get("length") : this.length; | |
| if (g === undefined) { | |
| g = null | |
| } | |
| var c = []; | |
| var f = null; | |
| var d = SC.Enumerator._popContext(); | |
| for (var a = 0; a < b; a++) { | |
| var e = this.nextObject(a, f, d); | |
| c[a] = h.call(g, e, a, this); | |
| f = e | |
| } | |
| f = null; | |
| d = SC.Enumerator._pushContext(d); | |
| return c | |
| }, | |
| mapProperty: function(a) { | |
| return this.map(function(b) { | |
| return b ? (b.get ? b.get(a) : b[a]) : null | |
| }) | |
| }, | |
| filter: function(h, g) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var b = this.get ? this.get("length") : this.length; | |
| if (g === undefined) { | |
| g = null | |
| } | |
| var c = []; | |
| var f = null; | |
| var d = SC.Enumerator._popContext(); | |
| for (var a = 0; | |
| a < b; a++) { | |
| var e = this.nextObject(a, f, d); | |
| if (h.call(g, e, a, this)) { | |
| c.push(e) | |
| } | |
| f = e | |
| } | |
| f = null; | |
| d = SC.Enumerator._pushContext(d); | |
| return c | |
| }, | |
| sortProperty: function(b) { | |
| var c = (typeof b === SC.T_STRING) ? arguments: b, | |
| a = c.length, | |
| d; | |
| if (this instanceof Array) { | |
| d = this | |
| } else { | |
| d = []; | |
| this.forEach(function(e) { | |
| d.push(e) | |
| }) | |
| } | |
| if (!d) { | |
| return [] | |
| } | |
| return d.sort(function(g, f) { | |
| var e, | |
| i, | |
| k, | |
| j, | |
| h = 0; | |
| for (e = 0; h === 0 && e < a; e++) { | |
| i = c[e]; | |
| k = g ? (g.get ? g.get(i) : g[i]) : null; | |
| j = f ? (f.get ? f.get(i) : f[i]) : null; | |
| h = SC.compare(k, j) | |
| } | |
| return h | |
| }) | |
| }, | |
| filterProperty: function(j, f) { | |
| var d = this.get ? this.get("length") : this.length; | |
| var e = []; | |
| var i = null; | |
| var b = SC.Enumerator._popContext(); | |
| for (var g = 0; g < d; g++) { | |
| var c = this.nextObject(g, i, b); | |
| var h = c ? (c.get ? c.get(j) : c[j]) : null; | |
| var a = (f === undefined) ? !!h: SC.isEqual(h, f); | |
| if (a) { | |
| e.push(c) | |
| } | |
| i = c | |
| } | |
| i = null; | |
| b = SC.Enumerator._pushContext(b); | |
| return e | |
| }, | |
| find: function(h, d) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var c = this.get ? this.get("length") : this.length; | |
| if (d === undefined) { | |
| d = null | |
| } | |
| var g = null, | |
| b, | |
| i = NO, | |
| e = null; | |
| var a = SC.Enumerator._popContext(); | |
| for (var f = 0; f < c && !i; f++) { | |
| b = this.nextObject(f, g, a); | |
| if (i = h.call(d, b, f, this)) { | |
| e = b | |
| } | |
| g = b | |
| } | |
| b = g = null; | |
| a = SC.Enumerator._pushContext(a); | |
| return e | |
| }, | |
| findProperty: function(i, f) { | |
| var c = this.get ? this.get("length") : this.length; | |
| var j = NO, | |
| d = null, | |
| h = null, | |
| b, | |
| g; | |
| var a = SC.Enumerator._popContext(); | |
| for (var e = 0; e < c && !j; e++) { | |
| b = this.nextObject(e, h, a); | |
| g = b ? (b.get ? b.get(i) : b[i]) : null; | |
| j = (f === undefined) ? !!g: SC.isEqual(g, f); | |
| if (j) { | |
| d = b | |
| } | |
| h = b | |
| } | |
| h = b = null; | |
| a = SC.Enumerator._pushContext(a); | |
| return d | |
| }, | |
| every: function(h, g) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var b = this.get ? this.get("length") : this.length; | |
| if (g === undefined) { | |
| g = null | |
| } | |
| var c = YES; | |
| var f = null; | |
| var d = SC.Enumerator._popContext(); | |
| for (var a = 0; c && (a < b); a++) { | |
| var e = this.nextObject(a, f, d); | |
| if (!h.call(g, e, a, this)) { | |
| c = NO | |
| } | |
| f = e | |
| } | |
| f = null; | |
| d = SC.Enumerator._pushContext(d); | |
| return c | |
| }, | |
| everyProperty: function(i, e) { | |
| var c = this.get ? this.get("length") : this.length; | |
| var d = YES; | |
| var h = null; | |
| var a = SC.Enumerator._popContext(); | |
| for (var f = 0; d && (f < c); f++) { | |
| var b = this.nextObject(f, h, a); | |
| var g = b ? (b.get ? b.get(i) : b[i]) : null; | |
| d = (e === undefined) ? !!g: SC.isEqual(g, e); | |
| h = b | |
| } | |
| h = null; | |
| a = SC.Enumerator._pushContext(a); | |
| return d | |
| }, | |
| some: function(h, g) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var b = this.get ? this.get("length") : this.length; | |
| if (g === undefined) { | |
| g = null | |
| } | |
| var c = NO; | |
| var f = null; | |
| var d = SC.Enumerator._popContext(); | |
| for (var a = 0; (!c) && (a < b); a++) { | |
| var e = this.nextObject(a, f, d); | |
| if (h.call(g, e, a, this)) { | |
| c = YES | |
| } | |
| f = e | |
| } | |
| f = null; | |
| d = SC.Enumerator._pushContext(d); | |
| return c | |
| }, | |
| someProperty: function(i, e) { | |
| var c = this.get ? this.get("length") : this.length; | |
| var d = NO; | |
| var h = null; | |
| var a = SC.Enumerator._popContext(); | |
| for (var f = 0; ! d && (f < c); f++) { | |
| var b = this.nextObject(f, h, a); | |
| var g = b ? (b.get ? b.get(i) : b[i]) : null; | |
| d = (e === undefined) ? !!g: SC.isEqual(g, e); | |
| h = b | |
| } | |
| h = null; | |
| a = SC.Enumerator._pushContext(a); | |
| return d | |
| }, | |
| reduce: function(g, h, i) { | |
| if (typeof g !== "function") { | |
| throw new TypeError() | |
| } | |
| var c = this.get ? this.get("length") : this.length; | |
| if (c === 0 && h === undefined) { | |
| throw new TypeError() | |
| } | |
| var d = h; | |
| var f = null; | |
| var a = SC.Enumerator._popContext(); | |
| for (var e = 0; e < c; e++) { | |
| var b = this.nextObject(e, f, a); | |
| if (b !== null) { | |
| if (d === undefined) { | |
| d = b | |
| } else { | |
| d = g.call(null, d, b, e, this, i) | |
| } | |
| } | |
| f = b | |
| } | |
| f = null; | |
| a = SC.Enumerator._pushContext(a); | |
| if (d === undefined) { | |
| throw new TypeError() | |
| } | |
| return d | |
| }, | |
| invoke: function(h) { | |
| var e = this.get ? this.get("length") : this.length; | |
| if (e <= 0) { | |
| return [] | |
| } | |
| var i; | |
| var g = []; | |
| var c = arguments.length; | |
| if (c > 1) { | |
| for (i = 1; i < c; i++) { | |
| g.push(arguments[i]) | |
| } | |
| } | |
| var f = []; | |
| var j = null; | |
| var b = SC.Enumerator._popContext(); | |
| for (i = 0; i < e; i++) { | |
| var d = this.nextObject(i, j, b); | |
| var a = d ? d[h] : null; | |
| if (a) { | |
| f[i] = a.apply(d, g) | |
| } | |
| j = d | |
| } | |
| j = null; | |
| b = SC.Enumerator._pushContext(b); | |
| return f | |
| }, | |
| invokeWhile: function(d, i) { | |
| var f = this.get ? this.get("length") : this.length; | |
| if (f <= 0) { | |
| return null | |
| } | |
| var j; | |
| var h = []; | |
| var c = arguments.length; | |
| if (c > 2) { | |
| for (j = 2; j < c; j++) { | |
| h.push(arguments[j]) | |
| } | |
| } | |
| var g = d; | |
| var k = null; | |
| var b = SC.Enumerator._popContext(); | |
| for (j = 0; (g === d) && (j < f); j++) { | |
| var e = this.nextObject(j, k, b); | |
| var a = e ? e[i] : null; | |
| if (a) { | |
| g = a.apply(e, h) | |
| } | |
| k = e | |
| } | |
| k = null; | |
| b = SC.Enumerator._pushContext(b); | |
| return g | |
| }, | |
| toArray: function() { | |
| var a = []; | |
| this.forEach(function(b) { | |
| a.push(b) | |
| }, | |
| this); | |
| return a | |
| } | |
| }; | |
| SC._buildReducerFor = function(a, b) { | |
| return function(d, e) { | |
| var f = this[a]; | |
| if (SC.typeOf(f) !== SC.T_FUNCTION) { | |
| return this.unknownProperty ? this.unknownProperty(d, e) : null | |
| } else { | |
| var c = SC.Enumerable.reduce.call(this, f, null, b); | |
| return c | |
| } | |
| }.property("[]") | |
| }; | |
| SC.Reducers = { | |
| "[]": function(a, b) { | |
| return this | |
| }.property(), | |
| enumerableContentDidChange: function(b, a) { | |
| this.notifyPropertyChange("[]"); | |
| return this | |
| }, | |
| reducedProperty: function(i, g, f) { | |
| if (!i || i.charAt(0) !== "@") { | |
| return undefined | |
| } | |
| var d = i.match(/^@([^(]*)(\(([^)]*)\))?$/); | |
| if (!d || d.length < 2) { | |
| return undefined | |
| } | |
| var h = d[1]; | |
| var j = d[3]; | |
| h = "reduce" + h.slice(0, 1).toUpperCase() + h.slice(1); | |
| var a = this[h]; | |
| if (SC.typeOf(a) !== SC.T_FUNCTION) { | |
| return undefined | |
| } | |
| if (f === NO) { | |
| return SC.Enumerable.reduce.call(this, a, null, j) | |
| } | |
| var c = SC._buildReducerFor(h, j); | |
| var b = this.constructor.prototype; | |
| if (b) { | |
| b[i] = c; | |
| var e = b._properties || []; | |
| e.push(i); | |
| b._properties = e; | |
| this.registerDependentKey(i, "[]") | |
| } | |
| return SC.Enumerable.reduce.call(this, a, null, j) | |
| }, | |
| reduceMax: function(a, d, b, f, c) { | |
| if (c && d) { | |
| d = d.get ? d.get(c) : d[c] | |
| } | |
| if (a === null) { | |
| return d | |
| } | |
| return (d > a) ? d: a | |
| }, | |
| reduceMaxObject: function(b, f, c, g, d) { | |
| var a = b, | |
| h = f; | |
| if (d) { | |
| if (f) { | |
| h = f.get ? f.get(d) : f[d] | |
| } | |
| if (b) { | |
| a = b.get ? b.get(d) : b[d] | |
| } | |
| } | |
| if (a === null) { | |
| return f | |
| } | |
| return (h > a) ? f: b | |
| }, | |
| reduceMin: function(a, d, b, f, c) { | |
| if (c && d) { | |
| d = d.get ? d.get(c) : d[c] | |
| } | |
| if (a === null) { | |
| return d | |
| } | |
| return (d < a) ? d: a | |
| }, | |
| reduceMinObject: function(b, f, c, g, d) { | |
| var a = b, | |
| h = f; | |
| if (d) { | |
| if (f) { | |
| h = f.get ? f.get(d) : f[d] | |
| } | |
| if (b) { | |
| a = b.get ? b.get(d) : b[d] | |
| } | |
| } | |
| if (a === null) { | |
| return f | |
| } | |
| return (h < a) ? f: b | |
| }, | |
| reduceAverage: function(b, g, d, h, f) { | |
| if (f && g) { | |
| g = g.get ? g.get(f) : g[f] | |
| } | |
| var c = (b || 0) + g; | |
| var a = h.get ? h.get("length") : h.length; | |
| if (d >= a - 1) { | |
| c = c / a | |
| } | |
| return c | |
| }, | |
| reduceSum: function(a, d, b, f, c) { | |
| if (c && d) { | |
| d = d.get ? d.get(c) : d[c] | |
| } | |
| return (a === null) ? d: a + d | |
| } | |
| }; | |
| SC.mixin(SC.Enumerable, SC.Reducers); | |
| SC.mixin(Array.prototype, SC.Reducers); | |
| Array.prototype.isEnumerable = YES; (function() { | |
| var a = { | |
| nextObject: SC.Enumerable.nextObject, | |
| enumerator: SC.Enumerable.enumerator, | |
| firstObject: SC.Enumerable.firstObject, | |
| sortProperty: SC.Enumerable.sortProperty, | |
| mapProperty: function(g) { | |
| var e = this.length; | |
| var f = []; | |
| for (var d = 0; d < e; d++) { | |
| var h = this[d]; | |
| f[d] = h ? (h.get ? h.get(g) : h[g]) : null | |
| } | |
| return f | |
| }, | |
| filterProperty: function(h, j) { | |
| var f = this.length; | |
| var g = []; | |
| for (var e = 0; e < f; e++) { | |
| var i = this[e]; | |
| var k = i ? (i.get ? i.get(h) : i[h]) : null; | |
| var d = (j === undefined) ? !!k: SC.isEqual(k, j); | |
| if (d) { | |
| g.push(i) | |
| } | |
| } | |
| return g | |
| }, | |
| find: function(j, i) { | |
| if (typeof j !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (i === undefined) { | |
| i = null | |
| } | |
| var g, | |
| f = null, | |
| h = NO; | |
| for (var d = 0; d < e && !h; d++) { | |
| g = this[d]; | |
| if (h = j.call(i, g, d, this)) { | |
| f = g | |
| } | |
| } | |
| g = null; | |
| return f | |
| }, | |
| findProperty: function(g, j) { | |
| var e = this.length; | |
| var h, | |
| k, | |
| i = NO, | |
| f = null; | |
| for (var d = 0; d < e && !i; d++) { | |
| k = (h = this[d]) ? (h.get ? h.get(g) : h[g]) : null; | |
| i = (j === undefined) ? !!k: SC.isEqual(k, j); | |
| if (i) { | |
| f = h | |
| } | |
| } | |
| h = null; | |
| return f | |
| }, | |
| everyProperty: function(g, i) { | |
| var e = this.length; | |
| var f = YES; | |
| for (var d = 0; f && (d < e); d++) { | |
| var h = this[d]; | |
| var j = h ? (h.get ? h.get(g) : h[g]) : null; | |
| f = (i === undefined) ? !!j: SC.isEqual(j, i) | |
| } | |
| return f | |
| }, | |
| someProperty: function(g, i) { | |
| var e = this.length; | |
| var f = NO; | |
| for (var d = 0; ! f && (d < e); | |
| d++) { | |
| var h = this[d]; | |
| var j = h ? (h.get ? h.get(g) : h[g]) : null; | |
| f = (i === undefined) ? !!j: SC.isEqual(j, i) | |
| } | |
| return f | |
| }, | |
| invoke: function(f) { | |
| var e = this.length; | |
| if (e <= 0) { | |
| return [] | |
| } | |
| var d; | |
| var h = []; | |
| var j = arguments.length; | |
| if (j > 1) { | |
| for (d = 1; d < j; d++) { | |
| h.push(arguments[d]) | |
| } | |
| } | |
| var g = []; | |
| for (d = 0; | |
| d < e; d++) { | |
| var i = this[d]; | |
| var k = i ? i[f] : null; | |
| if (k) { | |
| g[d] = k.apply(i, h) | |
| } | |
| } | |
| return g | |
| }, | |
| invokeWhile: function(f, k) { | |
| var h = this.length; | |
| if (h <= 0) { | |
| return null | |
| } | |
| var l; | |
| var j = []; | |
| var e = arguments.length; | |
| if (e > 2) { | |
| for (l = 2; l < e; l++) { | |
| j.push(arguments[l]) | |
| } | |
| } | |
| var i = f; | |
| for (l = 0; (i === f) && (l < h); l++) { | |
| var g = this[l]; | |
| var d = g ? g[k] : null; | |
| if (d) { | |
| i = d.apply(g, j) | |
| } | |
| } | |
| return i | |
| }, | |
| toArray: function() { | |
| var e = this.length; | |
| if (e <= 0) { | |
| return [] | |
| } | |
| var f = []; | |
| for (var d = 0; | |
| d < e; d++) { | |
| var g = this[d]; | |
| f.push(g) | |
| } | |
| return f | |
| }, | |
| getEach: function(g) { | |
| var f = []; | |
| var e = this.length; | |
| for (var d = 0; d < e; d++) { | |
| var h = this[d]; | |
| f[d] = h ? (h.get ? h.get(g) : h[g]) : null | |
| } | |
| return f | |
| }, | |
| setEach: function(f, g) { | |
| var e = this.length; | |
| for (var d = 0; d < e; d++) { | |
| var h = this[d]; | |
| if (h) { | |
| if (h.set) { | |
| h.set(f, g) | |
| } else { | |
| h[f] = g | |
| } | |
| } | |
| } | |
| return this | |
| } | |
| }; | |
| var c = { | |
| forEach: function(h, g) { | |
| if (typeof h !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (g === undefined) { | |
| g = null | |
| } | |
| for (var d = 0; d < e; d++) { | |
| var f = this[d]; | |
| h.call(g, f, d, this) | |
| } | |
| return this | |
| }, | |
| map: function(i, h) { | |
| if (typeof i !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (h === undefined) { | |
| h = null | |
| } | |
| var f = []; | |
| for (var d = 0; d < e; d++) { | |
| var g = this[d]; | |
| f[d] = i.call(h, g, d, this) | |
| } | |
| return f | |
| }, | |
| filter: function(i, h) { | |
| if (typeof i !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (h === undefined) { | |
| h = null | |
| } | |
| var f = []; | |
| for (var d = 0; d < e; d++) { | |
| var g = this[d]; | |
| if (i.call(h, g, d, this)) { | |
| f.push(g) | |
| } | |
| } | |
| return f | |
| }, | |
| every: function(i, h) { | |
| if (typeof i !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (h === undefined) { | |
| h = null | |
| } | |
| var f = YES; | |
| for (var d = 0; f && (d < e); d++) { | |
| var g = this[d]; | |
| if (!i.call(h, g, d, this)) { | |
| f = NO | |
| } | |
| } | |
| return f | |
| }, | |
| some: function(i, h) { | |
| if (typeof i !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (h === undefined) { | |
| h = null | |
| } | |
| var f = NO; | |
| for (var d = 0; (!f) && (d < e); d++) { | |
| var g = this[d]; | |
| if (i.call(h, g, d, this)) { | |
| f = YES | |
| } | |
| } | |
| return f | |
| }, | |
| reduce: function(j, f, i) { | |
| if (typeof j !== "function") { | |
| throw new TypeError() | |
| } | |
| var e = this.length; | |
| if (e === 0 && f === undefined) { | |
| throw new TypeError() | |
| } | |
| var g = f; | |
| for (var d = 0; | |
| d < e; d++) { | |
| var h = this[d]; | |
| if (h !== null) { | |
| if (g === undefined) { | |
| g = h | |
| } else { | |
| g = j.call(null, g, h, d, this, i) | |
| } | |
| } | |
| } | |
| if (g === undefined) { | |
| throw new TypeError() | |
| } | |
| return g | |
| } | |
| }; | |
| for (var b in c) { | |
| if (!c.hasOwnProperty(b)) { | |
| continue | |
| } | |
| if (!Array.prototype[b] || ((typeof Prototype === "object") && Prototype.Version.match(/^1\.6/))) { | |
| Array.prototype[b] = c[b] | |
| } | |
| } | |
| SC.mixin(Array.prototype, a) | |
| })(); | |
| SC.RangeObserver = { | |
| isRangeObserver: YES, | |
| toString: function() { | |
| var a = this.indexes ? this.indexes.toString() : "SC.IndexSet<..>"; | |
| return a.replace("IndexSet", "RangeObserver(%@)".fmt(SC.guidFor(this))) | |
| }, | |
| create: function(d, f, e, g, c, a) { | |
| var b = SC.beget(this); | |
| b.source = d; | |
| b.indexes = f ? f.frozenCopy() : null; | |
| b.target = e; | |
| b.method = g; | |
| b.context = c; | |
| b.isDeep = a || NO; | |
| b.beginObserving(); | |
| return b | |
| }, | |
| extend: function(e) { | |
| var d = SC.beget(this), | |
| c = arguments, | |
| b = c.length, | |
| a; | |
| for (a = 0; a < b; a++) { | |
| SC.mixin(d, c[a]) | |
| } | |
| return d | |
| }, | |
| destroy: function(a) { | |
| this.endObserving(); | |
| return this | |
| }, | |
| update: function(a, b) { | |
| if (this.indexes && this.indexes.isEqual(b)) { | |
| return this | |
| } | |
| this.indexes = b ? b.frozenCopy() : null; | |
| this.endObserving().beginObserving(); | |
| return this | |
| }, | |
| beginObserving: function() { | |
| if (!this.isDeep) { | |
| return this | |
| } | |
| var b = this.observing; | |
| if (!b) { | |
| b = this.observing = SC.CoreSet.create() | |
| } | |
| var a = this._beginObservingForEach; | |
| if (!a) { | |
| a = this._beginObservingForEach = function(c) { | |
| var d = this.source.objectAt(c); | |
| if (d && d.addObserver) { | |
| b.push(d); | |
| d._kvo_needsRangeObserver = YES | |
| } | |
| } | |
| } | |
| this.indexes.forEach(a, this); | |
| this.isObserving = NO; | |
| SC.Observers.addPendingRangeObserver(this); | |
| return this | |
| }, | |
| setupPending: function(a) { | |
| var d = this.observing; | |
| if (this.isObserving || !d || (d.get("length") === 0)) { | |
| return YES | |
| } | |
| if (d.contains(a)) { | |
| this.isObserving = YES; | |
| var b = this._setupPendingForEach; | |
| if (!b) { | |
| var c = this.source, | |
| e = this.objectPropertyDidChange; | |
| b = this._setupPendingForEach = function(f) { | |
| var i = this.source.objectAt(f), | |
| g = SC.guidFor(i), | |
| h; | |
| if (i && i.addObserver) { | |
| d.push(i); | |
| i.addObserver("*", this, e); | |
| h = this[g]; | |
| if (h === undefined || h === null) { | |
| this[g] = f | |
| } else { | |
| if (h.isIndexSet) { | |
| h.add(f) | |
| } else { | |
| h = this[g] = SC.IndexSet.create(h).add(f) | |
| } | |
| } | |
| } | |
| } | |
| } | |
| this.indexes.forEach(b, this); | |
| return YES | |
| } else { | |
| return NO | |
| } | |
| }, | |
| endObserving: function() { | |
| if (!this.isDeep) { | |
| return this | |
| } | |
| var e = this.observing; | |
| if (this.isObserving) { | |
| var b = this.objectPropertyDidChange, | |
| c = this.source, | |
| a, | |
| f, | |
| d; | |
| if (e) { | |
| f = e.length; | |
| for (a = 0; a < f; a++) { | |
| d = e[a]; | |
| d.removeObserver("*", this, b); | |
| this[SC.guidFor(d)] = null | |
| } | |
| e.length = 0 | |
| } | |
| this.isObserving = NO | |
| } | |
| if (e) { | |
| e.clear() | |
| } | |
| return this | |
| }, | |
| rangeDidChange: function(b) { | |
| var a = this.indexes; | |
| if (!b || !a || a.intersects(b)) { | |
| this.endObserving(); | |
| this.method.call(this.target, this.source, null, "[]", b, this.context); | |
| this.beginObserving() | |
| } | |
| return this | |
| }, | |
| objectPropertyDidChange: function(d, f, g, a) { | |
| var e = this.context, | |
| h = this.method, | |
| c = SC.guidFor(d), | |
| b = this[c]; | |
| if (b && !b.isIndexSet) { | |
| b = this[c] = SC.IndexSet.create(b).freeze() | |
| } | |
| if (e) { | |
| h.call(this.target, this.source, d, f, b, e, a) | |
| } else { | |
| h.call(this.target, this.source, d, f, b, a) | |
| } | |
| } | |
| }; | |
| sc_require("mixins/observable"); | |
| sc_require("mixins/enumerable"); | |
| sc_require("system/range_observer"); | |
| SC.OUT_OF_RANGE_EXCEPTION = "Index out of range"; | |
| SC.Array = { | |
| isSCArray: YES, | |
| replace: function(a, c, b) { | |
| throw "replace() must be implemented to support SC.Array" | |
| }, | |
| objectAt: function(a) { | |
| if (a < 0) { | |
| return undefined | |
| } | |
| if (a >= this.get("length")) { | |
| return undefined | |
| } | |
| return this.get(a) | |
| }, | |
| "[]": function(a, b) { | |
| if (b !== undefined) { | |
| this.replace(0, this.get("length"), b) | |
| } | |
| return this | |
| }.property(), | |
| insertAt: function(a, b) { | |
| if (a > this.get("length")) { | |
| throw SC.OUT_OF_RANGE_EXCEPTION | |
| } | |
| this.replace(a, 0, [b]); | |
| return this | |
| }, | |
| removeAt: function(d, a) { | |
| var c = 0, | |
| b = []; | |
| if (typeof d === SC.T_NUMBER) { | |
| if ((d < 0) || (d >= this.get("length"))) { | |
| throw SC.OUT_OF_RANGE_EXCEPTION | |
| } | |
| if (a === undefined) { | |
| this.replace(d, 1, b); | |
| return this | |
| } else { | |
| d = SC.IndexSet.create(d, a) | |
| } | |
| } | |
| this.beginPropertyChanges(); | |
| d.forEachRange(function(f, e) { | |
| f -= c; | |
| c += e; | |
| this.replace(f, e, b) | |
| }, | |
| this); | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| removeObject: function(b) { | |
| var c = this.get("length") || 0; | |
| while (--c >= 0) { | |
| var a = this.objectAt(c); | |
| if (a == b) { | |
| this.removeAt(c) | |
| } | |
| } | |
| return this | |
| }, | |
| removeObjects: function(a) { | |
| this.beginPropertyChanges(); | |
| a.forEach(function(b) { | |
| this.removeObject(b) | |
| }, | |
| this); | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| pushObject: function(a) { | |
| this.insertAt(this.get("length"), a); | |
| return a | |
| }, | |
| pushObjects: function(a) { | |
| this.beginPropertyChanges(); | |
| a.forEach(function(b) { | |
| this.pushObject(b) | |
| }, | |
| this); | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| popObject: function() { | |
| var a = this.get("length"); | |
| if (a === 0) { | |
| return null | |
| } | |
| var b = this.objectAt(a - 1); | |
| this.removeAt(a - 1); | |
| return b | |
| }, | |
| shiftObject: function() { | |
| if (this.get("length") === 0) { | |
| return null | |
| } | |
| var a = this.objectAt(0); | |
| this.removeAt(0); | |
| return a | |
| }, | |
| unshiftObject: function(a) { | |
| this.insertAt(0, a); | |
| return a | |
| }, | |
| unshiftObjects: function(a) { | |
| this.beginPropertyChanges(); | |
| a.forEach(function(b) { | |
| this.unshiftObject(b) | |
| }, | |
| this); | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| isEqual: function(a) { | |
| if (!a) { | |
| return false | |
| } | |
| if (a == this) { | |
| return true | |
| } | |
| var b = a.get("length"); | |
| if (b != this.get("length")) { | |
| return false | |
| } | |
| while (--b >= 0) { | |
| if (!SC.isEqual(a.objectAt(b), this.objectAt(b))) { | |
| return false | |
| } | |
| } | |
| return true | |
| }, | |
| compact: function() { | |
| return this.without(null) | |
| }, | |
| without: function(b) { | |
| if (this.indexOf(b) < 0) { | |
| return this | |
| } | |
| var a = []; | |
| this.forEach(function(c) { | |
| if (c !== b) { | |
| a[a.length] = c | |
| } | |
| }); | |
| return a | |
| }, | |
| uniq: function() { | |
| var a = []; | |
| this.forEach(function(b) { | |
| if (a.indexOf(b) < 0) { | |
| a[a.length] = b | |
| } | |
| }); | |
| return a | |
| }, | |
| rangeObserverClass: SC.RangeObserver, | |
| addRangeObserver: function(d, f, h, e) { | |
| var a = this._array_rangeObservers; | |
| if (!a) { | |
| a = this._array_rangeObservers = SC.CoreSet.create() | |
| } | |
| if (this._array_oldLength === undefined) { | |
| this._array_oldLength = this.get("length") | |
| } | |
| var g = this.rangeObserverClass; | |
| var b = NO; | |
| var c = g.create(this, d, f, h, e, b); | |
| a.add(c); | |
| if (!this._array_isNotifyingRangeObservers) { | |
| this._array_isNotifyingRangeObservers = YES; | |
| this.addObserver("[]", this, this._array_notifyRangeObservers) | |
| } | |
| return c | |
| }, | |
| updateRangeObserver: function(b, a) { | |
| return b.update(this, a) | |
| }, | |
| removeRangeObserver: function(c) { | |
| var b = c.destroy(this); | |
| var a = this._array_rangeObservers; | |
| if (a) { | |
| a.remove(c) | |
| } | |
| return b | |
| }, | |
| enumerableContentDidChange: function(h, g, f) { | |
| var a = this._array_rangeObservers, | |
| d = this._array_oldLength, | |
| e, | |
| c, | |
| b; | |
| this.beginPropertyChanges(); | |
| this.notifyPropertyChange("length"); | |
| if (a && a.length > 0) { | |
| if (d === undefined) { | |
| d = 0 | |
| } | |
| this._array_oldLength = e = this.get("length"); | |
| if (h === undefined) { | |
| h = 0 | |
| } | |
| if (f === undefined) { | |
| f = e - d | |
| } | |
| if (f !== 0 || g === undefined) { | |
| c = e - h; | |
| if (f < 0) { | |
| c -= f | |
| } | |
| } else { | |
| c = g | |
| } | |
| b = this._array_rangeChanges; | |
| if (!b) { | |
| b = this._array_rangeChanges = SC.IndexSet.create() | |
| } | |
| b.add(h, c) | |
| } | |
| this.notifyPropertyChange("[]"); | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| _array_notifyRangeObservers: function() { | |
| var c = this._array_rangeObservers, | |
| d = this._array_rangeChanges, | |
| b = c ? c.length: 0, | |
| a, | |
| e; | |
| if (b > 0 && d && d.length > 0) { | |
| for (a = 0; a < b; a++) { | |
| c[a].rangeDidChange(d) | |
| } | |
| d.clear() | |
| } | |
| } | |
| }; | |
| SC.mixin(Array.prototype, SC.Array); | |
| SC.Array = SC.mixin({}, | |
| SC.Enumerable, SC.Array); | |
| SC.Array.slice = function(b, d) { | |
| var a = []; | |
| var c = this.get("length"); | |
| if (SC.none(b)) { | |
| b = 0 | |
| } | |
| if (SC.none(d) || (d > c)) { | |
| d = c | |
| } | |
| while (b < d) { | |
| a[a.length] = this.objectAt(b++) | |
| } | |
| return a | |
| }; | |
| SC.Array.indexOf = function(d, c) { | |
| var b, | |
| a = this.get("length"); | |
| if (c === undefined) { | |
| c = 0 | |
| } else { | |
| c = (c < 0) ? Math.ceil(c) : Math.floor(c) | |
| } | |
| if (c < 0) { | |
| c += a | |
| } | |
| for (b = c; b < a; b++) { | |
| if (this.objectAt(b) === d) { | |
| return b | |
| } | |
| } | |
| return - 1 | |
| }; | |
| if (!Array.prototype.indexOf) { | |
| Array.prototype.indexOf = SC.Array.indexOf | |
| } | |
| SC.Array.lastIndexOf = function(d, c) { | |
| var b, | |
| a = this.get("length"); | |
| if (c === undefined) { | |
| c = a - 1 | |
| } else { | |
| c = (c < 0) ? Math.ceil(c) : Math.floor(c) | |
| } | |
| if (c < 0) { | |
| c += a | |
| } | |
| for (b = c; b >= 0; b--) { | |
| if (this.objectAt(b) === d) { | |
| return b | |
| } | |
| } | |
| return - 1 | |
| }; | |
| if (!Array.prototype.lastIndexOf) { | |
| Array.prototype.lastIndexOf = SC.Array.lastIndexOf | |
| } (function() { | |
| SC.mixin(Array.prototype, { | |
| replace: function(d, g, f) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (!f || f.length === 0) { | |
| this.splice(d, g) | |
| } else { | |
| var e = [d, g].concat(f); | |
| this.splice.apply(this, e) | |
| } | |
| var c = f ? (f.get ? f.get("length") : f.length) : 0; | |
| this.enumerableContentDidChange(d, g, c - g); | |
| return this | |
| }, | |
| unknownProperty: function(d, e) { | |
| var c = this.reducedProperty(d, e); | |
| if ((e !== undefined) && c === undefined) { | |
| c = this[d] = e | |
| } | |
| return c | |
| } | |
| }); | |
| var b = Array.prototype.indexOf; | |
| if (!b || (b === SC.Array.indexOf)) { | |
| Array.prototype.indexOf = function(f, e) { | |
| var d, | |
| c = this.length; | |
| if (e === undefined) { | |
| e = 0 | |
| } else { | |
| e = (e < 0) ? Math.ceil(e) : Math.floor(e) | |
| } | |
| if (e < 0) { | |
| e += c | |
| } | |
| for (d = e; | |
| d < c; d++) { | |
| if (this[d] === f) { | |
| return d | |
| } | |
| } | |
| return - 1 | |
| } | |
| } | |
| var a = Array.prototype.lastIndexOf; | |
| if (!a || (a === SC.Array.lastIndexOf)) { | |
| Array.prototype.lastIndexOf = function(f, e) { | |
| var d, | |
| c = this.length; | |
| if (e === undefined) { | |
| e = c - 1 | |
| } else { | |
| e = (e < 0) ? Math.ceil(e) : Math.floor(e) | |
| } | |
| if (e < 0) { | |
| e += c | |
| } | |
| for (d = e; | |
| d >= 0; d--) { | |
| if (this[d] === f) { | |
| return d | |
| } | |
| } | |
| return - 1 | |
| } | |
| } | |
| })(); | |
| SC.Comparable = { | |
| isComparable: YES, | |
| compare: function(d, c) { | |
| throw "%@.compare() is not implemented".fmt(this.toString()) | |
| } | |
| }; | |
| SC.Copyable = { | |
| isCopyable: YES, | |
| copy: function() { | |
| throw "%@.copy() is not implemented" | |
| }, | |
| frozenCopy: function() { | |
| var a = this.get ? this.get("isFrozen") : this.isFrozen; | |
| if (a === YES) { | |
| return this | |
| } else { | |
| if (a === undefined) { | |
| throw "%@ does not support freezing".fmt(this) | |
| } else { | |
| return this.copy().freeze() | |
| } | |
| } | |
| } | |
| }; | |
| SC.mixin(Array.prototype, SC.Copyable); | |
| Array.prototype.copy = Array.prototype.slice; | |
| SC.DelegateSupport = { | |
| delegateFor: function(c) { | |
| var b = 1, | |
| a = arguments.length, | |
| d; | |
| while (b < a) { | |
| d = arguments[b]; | |
| if (d && d[c] !== undefined) { | |
| return d | |
| } | |
| b++ | |
| } | |
| return (this[c] !== undefined) ? this: null | |
| }, | |
| invokeDelegateMethod: function(c, a, b) { | |
| b = SC.A(arguments); | |
| b = b.slice(2, b.length); | |
| if (!c || !c[a]) { | |
| c = this | |
| } | |
| var d = c[a]; | |
| return d ? d.apply(c, b) : null | |
| }, | |
| getDelegateProperty: function(d, e) { | |
| var b = 1, | |
| a = arguments.length, | |
| c; | |
| while (b < a) { | |
| c = arguments[b++]; | |
| if (c && c[d] !== undefined) { | |
| return c.get ? c.get(d) : c[d] | |
| } | |
| } | |
| return (this[d] !== undefined) ? this.get(d) : undefined | |
| } | |
| }; | |
| SC.FROZEN_ERROR = new Error("Cannot modify a frozen object"); | |
| SC.Freezable = { | |
| isFreezable: YES, | |
| isFrozen: NO, | |
| freeze: function() { | |
| if (this.set) { | |
| this.set("isFrozen", YES) | |
| } else { | |
| this.isFrozen = YES | |
| } | |
| return this | |
| } | |
| }; | |
| SC.mixin(Array.prototype, SC.Freezable); | |
| sc_require("mixins/enumerable"); | |
| sc_require("mixins/observable"); | |
| sc_require("mixins/freezable"); | |
| sc_require("mixins/copyable"); | |
| SC.Set = SC.mixin({}, | |
| SC.Enumerable, SC.Observable, SC.Freezable, { | |
| create: function(b) { | |
| var c, | |
| a, | |
| d = SC.Set._pool, | |
| e = this.isObservable; | |
| if (!e && b === undefined && d.length > 0) { | |
| c = d.pop() | |
| } else { | |
| c = SC.beget(this); | |
| if (e) { | |
| c.initObservable() | |
| } | |
| if (b && b.isEnumerable && b.get("length") > 0) { | |
| c.isObservable = NO; | |
| if (b.isSCArray) { | |
| a = b.get ? b.get("length") : b.length; | |
| while (--a >= 0) { | |
| c.add(b.objectAt(a)) | |
| } | |
| } else { | |
| if (b.isSet) { | |
| a = b.length; | |
| while (--a >= 0) { | |
| c.add(b[a]) | |
| } | |
| } else { | |
| b.forEach(function(f) { | |
| c.add(f) | |
| }, | |
| this) | |
| } | |
| } | |
| c.isObservable = e | |
| } | |
| } | |
| return c | |
| }, | |
| isSet: YES, | |
| length: 0, | |
| firstObject: function() { | |
| return (this.length > 0) ? this[0] : undefined | |
| }.property(), | |
| clear: function() { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| this.length = 0; | |
| return this | |
| }, | |
| contains: function(b) { | |
| if (b === null) { | |
| return NO | |
| } | |
| var a = this[SC.hashFor(b)]; | |
| return (!SC.none(a) && (a < this.length) && (this[a] === b)) | |
| }, | |
| isEqual: function(a) { | |
| if (!a || !a.isSet || (a.get("length") !== this.get("length"))) { | |
| return NO | |
| } | |
| var b = this.get("length"); | |
| while (--b >= 0) { | |
| if (!a.contains(this[b])) { | |
| return NO | |
| } | |
| } | |
| return YES | |
| }, | |
| add: function(d) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (d === null || d === undefined) { | |
| return this | |
| } | |
| var c = SC.hashFor(d); | |
| var b = this[c]; | |
| var a = this.length; | |
| if ((b === null || b === undefined) || (b >= a) || (this[b] !== d)) { | |
| this[a] = d; | |
| this[c] = a; | |
| this.length = a + 1 | |
| } | |
| if (this.isObservable) { | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| addEach: function(c) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (!c || !c.isEnumerable) { | |
| throw "%@.addEach must pass enumerable".fmt(this) | |
| } | |
| var a, | |
| b = this.isObservable; | |
| if (b) { | |
| this.beginPropertyChanges() | |
| } | |
| if (c.isSCArray) { | |
| a = c.get("length"); | |
| while (--a >= 0) { | |
| this.add(c.objectAt(a)) | |
| } | |
| } else { | |
| if (c.isSet) { | |
| a = c.length; | |
| while (--a >= 0) { | |
| this.add(c[a]) | |
| } | |
| } else { | |
| c.forEach(function(d) { | |
| this.add(d) | |
| }, | |
| this) | |
| } | |
| } | |
| if (b) { | |
| this.endPropertyChanges() | |
| } | |
| return this | |
| }, | |
| remove: function(d) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (SC.none(d)) { | |
| return this | |
| } | |
| var c = SC.hashFor(d); | |
| var b = this[c]; | |
| var a = this.length; | |
| if (SC.none(b) || (b >= a) || (this[b] !== d)) { | |
| return this | |
| } | |
| delete this[c]; | |
| if (b < (a - 1)) { | |
| d = this[b] = this[a - 1]; | |
| this[SC.hashFor(d)] = b | |
| } | |
| this.length = a - 1; | |
| if (this.isObservable) { | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| pop: function() { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| var a = (this.length > 0) ? this[this.length - 1] : null; | |
| if (a) { | |
| this.remove(a) | |
| } | |
| return a | |
| }, | |
| removeEach: function(c) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (!c || !c.isEnumerable) { | |
| throw "%@.addEach must pass enumerable".fmt(this) | |
| } | |
| var a, | |
| b = this.isObservable; | |
| if (b) { | |
| this.beginPropertyChanges() | |
| } | |
| if (c.isSCArray) { | |
| a = c.get("length"); | |
| while (--a >= 0) { | |
| this.remove(c.objectAt(a)) | |
| } | |
| } else { | |
| if (c.isSet) { | |
| a = c.length; | |
| while (--a >= 0) { | |
| this.remove(c[a]) | |
| } | |
| } else { | |
| c.forEach(function(d) { | |
| this.remove(d) | |
| }, | |
| this) | |
| } | |
| } | |
| if (b) { | |
| this.endPropertyChanges() | |
| } | |
| return this | |
| }, | |
| copy: function() { | |
| return this.constructor.create(this) | |
| }, | |
| destroy: function() { | |
| this.isFrozen = NO; | |
| if (!this.isObservable) { | |
| SC.Set._pool.push(this.clear()) | |
| } | |
| return this | |
| }, | |
| forEach: function(c, d) { | |
| var b = this.length; | |
| if (!d) { | |
| d = this | |
| } | |
| for (var a = 0; a < b; | |
| a++) { | |
| c.call(d, this[a], a, this) | |
| } | |
| return this | |
| }, | |
| toString: function() { | |
| var b = this.length, | |
| a, | |
| c = []; | |
| for (a = 0; a < b; a++) { | |
| c[a] = this[a] | |
| } | |
| return "SC.Set<%@>".fmt(c.join(",")) | |
| }, | |
| _pool: [], | |
| isObservable: YES | |
| }); | |
| SC.Set.constructor = SC.Set; | |
| SC.Set.clone = SC.Set.copy; | |
| SC.Set.push = SC.Set.unshift = SC.Set.add; | |
| SC.Set.shift = SC.Set.pop; | |
| SC.Set.addObject = SC.Set.add; | |
| SC.Set.removeObject = SC.Set.remove; | |
| SC.Set._pool = []; | |
| SC.CoreSet = SC.beget(SC.Set); | |
| SC.CoreSet.isObservable = NO; | |
| SC.CoreSet.constructor = SC.CoreSet; | |
| sc_require("core"); | |
| sc_require("mixins/observable"); | |
| sc_require("mixins/array"); | |
| sc_require("system/set"); | |
| SC.BENCHMARK_OBJECTS = NO; | |
| SC._object_extend = function _object_extend(g, f) { | |
| if (!f) { | |
| throw "SC.Object.extend expects a non-null value. Did you forget to 'sc_require' something? Or were you passing a Protocol to extend() as if it were a mixin?" | |
| } | |
| g._kvo_cloned = null; | |
| var w, | |
| m, | |
| s, | |
| e, | |
| h = g.concatenatedProperties, | |
| k = SC.K; | |
| var c, | |
| b; | |
| m = (h) ? h.length: 0; | |
| var a = (m > 0) ? {}: null; | |
| while (--m >= 0) { | |
| w = h[m]; | |
| c = g[w]; | |
| b = f[w]; | |
| if (c) { | |
| if (! (c instanceof Array)) { | |
| c = SC.$A(c) | |
| } | |
| a[w] = (b) ? c.concat(b) : b | |
| } else { | |
| if (! (b instanceof Array)) { | |
| b = SC.$A(b) | |
| } | |
| a[w] = b | |
| } | |
| } | |
| var v = g._bindings, | |
| l = NO; | |
| var t = g._observers, | |
| u = NO; | |
| var i = g._properties, | |
| d = NO; | |
| var p, | |
| j, | |
| n; | |
| var r = g.outlets, | |
| q = NO; | |
| if (f.outlets) { | |
| r = (r || SC.EMPTY_ARRAY).concat(f.outlets); | |
| q = YES | |
| } | |
| for (w in f) { | |
| if (w === "_kvo_cloned") { | |
| continue | |
| } | |
| if (!f.hasOwnProperty(w)) { | |
| continue | |
| } | |
| var o = (a.hasOwnProperty(w) ? a[w] : null) || f[w]; | |
| if (w.slice( - 7) === "Binding") { | |
| if (!l) { | |
| v = (v || SC.EMPTY_ARRAY).slice(); | |
| l = YES | |
| } | |
| if (v === null) { | |
| v = (g._bindings || SC.EMPTY_ARRAY).slice() | |
| } | |
| v[v.length] = w | |
| } else { | |
| if (o && (o instanceof Function)) { | |
| if (!o.superclass && (o !== (e = g[w]))) { | |
| o.superclass = o.base = e || k | |
| } | |
| if (o.propertyPaths) { | |
| if (!u) { | |
| t = (t || SC.EMPTY_ARRAY).slice(); | |
| u = YES | |
| } | |
| t[t.length] = w | |
| } else { | |
| if (p = o.localPropertyPaths) { | |
| j = p.length; | |
| while (--j >= 0) { | |
| n = g._kvo_for(SC.keyFor("_kvo_local", p[j]), SC.Set); | |
| n.add(w); | |
| g._kvo_for("_kvo_observed_keys", SC.CoreSet).add(p[j]) | |
| } | |
| } else { | |
| if (o.dependentKeys) { | |
| if (!d) { | |
| i = (i || SC.EMPTY_ARRAY).slice(); | |
| d = YES | |
| } | |
| i[i.length] = w | |
| } else { | |
| if (o.autoconfiguredOutlet) { | |
| if (!q) { | |
| r = (r || SC.EMPTY_ARRAY).slice(); | |
| q = YES | |
| } | |
| r[r.length] = w | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| g[w] = o | |
| } | |
| if (f.hasOwnProperty("toString")) { | |
| w = "toString"; | |
| o = (a.hasOwnProperty(w) ? a[w] : null) || f[w]; | |
| if (!o.superclass && (o !== (e = g[w]))) { | |
| o.superclass = o.base = e || k | |
| } | |
| g[w] = o | |
| } | |
| g._bindings = v || []; | |
| g._observers = t || []; | |
| g._properties = i || []; | |
| g.outlets = r || []; | |
| return g | |
| }; | |
| SC.Object = function(a) { | |
| return this._object_init(a) | |
| }; | |
| SC.mixin(SC.Object, { | |
| mixin: function(b) { | |
| var a = arguments.length, | |
| c; | |
| for (c = 0; c < a; c++) { | |
| SC.mixin(this, arguments[c]) | |
| } | |
| return this | |
| }, | |
| superclass: null, | |
| extend: function(e) { | |
| var d = SC.BENCHMARK_OBJECTS; | |
| if (d) { | |
| SC.Benchmark.start("SC.Object.extend") | |
| } | |
| var g, | |
| c = function(h) { | |
| return this._object_init(h) | |
| }; | |
| for (g in this) { | |
| if (!this.hasOwnProperty(g)) { | |
| continue | |
| } | |
| c[g] = this[g] | |
| } | |
| if (this.hasOwnProperty("toString")) { | |
| c.toString = this.toString | |
| } | |
| c.superclass = this; | |
| SC.generateGuid(c); | |
| c.subclasses = SC.Set.create(); | |
| this.subclasses.add(c); | |
| var f = (c.prototype = SC.beget(this.prototype)); | |
| var b, | |
| a = arguments.length; | |
| for (b = 0; b < a; b++) { | |
| SC._object_extend(f, arguments[b]) | |
| } | |
| f.constructor = c; | |
| if (d) { | |
| SC.Benchmark.end("SC.Object.extend") | |
| } | |
| return c | |
| }, | |
| create: function(a) { | |
| var b = this; | |
| return new b(arguments) | |
| }, | |
| isClass: YES, | |
| subclasses: SC.Set.create(), | |
| toString: function() { | |
| return SC._object_className(this) | |
| }, | |
| subclassOf: function(b) { | |
| if (this === b) { | |
| return NO | |
| } | |
| var a = this; | |
| while (a = a.superclass) { | |
| if (a === b) { | |
| return YES | |
| } | |
| } | |
| return NO | |
| }, | |
| hasSubclass: function(a) { | |
| return (a && a.subclassOf) ? a.subclassOf(this) : NO | |
| }, | |
| kindOf: function(a) { | |
| return (this === a) || this.subclassOf(a) | |
| } | |
| }); | |
| SC.Object.prototype = { | |
| _kvo_enabled: YES, | |
| _object_init: function(c) { | |
| var b, | |
| a = (c) ? c.length: 0; | |
| for (b = 0; b < a; b++) { | |
| SC._object_extend(this, c[b]) | |
| } | |
| SC.generateGuid(this); | |
| this.init(); | |
| var d = this.initMixin; | |
| a = (d) ? d.length: 0; | |
| for (b = 0; b < a; b++) { | |
| d[b].call(this) | |
| } | |
| return this | |
| }, | |
| mixin: function() { | |
| var b, | |
| a = arguments.length; | |
| for (b = 0; b < a; b++) { | |
| SC.mixin(this, arguments[b]) | |
| } | |
| for (b = 0; b < a; b++) { | |
| var c = arguments[b].initMixin; | |
| if (c) { | |
| c.call(this) | |
| } | |
| } | |
| return this | |
| }, | |
| init: function() { | |
| this.initObservable(); | |
| return this | |
| }, | |
| isDestroyed: NO, | |
| destroy: function() { | |
| if (this.get("isDestroyed")) { | |
| return this | |
| } | |
| this.set("isDestroyed", YES); | |
| var b, | |
| c = this.destroyMixin, | |
| a = (c) ? c.length: 0; | |
| for (b = 0; b < a; b++) { | |
| c[b].call(this) | |
| } | |
| return this | |
| }, | |
| isObject: true, | |
| respondsTo: function(a) { | |
| return !! (SC.typeOf(this[a]) === SC.T_FUNCTION) | |
| }, | |
| tryToPerform: function(b, c, a) { | |
| return this.respondsTo(b) && (this[b](c, a) !== NO) | |
| }, | |
| superclass: function(b) { | |
| var a = arguments.callee.caller; | |
| if (!a) { | |
| throw "superclass cannot determine the caller method" | |
| } | |
| return a.superclass ? a.superclass.apply(this, arguments) : null | |
| }, | |
| instanceOf: function(a) { | |
| return this.constructor === a | |
| }, | |
| kindOf: function(a) { | |
| return this.constructor.kindOf(a) | |
| }, | |
| toString: function() { | |
| if (!this._object_toString) { | |
| var a = SC._object_className(this.constructor); | |
| var b = "%@:%@".fmt(a, SC.guidFor(this)); | |
| if (a) { | |
| this._object_toString = b | |
| } else { | |
| return b | |
| } | |
| } | |
| return this._object_toString | |
| }, | |
| awake: function(a) { | |
| this.outlets.forEach(function(b) { | |
| this.get(b) | |
| }, | |
| this); | |
| this.bindings.invoke("sync") | |
| }, | |
| invokeOnce: function(a) { | |
| SC.RunLoop.currentRunLoop.invokeOnce(this, a); | |
| return this | |
| }, | |
| invokeLast: function(a) { | |
| SC.RunLoop.currentRunLoop.invokeLast(this, a); | |
| return this | |
| }, | |
| concatenatedProperties: ["concatenatedProperties", "initMixin", "destroyMixin"] | |
| }; | |
| SC.Object.prototype.constructor = SC.Object; | |
| SC.mixin(SC.Object.prototype, SC.Observable); | |
| function findClassNames() { | |
| if (SC._object_foundObjectClassNames) { | |
| return | |
| } | |
| SC._object_foundObjectClassNames = true; | |
| var b = []; | |
| var a = function(c, d, g) { | |
| g--; | |
| if (b.indexOf(d) >= 0) { | |
| return | |
| } | |
| b.push(d); | |
| for (var e in d) { | |
| if (e == "__scope__") { | |
| continue | |
| } | |
| if (e == "superclass") { | |
| continue | |
| } | |
| if (!e.match(/^[A-Z0-9]/)) { | |
| continue | |
| } | |
| var h = (c) ? [c, e].join(".") : e; | |
| var f = d[e]; | |
| switch (SC.typeOf(f)) { | |
| case SC.T_CLASS: | |
| if (!f._object_className) { | |
| f._object_className = h | |
| } | |
| if (g >= 0) { | |
| a(h, f, g) | |
| } | |
| break; | |
| case SC.T_OBJECT: | |
| if (g >= 0) { | |
| a(h, f, g) | |
| } | |
| break; | |
| case SC.T_HASH: | |
| if (((c) || (h === "SC")) && (g >= 0)) { | |
| a(h, f, g) | |
| } | |
| break; | |
| default: | |
| break | |
| } | |
| } | |
| }; | |
| a(null, SC.root, 2) //eh... | |
| } | |
| SC.instanceOf = function(a, b) { | |
| return !! (a && a.constructor === b) | |
| }; | |
| SC.kindOf = function(a, b) { | |
| if (a && !a.isClass) { | |
| a = a.constructor | |
| } | |
| return !! (a && a.kindOf && a.kindOf(b)) | |
| }; | |
| SC._object_className = function(b) { | |
| if (!SC.isReady) { | |
| return "" | |
| } | |
| if (!b._object_className) { | |
| findClassNames() | |
| } | |
| if (b._object_className) { | |
| return b._object_className | |
| } | |
| var a = b; | |
| while (a && !a._object_className) { | |
| a = a.superclass | |
| } | |
| return (a && a._object_className) ? a._object_className: "Anonymous" | |
| }; | |
| sc_require("system/object"); | |
| SC._ChainObserver = function(a) { | |
| this.property = a | |
| }; | |
| SC._ChainObserver.createChain = function(d, j, f, a, b) { | |
| var c = j.split("."), | |
| h = new SC._ChainObserver(c[0]), | |
| g = h, | |
| e = c.length; | |
| for (var i = 1; i < e; i++) { | |
| g = g.next = new SC._ChainObserver(c[i]) | |
| } | |
| h.objectDidChange(d); | |
| g.target = f; | |
| g.method = a; | |
| g.context = b; | |
| return h | |
| }; | |
| SC._ChainObserver.prototype = { | |
| isChainObserver: true, | |
| object: null, | |
| property: null, | |
| next: null, | |
| target: null, | |
| method: null, | |
| objectDidChange: function(a) { | |
| if (a === this.object) { | |
| return | |
| } | |
| if (this.object && this.object.removeObserver) { | |
| this.object.removeObserver(this.property, this, this.propertyDidChange) | |
| } | |
| this.object = a; | |
| if (this.object && this.object.addObserver) { | |
| this.object.addObserver(this.property, this, this.propertyDidChange) | |
| } | |
| this.propertyDidChange() | |
| }, | |
| propertyDidChange: function() { | |
| var b = this.object; | |
| var e = this.property; | |
| var d = (b && b.get) ? b.get(e) : null; | |
| if (this.next) { | |
| this.next.objectDidChange(d) | |
| } | |
| var f = this.target, | |
| g = this.method, | |
| c = this.context; | |
| if (f && g) { | |
| var a = b ? b.propertyRevision: null; | |
| if (c) { | |
| g.call(f, b, e, d, c, a) | |
| } else { | |
| g.call(f, b, e, d, a) | |
| } | |
| } | |
| }, | |
| destroyChain: function() { | |
| var a = this.object; | |
| if (a && a.removeObserver) { | |
| a.removeObserver(this.property, this, this.propertyDidChange) | |
| } | |
| if (this.next) { | |
| this.next.destroyChain() | |
| } | |
| this.next = this.target = this.method = this.object = this.context = null; | |
| return null | |
| } | |
| }; | |
| sc_require("mixins/observable"); | |
| sc_require("system/set"); | |
| SC.Observers = { | |
| queue: [], | |
| addObserver: function(c, d, e, b) { | |
| var a; | |
| if (SC.typeOf(c) === SC.T_STRING) { | |
| a = SC.tupleForPropertyPath(c, b) | |
| } else { | |
| a = c | |
| } | |
| if (a) { | |
| a[0].addObserver(a[1], d, e) | |
| } else { | |
| this.queue.push([c, d, e, b]) | |
| } | |
| }, | |
| removeObserver: function(f, g, h, d) { | |
| var c, | |
| b, | |
| a, | |
| e; | |
| a = SC.tupleForPropertyPath(f, d); | |
| if (a) { | |
| a[0].removeObserver(a[1], g, h) | |
| } | |
| c = this.queue.length; | |
| b = this.queue; | |
| while (--c >= 0) { | |
| e = b[c]; | |
| if ((e[0] === f) && (e[1] === g) && (e[2] == h) && (e[3] === d)) { | |
| b[c] = null | |
| } | |
| } | |
| }, | |
| addPendingRangeObserver: function(a) { | |
| var b = this.rangeObservers; | |
| if (!b) { | |
| b = this.rangeObservers = SC.CoreSet.create() | |
| } | |
| b.add(a); | |
| return this | |
| }, | |
| _TMP_OUT: [], | |
| flush: function(a) { | |
| var e = this.queue; | |
| if (e && e.length > 0) { | |
| var h = (this.queue = []); | |
| var i = e.length; | |
| while (--i >= 0) { | |
| var j = e[i]; | |
| if (!j) { | |
| continue | |
| } | |
| var f = SC.tupleForPropertyPath(j[0], j[3]); | |
| if (f) { | |
| f[0].addObserver(f[1], j[1], j[2]) | |
| } else { | |
| h.push(j) | |
| } | |
| } | |
| } | |
| if (a._kvo_needsRangeObserver) { | |
| var g = this.rangeObservers, | |
| d = g ? g.get("length") : 0, | |
| b = this._TMP_OUT, | |
| c; | |
| for (i = 0; i < d; i++) { | |
| c = g[i]; | |
| if (c.setupPending(a)) { | |
| b.push(c) | |
| } | |
| } | |
| if (b.length > 0) { | |
| g.removeEach(b) | |
| } | |
| b.length = 0; | |
| a._kvo_needsRangeObserver = NO | |
| } | |
| }, | |
| isObservingSuspended: 0, | |
| _pending: SC.CoreSet.create(), | |
| objectHasPendingChanges: function(a) { | |
| this._pending.add(a) | |
| }, | |
| suspendPropertyObserving: function() { | |
| this.isObservingSuspended++ | |
| }, | |
| resumePropertyObserving: function() { | |
| var c; | |
| if (--this.isObservingSuspended <= 0) { | |
| c = this._pending; | |
| this._pending = SC.CoreSet.create(); | |
| var b, | |
| a = c.length; | |
| for (b = 0; b < a; b++) { | |
| c[b]._notifyPropertyObservers() | |
| } | |
| c.clear(); | |
| c = null | |
| } | |
| } | |
| }; | |
| sc_require("system/object"); | |
| SC.LOG_BINDINGS = NO; | |
| SC.BENCHMARK_BINDING_NOTIFICATIONS = NO; | |
| SC.BENCHMARK_BINDING_SETUP = NO; | |
| SC.MULTIPLE_PLACEHOLDER = "@@MULT@@"; | |
| SC.NULL_PLACEHOLDER = "@@NULL@@"; | |
| SC.EMPTY_PLACEHOLDER = "@@EMPTY@@"; | |
| SC.Binding = { | |
| beget: function(b) { | |
| var a = SC.beget(this); | |
| a.parentBinding = this; | |
| if (b !== undefined) { | |
| a = a.from(b) | |
| } | |
| return a | |
| }, | |
| builder: function() { | |
| var b = this; | |
| var a = function(c) { | |
| return b.beget().from(c) | |
| }; | |
| a.beget = function() { | |
| return b.beget() | |
| }; | |
| return a | |
| }, | |
| from: function(b, a) { | |
| if (!b) { | |
| return this | |
| } | |
| var c = (this === SC.Binding) ? this.beget() : this; | |
| c._fromPropertyPath = b; | |
| c._fromRoot = a; | |
| c._fromTuple = null; | |
| return c | |
| }, | |
| to: function(b, a) { | |
| var c = (this === SC.Binding) ? this.beget() : this; | |
| c._toPropertyPath = b; | |
| c._toRoot = a; | |
| c._toTuple = null; | |
| return c | |
| }, | |
| connect: function() { | |
| if (this.isConnected) { | |
| return this | |
| } | |
| this.isConnected = YES; | |
| this._connectionPending = YES; | |
| this._syncOnConnect = YES; | |
| SC.Binding._connectQueue.add(this); | |
| return this | |
| }, | |
| _connect: function() { | |
| if (!this._connectionPending) { | |
| return | |
| } | |
| this._connectionPending = NO; | |
| var c, | |
| a; | |
| var b = SC.BENCHMARK_BINDING_SETUP; | |
| if (b) { | |
| SC.Benchmark.start("SC.Binding.connect()") | |
| } | |
| c = this._fromPropertyPath; | |
| a = this._fromRoot; | |
| if (SC.typeOf(c) === SC.T_STRING) { | |
| if (c.indexOf(".") === 0) { | |
| c = c.slice(1); | |
| if (!a) { | |
| a = this._toRoot | |
| } | |
| } else { | |
| if (c.indexOf("*") === 0) { | |
| c = [this._fromRoot || this._toRoot, c.slice(1)]; | |
| a = null | |
| } | |
| } | |
| } | |
| SC.Observers.addObserver(c, this, this.fromPropertyDidChange, a); | |
| if (!this._oneWay) { | |
| c = this._toPropertyPath; | |
| a = this._toRoot; | |
| SC.Observers.addObserver(c, this, this.toPropertyDidChange, a) | |
| } | |
| if (b) { | |
| SC.Benchmark.end("SC.Binding.connect()") | |
| } | |
| if (this._syncOnConnect) { | |
| this._syncOnConnect = NO; | |
| if (b) { | |
| SC.Benchmark.start("SC.Binding.connect().sync") | |
| } | |
| this.sync(); | |
| if (b) { | |
| SC.Benchmark.end("SC.Binding.connect().sync") | |
| } | |
| } | |
| }, | |
| disconnect: function() { | |
| if (!this.isConnected) { | |
| return this | |
| } | |
| if (this._connectionPending) { | |
| this._connectionPending = NO | |
| } else { | |
| SC.Observers.removeObserver(this._fromPropertyPath, this, this.fromPropertyDidChange, this._fromRoot); | |
| if (!this._oneWay) { | |
| SC.Observers.removeObserver(this._toPropertyPath, this, this.toPropertyDidChange, this._toRoot) | |
| } | |
| } | |
| this.isConnected = NO; | |
| return this | |
| }, | |
| fromPropertyDidChange: function(c, b) { | |
| var a = c ? c.get(b) : null; | |
| if (a !== this._bindingValue) { | |
| this._setBindingValue(c, b); | |
| this._changePending = YES; | |
| SC.Binding._changeQueue.add(this) | |
| } | |
| }, | |
| toPropertyDidChange: function(c, b) { | |
| if (this._oneWay) { | |
| return | |
| } | |
| var a = c.get(b); | |
| if (a !== this._transformedBindingValue) { | |
| this._setBindingValue(c, b); | |
| this._changePending = YES; | |
| SC.Binding._changeQueue.add(this) | |
| } | |
| }, | |
| _setBindingValue: function(b, a) { | |
| this._bindingSource = b; | |
| this._bindingKey = a | |
| }, | |
| _computeBindingValue: function() { | |
| var g = this._bindingSource, | |
| e = this._bindingKey, | |
| c; | |
| if (!g) { | |
| return | |
| } | |
| this._bindingValue = c = g.getPath(e); | |
| var f = this._transforms; | |
| if (f) { | |
| var b = f.length; | |
| for (var a = 0; a < b; a++) { | |
| var d = f[a]; | |
| c = d(c, this) | |
| } | |
| } | |
| if (this._noError && SC.typeOf(c) === SC.T_ERROR) { | |
| c = null | |
| } | |
| this._transformedBindingValue = c | |
| }, | |
| _connectQueue: SC.CoreSet.create(), | |
| _alternateConnectQueue: SC.CoreSet.create(), | |
| _changeQueue: SC.CoreSet.create(), | |
| _alternateChangeQueue: SC.CoreSet.create(), | |
| _changePending: NO, | |
| flushPendingChanges: function() { | |
| if (this._isFlushing) { | |
| return NO | |
| } | |
| this._isFlushing = YES; | |
| SC.Observers.suspendPropertyObserving(); | |
| var b = NO; | |
| var c = SC.LOG_BINDINGS; | |
| var a, | |
| d; | |
| while ((a = this._connectQueue).length > 0) { | |
| this._connectQueue = this._alternateConnectQueue; | |
| this._alternateConnectQueue = a; | |
| while (d = a.pop()) { | |
| d._connect() | |
| } | |
| } | |
| while ((a = this._changeQueue).length > 0) { | |
| if (c) { | |
| console.log("Begin: Trigger changed bindings") | |
| } | |
| b = YES; | |
| this._changeQueue = this._alternateChangeQueue; | |
| this._alternateChangeQueue = a; | |
| while (d = a.pop()) { | |
| d.applyBindingValue() | |
| } | |
| if (c) { | |
| console.log("End: Trigger changed bindings") | |
| } | |
| } | |
| this._isFlushing = NO; | |
| SC.Observers.resumePropertyObserving(); | |
| return b | |
| }, | |
| applyBindingValue: function() { | |
| this._changePending = NO; | |
| this._computeBindingTargets(); | |
| this._computeBindingValue(); | |
| var a = this._bindingValue; | |
| var b = this._transformedBindingValue; | |
| var c = SC.BENCHMARK_BINDING_NOTIFICATIONS; | |
| var d = SC.LOG_BINDINGS; | |
| if (!this._oneWay && this._fromTarget) { | |
| if (d) { | |
| console.log("%@: %@ -> %@".fmt(this, a, b)) | |
| } | |
| if (c) { | |
| SC.Benchmark.start(this.toString() + "->") | |
| } | |
| this._fromTarget.setPathIfChanged(this._fromPropertyKey, a); | |
| if (c) { | |
| SC.Benchmark.end(this.toString() + "->") | |
| } | |
| } | |
| if (this._toTarget) { | |
| if (d) { | |
| console.log("%@: %@ <- %@".fmt(this, a, b)) | |
| } | |
| if (c) { | |
| SC.Benchmark.start(this.toString() + "<-") | |
| } | |
| this._toTarget.setPathIfChanged(this._toPropertyKey, b); | |
| if (c) { | |
| SC.Benchmark.start(this.toString() + "<-") | |
| } | |
| } | |
| }, | |
| sync: function() { | |
| if (!this.isConnected) { | |
| return this | |
| } | |
| if (this._connectionPending) { | |
| this._syncOnConnect = YES | |
| } else { | |
| this._computeBindingTargets(); | |
| var c = this._fromTarget; | |
| var b = this._fromPropertyKey; | |
| if (!c || !b) { | |
| return this | |
| } | |
| var a = c.getPath(b); | |
| if (a !== this._bindingValue) { | |
| this._setBindingValue(c, b); | |
| this._changePending = YES; | |
| SC.Binding._changeQueue.add(this) | |
| } | |
| } | |
| return this | |
| }, | |
| _syncOnConnect: NO, | |
| _computeBindingTargets: function() { | |
| if (!this._fromTarget) { | |
| var c, | |
| b, | |
| a; | |
| c = this._fromPropertyPath; | |
| b = this._fromRoot; | |
| if (SC.typeOf(c) === SC.T_STRING) { | |
| if (c.indexOf(".") === 0) { | |
| c = c.slice(1); | |
| if (!b) { | |
| b = this._toRoot | |
| } | |
| } else { | |
| if (c.indexOf("*") === 0) { | |
| c = [b || this._toRoot, c.slice(1)]; | |
| b = null | |
| } | |
| } | |
| } | |
| a = SC.tupleForPropertyPath(c, b); | |
| if (a) { | |
| this._fromTarget = a[0]; | |
| this._fromPropertyKey = a[1] | |
| } | |
| } | |
| if (!this._toTarget) { | |
| c = this._toPropertyPath; | |
| b = this._toRoot; | |
| a = SC.tupleForPropertyPath(c, b); | |
| if (a) { | |
| this._toTarget = a[0]; | |
| this._toPropertyKey = a[1] | |
| } | |
| } | |
| }, | |
| oneWay: function(c, a) { | |
| if ((a === undefined) && (SC.typeOf(c) === SC.T_BOOL)) { | |
| a = c; | |
| c = null | |
| } | |
| var b = this.from(c); | |
| if (b === SC.Binding) { | |
| b = b.beget() | |
| } | |
| b._oneWay = (a === undefined) ? YES: a; | |
| return b | |
| }, | |
| transform: function(b) { | |
| var c = (this === SC.Binding) ? this.beget() : this; | |
| var a = c._transforms; | |
| if (a && (a === c.parentBinding._transform)) { | |
| a = c._transforms = a.slice() | |
| } | |
| if (!a) { | |
| a = c._transforms = [] | |
| } | |
| a.push(b); | |
| return c | |
| }, | |
| resetTransforms: function() { | |
| var a = (this === SC.Binding) ? this.beget() : this; | |
| a._transforms = null; | |
| return a | |
| }, | |
| noError: function(c, a) { | |
| if ((a === undefined) && (SC.typeOf(c) === SC.T_BOOL)) { | |
| a = c; | |
| c = null | |
| } | |
| var b = this.from(c); | |
| if (b === SC.Binding) { | |
| b = b.beget() | |
| } | |
| b._noError = (a === undefined) ? YES: a; | |
| return b | |
| }, | |
| single: function(b, a) { | |
| if (a === undefined) { | |
| a = SC.MULTIPLE_PLACEHOLDER | |
| } | |
| return this.from(b).transform(function(e, d) { | |
| if (e && e.isEnumerable) { | |
| var c = e.get("length"); | |
| e = (c > 1) ? a: (c <= 0) ? null: e.firstObject() | |
| } | |
| return e | |
| }) | |
| }, | |
| notEmpty: function(b, a) { | |
| if (a === undefined) { | |
| a = SC.EMPTY_PLACEHOLDER | |
| } | |
| return this.from(b).transform(function(d, c) { | |
| if (SC.none(d) || (d === "") || (SC.isArray(d) && d.length === 0)) { | |
| d = a | |
| } | |
| return d | |
| }) | |
| }, | |
| notNull: function(b, a) { | |
| if (a === undefined) { | |
| a = SC.EMPTY_PLACEHOLDER | |
| } | |
| return this.from(b).transform(function(d, c) { | |
| if (SC.none(d)) { | |
| d = a | |
| } | |
| return d | |
| }) | |
| }, | |
| multiple: function(a) { | |
| return this.from(a).transform(function(b) { | |
| if (!SC.isArray(b)) { | |
| b = (b == null) ? [] : [b] | |
| } | |
| return b | |
| }) | |
| }, | |
| bool: function(a) { | |
| return this.from(a).transform(function(b) { | |
| var c = SC.typeOf(b); | |
| if (c === SC.T_ERROR) { | |
| return b | |
| } | |
| return (c == SC.T_ARRAY) ? (b.length > 0) : (b === "") ? NO: !!b | |
| }) | |
| }, | |
| not: function(a) { | |
| return this.from(a).transform(function(b) { | |
| var c = SC.typeOf(b); | |
| if (c === SC.T_ERROR) { | |
| return b | |
| } | |
| return ! ((c == SC.T_ARRAY) ? (b.length > 0) : (b === "") ? NO: !!b) | |
| }) | |
| }, | |
| isNull: function(a) { | |
| return this.from(a).transform(function(b) { | |
| var c = SC.typeOf(b); | |
| return (c === SC.T_ERROR) ? b: SC.none(b) | |
| }) | |
| }, | |
| toString: function() { | |
| var c = this._fromRoot ? "<%@>:%@".fmt(this._fromRoot, this._fromPropertyPath) : this._fromPropertyPath; | |
| var b = this._toRoot ? "<%@>:%@".fmt(this._toRoot, this._toPropertyPath) : this._toPropertyPath; | |
| var a = this._oneWay ? "[oneWay]": ""; | |
| return "SC.Binding%@(%@ -> %@)%@".fmt(SC.guidFor(this), c, b, a) | |
| } | |
| }; | |
| SC.binding = function(b, a) { | |
| return SC.Binding.from(b, a) | |
| }; | |
| SC.Cookie = SC.Object.extend({ | |
| name: null, | |
| value: "", | |
| expires: null, | |
| path: null, | |
| domain: null, | |
| secure: NO, | |
| isCookie: YES, | |
| destroy: function() { | |
| this.set("expires", -1); | |
| this.write(); | |
| arguments.callee.base.apply(this, arguments) | |
| }, | |
| write: function() { | |
| var b = this.get("name"), | |
| i = this.get("value"), | |
| c = this.get("expires"), | |
| k = this.get("path"), | |
| e = this.get("domain"), | |
| a = this.get("secure"); | |
| var h = ""; | |
| if (c && (SC.typeOf(c) === SC.T_NUMBER || (SC.DateTime && c.get && c.get("milliseconds")) || SC.typeOf(c.toUTCString) === SC.T_FUNCTION)) { | |
| var d; | |
| if (SC.typeOf(c) === SC.T_NUMBER) { | |
| d = new Date(); | |
| d.setTime(d.getTime() + (c * 24 * 60 * 60 * 1000)) | |
| } else { | |
| if (SC.DateTime && c.get && c.get("milliseconds")) { | |
| d = new Date(c.get("milliseconds")) | |
| } else { | |
| if (SC.typeOf(c.toUTCString) === SC.T_FUNCTION) { | |
| d = c | |
| } | |
| } | |
| } | |
| if (d) { | |
| h = "; expires=" + d.toUTCString() | |
| } | |
| } | |
| var j = k ? "; path=" + k: ""; | |
| var g = e ? "; domain=" + e: ""; | |
| var f = a ? "; secure": ""; | |
| document.cookie = [b, "=", encodeURIComponent(i), h, j, g, f].join(""); | |
| return this | |
| } | |
| }); | |
| SC.Cookie.mixin({ | |
| find: function(a) { | |
| if (document.cookie && document.cookie != "") { | |
| var d = document.cookie.split(";"); | |
| for (var c = 0; c < d.length; c++) { | |
| var b = String(d[c]).trim(); | |
| if (b.substring(0, a.length + 1) === (a + "=")) { | |
| return SC.Cookie.create({ | |
| name: a, | |
| value: decodeURIComponent(b.substring(a.length + 1)) | |
| }) | |
| } | |
| } | |
| } | |
| return null | |
| } | |
| }); | |
| SC.Error = SC.Object.extend({ | |
| code: -1, | |
| message: "", | |
| errorValue: null, | |
| errorObject: function() { | |
| return this | |
| }.property().cacheable(), | |
| label: null, | |
| toString: function() { | |
| return "SC.Error:%@:%@ (%@)".fmt(SC.guidFor(this), this.get("message"), this.get("code")) | |
| }, | |
| isError: YES | |
| }); | |
| SC.Error.desc = function(d, a, e, c) { | |
| var b = { | |
| message: d | |
| }; | |
| if (a !== undefined) { | |
| b.label = a | |
| } | |
| if (c !== undefined) { | |
| b.code = c | |
| } | |
| if (e !== undefined) { | |
| b.errorValue = e | |
| } | |
| return this.create(b) | |
| }; | |
| SC.$error = function(b, a, d, e) { | |
| return SC.Error.desc(b, a, d, e) | |
| }; | |
| SC.ok = function(a) { | |
| return (a !== false) && !(a && a.isError) | |
| }; | |
| SC.$ok = SC.ok; | |
| SC.val = function(a) { | |
| if (a && a.isError) { | |
| return a.get ? a.get("errorValue") : null | |
| } else { | |
| return a | |
| } | |
| }; | |
| SC.$val = SC.val; | |
| SC.Error.HAS_MULTIPLE_VALUES = -100; | |
| sc_require("mixins/enumerable"); | |
| sc_require("mixins/observable"); | |
| sc_require("mixins/freezable"); | |
| sc_require("mixins/copyable"); | |
| SC.IndexSet = SC.mixin({}, | |
| SC.Enumerable, SC.Observable, SC.Freezable, SC.Copyable, { | |
| _sc_sliceContent: function(e) { | |
| if (e.length < 1000) { | |
| return e.slice() | |
| } | |
| var d = 0, | |
| a = [], | |
| b = e[0]; | |
| while (b !== 0) { | |
| a[d] = b; | |
| d = (b < 0) ? (0 - b) : b; | |
| b = e[d] | |
| } | |
| a[d] = 0; | |
| this._hint(0, d, a); | |
| return a | |
| }, | |
| create: function(c, b) { | |
| var a = SC.beget(this); | |
| a.initObservable(); | |
| if (c && c.isIndexSet) { | |
| a._content = this._sc_sliceContent(c._content); | |
| a.max = c.max; | |
| a.length = c.length; | |
| a.source = c.source | |
| } else { | |
| a._content = [0]; | |
| if (c !== undefined) { | |
| a.add(c, b) | |
| } | |
| } | |
| return a | |
| }, | |
| isIndexSet: YES, | |
| HINT_SIZE: 256, | |
| length: 0, | |
| max: 0, | |
| min: function() { | |
| var a = this._content, | |
| b = a[0]; | |
| return (b === 0) ? -1: (b > 0) ? 0: Math.abs(b) | |
| }.property("[]").cacheable(), | |
| firstObject: function() { | |
| return (this.get("length") > 0) ? this.get("min") : undefined | |
| }.property(), | |
| rangeStartForIndex: function(c) { | |
| var f = this._content, | |
| a = this.get("max"), | |
| b, | |
| e, | |
| d; | |
| if (c >= a) { | |
| return a | |
| } | |
| if (Math.abs(f[c]) > c) { | |
| return c | |
| } | |
| d = c - (c % SC.IndexSet.HINT_SIZE); | |
| b = f[d]; | |
| if (b < 0 || b > c) { | |
| b = d | |
| } | |
| e = Math.abs(f[b]); | |
| while (e < c) { | |
| b = e; | |
| e = Math.abs(f[b]) | |
| } | |
| return b | |
| }, | |
| isEqual: function(c) { | |
| if (c === this) { | |
| return YES | |
| } | |
| if (!c || !c.isIndexSet || (c.max !== this.max) || (c.length !== this.length)) { | |
| return NO | |
| } | |
| var e = this._content, | |
| b = c._content, | |
| d = 0, | |
| a = e[d]; | |
| do { | |
| if (b[d] !== a) { | |
| return NO | |
| } | |
| d = Math.abs(a); | |
| a = e[d] | |
| } | |
| while (d !== 0); | |
| return YES | |
| }, | |
| indexBefore: function(b) { | |
| if (b === 0) { | |
| return - 1 | |
| } | |
| b--; | |
| var c = this._content, | |
| a = this.get("max"), | |
| d = this.rangeStartForIndex(b); | |
| if (!c) { | |
| return null | |
| } | |
| while ((d === a) || (c[d] < 0)) { | |
| if (d === 0) { | |
| return - 1 | |
| } | |
| b = d - 1; | |
| d = this.rangeStartForIndex(b) | |
| } | |
| return b | |
| }, | |
| indexAfter: function(b) { | |
| var d = this._content, | |
| a = this.get("max"), | |
| e, | |
| c; | |
| if (!d || (b >= a)) { | |
| return - 1 | |
| } | |
| b++; | |
| e = this.rangeStartForIndex(b); | |
| c = d[e]; | |
| while (c < 0) { | |
| if (c === 0) { | |
| return - 1 | |
| } | |
| b = e = Math.abs(c); | |
| c = d[e] | |
| } | |
| return b | |
| }, | |
| contains: function(g, c) { | |
| var b, | |
| f, | |
| a, | |
| e, | |
| d; | |
| if (c === undefined) { | |
| if (g === null || g === undefined) { | |
| return NO | |
| } | |
| if (typeof g === SC.T_NUMBER) { | |
| c = 1 | |
| } else { | |
| if (g && g.isIndexSet) { | |
| if (g === this) { | |
| return YES | |
| } | |
| b = g._content; | |
| f = 0; | |
| a = b[f]; | |
| while (a !== 0) { | |
| if ((a > 0) && !this.contains(f, a - f)) { | |
| return NO | |
| } | |
| f = Math.abs(a); | |
| a = b[f] | |
| } | |
| return YES | |
| } else { | |
| c = g.length; | |
| g = g.start | |
| } | |
| } | |
| } | |
| e = this.rangeStartForIndex(g); | |
| d = this._content[e]; | |
| return (d > 0) && (e <= g) && (d >= (g + c)) | |
| }, | |
| intersects: function(f, c) { | |
| var b, | |
| e, | |
| a, | |
| d; | |
| if (c === undefined) { | |
| if (typeof f === SC.T_NUMBER) { | |
| c = 1 | |
| } else { | |
| if (f && f.isIndexSet) { | |
| if (f === this) { | |
| return YES | |
| } | |
| b = f._content; | |
| e = 0; | |
| a = b[e]; | |
| while (a !== 0) { | |
| if ((a > 0) && this.intersects(e, a - e)) { | |
| return YES | |
| } | |
| e = Math.abs(a); | |
| a = b[e] | |
| } | |
| return NO | |
| } else { | |
| c = f.length; | |
| f = f.start | |
| } | |
| } | |
| } | |
| e = this.rangeStartForIndex(f); | |
| b = this._content; | |
| a = b[e]; | |
| d = f + c; | |
| while (e < d) { | |
| if (a === 0) { | |
| return NO | |
| } | |
| if ((a > 0) && (a > f)) { | |
| return YES | |
| } | |
| e = Math.abs(a); | |
| a = b[e] | |
| } | |
| return NO | |
| }, | |
| without: function(b, a) { | |
| if (b === this) { | |
| return SC.IndexSet.create() | |
| } | |
| return this.clone().remove(b, a) | |
| }, | |
| replace: function(c, a) { | |
| if (a === undefined) { | |
| if (typeof c === SC.T_NUMBER) { | |
| a = 1 | |
| } else { | |
| if (c && c.isIndexSet) { | |
| this._content = this._sc_sliceContent(c._content); | |
| this.beginPropertyChanges().set("max", c.max).set("length", c.length).set("source", c.source).enumerableContentDidChange().endPropertyChanges(); | |
| return this | |
| } else { | |
| a = c.length; | |
| c = c.start | |
| } | |
| } | |
| } | |
| var b = this.length; | |
| this._content.length = 1; | |
| this._content[0] = 0; | |
| this.length = this.max = 0; | |
| return this.add(c, a) | |
| }, | |
| add: function(a, b) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| var e, | |
| i, | |
| d; | |
| if (a && a.isIndexSet) { | |
| e = a._content; | |
| if (!e) { | |
| return this | |
| } | |
| i = 0; | |
| d = e[0]; | |
| while (d !== 0) { | |
| if (d > 0) { | |
| this.add(i, d - i) | |
| } | |
| i = d < 0 ? 0 - d: d; | |
| d = e[i] | |
| } | |
| return this | |
| } else { | |
| if (b === undefined) { | |
| if (a === null || a === undefined) { | |
| return this | |
| } else { | |
| if (typeof a === SC.T_NUMBER) { | |
| b = 1 | |
| } else { | |
| b = a.length; | |
| a = a.start | |
| } | |
| } | |
| } else { | |
| if (b === null) { | |
| b = 1 | |
| } | |
| } | |
| } | |
| if (b <= 0) { | |
| return this | |
| } | |
| var f = this.get("max"), | |
| c = f, | |
| h, | |
| g; | |
| e = this._content; | |
| if (a === f) { | |
| if (a > 0) { | |
| i = this.rangeStartForIndex(a - 1); | |
| d = e[i]; | |
| if (d > 0) { | |
| delete e[f]; | |
| e[i] = f = a + b; | |
| a = i | |
| } else { | |
| e[f] = f = a + b | |
| } | |
| } else { | |
| e[a] = f = b | |
| } | |
| e[f] = 0; | |
| this.set("max", f); | |
| this.set("length", this.length + b); | |
| b = f - a | |
| } else { | |
| if (a > f) { | |
| e[f] = 0 - a; | |
| e[a] = a + b; | |
| e[a + b] = 0; | |
| this.set("max", a + b); | |
| this.set("length", this.length + b); | |
| b = a + b - f; | |
| a = f | |
| } else { | |
| i = this.rangeStartForIndex(a); | |
| d = e[i]; | |
| f = a + b; | |
| h = 0; | |
| if ((a > 0) && (i === a) && (d <= 0)) { | |
| i = this.rangeStartForIndex(a - 1); | |
| d = e[i] | |
| } | |
| if (d < 0) { | |
| e[i] = 0 - a; | |
| if (Math.abs(d) > f) { | |
| e[a] = 0 - f; | |
| e[f] = d | |
| } else { | |
| e[a] = d | |
| } | |
| } else { | |
| a = i; | |
| if (d > f) { | |
| f = d | |
| } | |
| } | |
| i = a; | |
| while (i < f) { | |
| g = e[i]; | |
| if (g === 0) { | |
| e[f] = 0; | |
| d = f; | |
| h += f - i | |
| } else { | |
| d = Math.abs(g); | |
| if (d > f) { | |
| e[f] = g; | |
| d = f | |
| } | |
| if (g < 0) { | |
| h += d - i | |
| } | |
| } | |
| delete e[i]; | |
| i = d | |
| } | |
| if ((i = e[f]) > 0) { | |
| delete e[f]; | |
| f = i | |
| } | |
| e[a] = f; | |
| if (f > c) { | |
| this.set("max", f) | |
| } | |
| this.set("length", this.get("length") + h); | |
| b = f - a | |
| } | |
| } | |
| this._hint(a, b); | |
| if (h !== 0) { | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| remove: function(a, b) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (b === undefined) { | |
| if (a === null || a === undefined) { | |
| return this | |
| } else { | |
| if (typeof a === SC.T_NUMBER) { | |
| b = 1 | |
| } else { | |
| if (a.isIndexSet) { | |
| a.forEachRange(this.remove, this); | |
| return this | |
| } else { | |
| b = a.length; | |
| a = a.start | |
| } | |
| } | |
| } | |
| } | |
| if (b <= 0) { | |
| return this | |
| } | |
| var f = this.get("max"), | |
| c = f, | |
| e = this._content, | |
| j, | |
| d, | |
| i, | |
| g, | |
| h; | |
| if (a >= f) { | |
| return this | |
| } | |
| j = this.rangeStartForIndex(a); | |
| d = e[j]; | |
| h = a + b; | |
| i = 0; | |
| if ((a > 0) && (j === a) && (d > 0)) { | |
| j = this.rangeStartForIndex(a - 1); | |
| d = e[j] | |
| } | |
| if (d > 0) { | |
| e[j] = a; | |
| if (d > h) { | |
| e[a] = h; | |
| e[h] = d | |
| } else { | |
| e[a] = d | |
| } | |
| } else { | |
| a = j; | |
| d = Math.abs(d); | |
| if (d > h) { | |
| h = d | |
| } | |
| } | |
| j = a; | |
| while (j < h) { | |
| g = e[j]; | |
| if (g === 0) { | |
| e[h] = 0; | |
| d = h | |
| } else { | |
| d = Math.abs(g); | |
| if (d > h) { | |
| e[h] = g; | |
| d = h | |
| } | |
| if (g > 0) { | |
| i += d - j | |
| } | |
| } | |
| delete e[j]; | |
| j = d | |
| } | |
| if ((j = e[h]) < 0) { | |
| delete e[h]; | |
| h = Math.abs(j) | |
| } | |
| if (e[h] === 0) { | |
| delete e[h]; | |
| e[a] = 0; | |
| this.set("max", a) | |
| } else { | |
| e[a] = 0 - h | |
| } | |
| this.set("length", this.get("length") - i); | |
| b = h - a; | |
| this._hint(a, b); | |
| if (i !== 0) { | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| _hint: function(g, d, c) { | |
| if (c === undefined) { | |
| c = this._content | |
| } | |
| var b = SC.IndexSet.HINT_SIZE, | |
| a = Math.abs(c[g]), | |
| f = g - (g % b) + b, | |
| e = g + d; | |
| while (f < e) { | |
| while ((a !== 0) && (a <= f)) { | |
| g = a; | |
| a = Math.abs(c[g]) | |
| } | |
| if (a === 0) { | |
| delete c[f] | |
| } else { | |
| if (f !== g) { | |
| c[f] = g | |
| } | |
| } | |
| f += b | |
| } | |
| }, | |
| clear: function() { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| var a = this.length; | |
| this._content.length = 1; | |
| this._content[0] = 0; | |
| this.set("length", 0).set("max", 0); | |
| if (a > 0) { | |
| this.enumerableContentDidChange() | |
| } | |
| }, | |
| addEach: function(b) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| this.beginPropertyChanges(); | |
| var a = b.get("length"); | |
| if (b.isSCArray) { | |
| while (--a >= 0) { | |
| this.add(b.objectAt(a)) | |
| } | |
| } else { | |
| if (b.isEnumerable) { | |
| b.forEach(function(c) { | |
| this.add(c) | |
| }, | |
| this) | |
| } | |
| } | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| removeEach: function(b) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| this.beginPropertyChanges(); | |
| var a = b.get("length"); | |
| if (b.isSCArray) { | |
| while (--a >= 0) { | |
| this.remove(b.objectAt(a)) | |
| } | |
| } else { | |
| if (b.isEnumerable) { | |
| b.forEach(function(c) { | |
| this.remove(c) | |
| }, | |
| this) | |
| } | |
| } | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| clone: function() { | |
| return SC.IndexSet.create(this) | |
| }, | |
| inspect: function() { | |
| var e = this._content, | |
| b = e.length, | |
| a = 0, | |
| c = [], | |
| d; | |
| for (a = 0; a < b; a++) { | |
| d = e[a]; | |
| if (d !== undefined) { | |
| c.push("%@:%@".fmt(a, d)) | |
| } | |
| } | |
| return "SC.IndexSet<%@>".fmt(c.join(" , ")) | |
| }, | |
| forEachRange: function(f, d) { | |
| var b = this._content, | |
| e = 0, | |
| a = b[e], | |
| c = this.source; | |
| if (d === undefined) { | |
| d = null | |
| } | |
| while (a !== 0) { | |
| if (a > 0) { | |
| f.call(d, e, a - e, this, c) | |
| } | |
| e = Math.abs(a); | |
| a = b[e] | |
| } | |
| return this | |
| }, | |
| forEachIn: function(b, c, j, f) { | |
| var g = this._content, | |
| i = 0, | |
| h = 0, | |
| d = b + c, | |
| a = this.source, | |
| e = g[i]; | |
| if (f === undefined) { | |
| f = null | |
| } | |
| while (e !== 0) { | |
| if (i < b) { | |
| i = b | |
| } | |
| while ((i < e) && (i < d)) { | |
| j.call(f, i++, h++, this, a) | |
| } | |
| if (i >= d) { | |
| i = e = 0 | |
| } else { | |
| i = Math.abs(e); | |
| e = g[i] | |
| } | |
| } | |
| return this | |
| }, | |
| lengthIn: function(g, d) { | |
| var a = 0; | |
| if (d === undefined) { | |
| if (g === null || g === undefined) { | |
| return 0 | |
| } else { | |
| if (typeof g === SC.T_NUMBER) { | |
| d = 1 | |
| } else { | |
| if (g.isIndexSet) { | |
| g.forEachRange(function(i, h) { | |
| a += this.lengthIn(i, h) | |
| }, | |
| this); | |
| return a | |
| } else { | |
| d = g.length; | |
| g = g.start | |
| } | |
| } | |
| } | |
| } | |
| if (this.get("length") === 0) { | |
| return 0 | |
| } | |
| var c = this._content, | |
| f = 0, | |
| b = c[f], | |
| e = g + d; | |
| while (f < e && b !== 0) { | |
| if (b > 0) { | |
| a += (b > e) ? e - f: b - f | |
| } | |
| f = Math.abs(b); | |
| b = c[f] | |
| } | |
| return a | |
| }, | |
| source: null, | |
| indexOf: function(d, c) { | |
| var f = this.source; | |
| if (!f) { | |
| throw "%@.indexOf() requires source".fmt(this) | |
| } | |
| var b = f.get("length"), | |
| e = this._content, | |
| g = e[0] < 0 ? Math.abs(e[0]) : 0, | |
| a; | |
| while (g >= 0 && g < b) { | |
| a = f.indexOf(d, g); | |
| if (a < 0) { | |
| return - 1 | |
| } | |
| if (this.contains(a)) { | |
| return a | |
| } | |
| g = a + 1 | |
| } | |
| return - 1 | |
| }, | |
| lastIndexOf: function(d, c) { | |
| var e = this.source; | |
| if (!e) { | |
| throw "%@.lastIndexOf() requires source".fmt(this) | |
| } | |
| var b = e.get("length"), | |
| f = this.max - 1, | |
| a; | |
| if (f >= b) { | |
| f = b - 1 | |
| } | |
| while (f >= 0) { | |
| a = e.lastIndexOf(d, f); | |
| if (a < 0) { | |
| return - 1 | |
| } | |
| if (this.contains(a)) { | |
| return a | |
| } | |
| f = a + 1 | |
| } | |
| return - 1 | |
| }, | |
| forEachObject: function(g, e) { | |
| var d = this.source; | |
| if (!d) { | |
| throw "%@.forEachObject() requires source".fmt(this) | |
| } | |
| var c = this._content, | |
| f = 0, | |
| a = 0, | |
| b = c[f]; | |
| if (e === undefined) { | |
| e = null | |
| } | |
| while (b !== 0) { | |
| while (f < b) { | |
| g.call(e, d.objectAt(f), f, d, this); | |
| f++ | |
| } | |
| f = Math.abs(b); | |
| b = c[f] | |
| } | |
| return this | |
| }, | |
| addObject: function(c, d) { | |
| var e = this.source; | |
| if (!e) { | |
| throw "%@.addObject() requires source".fmt(this) | |
| } | |
| var b = e.get("length"), | |
| f = 0, | |
| a; | |
| while (f >= 0 && f < b) { | |
| a = e.indexOf(c, f); | |
| if (a >= 0) { | |
| this.add(a); | |
| if (d) { | |
| return this | |
| } | |
| f = a++ | |
| } else { | |
| return this | |
| } | |
| } | |
| return this | |
| }, | |
| addObjects: function(b, a) { | |
| b.forEach(function(c) { | |
| this.addObject(c, a) | |
| }, | |
| this); | |
| return this | |
| }, | |
| removeObject: function(c, d) { | |
| var e = this.source; | |
| if (!e) { | |
| throw "%@.removeObject() requires source".fmt(this) | |
| } | |
| var b = e.get("length"), | |
| f = 0, | |
| a; | |
| while (f >= 0 && f < b) { | |
| a = e.indexOf(c, f); | |
| if (a >= 0) { | |
| this.remove(a); | |
| if (d) { | |
| return this | |
| } | |
| f = a + 1 | |
| } else { | |
| return this | |
| } | |
| } | |
| return this | |
| }, | |
| removeObjects: function(b, a) { | |
| b.forEach(function(c) { | |
| this.removeObject(c, a) | |
| }, | |
| this); | |
| return this | |
| }, | |
| LOG_OBSERVING: NO, | |
| forEach: function(g, e) { | |
| var c = this._content, | |
| f = 0, | |
| a = 0, | |
| d = this.source, | |
| b = c[f]; | |
| if (e === undefined) { | |
| e = null | |
| } | |
| while (b !== 0) { | |
| while (f < b) { | |
| g.call(e, f++, a++, this, d) | |
| } | |
| f = Math.abs(b); | |
| b = c[f] | |
| } | |
| return this | |
| }, | |
| nextObject: function(f, b, c) { | |
| var e = this._content, | |
| d = c.next, | |
| a = this.get("max"); | |
| if (b === null) { | |
| b = d = 0 | |
| } else { | |
| if (b >= a) { | |
| delete c.next; | |
| return null | |
| } else { | |
| b++ | |
| } | |
| } | |
| if (b === d) { | |
| do { | |
| b = Math.abs(d); | |
| d = e[b] | |
| } | |
| while (d < 0); | |
| c.next = d | |
| } | |
| return b | |
| }, | |
| toString: function() { | |
| var a = []; | |
| this.forEachRange(function(c, b) { | |
| a.push(b === 1 ? c: "%@..%@".fmt(c, c + b - 1)) | |
| }, | |
| this); | |
| return "SC.IndexSet<%@>".fmt(a.join(",")) | |
| }, | |
| max: 0 | |
| }); | |
| SC.IndexSet.slice = SC.IndexSet.copy = SC.IndexSet.clone; | |
| SC.IndexSet.EMPTY = SC.IndexSet.create().freeze(); | |
| SC.LOGGER_LOG_DELIMITER = ", "; | |
| SC.LOGGER_LOG_ERROR = "ERROR: "; | |
| SC.LOGGER_LOG_INFO = "INFO: "; | |
| SC.LOGGER_LOG_WARN = "WARNING: "; | |
| SC.Logger = SC.Object.create({ | |
| exists: function() { | |
| return typeof(this.get("reporter")) !== "undefined" && this.get("reporter") != null | |
| }.property("reporter").cacheable(), | |
| fallBackOnAlert: NO, | |
| fallBackOnLog: YES, | |
| format: YES, | |
| reporter: SC.console, | |
| log: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.log) === "function") { | |
| if (this.get("format")) { | |
| a.log(this._argumentsToString.apply(this, arguments)) | |
| } else { | |
| a.log.apply(a, arguments) | |
| } | |
| return true | |
| } else { | |
| if (this.fallBackOnAlert) { | |
| var b = this.get("format") ? this._argumentsToString.apply(this, arguments) : arguments; | |
| if (this.get("exists") && typeof(a.alert) === "function") { | |
| a.alert(b) | |
| } else { | |
| alert(b) | |
| } | |
| return true | |
| } | |
| } | |
| return false | |
| }, | |
| dir: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.dir) === "function") { | |
| a.dir.apply(a, arguments); | |
| return true | |
| } | |
| return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false | |
| }, | |
| dirxml: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.dirxml) === "function") { | |
| a.dirxml.apply(a, arguments); | |
| return true | |
| } | |
| return (this.fallBackOnLog) ? this.log.apply(this, arguments) : false | |
| }, | |
| error: function() { | |
| var c = this.get("reporter"); | |
| if (this.get("exists") && typeof(c.error) === "function") { | |
| c.error.apply(c, arguments); | |
| return true | |
| } else { | |
| if (this.fallBackOnLog) { | |
| var b = this._argumentsToArray(arguments); | |
| if (typeof(b.unshift) === "function") { | |
| b.unshift(SC.LOGGER_LOG_ERROR) | |
| } | |
| return this.log.apply(this, b) | |
| } | |
| } | |
| return false | |
| }, | |
| group: function(b) { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.group) === "function") { | |
| a.group(b); | |
| return true | |
| } | |
| return false | |
| }, | |
| groupEnd: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.groupEnd) === "function") { | |
| a.groupEnd(); | |
| return true | |
| } | |
| return false | |
| }, | |
| info: function() { | |
| var c = this.get("reporter"); | |
| if (this.get("exists") && typeof(c.info) === "function") { | |
| c.info.apply(c, arguments); | |
| return true | |
| } else { | |
| if (this.fallBackOnLog) { | |
| var b = this._argumentsToArray(arguments); | |
| if (typeof(b.unshift) === "function") { | |
| b.unshift(SC.LOGGER_LOG_INFO) | |
| } | |
| return this.log.apply(this, b) | |
| } | |
| } | |
| return false | |
| }, | |
| profile: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.profile) === "function") { | |
| a.profile(); | |
| return true | |
| } | |
| return false | |
| }, | |
| profileEnd: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.profileEnd) === "function") { | |
| a.profileEnd(); | |
| return true | |
| } | |
| return false | |
| }, | |
| time: function(b) { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.time) === "function") { | |
| a.time(b); | |
| return true | |
| } | |
| return false | |
| }, | |
| timeEnd: function(b) { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.timeEnd) === "function") { | |
| a.timeEnd(b); | |
| return true | |
| } | |
| return false | |
| }, | |
| trace: function() { | |
| var a = this.get("reporter"); | |
| if (this.get("exists") && typeof(a.trace) === "function") { | |
| a.trace(); | |
| return true | |
| } | |
| return false | |
| }, | |
| warn: function() { | |
| var c = this.get("reporter"); | |
| if (this.get("exists") && typeof(c.warn) === "function") { | |
| c.warn.apply(c, arguments); | |
| return true | |
| } else { | |
| if (this.fallBackOnLog) { | |
| var b = this._argumentsToArray(arguments); | |
| if (typeof(b.unshift) === "function") { | |
| b.unshift(SC.LOGGER_LOG_WARN) | |
| } | |
| return this.log.apply(this, b) | |
| } | |
| } | |
| return false | |
| }, | |
| _argumentsToArray: function(d) { | |
| if (!d) { | |
| return [] | |
| } | |
| var b = []; | |
| for (var c = 0; c < d.length; c++) { | |
| b[c] = d[c] | |
| } | |
| return b | |
| }, | |
| _argumentsToString: function() { | |
| var b = ""; | |
| for (var a = 0; a < arguments.length - 1; a++) { | |
| b += arguments[a] + SC.LOGGER_LOG_DELIMITER | |
| } | |
| b += arguments[arguments.length - 1]; | |
| return b | |
| } | |
| }); | |
| sc_require("private/observer_set"); | |
| SC.RunLoop = SC.Object.extend({ | |
| beginRunLoop: function() { | |
| this._start = new Date().getTime(); | |
| if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) { | |
| console.log("-- SC.RunLoop.beginRunLoop at %@".fmt(this._start)) | |
| } | |
| return this | |
| }, | |
| endRunLoop: function() { | |
| var a; | |
| if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) { | |
| console.log("-- SC.RunLoop.endRunLoop ~ flushing application queues") | |
| } | |
| do { | |
| a = this.flushApplicationQueues(); | |
| if (!a) { | |
| a = this._flushinvokeLastQueue() | |
| } | |
| } | |
| while (a); | |
| this._start = null; | |
| if (SC.LOG_BINDINGS || SC.LOG_OBSERVERS) { | |
| console.log("-- SC.RunLoop.endRunLoop ~ End") | |
| } | |
| return this | |
| }, | |
| invokeOnce: function(a, b) { | |
| if (b === undefined) { | |
| b = a; | |
| a = this | |
| } | |
| if (SC.typeOf(b) === SC.T_STRING) { | |
| b = a[b] | |
| } | |
| if (!this._invokeQueue) { | |
| this._invokeQueue = SC.ObserverSet.create() | |
| } | |
| this._invokeQueue.add(a, b); | |
| return this | |
| }, | |
| invokeLast: function(a, b) { | |
| if (b === undefined) { | |
| b = a; | |
| a = this | |
| } | |
| if (SC.typeOf(b) === SC.T_STRING) { | |
| b = a[b] | |
| } | |
| if (!this._invokeLastQueue) { | |
| this._invokeLastQueue = SC.ObserverSet.create() | |
| } | |
| this._invokeLastQueue.add(a, b); | |
| return this | |
| }, | |
| flushApplicationQueues: function() { | |
| var b = NO; | |
| var a = this._invokeQueue; | |
| if (a && a.targets > 0) { | |
| this._invokeQueue = null; | |
| b = YES; | |
| a.invokeMethods() | |
| } | |
| return SC.Binding.flushPendingChanges() || b | |
| }, | |
| _flushinvokeLastQueue: function() { | |
| var a = this._invokeLastQueue, | |
| b = NO; | |
| if (a && a.targets > 0) { | |
| this._invokeLastQueue = null; | |
| b = YES; | |
| if (b) { | |
| a.invokeMethods() | |
| } | |
| } | |
| return b | |
| } | |
| }); | |
| SC.RunLoop.currentRunLoop = null; | |
| SC.RunLoop.runLoopClass = SC.RunLoop; | |
| SC.RunLoop.begin = function() { | |
| var a = this.currentRunLoop; | |
| if (!a) { | |
| a = this.currentRunLoop = this.runLoopClass.create() | |
| } | |
| a.beginRunLoop(); | |
| return this | |
| }; | |
| SC.RunLoop.end = function() { | |
| var a = this.currentRunLoop; | |
| if (!a) { | |
| throw "SC.RunLoop.end() called outside of a runloop!" | |
| } | |
| a.endRunLoop(); | |
| return this | |
| }; | |
| SC.run = function(b, a) { | |
| SC.RunLoop.begin(); | |
| b.call(a); | |
| SC.RunLoop.end() | |
| }; | |
| sc_require("system/object"); | |
| sc_require("mixins/enumerable"); | |
| sc_require("mixins/copyable"); | |
| sc_require("mixins/freezable"); | |
| SC.SelectionSet = SC.Object.extend(SC.Enumerable, SC.Freezable, SC.Copyable, { | |
| isSelectionSet: YES, | |
| length: function() { | |
| var a = 0, | |
| b = this._sets, | |
| c = this._objects; | |
| if (c) { | |
| a += c.get("length") | |
| } | |
| if (b) { | |
| b.forEach(function(d) { | |
| a += d.get("length") | |
| }) | |
| } | |
| return a | |
| }.property().cacheable(), | |
| sources: function() { | |
| var c = [], | |
| d = this._sets, | |
| b = d ? d.length: 0, | |
| a, | |
| f, | |
| e; | |
| for (a = 0; a < b; a++) { | |
| f = d[a]; | |
| if (f && f.get("length") > 0 && f.source) { | |
| c.push(f.source) | |
| } | |
| } | |
| return c | |
| }.property().cacheable(), | |
| indexSetForSource: function(e) { | |
| if (!e || !e.isSCArray) { | |
| return null | |
| } | |
| var b = this._indexSetCache, | |
| d = this._objects, | |
| c, | |
| a; | |
| if (!b) { | |
| b = this._indexSetCache = {} | |
| } | |
| c = b[SC.guidFor(e)]; | |
| if (c && c._sourceRevision && (c._sourceRevision !== e.propertyRevision)) { | |
| c = null | |
| } | |
| if (!c) { | |
| c = this._indexSetForSource(e, NO); | |
| if (c && c.get("length") === 0) { | |
| c = null | |
| } | |
| if (d) { | |
| if (c) { | |
| c = c.copy() | |
| } | |
| d.forEach(function(f) { | |
| if ((a = e.indexOf(f)) >= 0) { | |
| if (!c) { | |
| c = SC.IndexSet.create() | |
| } | |
| c.add(a) | |
| } | |
| }, | |
| this) | |
| } | |
| if (c) { | |
| c = b[SC.guidFor(e)] = c.frozenCopy(); | |
| c._sourceRevision = e.propertyRevision | |
| } | |
| } | |
| return c | |
| }, | |
| _indexSetForSource: function(f, g) { | |
| if (g === undefined) { | |
| g = YES | |
| } | |
| var d = SC.guidFor(f), | |
| c = this[d], | |
| e = this._sets, | |
| a = e ? e.length: 0, | |
| b = null; | |
| if (c >= a) { | |
| c = null | |
| } | |
| if (SC.none(c)) { | |
| if (g && !this.isFrozen) { | |
| this.propertyWillChange("sources"); | |
| if (!e) { | |
| e = this._sets = [] | |
| } | |
| b = e[a] = SC.IndexSet.create(); | |
| b.source = f; | |
| this[d] = a; | |
| this.propertyDidChange("sources") | |
| } | |
| } else { | |
| b = e ? e[c] : null | |
| } | |
| return b | |
| }, | |
| add: function(a, b, d) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| var g, | |
| f, | |
| j, | |
| i, | |
| c, | |
| e, | |
| h, | |
| k; | |
| if (b === undefined && d === undefined) { | |
| if (!a) { | |
| throw "Must pass params to SC.SelectionSet.add()" | |
| } | |
| if (a.isIndexSet) { | |
| return this.add(a.source, a) | |
| } | |
| if (a.isSelectionSet) { | |
| g = a._sets; | |
| k = a._objects; | |
| f = g ? g.length: 0; | |
| this.beginPropertyChanges(); | |
| for (j = 0; j < f; j++) { | |
| i = g[j]; | |
| if (i && i.get("length") > 0) { | |
| this.add(i.source, i) | |
| } | |
| } | |
| if (k) { | |
| this.addObjects(k) | |
| } | |
| this.endPropertyChanges(); | |
| return this | |
| } | |
| } | |
| i = this._indexSetForSource(a, YES); | |
| c = this.get("length"); | |
| h = i.get("length"); | |
| e = c - h; | |
| i.add(b, d); | |
| this._indexSetCache = null; | |
| e += i.get("length"); | |
| if (e !== c) { | |
| this.propertyDidChange("length"); | |
| this.enumerableContentDidChange(); | |
| if (h === 0) { | |
| this.notifyPropertyChange("sources") | |
| } | |
| } | |
| return this | |
| }, | |
| remove: function(a, b, d) { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| var g, | |
| f, | |
| j, | |
| i, | |
| c, | |
| e, | |
| h, | |
| k; | |
| if (b === undefined && d === undefined) { | |
| if (!a) { | |
| throw "Must pass params to SC.SelectionSet.remove()" | |
| } | |
| if (a.isIndexSet) { | |
| return this.remove(a.source, a) | |
| } | |
| if (a.isSelectionSet) { | |
| g = a._sets; | |
| k = a._objects; | |
| f = g ? g.length: 0; | |
| this.beginPropertyChanges(); | |
| for (j = 0; j < f; j++) { | |
| i = g[j]; | |
| if (i && i.get("length") > 0) { | |
| this.remove(i.source, i) | |
| } | |
| } | |
| if (k) { | |
| this.removeObjects(k) | |
| } | |
| this.endPropertyChanges(); | |
| return this | |
| } | |
| } | |
| i = this._indexSetForSource(a, YES); | |
| c = this.get("length"); | |
| e = c - i.get("length"); | |
| if (i && (k = this._objects)) { | |
| if (d !== undefined) { | |
| b = SC.IndexSet.create(b, d); | |
| d = undefined | |
| } | |
| k.forEach(function(l) { | |
| j = a.indexOf(l); | |
| if (b.contains(j)) { | |
| k.remove(l); | |
| e-- | |
| } | |
| }, | |
| this) | |
| } | |
| i.remove(b, d); | |
| h = i.get("length"); | |
| e += h; | |
| this._indexSetCache = null; | |
| if (e !== c) { | |
| this.propertyDidChange("length"); | |
| this.enumerableContentDidChange(); | |
| if (h === 0) { | |
| this.notifyPropertyChange("sources") | |
| } | |
| } | |
| return this | |
| }, | |
| contains: function(b, d, a) { | |
| if (d === undefined && a === undefined) { | |
| return this.containsObject(b) | |
| } | |
| var c = this.indexSetForSource(b); | |
| if (!c) { | |
| return NO | |
| } | |
| return c.contains(d, a) | |
| }, | |
| intersects: function(b, d, a) { | |
| var c = this.indexSetForSource(b, NO); | |
| if (!c) { | |
| return NO | |
| } | |
| return c.intersects(d, a) | |
| }, | |
| _TMP_ARY: [], | |
| addObject: function(b) { | |
| var c = this._TMP_ARY, | |
| a; | |
| c[0] = b; | |
| a = this.addObjects(c); | |
| c.length = 0; | |
| return a | |
| }, | |
| addObjects: function(a) { | |
| var d = this._objects, | |
| b, | |
| c; | |
| if (!d) { | |
| d = this._objects = SC.CoreSet.create() | |
| } | |
| b = d.get("length"); | |
| d.addEach(a); | |
| c = d.get("length"); | |
| this._indexSetCache = null; | |
| if (c !== b) { | |
| this.propertyDidChange("length"); | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| removeObject: function(b) { | |
| var c = this._TMP_ARY, | |
| a; | |
| c[0] = b; | |
| a = this.removeObjects(c); | |
| c.length = 0; | |
| return a | |
| }, | |
| removeObjects: function(b) { | |
| var e = this._objects, | |
| c, | |
| d, | |
| a; | |
| if (!e) { | |
| return this | |
| } | |
| c = e.get("length"); | |
| e.removeEach(b); | |
| d = e.get("length"); | |
| if (a = this._sets) { | |
| a.forEach(function(f) { | |
| c += f.get("length"); | |
| f.removeObjects(b); | |
| d += f.get("length") | |
| }, | |
| this) | |
| } | |
| this._indexSetCache = null; | |
| if (d !== c) { | |
| this.propertyDidChange("length"); | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| containsObject: function(c) { | |
| var e = this._objects; | |
| if (e && e.contains(c)) { | |
| return YES | |
| } | |
| var d = this._sets, | |
| b = d ? d.length: 0, | |
| a, | |
| f; | |
| for (a = 0; a < b; a++) { | |
| f = d[a]; | |
| if (f && f.indexOf(c) >= 0) { | |
| return YES | |
| } | |
| } | |
| return NO | |
| }, | |
| constrain: function(d) { | |
| var e, | |
| b, | |
| a, | |
| c; | |
| this.beginPropertyChanges(); | |
| this.get("sources").forEach(function(f) { | |
| if (f === d) { | |
| return | |
| } | |
| var g = this._indexSetForSource(d, NO); | |
| if (g) { | |
| this.remove(d, g) | |
| } | |
| }, | |
| this); | |
| e = this._indexSetForSource(d, NO); | |
| if (e && ((a = e.get("max")) > (b = d.get("length")))) { | |
| this.remove(d, b, a - b) | |
| } | |
| if (c = this._objects) { | |
| c.forEach(function(f) { | |
| if (d.indexOf(f) < 0) { | |
| this.removeObject(f) | |
| } | |
| }, | |
| this) | |
| } | |
| this.endPropertyChanges(); | |
| return this | |
| }, | |
| isEqual: function(g) { | |
| var f, | |
| d, | |
| b, | |
| a, | |
| c, | |
| e; | |
| if (!g || !g.isSelectionSet) { | |
| return NO | |
| } | |
| if (g === this) { | |
| return YES | |
| } | |
| if ((this._sets === g._sets) && (this._objects === g._objects)) { | |
| return YES | |
| } | |
| if (this.get("length") !== g.get("length")) { | |
| return NO | |
| } | |
| f = this._objects; | |
| d = g._objects; | |
| if (f || d) { | |
| if ((f ? f.get("length") : 0) !== (d ? d.get("length") : 0)) { | |
| return NO | |
| } | |
| if (f && !f.isEqual(d)) { | |
| return NO | |
| } | |
| } | |
| c = this.get("sources"); | |
| a = c.get("length"); | |
| for (b = 0; b < a; b++) { | |
| e = c.objectAt(b); | |
| f = this._indexSetForSource(e, NO); | |
| d = this._indexSetForSource(e, NO); | |
| if ( !! d !== !!f) { | |
| return NO | |
| } | |
| if (f && !f.isEqual(d)) { | |
| return NO | |
| } | |
| } | |
| return YES | |
| }, | |
| clear: function() { | |
| if (this.isFrozen) { | |
| throw SC.FROZEN_ERROR | |
| } | |
| if (this._sets) { | |
| this._sets.length = 0 | |
| } | |
| if (this._objects) { | |
| this._objects = null | |
| } | |
| this._indexSetCache = null; | |
| this.propertyDidChange("length"); | |
| this.enumerableContentDidChange(); | |
| this.notifyPropertyChange("sources"); | |
| return this | |
| }, | |
| copy: function() { | |
| var c = this.constructor.create(), | |
| d = this._sets, | |
| b = d ? d.length: 0, | |
| a, | |
| e; | |
| if (d && b > 0) { | |
| d = c._sets = d.slice(); | |
| for (a = 0; a < b; a++) { | |
| if (! (e = d[a])) { | |
| continue | |
| } | |
| e = d[a] = e.copy(); | |
| c[SC.guidFor(e.source)] = a | |
| } | |
| } | |
| if (this._objects) { | |
| c._objects = this._objects.copy() | |
| } | |
| return c | |
| }, | |
| freeze: function() { | |
| if (this.isFrozen) { | |
| return this | |
| } | |
| var a = this._sets, | |
| b = a ? a.length: 0, | |
| c; | |
| while (--b >= 0) { | |
| if (c = a[b]) { | |
| c.freeze() | |
| } | |
| } | |
| if (this._objects) { | |
| this._objects.freeze() | |
| } | |
| return arguments.callee.base.apply(this, arguments) | |
| }, | |
| toString: function() { | |
| var a = this._sets || []; | |
| a = a.map(function(b) { | |
| return b.toString().replace("SC.IndexSet", SC.guidFor(b.source)) | |
| }, | |
| this); | |
| if (this._objects) { | |
| a.push(this._objects.toString()) | |
| } | |
| return "SC.SelectionSet:%@<%@>".fmt(SC.guidFor(this), a.join(",")) | |
| }, | |
| firstObject: function() { | |
| var b = this._sets, | |
| c = this._objects; | |
| if (b && b.get("length") > 0) { | |
| var e = b ? b[0] : null, | |
| d = e ? e.source: null, | |
| a = e ? e.firstObject() : -1; | |
| if (d && a >= 0) { | |
| return d.objectAt(a) | |
| } | |
| } | |
| return c ? c.firstObject() : undefined | |
| }.property(), | |
| nextObject: function(c, e, b) { | |
| var d, | |
| a; | |
| if (c === 0) { | |
| d = b.objects = []; | |
| this.forEach(function(f) { | |
| d.push(f) | |
| }, | |
| this); | |
| b.max = d.length | |
| } | |
| d = b.objects; | |
| a = d[c]; | |
| if (c + 1 >= b.max) { | |
| b.objects = b.max = null | |
| } | |
| return a | |
| }, | |
| forEach: function(g, e) { | |
| var c = this._sets, | |
| d = this._objects, | |
| b = c ? c.length: 0, | |
| f, | |
| a; | |
| for (a = 0; a < b; a++) { | |
| f = c[a]; | |
| if (f) { | |
| f.forEachObject(g, e) | |
| } | |
| } | |
| if (d) { | |
| d.forEach(g, e) | |
| } | |
| return this | |
| } | |
| }); | |
| SC.SelectionSet.prototype.clone = SC.SelectionSet.prototype.copy; | |
| SC.SelectionSet.EMPTY = SC.SelectionSet.create().freeze(); | |
| sc_require("mixins/enumerable"); | |
| sc_require("mixins/array"); | |
| sc_require("mixins/observable"); | |
| sc_require("mixins/delegate_support"); | |
| SC.SparseArray = SC.Object.extend(SC.Observable, SC.Enumerable, SC.Array, SC.DelegateSupport, { | |
| _requestingLength: 0, | |
| _requestingIndex: 0, | |
| length: function() { | |
| var a = this.delegate; | |
| if (a && SC.none(this._length) && a.sparseArrayDidRequestLength) { | |
| this._requestingLength++; | |
| a.sparseArrayDidRequestLength(this); | |
| this._requestingLength-- | |
| } | |
| return this._length || 0 | |
| }.property().cacheable(), | |
| provideLength: function(a) { | |
| if (SC.none(a)) { | |
| this._sa_content = null | |
| } | |
| if (a !== this._length) { | |
| this._length = a; | |
| if (this._requestingLength <= 0) { | |
| this.enumerableContentDidChange() | |
| } | |
| } | |
| return this | |
| }, | |
| rangeWindowSize: 1, | |
| requestedRangeIndex: [], | |
| objectAt: function(a) { | |
| var c = this._sa_content, | |
| b; | |
| if (!c) { | |
| c = this._sa_content = [] | |
| } | |
| if ((b = c[a]) === undefined) { | |
| this.requestIndex(a); | |
| b = c[a] | |
| } | |
| return b | |
| }, | |
| definedIndexes: function(d) { | |
| var c = SC.IndexSet.create(), | |
| e = this._sa_content, | |
| b, | |
| a; | |
| if (!e) { | |
| return c.freeze() | |
| } | |
| if (d) { | |
| d.forEach(function(f) { | |
| if (e[f] !== undefined) { | |
| c.add(f) | |
| } | |
| }) | |
| } else { | |
| a = e.length; | |
| for (b = 0; b < a; b++) { | |
| if (e[b] !== undefined) { | |
| c.add(b) | |
| } | |
| } | |
| } | |
| return c.freeze() | |
| }, | |
| _TMP_RANGE: {}, | |
| requestIndex: function(b) { | |
| var c = this.delegate; | |
| if (!c) { | |
| return this | |
| } | |
| var a = this.get("rangeWindowSize"), | |
| e = b; | |
| if (a > 1) { | |
| e = e - Math.floor(e % a) | |
| } | |
| if (a < 1) { | |
| a = 1 | |
| } | |
| this._requestingIndex++; | |
| if (c.sparseArrayDidRequestRange) { | |
| var d = this._TMP_RANGE; | |
| if (this.wasRangeRequested(e) === -1) { | |
| d.start = e; | |
| d.length = a; | |
| c.sparseArrayDidRequestRange(this, d); | |
| this.requestedRangeIndex.push(e) | |
| } | |
| } else { | |
| if (c.sparseArrayDidRequestIndex) { | |
| while (--a >= 0) { | |
| c.sparseArrayDidRequestIndex(this, e + a) | |
| } | |
| } | |
| } | |
| this._requestingIndex--; | |
| return this | |
| }, | |
| wasRangeRequested: function(c) { | |
| var b, | |
| a; | |
| for (b = 0, a = this.requestedRangeIndex.length; | |
| b < a; b++) { | |
| if (this.requestedRangeIndex[b] === c) { | |
| return b | |
| } | |
| } | |
| return - 1 | |
| }, | |
| rangeRequestCompleted: function(b) { | |
| var a = this.wasRangeRequested(b); | |
| if (a >= 0) { | |
| this.requestedRangeIndex.removeAt(a, 1); | |
| return YES | |
| } | |
| return NO | |
| }, | |
| provideObjectsInRange: function(b, e) { | |
| var c = this._sa_content; | |
| if (!c) { | |
| c = this._sa_content = [] | |
| } | |
| var d = b.start, | |
| a = b.length; | |
| while (--a >= 0) { | |
| c[d + a] = e[a] | |
| } | |
| if (this._requestingIndex <= 0) { | |
| this.enumerableContentDidChange() | |
| } | |
| return this | |
| }, | |
| _TMP_PROVIDE_ARRAY: [], | |
| _TMP_PROVIDE_RANGE: { | |
| length: 1 | |
| }, | |
| provideObjectAtIndex: function(c, b) { | |
| var d = this._TMP_PROVIDE_ARRAY, | |
| a = this._TMP_PROVIDE_RANGE; | |
| d[0] = b; | |
| a.start = c; | |
| return this.provideObjectsInRange(a, d) | |
| }, | |
| objectsDidChangeInRange: function(a) { | |
| var b = this._sa_content; | |
| if (b) { | |
| if (a.start === 0 && SC.maxRange(a) >= b.length) { | |
| this._sa_content = null | |
| } else { | |
| var d = a.start, | |
| c = Math.min(d + a.length, b.length); | |
| while (--c >= d) { | |
| b[c] = undefined | |
| } | |
| } | |
| } | |
| this.enumerableContentDidChange(a); | |
| return this | |
| }, | |
| indexOf: function(c) { | |
| var a = this.delegate; | |
| if (a && a.sparseArrayDidRequestIndexOf) { | |
| return a.sparseArrayDidRequestIndexOf(this, c) | |
| } else { | |
| var b = this._sa_content; | |
| if (!b) { | |
| b = this._sa_content = [] | |
| } | |
| return b.indexOf(c) | |
| } | |
| }, | |
| replace: function(b, g, e) { | |
| e = e || []; | |
| var c = this.delegate; | |
| if (c) { | |
| if (!c.sparseArrayShouldReplace || !c.sparseArrayShouldReplace(this, b, g, e)) { | |
| return this | |
| } | |
| } | |
| var d = this._sa_content; | |
| if (!d) { | |
| d = this._sa_content = [] | |
| } | |
| d.replace(b, g, e); | |
| var a = e ? (e.get ? e.get("length") : e.length) : 0; | |
| var f = a - g; | |
| if (!SC.none(this._length)) { | |
| this.propertyWillChange("length"); | |
| this._length += f; | |
| this.propertyDidChange("length") | |
| } | |
| this.enumerableContentDidChange(b, g, f); | |
| return this | |
| }, | |
| reset: function() { | |
| this._sa_content = null; | |
| this._length = null; | |
| this.enumerableContentDidChange(); | |
| this.invokeDelegateMethod(this.delegate, "sparseArrayDidReset", this); | |
| return this | |
| } | |
| }); | |
| SC.SparseArray.array = function(a) { | |
| return this.create({ | |
| _length: a || 0 | |
| }) | |
| }; | |
| if ((typeof SC !== "undefined") && SC && SC.bundleDidLoad) { | |
| SC.bundleDidLoad("sproutcore/runtime") | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment