| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 | 
							- /**
 
-  * @license
 
-  * Knockout ES5 plugin - https://github.com/SteveSanderson/knockout-es5
 
-  * Copyright (c) Steve Sanderson
 
-  * MIT license
 
-  */
 
- define(function() {
 
-     'use strict';
 
-     var OBSERVABLES_PROPERTY = '__knockoutObservables';
 
-     var SUBSCRIBABLE_PROPERTY = '__knockoutSubscribable';
 
-     // Model tracking
 
-     // --------------
 
-     //
 
-     // This is the central feature of Knockout-ES5. We augment model objects by converting properties
 
-     // into ES5 getter/setter pairs that read/write an underlying Knockout observable. This means you can
 
-     // use plain JavaScript syntax to read/write the property while still getting the full benefits of
 
-     // Knockout's automatic dependency detection and notification triggering.
 
-     //
 
-     // For comparison, here's Knockout ES3-compatible syntax:
 
-     //
 
-     //     var firstNameLength = myModel.user().firstName().length; // Read
 
-     //     myModel.user().firstName('Bert'); // Write
 
-     //
 
-     // ... versus Knockout-ES5 syntax:
 
-     //
 
-     //     var firstNameLength = myModel.user.firstName.length; // Read
 
-     //     myModel.user.firstName = 'Bert'; // Write
 
-     // `ko.track(model)` converts each property on the given model object into a getter/setter pair that
 
-     // wraps a Knockout observable. Optionally specify an array of property names to wrap; otherwise we
 
-     // wrap all properties. If any of the properties are already observables, we replace them with
 
-     // ES5 getter/setter pairs that wrap your original observable instances. In the case of readonly
 
-     // ko.computed properties, we simply do not define a setter (so attempted writes will be ignored,
 
-     // which is how ES5 readonly properties normally behave).
 
-     //
 
-     // By design, this does *not* recursively walk child object properties, because making literally
 
-     // everything everywhere independently observable is usually unhelpful. When you do want to track
 
-     // child object properties independently, define your own class for those child objects and put
 
-     // a separate ko.track call into its constructor --- this gives you far more control.
 
-     function track(obj, propertyNames) {
 
-         if (!obj /*|| typeof obj !== 'object'*/) {
 
-             throw new Error('When calling ko.track, you must pass an object as the first parameter.');
 
-         }
 
-         var ko = this,
 
-             allObservablesForObject = getAllObservablesForObject(obj, true);
 
-         propertyNames = propertyNames || Object.getOwnPropertyNames(obj);
 
-         propertyNames.forEach(function(propertyName) {
 
-             // Skip storage properties
 
-             if (propertyName === OBSERVABLES_PROPERTY || propertyName === SUBSCRIBABLE_PROPERTY) {
 
-                 return;
 
-             }
 
-             // Skip properties that are already tracked
 
-             if (propertyName in allObservablesForObject) {
 
-                 return;
 
-             }
 
-             var origValue = obj[propertyName],
 
-                 isArray = origValue instanceof Array,
 
-                 observable = ko.isObservable(origValue) ? origValue
 
-                                               : isArray ? ko.observableArray(origValue)
 
-                                                         : ko.observable(origValue);
 
-             Object.defineProperty(obj, propertyName, {
 
-                 configurable: true,
 
-                 enumerable: true,
 
-                 get: observable,
 
-                 set: ko.isWriteableObservable(observable) ? observable : undefined
 
-             });
 
-             allObservablesForObject[propertyName] = observable;
 
-             if (isArray) {
 
-                 notifyWhenPresentOrFutureArrayValuesMutate(ko, observable);
 
-             }
 
-         });
 
-         return obj;
 
-     }
 
-     // Gets or creates the hidden internal key-value collection of observables corresponding to
 
-     // properties on the model object.
 
-     function getAllObservablesForObject(obj, createIfNotDefined) {
 
-         var result = obj[OBSERVABLES_PROPERTY];
 
-         if (!result && createIfNotDefined) {
 
-             result = {};
 
-             Object.defineProperty(obj, OBSERVABLES_PROPERTY, {
 
-                 value : result
 
-             });
 
-         }
 
-         return result;
 
-     }
 
-     // Computed properties
 
-     // -------------------
 
-     //
 
-     // The preceding code is already sufficient to upgrade ko.computed model properties to ES5
 
-     // getter/setter pairs (or in the case of readonly ko.computed properties, just a getter).
 
-     // These then behave like a regular property with a getter function, except they are smarter:
 
-     // your evaluator is only invoked when one of its dependencies changes. The result is cached
 
-     // and used for all evaluations until the next time a dependency changes).
 
-     //
 
-     // However, instead of forcing developers to declare a ko.computed property explicitly, it's
 
-     // nice to offer a utility function that declares a computed getter directly.
 
-     // Implements `ko.defineProperty`
 
-     function defineComputedProperty(obj, propertyName, evaluatorOrOptions) {
 
-         var ko = this,
 
-             computedOptions = { owner: obj, deferEvaluation: true };
 
-         if (typeof evaluatorOrOptions === 'function') {
 
-             computedOptions.read = evaluatorOrOptions;
 
-         } else {
 
-             if ('value' in evaluatorOrOptions) {
 
-                 throw new Error('For ko.defineProperty, you must not specify a "value" for the property. You must provide a "get" function.');
 
-             }
 
-             if (typeof evaluatorOrOptions.get !== 'function') {
 
-                 throw new Error('For ko.defineProperty, the third parameter must be either an evaluator function, or an options object containing a function called "get".');
 
-             }
 
-             computedOptions.read = evaluatorOrOptions.get;
 
-             computedOptions.write = evaluatorOrOptions.set;
 
-         }
 
-         obj[propertyName] = ko.computed(computedOptions);
 
-         track.call(ko, obj, [propertyName]);
 
-         return obj;
 
-     }
 
-     // Array handling
 
-     // --------------
 
-     //
 
-     // Arrays are special, because unlike other property types, they have standard mutator functions
 
-     // (`push`/`pop`/`splice`/etc.) and it's desirable to trigger a change notification whenever one of
 
-     // those mutator functions is invoked.
 
-     //
 
-     // Traditionally, Knockout handles this by putting special versions of `push`/`pop`/etc. on observable
 
-     // arrays that mutate the underlying array and then trigger a notification. That approach doesn't
 
-     // work for Knockout-ES5 because properties now return the underlying arrays, so the mutator runs
 
-     // in the context of the underlying array, not any particular observable:
 
-     //
 
-     //     // Operates on the underlying array value
 
-     //     myModel.someCollection.push('New value');
 
-     //
 
-     // To solve this, Knockout-ES5 detects array values, and modifies them as follows:
 
-     //  1. Associates a hidden subscribable with each array instance that it encounters
 
-     //  2. Intercepts standard mutators (`push`/`pop`/etc.) and makes them trigger the subscribable
 
-     // Then, for model properties whose values are arrays, the property's underlying observable
 
-     // subscribes to the array subscribable, so it can trigger a change notification after mutation.
 
-     // Given an observable that underlies a model property, watch for any array value that might
 
-     // be assigned as the property value, and hook into its change events
 
-     function notifyWhenPresentOrFutureArrayValuesMutate(ko, observable) {
 
-         var watchingArraySubscription = null;
 
-         ko.computed(function () {
 
-             // Unsubscribe to any earlier array instance
 
-             if (watchingArraySubscription) {
 
-                 watchingArraySubscription.dispose();
 
-                 watchingArraySubscription = null;
 
-             }
 
-             // Subscribe to the new array instance
 
-             var newArrayInstance = observable();
 
-             if (newArrayInstance instanceof Array) {
 
-                 watchingArraySubscription = startWatchingArrayInstance(ko, observable, newArrayInstance);
 
-             }
 
-         });
 
-     }
 
-     // Listens for array mutations, and when they happen, cause the observable to fire notifications.
 
-     // This is used to make model properties of type array fire notifications when the array changes.
 
-     // Returns a subscribable that can later be disposed.
 
-     function startWatchingArrayInstance(ko, observable, arrayInstance) {
 
-         var subscribable = getSubscribableForArray(ko, arrayInstance);
 
-         return subscribable.subscribe(observable);
 
-     }
 
-     // Gets or creates a subscribable that fires after each array mutation
 
-     function getSubscribableForArray(ko, arrayInstance) {
 
-         var subscribable = arrayInstance[SUBSCRIBABLE_PROPERTY];
 
-         if (!subscribable) {
 
-             subscribable = new ko.subscribable();
 
-             Object.defineProperty(arrayInstance, SUBSCRIBABLE_PROPERTY, {
 
-                 value : subscribable
 
-             });
 
-             var notificationPauseSignal = {};
 
-             wrapStandardArrayMutators(arrayInstance, subscribable, notificationPauseSignal);
 
-             addKnockoutArrayMutators(ko, arrayInstance, subscribable, notificationPauseSignal);
 
-         }
 
-         return subscribable;
 
-     }
 
-     // After each array mutation, fires a notification on the given subscribable
 
-     function wrapStandardArrayMutators(arrayInstance, subscribable, notificationPauseSignal) {
 
-         ['pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift'].forEach(function(fnName) {
 
-             var origMutator = arrayInstance[fnName];
 
-             arrayInstance[fnName] = function() {
 
-                 var result = origMutator.apply(this, arguments);
 
-                 if (notificationPauseSignal.pause !== true) {
 
-                     subscribable.notifySubscribers(this);
 
-                 }
 
-                 return result;
 
-             };
 
-         });
 
-     }
 
-     // Adds Knockout's additional array mutation functions to the array
 
-     function addKnockoutArrayMutators(ko, arrayInstance, subscribable, notificationPauseSignal) {
 
-         ['remove', 'removeAll', 'destroy', 'destroyAll', 'replace'].forEach(function(fnName) {
 
-             // Make it a non-enumerable property for consistency with standard Array functions
 
-             Object.defineProperty(arrayInstance, fnName, {
 
-                 enumerable: false,
 
-                 value: function() {
 
-                     var result;
 
-                     // These additional array mutators are built using the underlying push/pop/etc.
 
-                     // mutators, which are wrapped to trigger notifications. But we don't want to
 
-                     // trigger multiple notifications, so pause the push/pop/etc. wrappers and
 
-                     // delivery only one notification at the end of the process.
 
-                     notificationPauseSignal.pause = true;
 
-                     try {
 
-                         // Creates a temporary observableArray that can perform the operation.
 
-                         result = ko.observableArray.fn[fnName].apply(ko.observableArray(arrayInstance), arguments);
 
-                     }
 
-                     finally {
 
-                         notificationPauseSignal.pause = false;
 
-                     }
 
-                     subscribable.notifySubscribers(arrayInstance);
 
-                     return result;
 
-                 }
 
-             });
 
-         });
 
-     }
 
-     // Static utility functions
 
-     // ------------------------
 
-     //
 
-     // Since Knockout-ES5 sets up properties that return values, not observables, you can't
 
-     // trivially subscribe to the underlying observables (e.g., `someProperty.subscribe(...)`),
 
-     // or tell them that object values have mutated, etc. To handle this, we set up some
 
-     // extra utility functions that can return or work with the underlying observables.
 
-     // Returns the underlying observable associated with a model property (or `null` if the
 
-     // model or property doesn't exist, or isn't associated with an observable). This means
 
-     // you can subscribe to the property, e.g.:
 
-     //
 
-     //     ko.getObservable(model, 'propertyName')
 
-     //       .subscribe(function(newValue) { ... });
 
-     function getObservable(obj, propertyName) {
 
-         if (!obj /*|| typeof obj !== 'object'*/) {
 
-             return null;
 
-         }
 
-         var allObservablesForObject = getAllObservablesForObject(obj, false);
 
-         return (allObservablesForObject && allObservablesForObject[propertyName]) || null;
 
-     }
 
-     // Causes a property's associated observable to fire a change notification. Useful when
 
-     // the property value is a complex object and you've modified a child property.
 
-     function valueHasMutated(obj, propertyName) {
 
-         var observable = getObservable(obj, propertyName);
 
-         if (observable) {
 
-             observable.valueHasMutated();
 
-         }
 
-     }
 
-     // Extends a Knockout instance with Knockout-ES5 functionality
 
-     function attachToKo(ko) {
 
-         ko.track = track;
 
-         ko.getObservable = getObservable;
 
-         ko.valueHasMutated = valueHasMutated;
 
-         ko.defineProperty = defineComputedProperty;
 
-     }
 
-     return {
 
-         attachToKo : attachToKo
 
-     };
 
- });
 
 
  |