(() => { // Hide or don't minify context properties, see https://github.com/knockout/knockout/issues/2294 var contextSubscribable = Symbol('_subscribable'); var contextAncestorBindingInfo = Symbol('_ancestorBindingInfo'); var contextDataDependency = Symbol('_dataDependency'); ko.bindingHandlers = {}; // Use an overridable method for retrieving binding handlers so that plugins may support dynamically created handlers ko['getBindingHandler'] = bindingKey => ko.bindingHandlers[bindingKey]; var inheritParentVm = {}; // The ko.bindingContext constructor is only called directly to create the root context. For child // contexts, use bindingContext.createChildContext or bindingContext.extend. ko.bindingContext = function(dataItemOrAccessor, parentContext, dataItemAlias, extendCallback, options) { // The binding context object includes static properties for the current, parent, and root view models. // If a view model is actually stored in an observable, the corresponding binding context object, and // any child contexts, must be updated when the view model is changed. function updateContext() { // Most of the time, the context will directly get a view model object, but if a function is given, // we call the function to retrieve the view model. If the function accesses any observables or returns // an observable, the dependency is tracked, and those observables can later cause the binding // context to be updated. var dataItemOrObservable = isFunc ? realDataItemOrAccessor() : realDataItemOrAccessor, dataItem = ko.utils.unwrapObservable(dataItemOrObservable); if (parentContext) { // Copy $root and any custom properties from the parent context ko.utils.extend(self, parentContext); // Copy Symbol properties if (contextAncestorBindingInfo in parentContext) { self[contextAncestorBindingInfo] = parentContext[contextAncestorBindingInfo]; } } else { self['$parents'] = []; self['$root'] = dataItem; // Export 'ko' in the binding context so it will be available in bindings and templates // even if 'ko' isn't exported as a global, such as when using an AMD loader. // See https://github.com/SteveSanderson/knockout/issues/490 self['ko'] = ko; } self[contextSubscribable] = subscribable; if (shouldInheritData) { dataItem = self['$data']; } else { self['$rawData'] = dataItemOrObservable; self['$data'] = dataItem; } if (dataItemAlias) self[dataItemAlias] = dataItem; // The extendCallback function is provided when creating a child context or extending a context. // It handles the specific actions needed to finish setting up the binding context. Actions in this // function could also add dependencies to this binding context. if (extendCallback) extendCallback(self, parentContext, dataItem); // When a "parent" context is given and we don't already have a dependency on its context, register a dependency on it. // Thus whenever the parent context is updated, this context will also be updated. if (parentContext && parentContext[contextSubscribable] && !ko.computedContext.computed().hasAncestorDependency(parentContext[contextSubscribable])) { parentContext[contextSubscribable](); } if (dataDependency) { self[contextDataDependency] = dataDependency; } return self['$data']; } var self = this, shouldInheritData = dataItemOrAccessor === inheritParentVm, realDataItemOrAccessor = shouldInheritData ? undefined : dataItemOrAccessor, isFunc = typeof(realDataItemOrAccessor) == "function" && !ko.isObservable(realDataItemOrAccessor), subscribable, dataDependency = options && options['dataDependency']; if (options && options['exportDependencies']) { // The "exportDependencies" option means that the calling code will track any dependencies and re-create // the binding context when they change. updateContext(); } else { subscribable = ko.pureComputed(updateContext); subscribable.peek(); // At this point, the binding context has been initialized, and the "subscribable" computed observable is // subscribed to any observables that were accessed in the process. If there is nothing to track, the // computed will be inactive, and we can safely throw it away. If it's active, the computed is stored in // the context object. if (subscribable.isActive()) { // Always notify because even if the model ($data) hasn't changed, other context properties might have changed subscribable['equalityComparer'] = null; } else { self[contextSubscribable] = undefined; } } } // Extend the binding context hierarchy with a new view model object. If the parent context is watching // any observables, the new child context will automatically get a dependency on the parent context. // But this does not mean that the $data value of the child context will also get updated. If the child // view model also depends on the parent view model, you must provide a function that returns the correct // view model on each update. ko.bindingContext.prototype['createChildContext'] = function (dataItemOrAccessor, dataItemAlias, extendCallback, options) { if (!options && dataItemAlias && typeof dataItemAlias == "object") { options = dataItemAlias; dataItemAlias = options['as']; extendCallback = options['extend']; } if (dataItemAlias && options && options['noChildContext']) { var isFunc = typeof(dataItemOrAccessor) == "function" && !ko.isObservable(dataItemOrAccessor); return new ko.bindingContext(inheritParentVm, this, null, self => { if (extendCallback) extendCallback(self); self[dataItemAlias] = isFunc ? dataItemOrAccessor() : dataItemOrAccessor; }, options); } return new ko.bindingContext(dataItemOrAccessor, this, dataItemAlias, (self, parentContext) => { // Extend the context hierarchy by setting the appropriate pointers self['$parentContext'] = parentContext; self['$parent'] = parentContext['$data']; self['$parents'] = (parentContext['$parents'] || []).slice(0); self['$parents'].unshift(self['$parent']); if (extendCallback) extendCallback(self); }, options); }; // Extend the binding context with new custom properties. This doesn't change the context hierarchy. // Similarly to "child" contexts, provide a function here to make sure that the correct values are set // when an observable view model is updated. ko.bindingContext.prototype['extend'] = function(properties, options) { return new ko.bindingContext(inheritParentVm, this, null, self => ko.utils.extend(self, typeof(properties) == "function" ? properties(self) : properties) , options); }; var boundElementDomDataKey = ko.utils.domData.nextKey(); function asyncContextDispose(node) { var bindingInfo = ko.utils.domData.get(node, boundElementDomDataKey), asyncContext = bindingInfo && bindingInfo.asyncContext; if (asyncContext) { bindingInfo.asyncContext = null; asyncContext.notifyAncestor(); } } function AsyncCompleteContext(node, bindingInfo, ancestorBindingInfo) { this.node = node; this.bindingInfo = bindingInfo; this.asyncDescendants = []; this.childrenComplete = false; if (!bindingInfo.asyncContext) { ko.utils.domNodeDisposal.addDisposeCallback(node, asyncContextDispose); } if (ancestorBindingInfo && ancestorBindingInfo.asyncContext) { ancestorBindingInfo.asyncContext.asyncDescendants.push(node); this.ancestorBindingInfo = ancestorBindingInfo; } } AsyncCompleteContext.prototype.notifyAncestor = function () { if (this.ancestorBindingInfo && this.ancestorBindingInfo.asyncContext) { this.ancestorBindingInfo.asyncContext.descendantComplete(this.node); } }; AsyncCompleteContext.prototype.descendantComplete = function (node) { ko.utils.arrayRemoveItem(this.asyncDescendants, node); if (!this.asyncDescendants.length && this.childrenComplete) { this.completeChildren(); } }; AsyncCompleteContext.prototype.completeChildren = function () { this.childrenComplete = true; if (this.bindingInfo.asyncContext && !this.asyncDescendants.length) { this.bindingInfo.asyncContext = null; ko.utils.domNodeDisposal.removeDisposeCallback(this.node, asyncContextDispose); ko.bindingEvent.notify(this.node, ko.bindingEvent.descendantsComplete); this.notifyAncestor(); } }; ko.bindingEvent = { childrenComplete: "childrenComplete", descendantsComplete : "descendantsComplete", subscribe: (node, event, callback, context, options) => { var bindingInfo = ko.utils.domData.getOrSet(node, boundElementDomDataKey, {}); if (!bindingInfo.eventSubscribable) { bindingInfo.eventSubscribable = new ko.subscribable; } if (options && options['notifyImmediately'] && bindingInfo.notifiedEvents[event]) { ko.dependencyDetection.ignore(callback, context, [node]); } return bindingInfo.eventSubscribable.subscribe(callback, context, event); }, notify: (node, event) => { var bindingInfo = ko.utils.domData.get(node, boundElementDomDataKey); if (bindingInfo) { bindingInfo.notifiedEvents[event] = true; if (bindingInfo.eventSubscribable) { bindingInfo.eventSubscribable['notifySubscribers'](node, event); } if (event == ko.bindingEvent.childrenComplete) { if (bindingInfo.asyncContext) { bindingInfo.asyncContext.completeChildren(); } else if (bindingInfo.asyncContext === undefined && bindingInfo.eventSubscribable && bindingInfo.eventSubscribable.hasSubscriptionsForEvent(ko.bindingEvent.descendantsComplete)) { // It's currently an error to register a descendantsComplete handler for a node that was never registered as completing asynchronously. // That's because without the asyncContext, we don't have a way to know that all descendants have completed. throw new Error("descendantsComplete event not supported for bindings on this node"); } } } }, startPossiblyAsyncContentBinding: (node, bindingContext) => { var bindingInfo = ko.utils.domData.getOrSet(node, boundElementDomDataKey, {}); if (!bindingInfo.asyncContext) { bindingInfo.asyncContext = new AsyncCompleteContext(node, bindingInfo, bindingContext[contextAncestorBindingInfo]); } // If the provided context was already extended with this node's binding info, just return the extended context if (bindingContext[contextAncestorBindingInfo] == bindingInfo) { return bindingContext; } return bindingContext['extend'](ctx => { ctx[contextAncestorBindingInfo] = bindingInfo; }); } }; // Given a function that returns bindings, create and return a new object that contains // binding value-accessors functions. Each accessor function calls the original function // so that it always gets the latest value and all dependencies are captured. This is used // by ko.applyBindingsToNode and getBindingsAndMakeAccessors. function makeAccessorsFromFunction(callback) { return ko.utils.objectMap(ko.dependencyDetection.ignore(callback), (value, key) => () => callback()[key] ); } // Given a bindings function or object, create and return a new object that contains // binding value-accessors functions. This is used by ko.applyBindingsToNode. function makeBindingAccessors(bindings, context, node) { return (typeof bindings === 'function') ? makeAccessorsFromFunction(bindings.bind(null, context, node)) : ko.utils.objectMap(bindings, value => () => value); } // This function is used if the binding provider doesn't include a getBindingAccessors function. // It must be called with 'this' set to the provider instance. function getBindingsAndMakeAccessors(node, context) { return makeAccessorsFromFunction(this['getBindings'].bind(this, node, context)); } function validateThatBindingIsAllowedForVirtualElements(bindingName) { var validator = ko.virtualElements.allowedBindings[bindingName]; if (!validator) throw new Error("The binding '" + bindingName + "' cannot be used with virtual elements") } function applyBindingsToDescendantsInternal(bindingContext, elementOrVirtualElement) { var nextInQueue = ko.virtualElements.firstChild(elementOrVirtualElement); if (nextInQueue) { var currentChild, provider = ko.bindingProvider['instance'], preprocessNode = provider['preprocessNode']; // Preprocessing allows a binding provider to mutate a node before bindings are applied to it. For example it's // possible to insert new siblings after it, and/or replace the node with a different one. This can be used to // implement custom binding syntaxes, such as {{ value }} for string interpolation, or custom element types that // trigger insertion of