@tko/bind 4.0.0-alpha8.0 → 4.0.0-beta1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bind.js DELETED
@@ -1,1185 +0,0 @@
1
- /*!
2
- * TKO DOM-Observable Binding 🥊 @tko/bind@4.0.0-alpha8.0
3
- * (c) The Knockout.js Team - https://tko.io
4
- * License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
- */
6
-
7
- import { domData, extend, options, virtualElements, objectMap, tagNameLower, objectForEach, arrayIndexOf, arrayForEach, fixUpContinuousNodeArray, replaceDomNodes, arrayPushAll, anyDomNodeIsAttachedToDocument, arrayMap, cleanNode, removeNode, compareArrays } from '@tko/utils';
8
- import { subscribable, unwrap, isObservable, isWriteableObservable, dependencyDetection, observable } from '@tko/observable';
9
- import { pureComputed, computed } from '@tko/computed';
10
- import { LifeCycle } from '@tko/lifecycle';
11
-
12
- var contextAncestorBindingInfo = Symbol('_ancestorBindingInfo');
13
- var boundElementDomDataKey = domData.nextKey();
14
- var bindingEvent = {
15
- childrenComplete: 'childrenComplete',
16
- descendantsComplete: 'descendantsComplete',
17
- subscribe: function (node, event, callback, context) {
18
- var bindingInfo = domData.getOrSet(node, boundElementDomDataKey, {});
19
- if (!bindingInfo.eventSubscribable) {
20
- bindingInfo.eventSubscribable = new subscribable();
21
- }
22
- return bindingInfo.eventSubscribable.subscribe(callback, context, event);
23
- },
24
- notify: function (node, event) {
25
- var bindingInfo = domData.get(node, boundElementDomDataKey);
26
- if (bindingInfo) {
27
- if (bindingInfo.eventSubscribable) {
28
- bindingInfo.eventSubscribable.notifySubscribers(node, event);
29
- }
30
- }
31
- }
32
- };
33
-
34
- var boundElementDomDataKey$1 = domData.nextKey();
35
- var contextSubscribeSymbol = Symbol('Knockout Context Subscription');
36
- // Unique stub to indicate inheritance.
37
- var inheritParentIndicator = Symbol('Knockout Parent Indicator');
38
- // The bindingContext constructor is only called directly to create the root context. For child
39
- // contexts, use bindingContext.createChildContext or bindingContext.extend.
40
- function bindingContext(dataItemOrAccessor, parentContext, dataItemAlias, extendCallback, settings) {
41
- var self = this;
42
- var shouldInheritData = dataItemOrAccessor === inheritParentIndicator;
43
- var realDataItemOrAccessor = shouldInheritData ? undefined : dataItemOrAccessor;
44
- var isFunc = typeof realDataItemOrAccessor === 'function' && !isObservable(realDataItemOrAccessor);
45
- // Export 'ko' in the binding context so it will be available in bindings and templates
46
- // even if 'ko' isn't exported as a global, such as when using an AMD loader.
47
- // See https://github.com/SteveSanderson/knockout/issues/490
48
- self.ko = options.knockoutInstance;
49
- var subscribable$$1;
50
- // The binding context object includes static properties for the current, parent, and root view models.
51
- // If a view model is actually stored in an observable, the corresponding binding context object, and
52
- // any child contexts, must be updated when the view model is changed.
53
- function updateContext() {
54
- // Most of the time, the context will directly get a view model object, but if a function is given,
55
- // we call the function to retrieve the view model. If the function accesses any observables or returns
56
- // an observable, the dependency is tracked, and those observables can later cause the binding
57
- // context to be updated.
58
- var dataItemOrObservable = isFunc ? realDataItemOrAccessor() : realDataItemOrAccessor;
59
- var dataItem = unwrap(dataItemOrObservable);
60
- if (parentContext) {
61
- // When a "parent" context is given, register a dependency on the parent context. Thus whenever the
62
- // parent context is updated, this context will also be updated.
63
- if (parentContext[contextSubscribeSymbol]) {
64
- parentContext[contextSubscribeSymbol]();
65
- }
66
- // Copy $root and any custom properties from the parent context
67
- extend(self, parentContext);
68
- // Copy Symbol properties
69
- if (contextAncestorBindingInfo in parentContext) {
70
- self[contextAncestorBindingInfo] = parentContext[contextAncestorBindingInfo];
71
- }
72
- }
73
- else {
74
- self.$parents = [];
75
- self.$root = dataItem;
76
- }
77
- self[contextSubscribeSymbol] = subscribable$$1;
78
- if (shouldInheritData) {
79
- dataItem = self.$data;
80
- }
81
- else {
82
- self.$rawData = dataItemOrObservable;
83
- self.$data = dataItem;
84
- }
85
- if (dataItemAlias) {
86
- self[dataItemAlias] = dataItem;
87
- }
88
- // The extendCallback function is provided when creating a child context or extending a context.
89
- // It handles the specific actions needed to finish setting up the binding context. Actions in this
90
- // function could also add dependencies to this binding context.
91
- if (extendCallback) {
92
- extendCallback(self, parentContext, dataItem);
93
- }
94
- return self.$data;
95
- }
96
- if (settings && settings.exportDependencies) {
97
- // The "exportDependencies" option means that the calling code will track any dependencies and re-create
98
- // the binding context when they change.
99
- updateContext();
100
- }
101
- else {
102
- subscribable$$1 = pureComputed(updateContext);
103
- subscribable$$1.peek();
104
- // At this point, the binding context has been initialized, and the "subscribable" computed observable is
105
- // subscribed to any observables that were accessed in the process. If there is nothing to track, the
106
- // computed will be inactive, and we can safely throw it away. If it's active, the computed is stored in
107
- // the context object.
108
- if (subscribable$$1.isActive()) {
109
- self[contextSubscribeSymbol] = subscribable$$1;
110
- // Always notify because even if the model ($data) hasn't changed, other context properties might have changed
111
- subscribable$$1['equalityComparer'] = null;
112
- }
113
- else {
114
- self[contextSubscribeSymbol] = undefined;
115
- }
116
- }
117
- }
118
- Object.assign(bindingContext.prototype, {
119
- lookup: function (token, globals, node) {
120
- // short circuits
121
- switch (token) {
122
- case '$element': return node;
123
- case '$context': return this;
124
- case 'this':
125
- case '$data': return this.$data;
126
- }
127
- var $data = this.$data;
128
- // instanceof Object covers 1. {}, 2. [], 3. function() {}, 4. new *; it excludes undefined, null, primitives.
129
- if ($data instanceof Object && token in $data) {
130
- return $data[token];
131
- }
132
- if (token in this) {
133
- return this[token];
134
- }
135
- if (token in globals) {
136
- return globals[token];
137
- }
138
- throw new Error("The variable \"" + token + "\" was not found on $data, $context, or globals.");
139
- },
140
- // Extend the binding context hierarchy with a new view model object. If the parent context is watching
141
- // any observables, the new child context will automatically get a dependency on the parent context.
142
- // But this does not mean that the $data value of the child context will also get updated. If the child
143
- // view model also depends on the parent view model, you must provide a function that returns the correct
144
- // view model on each update.
145
- createChildContext: function (dataItemOrAccessor, dataItemAlias, extendCallback, settings) {
146
- return new bindingContext(dataItemOrAccessor, this, dataItemAlias, function (self, parentContext) {
147
- // Extend the context hierarchy by setting the appropriate pointers
148
- self.$parentContext = parentContext;
149
- self.$parent = parentContext.$data;
150
- self.$parents = (parentContext.$parents || []).slice(0);
151
- self.$parents.unshift(self.$parent);
152
- if (extendCallback) {
153
- extendCallback(self);
154
- }
155
- }, settings);
156
- },
157
- // Extend the binding context with new custom properties. This doesn't change the context hierarchy.
158
- // Similarly to "child" contexts, provide a function here to make sure that the correct values are set
159
- // when an observable view model is updated.
160
- extend: function (properties) {
161
- // If the parent context references an observable view model, "_subscribable" will always be the
162
- // latest view model object. If not, "_subscribable" isn't set, and we can use the static "$data" value.
163
- return new bindingContext(inheritParentIndicator, this, null, function (self, parentContext) {
164
- extend(self, typeof properties === 'function' ? properties.call(self) : properties);
165
- });
166
- },
167
- createStaticChildContext: function (dataItemOrAccessor, dataItemAlias) {
168
- return this.createChildContext(dataItemOrAccessor, dataItemAlias, null, { 'exportDependencies': true });
169
- }
170
- });
171
- function storedBindingContextForNode(node) {
172
- var bindingInfo = domData.get(node, boundElementDomDataKey$1);
173
- return bindingInfo && bindingInfo.context;
174
- }
175
- // Retrieving binding context from arbitrary nodes
176
- function contextFor(node) {
177
- // We can only do something meaningful for elements and comment nodes (in particular, not text nodes, as IE can't store domdata for them)
178
- if (node && (node.nodeType === 1 || node.nodeType === 8)) {
179
- return storedBindingContextForNode(node);
180
- }
181
- }
182
- function dataFor(node) {
183
- var context = contextFor(node);
184
- return context ? context.$data : undefined;
185
- }
186
-
187
- /*! *****************************************************************************
188
- Copyright (c) Microsoft Corporation. All rights reserved.
189
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
190
- this file except in compliance with the License. You may obtain a copy of the
191
- License at http://www.apache.org/licenses/LICENSE-2.0
192
-
193
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
194
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
195
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
196
- MERCHANTABLITY OR NON-INFRINGEMENT.
197
-
198
- See the Apache Version 2.0 License for specific language governing permissions
199
- and limitations under the License.
200
- ***************************************************************************** */
201
- /* global Reflect, Promise */
202
-
203
- var extendStatics = Object.setPrototypeOf ||
204
- ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
205
- function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
206
-
207
- function __extends(d, b) {
208
- extendStatics(d, b);
209
- function __() { this.constructor = d; }
210
- d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
211
- }
212
-
213
- function __awaiter(thisArg, _arguments, P, generator) {
214
- return new (P || (P = Promise))(function (resolve, reject) {
215
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
216
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
217
- function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
218
- step((generator = generator.apply(thisArg, _arguments || [])).next());
219
- });
220
- }
221
-
222
- function __generator(thisArg, body) {
223
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
224
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
225
- function verb(n) { return function (v) { return step([n, v]); }; }
226
- function step(op) {
227
- if (f) throw new TypeError("Generator is already executing.");
228
- while (_) try {
229
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
230
- if (y = 0, t) op = [op[0] & 2, t.value];
231
- switch (op[0]) {
232
- case 0: case 1: t = op; break;
233
- case 4: _.label++; return { value: op[1], done: false };
234
- case 5: _.label++; y = op[1]; op = [0]; continue;
235
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
236
- default:
237
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
238
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
239
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
240
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
241
- if (t[2]) _.ops.pop();
242
- _.trys.pop(); continue;
243
- }
244
- op = body.call(thisArg, _);
245
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
246
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
247
- }
248
- }
249
-
250
- function __values(o) {
251
- var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
252
- if (m) return m.call(o);
253
- return {
254
- next: function () {
255
- if (o && i >= o.length) o = void 0;
256
- return { value: o && o[i++], done: !o };
257
- }
258
- };
259
- }
260
-
261
- function __read(o, n) {
262
- var m = typeof Symbol === "function" && o[Symbol.iterator];
263
- if (!m) return o;
264
- var i = m.call(o), r, ar = [], e;
265
- try {
266
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
267
- }
268
- catch (error) { e = { error: error }; }
269
- finally {
270
- try {
271
- if (r && !r.done && (m = i["return"])) m.call(i);
272
- }
273
- finally { if (e) throw e.error; }
274
- }
275
- return ar;
276
- }
277
-
278
- function __spread() {
279
- for (var ar = [], i = 0; i < arguments.length; i++)
280
- ar = ar.concat(__read(arguments[i]));
281
- return ar;
282
- }
283
-
284
- var BindingResult = /** @class */ (function () {
285
- function BindingResult(_a) {
286
- var asyncBindingsApplied = _a.asyncBindingsApplied, rootNode = _a.rootNode, bindingContext = _a.bindingContext;
287
- Object.assign(this, {
288
- rootNode: rootNode,
289
- bindingContext: bindingContext,
290
- isSync: asyncBindingsApplied.size === 0,
291
- isComplete: this.isSync
292
- });
293
- if (!this.isSync) {
294
- this.completionPromise = this.completeWhenBindingsFinish(asyncBindingsApplied);
295
- }
296
- }
297
- BindingResult.prototype.completeWhenBindingsFinish = function (asyncBindingsApplied) {
298
- return __awaiter(this, void 0, void 0, function () {
299
- return __generator(this, function (_a) {
300
- switch (_a.label) {
301
- case 0: return [4 /*yield*/, Promise.all(asyncBindingsApplied)];
302
- case 1:
303
- _a.sent();
304
- this.isComplete = true;
305
- return [2 /*return*/, this];
306
- }
307
- });
308
- });
309
- };
310
- return BindingResult;
311
- }());
312
-
313
- var BindingHandler = /** @class */ (function (_super) {
314
- __extends(BindingHandler, _super);
315
- function BindingHandler(params) {
316
- var _this = _super.call(this) || this;
317
- var $element = params.$element, valueAccessor = params.valueAccessor, allBindings = params.allBindings, $context = params.$context;
318
- Object.assign(_this, {
319
- valueAccessor: valueAccessor,
320
- allBindings: allBindings,
321
- $element: $element,
322
- $context: $context,
323
- $data: $context.$data
324
- });
325
- _this.anchorTo($element);
326
- return _this;
327
- }
328
- Object.defineProperty(BindingHandler.prototype, "value", {
329
- get: function () { return this.valueAccessor(); },
330
- set: function (v) {
331
- var va = this.valueAccessor();
332
- if (isWriteableObservable(va)) {
333
- va(v);
334
- }
335
- else {
336
- this.valueAccessor(v);
337
- }
338
- },
339
- enumerable: true,
340
- configurable: true
341
- });
342
- Object.defineProperty(BindingHandler.prototype, "controlsDescendants", {
343
- get: function () { return false; },
344
- enumerable: true,
345
- configurable: true
346
- });
347
- Object.defineProperty(BindingHandler, "allowVirtualElements", {
348
- get: function () { return false; },
349
- enumerable: true,
350
- configurable: true
351
- });
352
- Object.defineProperty(BindingHandler, "isBindingHandlerClass", {
353
- get: function () { return true; },
354
- enumerable: true,
355
- configurable: true
356
- });
357
- Object.defineProperty(BindingHandler.prototype, "bindingCompleted", {
358
- /* Overload this for asynchronous bindings or bindings that recursively
359
- apply bindings (e.g. components, foreach, template).
360
-
361
- A binding should be complete when it has run through once, notably
362
- in server-side bindings for pre-rendering.
363
- */
364
- get: function () { return true; },
365
- enumerable: true,
366
- configurable: true
367
- });
368
- BindingHandler.registerAs = function (name, provider) {
369
- if (provider === void 0) { provider = options.bindingProviderInstance; }
370
- provider.bindingHandlers.set(name, this);
371
- };
372
- return BindingHandler;
373
- }(LifeCycle));
374
- /**
375
- * An AsyncBindingHandler shall call `completeBinding` when the binding
376
- * is to be considered complete.
377
- */
378
- var ResolveSymbol = Symbol('Async Binding Resolved');
379
- var AsyncBindingHandler = /** @class */ (function (_super) {
380
- __extends(AsyncBindingHandler, _super);
381
- function AsyncBindingHandler(params) {
382
- var _this = _super.call(this, params) || this;
383
- _this.bindingCompletion = new Promise(function (resolve) {
384
- _this[ResolveSymbol] = resolve;
385
- });
386
- _this.completeBinding = function (bindingResult) { return _this[ResolveSymbol](bindingResult); };
387
- return _this;
388
- }
389
- Object.defineProperty(AsyncBindingHandler.prototype, "bindingCompleted", {
390
- get: function () { return this.bindingCompletion; },
391
- enumerable: true,
392
- configurable: true
393
- });
394
- return AsyncBindingHandler;
395
- }(BindingHandler));
396
-
397
- /**
398
- * We have no guarantees, for users employing legacy bindings,
399
- * that it has not been changed with a modification like
400
- *
401
- * ko.bindingHandlers[name] = { init: ...}
402
- *
403
- * ... so we have to keep track by way of a map.
404
- */
405
- var PossibleWeakMap = options.global.WeakMap || Map;
406
- var legacyBindingMap = new PossibleWeakMap();
407
- var LegacyBindingHandler = /** @class */ (function (_super) {
408
- __extends(LegacyBindingHandler, _super);
409
- function LegacyBindingHandler(params) {
410
- var _this = _super.call(this, params) || this;
411
- var handler = _this.handler;
412
- _this.onError = params.onError;
413
- if (typeof handler.dispose === 'function') {
414
- _this.addDisposable(handler);
415
- }
416
- try {
417
- _this.initReturn = handler.init && handler.init.apply(handler, __spread(_this.legacyArgs));
418
- }
419
- catch (e) {
420
- params.onError('init', e);
421
- }
422
- return _this;
423
- }
424
- LegacyBindingHandler.prototype.onValueChange = function () {
425
- var handler = this.handler;
426
- if (typeof handler.update !== 'function') {
427
- return;
428
- }
429
- try {
430
- handler.update.apply(handler, __spread(this.legacyArgs));
431
- }
432
- catch (e) {
433
- this.onError('update', e);
434
- }
435
- };
436
- Object.defineProperty(LegacyBindingHandler.prototype, "legacyArgs", {
437
- get: function () {
438
- return [
439
- this.$element, this.valueAccessor, this.allBindings,
440
- this.$data, this.$context
441
- ];
442
- },
443
- enumerable: true,
444
- configurable: true
445
- });
446
- Object.defineProperty(LegacyBindingHandler.prototype, "controlsDescendants", {
447
- get: function () {
448
- var objectToTest = this.initReturn || this.handler || {};
449
- return objectToTest.controlsDescendantBindings;
450
- },
451
- enumerable: true,
452
- configurable: true
453
- });
454
- /**
455
- * Create a handler instance from the `origin`, which may be:
456
- *
457
- * 1. an object (becomes LegacyBindingHandler)
458
- * 2. a function (becomes LegacyBindingHandler with `init: function`)
459
- *
460
- * If given an object (the only kind supported in knockout 3.x and before), it
461
- * shall draw the `init`, `update`, and `allowVirtualElements` properties
462
- */
463
- LegacyBindingHandler.getOrCreateFor = function (key, handler) {
464
- if (legacyBindingMap.has(handler)) {
465
- return legacyBindingMap.get(handler);
466
- }
467
- var newLegacyHandler = this.createFor(key, handler);
468
- legacyBindingMap.set(handler, newLegacyHandler);
469
- return newLegacyHandler;
470
- };
471
- LegacyBindingHandler.createFor = function (key, handler) {
472
- if (typeof handler === 'function') {
473
- var _a = __read([handler, handler.dispose], 2), initFn_1 = _a[0], disposeFn_1 = _a[1];
474
- return /** @class */ (function (_super) {
475
- __extends(class_1, _super);
476
- function class_1() {
477
- return _super !== null && _super.apply(this, arguments) || this;
478
- }
479
- Object.defineProperty(class_1.prototype, "handler", {
480
- get: function () {
481
- var init = initFn_1.bind(this);
482
- var dispose = disposeFn_1 ? disposeFn_1.bind(this) : null;
483
- return { init: init, dispose: dispose };
484
- },
485
- enumerable: true,
486
- configurable: true
487
- });
488
- Object.defineProperty(class_1, "after", {
489
- get: function () { return handler.after; },
490
- enumerable: true,
491
- configurable: true
492
- });
493
- Object.defineProperty(class_1, "allowVirtualElements", {
494
- get: function () {
495
- return handler.allowVirtualElements || virtualElements.allowedBindings[key];
496
- },
497
- enumerable: true,
498
- configurable: true
499
- });
500
- return class_1;
501
- }(LegacyBindingHandler));
502
- }
503
- if (typeof handler === 'object') {
504
- return /** @class */ (function (_super) {
505
- __extends(class_2, _super);
506
- function class_2() {
507
- return _super !== null && _super.apply(this, arguments) || this;
508
- }
509
- Object.defineProperty(class_2.prototype, "handler", {
510
- get: function () { return handler; },
511
- enumerable: true,
512
- configurable: true
513
- });
514
- Object.defineProperty(class_2, "after", {
515
- get: function () { return handler.after; },
516
- enumerable: true,
517
- configurable: true
518
- });
519
- Object.defineProperty(class_2, "allowVirtualElements", {
520
- get: function () {
521
- return handler.allowVirtualElements || virtualElements.allowedBindings[key];
522
- },
523
- enumerable: true,
524
- configurable: true
525
- });
526
- return class_2;
527
- }(LegacyBindingHandler));
528
- }
529
- throw new Error('The given handler is not an appropriate type.');
530
- };
531
- return LegacyBindingHandler;
532
- }(BindingHandler));
533
-
534
- /* eslint no-cond-assign: 0 */
535
- // The following element types will not be recursed into during binding.
536
- var bindingDoesNotRecurseIntoElementTypes = {
537
- // Don't want bindings that operate on text nodes to mutate <script> and <textarea> contents,
538
- // because it's unexpected and a potential XSS issue.
539
- // Also bindings should not operate on <template> elements since this breaks in Internet Explorer
540
- // and because such elements' contents are always intended to be bound in a different context
541
- // from where they appear in the document.
542
- 'script': true,
543
- 'textarea': true,
544
- 'template': true
545
- };
546
- function getBindingProvider() {
547
- return options.bindingProviderInstance.instance || options.bindingProviderInstance;
548
- }
549
- function isProviderForNode(provider, node) {
550
- var nodeTypes = provider.FOR_NODE_TYPES || [1, 3, 8];
551
- return nodeTypes.includes(node.nodeType);
552
- }
553
- function asProperHandlerClass(handler, bindingKey) {
554
- if (!handler) {
555
- return;
556
- }
557
- return handler.isBindingHandlerClass ? handler
558
- : LegacyBindingHandler.getOrCreateFor(bindingKey, handler);
559
- }
560
- function getBindingHandlerFromComponent(bindingKey, $component) {
561
- if (!$component || typeof $component.getBindingHandler !== 'function') {
562
- return;
563
- }
564
- return asProperHandlerClass($component.getBindingHandler(bindingKey));
565
- }
566
- function getBindingHandler(bindingKey) {
567
- var bindingDefinition = options.getBindingHandler(bindingKey) || getBindingProvider().bindingHandlers.get(bindingKey);
568
- return asProperHandlerClass(bindingDefinition, bindingKey);
569
- }
570
- // Returns the value of a valueAccessor function
571
- function evaluateValueAccessor(valueAccessor) {
572
- return valueAccessor();
573
- }
574
- function applyBindingsToDescendantsInternal(bindingContext$$1, elementOrVirtualElement, asyncBindingsApplied) {
575
- var nextInQueue = virtualElements.firstChild(elementOrVirtualElement);
576
- if (!nextInQueue) {
577
- return;
578
- }
579
- var currentChild;
580
- var provider = getBindingProvider();
581
- var preprocessNode = provider.preprocessNode;
582
- // Preprocessing allows a binding provider to mutate a node before bindings are applied to it. For example it's
583
- // possible to insert new siblings after it, and/or replace the node with a different one. This can be used to
584
- // implement custom binding syntaxes, such as {{ value }} for string interpolation, or custom element types that
585
- // trigger insertion of <template> contents at that point in the document.
586
- if (preprocessNode) {
587
- while (currentChild = nextInQueue) {
588
- nextInQueue = virtualElements.nextSibling(currentChild);
589
- preprocessNode.call(provider, currentChild);
590
- }
591
- // Reset nextInQueue for the next loop
592
- nextInQueue = virtualElements.firstChild(elementOrVirtualElement);
593
- }
594
- while (currentChild = nextInQueue) {
595
- // Keep a record of the next child *before* applying bindings, in case the binding removes the current child from its position
596
- nextInQueue = virtualElements.nextSibling(currentChild);
597
- applyBindingsToNodeAndDescendantsInternal(bindingContext$$1, currentChild, asyncBindingsApplied);
598
- }
599
- bindingEvent.notify(elementOrVirtualElement, bindingEvent.childrenComplete);
600
- }
601
- function hasBindings(node) {
602
- var provider = getBindingProvider();
603
- return isProviderForNode(provider, node) && provider.nodeHasBindings(node);
604
- }
605
- function nodeOrChildHasBindings(node) {
606
- return hasBindings(node) || __spread(node.childNodes).some(function (c) { return nodeOrChildHasBindings(c); });
607
- }
608
- function applyBindingsToNodeAndDescendantsInternal(bindingContext$$1, nodeVerified, asyncBindingsApplied) {
609
- var isElement = nodeVerified.nodeType === 1;
610
- if (isElement) { // Workaround IE <= 8 HTML parsing weirdness
611
- virtualElements.normaliseVirtualElementDomStructure(nodeVerified);
612
- }
613
- // Perf optimisation: Apply bindings only if...
614
- // (1) We need to store the binding info for the node (all element nodes)
615
- // (2) It might have bindings (e.g., it has a data-bind attribute, or it's a marker for a containerless template)
616
- var shouldApplyBindings = isElement || // Case (1)
617
- hasBindings(nodeVerified); // Case (2)
618
- var shouldBindDescendants = (shouldApplyBindings
619
- ? applyBindingsToNodeInternal(nodeVerified, null, bindingContext$$1, asyncBindingsApplied)
620
- : { shouldBindDescendants: true }).shouldBindDescendants;
621
- if (shouldBindDescendants && !bindingDoesNotRecurseIntoElementTypes[tagNameLower(nodeVerified)]) {
622
- // We're recursing automatically into (real or virtual) child nodes without changing binding contexts. So,
623
- // * For children of a *real* element, the binding context is certainly the same as on their DOM .parentNode,
624
- // hence bindingContextsMayDifferFromDomParentElement is false
625
- // * For children of a *virtual* element, we can't be sure. Evaluating .parentNode on those children may
626
- // skip over any number of intermediate virtual elements, any of which might define a custom binding context,
627
- // hence bindingContextsMayDifferFromDomParentElement is true
628
- applyBindingsToDescendantsInternal(bindingContext$$1, nodeVerified, asyncBindingsApplied);
629
- }
630
- }
631
- function topologicalSortBindings(bindings, $component) {
632
- var e_1, _a, results, bindingsConsidered, cyclicDependencyStack, results_1, results_1_1, result, e_1_1;
633
- return __generator(this, function (_b) {
634
- switch (_b.label) {
635
- case 0:
636
- results = [];
637
- bindingsConsidered = {} // A temporary record of which bindings are already in 'result'
638
- ;
639
- cyclicDependencyStack = [] // Keeps track of a depth-search so that, if there's a cycle, we know which bindings caused it
640
- ;
641
- objectForEach(bindings, function pushBinding(bindingKey) {
642
- if (!bindingsConsidered[bindingKey]) {
643
- var binding = getBindingHandlerFromComponent(bindingKey, $component) || getBindingHandler(bindingKey);
644
- if (!binding) {
645
- return;
646
- }
647
- // First add dependencies (if any) of the current binding
648
- if (binding.after) {
649
- cyclicDependencyStack.push(bindingKey);
650
- arrayForEach(binding.after, function (bindingDependencyKey) {
651
- if (!bindings[bindingDependencyKey]) {
652
- return;
653
- }
654
- if (arrayIndexOf(cyclicDependencyStack, bindingDependencyKey) !== -1) {
655
- throw Error('Cannot combine the following bindings, because they have a cyclic dependency: ' + cyclicDependencyStack.join(', '));
656
- }
657
- else {
658
- pushBinding(bindingDependencyKey);
659
- }
660
- });
661
- cyclicDependencyStack.length--;
662
- }
663
- // Next add the current binding
664
- results.push([bindingKey, binding]);
665
- }
666
- bindingsConsidered[bindingKey] = true;
667
- });
668
- _b.label = 1;
669
- case 1:
670
- _b.trys.push([1, 6, 7, 8]);
671
- results_1 = __values(results), results_1_1 = results_1.next();
672
- _b.label = 2;
673
- case 2:
674
- if (!!results_1_1.done) return [3 /*break*/, 5];
675
- result = results_1_1.value;
676
- return [4 /*yield*/, result];
677
- case 3:
678
- _b.sent();
679
- _b.label = 4;
680
- case 4:
681
- results_1_1 = results_1.next();
682
- return [3 /*break*/, 2];
683
- case 5: return [3 /*break*/, 8];
684
- case 6:
685
- e_1_1 = _b.sent();
686
- e_1 = { error: e_1_1 };
687
- return [3 /*break*/, 8];
688
- case 7:
689
- try {
690
- if (results_1_1 && !results_1_1.done && (_a = results_1["return"])) _a.call(results_1);
691
- }
692
- finally { if (e_1) throw e_1.error; }
693
- return [7 /*endfinally*/];
694
- case 8: return [2 /*return*/];
695
- }
696
- });
697
- }
698
- function applyBindingsToNodeInternal(node, sourceBindings, bindingContext$$1, asyncBindingsApplied) {
699
- var e_2, _a;
700
- var bindingInfo = domData.getOrSet(node, boundElementDomDataKey$1, {});
701
- // Prevent multiple applyBindings calls for the same node, except when a binding value is specified
702
- var alreadyBound = bindingInfo.alreadyBound;
703
- if (!sourceBindings) {
704
- if (alreadyBound) {
705
- if (!nodeOrChildHasBindings(node)) {
706
- return false;
707
- }
708
- onBindingError({
709
- during: 'apply',
710
- errorCaptured: new Error('You cannot apply bindings multiple times to the same element.'),
711
- element: node,
712
- bindingContext: bindingContext$$1
713
- });
714
- return false;
715
- }
716
- bindingInfo.alreadyBound = true;
717
- }
718
- if (!alreadyBound) {
719
- bindingInfo.context = bindingContext$$1;
720
- }
721
- // Use bindings if given, otherwise fall back on asking the bindings provider to give us some bindings
722
- var bindings;
723
- if (sourceBindings && typeof sourceBindings !== 'function') {
724
- bindings = sourceBindings;
725
- }
726
- else {
727
- var provider_1 = getBindingProvider();
728
- var getBindings_1 = provider_1.getBindingAccessors;
729
- if (isProviderForNode(provider_1, node)) {
730
- // Get the binding from the provider within a computed observable so that we can update the bindings whenever
731
- // the binding context is updated or if the binding provider accesses observables.
732
- var bindingsUpdater = computed(function () {
733
- bindings = sourceBindings ? sourceBindings(bindingContext$$1, node) : getBindings_1.call(provider_1, node, bindingContext$$1);
734
- // Register a dependency on the binding context to support observable view models.
735
- if (bindings && bindingContext$$1[contextSubscribeSymbol]) {
736
- bindingContext$$1[contextSubscribeSymbol]();
737
- }
738
- return bindings;
739
- }, null, { disposeWhenNodeIsRemoved: node });
740
- if (!bindings || !bindingsUpdater.isActive()) {
741
- bindingsUpdater = null;
742
- }
743
- }
744
- }
745
- var bindingHandlerThatControlsDescendantBindings;
746
- if (bindings) {
747
- var $component = bindingContext$$1.$component || {};
748
- var allBindingHandlers = {};
749
- domData.set(node, 'bindingHandlers', allBindingHandlers);
750
- // Return the value accessor for a given binding. When bindings are static (won't be updated because of a binding
751
- // context update), just return the value accessor from the binding. Otherwise, return a function that always gets
752
- // the latest binding value and registers a dependency on the binding updater.
753
- var getValueAccessor_1 = bindingsUpdater
754
- ? function (bindingKey) { return function (optionalValue) {
755
- var valueAccessor = bindingsUpdater()[bindingKey];
756
- if (arguments.length === 0) {
757
- return evaluateValueAccessor(valueAccessor);
758
- }
759
- else {
760
- return valueAccessor(optionalValue);
761
- }
762
- }; } : function (bindingKey) { return bindings[bindingKey]; };
763
- // Use of allBindings as a function is maintained for backwards compatibility, but its use is deprecated
764
- function allBindings() {
765
- return objectMap(bindingsUpdater ? bindingsUpdater() : bindings, evaluateValueAccessor);
766
- }
767
- // The following is the 3.x allBindings API
768
- allBindings.has = function (key) { return key in bindings; };
769
- allBindings.get = function (key) { return bindings[key] && evaluateValueAccessor(getValueAccessor_1(key)); };
770
- if (bindingEvent.childrenComplete in bindings) {
771
- bindingEvent.subscribe(node, bindingEvent.childrenComplete, function () {
772
- var callback = evaluateValueAccessor(bindings[bindingEvent.childrenComplete]);
773
- if (!callback) {
774
- return;
775
- }
776
- var nodes = virtualElements.childNodes(node);
777
- if (nodes.length) {
778
- callback(nodes, dataFor(nodes[0]));
779
- }
780
- });
781
- }
782
- var bindingsGenerated = topologicalSortBindings(bindings, $component);
783
- var nodeAsyncBindingPromises = new Set();
784
- var _loop_1 = function (key, BindingHandlerClass) {
785
- // Go through the sorted bindings, calling init and update for each
786
- function reportBindingError(during, errorCaptured) {
787
- onBindingError({
788
- during: during,
789
- errorCaptured: errorCaptured,
790
- bindings: bindings,
791
- allBindings: allBindings,
792
- bindingKey: key,
793
- bindingContext: bindingContext$$1,
794
- element: node,
795
- valueAccessor: getValueAccessor_1(key)
796
- });
797
- }
798
- if (node.nodeType === 8 && !BindingHandlerClass.allowVirtualElements) {
799
- throw new Error("The binding '" + key + "' cannot be used with virtual elements");
800
- }
801
- try {
802
- var bindingHandler_1 = dependencyDetection.ignore(function () {
803
- return new BindingHandlerClass({
804
- allBindings: allBindings,
805
- $element: node,
806
- $context: bindingContext$$1,
807
- onError: reportBindingError,
808
- valueAccessor: function () {
809
- var v = [];
810
- for (var _i = 0; _i < arguments.length; _i++) {
811
- v[_i] = arguments[_i];
812
- }
813
- return getValueAccessor_1(key).apply(void 0, __spread(v));
814
- }
815
- });
816
- });
817
- if (bindingHandler_1.onValueChange) {
818
- dependencyDetection.ignore(function () {
819
- return bindingHandler_1.computed('onValueChange');
820
- });
821
- }
822
- // Expose the bindings via domData.
823
- allBindingHandlers[key] = bindingHandler_1;
824
- if (bindingHandler_1.controlsDescendants) {
825
- if (bindingHandlerThatControlsDescendantBindings !== undefined) {
826
- throw new Error('Multiple bindings (' + bindingHandlerThatControlsDescendantBindings + ' and ' + key + ') are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.');
827
- }
828
- bindingHandlerThatControlsDescendantBindings = key;
829
- }
830
- if (bindingHandler_1.bindingCompleted instanceof Promise) {
831
- asyncBindingsApplied.add(bindingHandler_1.bindingCompleted);
832
- nodeAsyncBindingPromises.add(bindingHandler_1.bindingCompleted);
833
- }
834
- }
835
- catch (err) {
836
- reportBindingError('creation', err);
837
- }
838
- };
839
- try {
840
- for (var bindingsGenerated_1 = __values(bindingsGenerated), bindingsGenerated_1_1 = bindingsGenerated_1.next(); !bindingsGenerated_1_1.done; bindingsGenerated_1_1 = bindingsGenerated_1.next()) {
841
- var _b = __read(bindingsGenerated_1_1.value, 2), key = _b[0], BindingHandlerClass = _b[1];
842
- _loop_1(key, BindingHandlerClass);
843
- }
844
- }
845
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
846
- finally {
847
- try {
848
- if (bindingsGenerated_1_1 && !bindingsGenerated_1_1.done && (_a = bindingsGenerated_1["return"])) _a.call(bindingsGenerated_1);
849
- }
850
- finally { if (e_2) throw e_2.error; }
851
- }
852
- triggerDescendantsComplete(node, bindings, nodeAsyncBindingPromises);
853
- }
854
- var shouldBindDescendants = bindingHandlerThatControlsDescendantBindings === undefined;
855
- return { shouldBindDescendants: shouldBindDescendants };
856
- }
857
- /**
858
- *
859
- * @param {HTMLElement} node
860
- * @param {Object} bindings
861
- * @param {[Promise]} nodeAsyncBindingPromises
862
- */
863
- function triggerDescendantsComplete(node, bindings, nodeAsyncBindingPromises) {
864
- /** descendantsComplete ought to be an instance of the descendantsComplete
865
- * binding handler. */
866
- var hasBindingHandler = bindingEvent.descendantsComplete in bindings;
867
- var hasFirstChild = virtualElements.firstChild(node);
868
- var accessor = hasBindingHandler && evaluateValueAccessor(bindings[bindingEvent.descendantsComplete]);
869
- var callback = function () {
870
- bindingEvent.notify(node, bindingEvent.descendantsComplete);
871
- if (accessor && hasFirstChild) {
872
- accessor(node);
873
- }
874
- };
875
- if (nodeAsyncBindingPromises.size) {
876
- Promise.all(nodeAsyncBindingPromises).then(callback);
877
- }
878
- else {
879
- callback();
880
- }
881
- }
882
- function getBindingContext(viewModelOrBindingContext, extendContextCallback) {
883
- return viewModelOrBindingContext && (viewModelOrBindingContext instanceof bindingContext)
884
- ? viewModelOrBindingContext
885
- : new bindingContext(viewModelOrBindingContext, undefined, undefined, extendContextCallback);
886
- }
887
- function applyBindingAccessorsToNode(node, bindings, viewModelOrBindingContext, asyncBindingsApplied) {
888
- if (node.nodeType === 1) { // If it's an element, workaround IE <= 8 HTML parsing weirdness
889
- virtualElements.normaliseVirtualElementDomStructure(node);
890
- }
891
- return applyBindingsToNodeInternal(node, bindings, getBindingContext(viewModelOrBindingContext), asyncBindingsApplied);
892
- }
893
- function applyBindingsToNode(node, bindings, viewModelOrBindingContext) {
894
- var asyncBindingsApplied = new Set();
895
- var bindingContext$$1 = getBindingContext(viewModelOrBindingContext);
896
- var bindingAccessors = getBindingProvider().makeBindingAccessors(bindings, bindingContext$$1, node);
897
- applyBindingAccessorsToNode(node, bindingAccessors, bindingContext$$1, asyncBindingsApplied);
898
- return new BindingResult({ asyncBindingsApplied: asyncBindingsApplied, rootNode: node, bindingContext: bindingContext$$1 });
899
- }
900
- function applyBindingsToDescendants(viewModelOrBindingContext, rootNode) {
901
- var asyncBindingsApplied = new Set();
902
- if (rootNode.nodeType === 1 || rootNode.nodeType === 8) {
903
- var bindingContext_1 = getBindingContext(viewModelOrBindingContext);
904
- applyBindingsToDescendantsInternal(bindingContext_1, rootNode, asyncBindingsApplied);
905
- return new BindingResult({ asyncBindingsApplied: asyncBindingsApplied, rootNode: rootNode, bindingContext: bindingContext_1 });
906
- }
907
- return new BindingResult({ asyncBindingsApplied: asyncBindingsApplied, rootNode: rootNode });
908
- }
909
- function applyBindings(viewModelOrBindingContext, rootNode, extendContextCallback) {
910
- var asyncBindingsApplied = new Set();
911
- // If jQuery is loaded after Knockout, we won't initially have access to it. So save it here.
912
- if (!options.jQuery === undefined && options.jQuery) {
913
- options.jQuery = options.jQuery;
914
- }
915
- // rootNode is optional
916
- if (!rootNode) {
917
- rootNode = window.document.body;
918
- if (!rootNode) {
919
- throw Error('ko.applyBindings: could not find window.document.body; has the document been loaded?');
920
- }
921
- }
922
- else if (rootNode.nodeType !== 1 && rootNode.nodeType !== 8) {
923
- throw Error('ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node');
924
- }
925
- var rootContext = getBindingContext(viewModelOrBindingContext, extendContextCallback);
926
- applyBindingsToNodeAndDescendantsInternal(rootContext, rootNode, asyncBindingsApplied);
927
- return Promise.all(asyncBindingsApplied);
928
- }
929
- function onBindingError(spec) {
930
- var error;
931
- if (spec.bindingKey) {
932
- // During: 'init' or initial 'update'
933
- error = spec.errorCaptured;
934
- spec.message = 'Unable to process binding "' + spec.bindingKey +
935
- '" in binding "' + spec.bindingKey +
936
- '"\nMessage: ' + (error.message ? error.message : error);
937
- }
938
- else {
939
- // During: 'apply'
940
- error = spec.errorCaptured;
941
- }
942
- try {
943
- extend(error, spec);
944
- }
945
- catch (e) {
946
- // Read-only error e.g. a DOMEXception.
947
- spec.stack = error.stack;
948
- error = new Error(error.message ? error.message : error);
949
- extend(error, spec);
950
- }
951
- options.onError(error);
952
- }
953
-
954
- /* eslint no-cond-assign: 0 */
955
- // Objective:
956
- // * Given an input array, a container DOM node, and a function from array elements to arrays of DOM nodes,
957
- // map the array elements to arrays of DOM nodes, concatenate together all these arrays, and use them to populate the container DOM node
958
- // * Next time we're given the same combination of things (with the array possibly having mutated), update the container DOM node
959
- // so that its children is again the concatenation of the mappings of the array elements, but don't re-map any array elements that we
960
- // previously mapped - retain those nodes, and just insert/delete other ones
961
- // "callbackAfterAddingNodes" will be invoked after any "mapping"-generated nodes are inserted into the container node
962
- // You can use this, for example, to activate bindings on those nodes.
963
- function mapNodeAndRefreshWhenChanged(containerNode, mapping, valueToMap, callbackAfterAddingNodes, index) {
964
- // Map this array value inside a dependentObservable so we re-map when any dependency changes
965
- var mappedNodes = [];
966
- var dependentObservable = computed(function () {
967
- var newMappedNodes = mapping(valueToMap, index, fixUpContinuousNodeArray(mappedNodes, containerNode)) || [];
968
- // On subsequent evaluations, just replace the previously-inserted DOM nodes
969
- if (mappedNodes.length > 0) {
970
- replaceDomNodes(mappedNodes, newMappedNodes);
971
- if (callbackAfterAddingNodes) {
972
- dependencyDetection.ignore(callbackAfterAddingNodes, null, [valueToMap, newMappedNodes, index]);
973
- }
974
- }
975
- // Replace the contents of the mappedNodes array, thereby updating the record
976
- // of which nodes would be deleted if valueToMap was itself later removed
977
- mappedNodes.length = 0;
978
- arrayPushAll(mappedNodes, newMappedNodes);
979
- }, null, { disposeWhenNodeIsRemoved: containerNode, disposeWhen: function () { return !anyDomNodeIsAttachedToDocument(mappedNodes); } });
980
- return { mappedNodes: mappedNodes, dependentObservable: (dependentObservable.isActive() ? dependentObservable : undefined) };
981
- }
982
- var lastMappingResultDomDataKey = domData.nextKey();
983
- var deletedItemDummyValue = domData.nextKey();
984
- function setDomNodeChildrenFromArrayMapping(domNode, array, mapping, options$$1, callbackAfterAddingNodes, editScript) {
985
- // Compare the provided array against the previous one
986
- array = array || [];
987
- if (typeof array.length === 'undefined') {
988
- array = [array];
989
- }
990
- options$$1 = options$$1 || {};
991
- var lastMappingResult = domData.get(domNode, lastMappingResultDomDataKey);
992
- var isFirstExecution = !lastMappingResult;
993
- // Build the new mapping result
994
- var newMappingResult = [];
995
- var lastMappingResultIndex = 0;
996
- var newMappingResultIndex = 0;
997
- var nodesToDelete = [];
998
- var itemsToProcess = [];
999
- var itemsForBeforeRemoveCallbacks = [];
1000
- var itemsForMoveCallbacks = [];
1001
- var itemsForAfterAddCallbacks = [];
1002
- var mapData;
1003
- var countWaitingForRemove = 0;
1004
- function itemAdded(value) {
1005
- mapData = { arrayEntry: value, indexObservable: observable(newMappingResultIndex++) };
1006
- newMappingResult.push(mapData);
1007
- itemsToProcess.push(mapData);
1008
- if (!isFirstExecution) {
1009
- itemsForAfterAddCallbacks.push(mapData);
1010
- }
1011
- }
1012
- function itemMovedOrRetained(oldPosition) {
1013
- mapData = lastMappingResult[oldPosition];
1014
- if (newMappingResultIndex !== oldPosition) {
1015
- itemsForMoveCallbacks.push(mapData);
1016
- }
1017
- // Since updating the index might change the nodes, do so before calling fixUpContinuousNodeArray
1018
- mapData.indexObservable(newMappingResultIndex++);
1019
- fixUpContinuousNodeArray(mapData.mappedNodes, domNode);
1020
- newMappingResult.push(mapData);
1021
- itemsToProcess.push(mapData);
1022
- }
1023
- function callCallback(callback, items) {
1024
- if (callback) {
1025
- for (var i = 0, n = items.length; i < n; i++) {
1026
- arrayForEach(items[i].mappedNodes, function (node) {
1027
- callback(node, i, items[i].arrayEntry);
1028
- });
1029
- }
1030
- }
1031
- }
1032
- if (isFirstExecution) {
1033
- arrayForEach(array, itemAdded);
1034
- }
1035
- else {
1036
- if (!editScript || (lastMappingResult && lastMappingResult['_countWaitingForRemove'])) {
1037
- // Compare the provided array against the previous one
1038
- var lastArray = isFirstExecution ? [] : arrayMap(lastMappingResult, function (x) { return x.arrayEntry; });
1039
- var compareOptions = {
1040
- 'dontLimitMoves': options$$1['dontLimitMoves'],
1041
- 'sparse': true
1042
- };
1043
- editScript = compareArrays(lastArray, array, compareOptions);
1044
- }
1045
- for (var i = 0, editScriptItem, movedIndex, itemIndex; editScriptItem = editScript[i]; i++) {
1046
- movedIndex = editScriptItem['moved'];
1047
- itemIndex = editScriptItem['index'];
1048
- switch (editScriptItem['status']) {
1049
- case 'deleted':
1050
- while (lastMappingResultIndex < itemIndex) {
1051
- itemMovedOrRetained(lastMappingResultIndex++);
1052
- }
1053
- if (movedIndex === undefined) {
1054
- mapData = lastMappingResult[lastMappingResultIndex];
1055
- // Stop tracking changes to the mapping for these nodes
1056
- if (mapData.dependentObservable) {
1057
- mapData.dependentObservable.dispose();
1058
- mapData.dependentObservable = undefined;
1059
- }
1060
- // Queue these nodes for later removal
1061
- if (fixUpContinuousNodeArray(mapData.mappedNodes, domNode).length) {
1062
- if (options$$1['beforeRemove']) {
1063
- newMappingResult.push(mapData);
1064
- itemsToProcess.push(mapData);
1065
- countWaitingForRemove++;
1066
- if (mapData.arrayEntry === deletedItemDummyValue) {
1067
- mapData = null;
1068
- }
1069
- else {
1070
- itemsForBeforeRemoveCallbacks.push(mapData);
1071
- }
1072
- }
1073
- if (mapData) {
1074
- nodesToDelete.push.apply(nodesToDelete, mapData.mappedNodes);
1075
- }
1076
- }
1077
- }
1078
- lastMappingResultIndex++;
1079
- break;
1080
- case 'added':
1081
- while (newMappingResultIndex < itemIndex) {
1082
- itemMovedOrRetained(lastMappingResultIndex++);
1083
- }
1084
- if (movedIndex !== undefined) {
1085
- itemMovedOrRetained(movedIndex);
1086
- }
1087
- else {
1088
- itemAdded(editScriptItem['value']);
1089
- }
1090
- break;
1091
- }
1092
- }
1093
- while (newMappingResultIndex < array.length) {
1094
- itemMovedOrRetained(lastMappingResultIndex++);
1095
- }
1096
- // Record that the current view may still contain deleted items
1097
- // because it means we won't be able to use a provided editScript.
1098
- newMappingResult['_countWaitingForRemove'] = countWaitingForRemove;
1099
- }
1100
- // Store a copy of the array items we just considered so we can difference it next time
1101
- domData.set(domNode, lastMappingResultDomDataKey, newMappingResult);
1102
- // Call beforeMove first before any changes have been made to the DOM
1103
- callCallback(options$$1['beforeMove'], itemsForMoveCallbacks);
1104
- // Next remove nodes for deleted items (or just clean if there's a beforeRemove callback)
1105
- arrayForEach(nodesToDelete, options$$1['beforeRemove'] ? cleanNode : removeNode);
1106
- // Next add/reorder the remaining items (will include deleted items if there's a beforeRemove callback)
1107
- i = 0;
1108
- for (var nextNode = virtualElements.firstChild(domNode), lastNode, node; mapData = itemsToProcess[i]; i++) {
1109
- // Get nodes for newly added items
1110
- if (!mapData.mappedNodes) {
1111
- extend(mapData, mapNodeAndRefreshWhenChanged(domNode, mapping, mapData.arrayEntry, callbackAfterAddingNodes, mapData.indexObservable));
1112
- }
1113
- // Put nodes in the right place if they aren't there already
1114
- for (var j = 0; node = mapData.mappedNodes[j]; nextNode = node.nextSibling, lastNode = node, j++) {
1115
- if (node !== nextNode) {
1116
- virtualElements.insertAfter(domNode, node, lastNode);
1117
- }
1118
- }
1119
- // Run the callbacks for newly added nodes (for example, to apply bindings, etc.)
1120
- if (!mapData.initialized && callbackAfterAddingNodes) {
1121
- callbackAfterAddingNodes(mapData.arrayEntry, mapData.mappedNodes, mapData.indexObservable);
1122
- mapData.initialized = true;
1123
- }
1124
- }
1125
- // If there's a beforeRemove callback, call it after reordering.
1126
- // Note that we assume that the beforeRemove callback will usually be used to remove the nodes using
1127
- // some sort of animation, which is why we first reorder the nodes that will be removed. If the
1128
- // callback instead removes the nodes right away, it would be more efficient to skip reordering them.
1129
- // Perhaps we'll make that change in the future if this scenario becomes more common.
1130
- callCallback(options$$1['beforeRemove'], itemsForBeforeRemoveCallbacks);
1131
- // Replace the stored values of deleted items with a dummy value. This provides two benefits: it marks this item
1132
- // as already "removed" so we won't call beforeRemove for it again, and it ensures that the item won't match up
1133
- // with an actual item in the array and appear as "retained" or "moved".
1134
- for (i = 0; i < itemsForBeforeRemoveCallbacks.length; ++i) {
1135
- itemsForBeforeRemoveCallbacks[i].arrayEntry = deletedItemDummyValue;
1136
- }
1137
- // Finally call afterMove and afterAdd callbacks
1138
- callCallback(options$$1['afterMove'], itemsForMoveCallbacks);
1139
- callCallback(options$$1['afterAdd'], itemsForAfterAddCallbacks);
1140
- }
1141
-
1142
- /**
1143
- * This DescendantBindingHandler is a base class for bindings that control
1144
- * descendants, such as the `if`, `with`, `component`, `foreach` and `template`
1145
- * bindings.
1146
- */
1147
- var DescendantBindingHandler = /** @class */ (function (_super) {
1148
- __extends(DescendantBindingHandler, _super);
1149
- function DescendantBindingHandler() {
1150
- return _super !== null && _super.apply(this, arguments) || this;
1151
- }
1152
- Object.defineProperty(DescendantBindingHandler.prototype, "controlsDescendants", {
1153
- get: function () { return true; },
1154
- enumerable: true,
1155
- configurable: true
1156
- });
1157
- DescendantBindingHandler.prototype.applyBindingsToDescendants = function (childContext, callback) {
1158
- return __awaiter(this, void 0, void 0, function () {
1159
- var bindingResult;
1160
- return __generator(this, function (_a) {
1161
- switch (_a.label) {
1162
- case 0:
1163
- bindingResult = applyBindingsToDescendants(childContext, this.$element);
1164
- if (!bindingResult.isSync) return [3 /*break*/, 1];
1165
- this.bindingCompletion = bindingResult;
1166
- return [3 /*break*/, 3];
1167
- case 1: return [4 /*yield*/, bindingResult.completionPromise];
1168
- case 2:
1169
- _a.sent();
1170
- _a.label = 3;
1171
- case 3:
1172
- if (callback) {
1173
- callback(bindingResult);
1174
- }
1175
- this.completeBinding(bindingResult);
1176
- return [2 /*return*/];
1177
- }
1178
- });
1179
- });
1180
- };
1181
- return DescendantBindingHandler;
1182
- }(AsyncBindingHandler));
1183
-
1184
- export { BindingHandler, AsyncBindingHandler, DescendantBindingHandler, bindingEvent, boundElementDomDataKey$1 as boundElementDomDataKey, contextSubscribeSymbol, bindingContext, storedBindingContextForNode, contextFor, dataFor, getBindingHandler, applyBindingAccessorsToNode, applyBindingsToNode, applyBindingsToDescendants, applyBindings, setDomNodeChildrenFromArrayMapping };
1185
- //# sourceMappingURL=bind.js.map