@tko/bind 4.0.0-beta1.3 → 4.0.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/BindingHandler.js +17 -9
- package/dist/BindingHandler.js.map +2 -2
- package/dist/BindingResult.js +10 -33
- package/dist/BindingResult.js.map +2 -2
- package/dist/DescendantBindingHandler.js +13 -34
- package/dist/DescendantBindingHandler.js.map +2 -2
- package/dist/LegacyBindingHandler.js +15 -8
- package/dist/LegacyBindingHandler.js.map +2 -2
- package/dist/applyBindings.js +91 -76
- package/dist/applyBindings.js.map +3 -3
- package/dist/arrayToDomNodeChildren.js +66 -53
- package/dist/arrayToDomNodeChildren.js.map +2 -2
- package/dist/bindingContext.js +37 -30
- package/dist/bindingContext.js.map +2 -2
- package/dist/bindingEvent.js +7 -4
- package/dist/bindingEvent.js.map +2 -2
- package/dist/index.cjs +728 -513
- package/dist/index.cjs.map +4 -4
- package/dist/index.js +4 -8
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +4 -8
- package/dist/index.mjs.map +2 -2
- package/package.json +8 -9
- package/LICENSE +0 -22
package/dist/BindingHandler.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// @tko/bind 🥊 4.0.0
|
|
1
|
+
// @tko/bind 🥊 4.0.0 ESM
|
|
2
|
+
"use strict";
|
|
2
3
|
import { options } from "@tko/utils";
|
|
3
4
|
import { isWriteableObservable } from "@tko/observable";
|
|
4
5
|
import { LifeCycle } from "@tko/lifecycle";
|
|
@@ -6,13 +7,11 @@ export class BindingHandler extends LifeCycle {
|
|
|
6
7
|
constructor(params) {
|
|
7
8
|
super();
|
|
8
9
|
const { $element, valueAccessor, allBindings, $context } = params;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
$data: $context.$data
|
|
15
|
-
});
|
|
10
|
+
this.$element = $element;
|
|
11
|
+
this.valueAccessor = valueAccessor;
|
|
12
|
+
this.allBindings = allBindings;
|
|
13
|
+
this.$context = $context;
|
|
14
|
+
this.$data = $context.$data;
|
|
16
15
|
this.anchorTo($element);
|
|
17
16
|
}
|
|
18
17
|
get value() {
|
|
@@ -35,14 +34,23 @@ export class BindingHandler extends LifeCycle {
|
|
|
35
34
|
static get isBindingHandlerClass() {
|
|
36
35
|
return true;
|
|
37
36
|
}
|
|
37
|
+
/* Overload this for asynchronous bindings or bindings that recursively
|
|
38
|
+
apply bindings (e.g. components, foreach, template).
|
|
39
|
+
|
|
40
|
+
A binding should be complete when it has run through once, notably
|
|
41
|
+
in server-side bindings for pre-rendering.
|
|
42
|
+
*/
|
|
38
43
|
get bindingCompleted() {
|
|
39
44
|
return true;
|
|
40
45
|
}
|
|
41
46
|
static registerAs(name, provider = options.bindingProviderInstance) {
|
|
42
47
|
provider.bindingHandlers.set(name, this);
|
|
43
48
|
}
|
|
49
|
+
static registerBindingHandler(handler, name, provider = options.bindingProviderInstance) {
|
|
50
|
+
provider.bindingHandlers.set(name, handler);
|
|
51
|
+
}
|
|
44
52
|
}
|
|
45
|
-
const ResolveSymbol = Symbol("Async Binding Resolved");
|
|
53
|
+
const ResolveSymbol = /* @__PURE__ */ Symbol("Async Binding Resolved");
|
|
46
54
|
export class AsyncBindingHandler extends BindingHandler {
|
|
47
55
|
constructor(params) {
|
|
48
56
|
super(params);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BindingHandler.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["import { options } from '@tko/utils'\nimport { isWriteableObservable } from '@tko/observable'\nimport { LifeCycle } from '@tko/lifecycle'\nimport type { BindingContext } from './bindingContext'\n\nexport type BindingHandlerControlsDescendant = { controlsDescendantBindings: boolean }\nexport type BindingHandlerAddBinding = (name: string, value: any) => void\n\n// usage in applyBindings, BindingHandler, event, checked, options\nexport interface AllBindings {\n (): any\n\n get(name: string): any\n get<T = any>(name: string): T\n\n has(name: string): boolean\n}\n\nexport class BindingHandler<T = any> extends LifeCycle {\n after?: string[]\n init?: (\n element: any,\n valueAccessor: () => T,\n allBindings: AllBindings,\n viewModel: any,\n bindingContext: BindingContext<any>\n ) => void | BindingHandlerControlsDescendant\n update?: (\n element: any,\n valueAccessor: () => T,\n allBindings: AllBindings,\n viewModel: any,\n bindingContext: BindingContext<any>\n ) => void\n options?: any\n preprocess?: (\n value: string | undefined,\n name: string,\n addBinding: BindingHandlerAddBinding\n ) => string | undefined | void\n\n $context: BindingContext // most likly BindingContext but params must be typed first\n $element: HTMLElement\n $data: any\n bindingCompletion: any\n valueAccessor: Function\n completeBinding: any\n allBindings: AllBindings\n\n constructor(params) {\n super()\n const { $element, valueAccessor, allBindings, $context } = params\n\n this.$element = $element\n this.valueAccessor = valueAccessor\n this.allBindings = allBindings\n this.$context = $context\n this.$data = $context.$data\n\n this.anchorTo($element)\n }\n\n get value() {\n return this.valueAccessor()\n }\n set value(v) {\n const va = this.valueAccessor()\n if (isWriteableObservable(va)) {\n va(v)\n } else {\n this.valueAccessor(v)\n }\n }\n\n get controlsDescendants() {\n return false\n }\n\n static get allowVirtualElements() {\n return false\n }\n static get isBindingHandlerClass() {\n return true\n }\n\n /* Overload this for asynchronous bindings or bindings that recursively\n apply bindings (e.g. components, foreach, template).\n\n A binding should be complete when it has run through once, notably\n in server-side bindings for pre-rendering.\n */\n get bindingCompleted(): Promise<boolean> | boolean {\n return true\n }\n\n static registerAs(name: string, provider = options.bindingProviderInstance) {\n provider.bindingHandlers.set(name, this) //todo dangerous javascript: this in static function = this is calling object\n }\n\n static registerBindingHandler(handler: BindingHandler, name: string, provider = options.bindingProviderInstance) {\n provider.bindingHandlers.set(name, handler)\n }\n}\n\n/**\n * An AsyncBindingHandler shall call `completeBinding` when the binding\n * is to be considered complete.\n */\nconst ResolveSymbol = Symbol('Async Binding Resolved')\n\nexport class AsyncBindingHandler extends BindingHandler {\n constructor(params) {\n super(params)\n this.bindingCompletion = new Promise(resolve => {\n this[ResolveSymbol] = resolve\n })\n this.completeBinding = bindingResult => this[ResolveSymbol](bindingResult)\n }\n\n override get bindingCompleted(): Promise<boolean> {\n return this.bindingCompletion\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,eAAe;AACxB,SAAS,6BAA6B;AACtC,SAAS,iBAAiB;AAgBnB,aAAM,uBAAgC,UAAU;AAAA,EA+BrD,YAAY,QAAQ;AAClB,UAAM;AACN,UAAM,EAAE,UAAU,eAAe,aAAa,SAAS,IAAI;AAE3D,SAAK,WAAW;AAChB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,QAAQ,SAAS;AAEtB,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEA,IAAI,QAAQ;AACV,WAAO,KAAK,cAAc;AAAA,EAC5B;AAAA,EACA,IAAI,MAAM,GAAG;AACX,UAAM,KAAK,KAAK,cAAc;AAC9B,QAAI,sBAAsB,EAAE,GAAG;AAC7B,SAAG,CAAC;AAAA,IACN,OAAO;AACL,WAAK,cAAc,CAAC;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,IAAI,sBAAsB;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,WAAW,uBAAuB;AAChC,WAAO;AAAA,EACT;AAAA,EACA,WAAW,wBAAwB;AACjC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,mBAA+C;AACjD,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,WAAW,MAAc,WAAW,QAAQ,yBAAyB;AAC1E,aAAS,gBAAgB,IAAI,MAAM,IAAI;AAAA,EACzC;AAAA,EAEA,OAAO,uBAAuB,SAAyB,MAAc,WAAW,QAAQ,yBAAyB;AAC/G,aAAS,gBAAgB,IAAI,MAAM,OAAO;AAAA,EAC5C;AACF;AAMA,MAAM,gBAAgB,uBAAO,wBAAwB;AAE9C,aAAM,4BAA4B,eAAe;AAAA,EACtD,YAAY,QAAQ;AAClB,UAAM,MAAM;AACZ,SAAK,oBAAoB,IAAI,QAAQ,aAAW;AAC9C,WAAK,aAAa,IAAI;AAAA,IACxB,CAAC;AACD,SAAK,kBAAkB,mBAAiB,KAAK,aAAa,EAAE,aAAa;AAAA,EAC3E;AAAA,EAEA,IAAa,mBAAqC;AAChD,WAAO,KAAK;AAAA,EACd;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/BindingResult.js
CHANGED
|
@@ -1,41 +1,18 @@
|
|
|
1
|
-
// @tko/bind 🥊 4.0.0
|
|
2
|
-
|
|
3
|
-
return new Promise((resolve, reject) => {
|
|
4
|
-
var fulfilled = (value) => {
|
|
5
|
-
try {
|
|
6
|
-
step(generator.next(value));
|
|
7
|
-
} catch (e) {
|
|
8
|
-
reject(e);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var rejected = (value) => {
|
|
12
|
-
try {
|
|
13
|
-
step(generator.throw(value));
|
|
14
|
-
} catch (e) {
|
|
15
|
-
reject(e);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
19
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
1
|
+
// @tko/bind 🥊 4.0.0 ESM
|
|
2
|
+
"use strict";
|
|
22
3
|
export class BindingResult {
|
|
23
4
|
constructor({ asyncBindingsApplied, rootNode, bindingContext }) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
isComplete: this.isSync
|
|
29
|
-
});
|
|
5
|
+
this.rootNode = rootNode;
|
|
6
|
+
this.bindingContext = bindingContext;
|
|
7
|
+
this.isSync = asyncBindingsApplied.size === 0;
|
|
8
|
+
this.isComplete = this.isSync;
|
|
30
9
|
if (!this.isSync) {
|
|
31
10
|
this.completionPromise = this.completeWhenBindingsFinish(asyncBindingsApplied);
|
|
32
11
|
}
|
|
33
12
|
}
|
|
34
|
-
completeWhenBindingsFinish(asyncBindingsApplied) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return this;
|
|
39
|
-
});
|
|
13
|
+
async completeWhenBindingsFinish(asyncBindingsApplied) {
|
|
14
|
+
await Promise.all(asyncBindingsApplied);
|
|
15
|
+
this.isComplete = true;
|
|
16
|
+
return this;
|
|
40
17
|
}
|
|
41
18
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/BindingResult.ts"],
|
|
4
|
-
"sourcesContent": ["\n\nexport class BindingResult {\n constructor
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { BindingContext } from './bindingContext'\n\nexport class BindingResult {\n isSync: boolean\n isComplete: boolean\n completionPromise: Promise<BindingResult>\n rootNode: Node\n bindingContext: BindingContext\n\n constructor({ asyncBindingsApplied, rootNode, bindingContext }) {\n this.rootNode = rootNode\n this.bindingContext = bindingContext\n this.isSync = asyncBindingsApplied.size === 0\n this.isComplete = this.isSync\n\n if (!this.isSync) {\n this.completionPromise = this.completeWhenBindingsFinish(asyncBindingsApplied)\n }\n }\n\n async completeWhenBindingsFinish(asyncBindingsApplied: Set<any>) {\n await Promise.all(asyncBindingsApplied)\n this.isComplete = true\n return this\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAEO,aAAM,cAAc;AAAA,EAOzB,YAAY,EAAE,sBAAsB,UAAU,eAAe,GAAG;AAC9D,SAAK,WAAW;AAChB,SAAK,iBAAiB;AACtB,SAAK,SAAS,qBAAqB,SAAS;AAC5C,SAAK,aAAa,KAAK;AAEvB,QAAI,CAAC,KAAK,QAAQ;AAChB,WAAK,oBAAoB,KAAK,2BAA2B,oBAAoB;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,MAAM,2BAA2B,sBAAgC;AAC/D,UAAM,QAAQ,IAAI,oBAAoB;AACtC,SAAK,aAAa;AAClB,WAAO;AAAA,EACT;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,42 +1,21 @@
|
|
|
1
|
-
// @tko/bind 🥊 4.0.0
|
|
2
|
-
|
|
3
|
-
return new Promise((resolve, reject) => {
|
|
4
|
-
var fulfilled = (value) => {
|
|
5
|
-
try {
|
|
6
|
-
step(generator.next(value));
|
|
7
|
-
} catch (e) {
|
|
8
|
-
reject(e);
|
|
9
|
-
}
|
|
10
|
-
};
|
|
11
|
-
var rejected = (value) => {
|
|
12
|
-
try {
|
|
13
|
-
step(generator.throw(value));
|
|
14
|
-
} catch (e) {
|
|
15
|
-
reject(e);
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
19
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
20
|
-
});
|
|
21
|
-
};
|
|
1
|
+
// @tko/bind 🥊 4.0.0 ESM
|
|
2
|
+
"use strict";
|
|
22
3
|
import { applyBindingsToDescendants } from "./applyBindings";
|
|
23
4
|
import { AsyncBindingHandler } from "./BindingHandler";
|
|
24
5
|
export class DescendantBindingHandler extends AsyncBindingHandler {
|
|
25
6
|
get controlsDescendants() {
|
|
26
7
|
return true;
|
|
27
8
|
}
|
|
28
|
-
applyBindingsToDescendants(childContext, callback) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.completeBinding(bindingResult);
|
|
40
|
-
});
|
|
9
|
+
async applyBindingsToDescendants(childContext, callback) {
|
|
10
|
+
const bindingResult = applyBindingsToDescendants(childContext, this.$element);
|
|
11
|
+
if (bindingResult.isSync) {
|
|
12
|
+
this.bindingCompletion = bindingResult;
|
|
13
|
+
} else {
|
|
14
|
+
await bindingResult.completionPromise;
|
|
15
|
+
}
|
|
16
|
+
if (callback) {
|
|
17
|
+
callback(bindingResult);
|
|
18
|
+
}
|
|
19
|
+
this.completeBinding(bindingResult);
|
|
41
20
|
}
|
|
42
21
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/DescendantBindingHandler.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import { applyBindingsToDescendants } from './applyBindings'\nimport { AsyncBindingHandler } from './BindingHandler'\nimport type { BindingResult } from './BindingResult'\nimport type { BindingContext } from './bindingContext'\n\n/**\n * This DescendantBindingHandler is a base class for bindings that control\n * descendants, such as the `if`, `with`, `component`, `foreach` and `template`\n * bindings.\n */\nexport class DescendantBindingHandler extends AsyncBindingHandler {\n override get controlsDescendants() {\n return true\n }\n\n async applyBindingsToDescendants(childContext: BindingContext, callback?: (result: BindingResult) => void) {\n const bindingResult = applyBindingsToDescendants(childContext, this.$element)\n if (bindingResult.isSync) {\n this.bindingCompletion = bindingResult\n } else {\n await bindingResult.completionPromise\n }\n if (callback) {\n callback(bindingResult)\n }\n this.completeBinding(bindingResult)\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,kCAAkC;AAC3C,SAAS,2BAA2B;AAS7B,aAAM,iCAAiC,oBAAoB;AAAA,EAChE,IAAa,sBAAsB;AACjC,WAAO;AAAA,EACT;AAAA,EAEA,MAAM,2BAA2B,cAA8B,UAA4C;AACzG,UAAM,gBAAgB,2BAA2B,cAAc,KAAK,QAAQ;AAC5E,QAAI,cAAc,QAAQ;AACxB,WAAK,oBAAoB;AAAA,IAC3B,OAAO;AACL,YAAM,cAAc;AAAA,IACtB;AACA,QAAI,UAAU;AACZ,eAAS,aAAa;AAAA,IACxB;AACA,SAAK,gBAAgB,aAAa;AAAA,EACpC;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
// @tko/bind 🥊 4.0.0
|
|
1
|
+
// @tko/bind 🥊 4.0.0 ESM
|
|
2
|
+
"use strict";
|
|
2
3
|
import { virtualElements, options } from "@tko/utils";
|
|
3
4
|
import { BindingHandler } from "./BindingHandler";
|
|
4
5
|
const PossibleWeakMap = options.global.WeakMap || Map;
|
|
5
6
|
const legacyBindingMap = new PossibleWeakMap();
|
|
6
7
|
export class LegacyBindingHandler extends BindingHandler {
|
|
8
|
+
get handler() {
|
|
9
|
+
return void 0;
|
|
10
|
+
}
|
|
7
11
|
constructor(params) {
|
|
8
12
|
super(params);
|
|
9
13
|
const handler = this.handler;
|
|
@@ -29,18 +33,21 @@ export class LegacyBindingHandler extends BindingHandler {
|
|
|
29
33
|
}
|
|
30
34
|
}
|
|
31
35
|
get legacyArgs() {
|
|
32
|
-
return [
|
|
33
|
-
this.$element,
|
|
34
|
-
this.valueAccessor,
|
|
35
|
-
this.allBindings,
|
|
36
|
-
this.$data,
|
|
37
|
-
this.$context
|
|
38
|
-
];
|
|
36
|
+
return [this.$element, this.valueAccessor, this.allBindings, this.$data, this.$context];
|
|
39
37
|
}
|
|
40
38
|
get controlsDescendants() {
|
|
41
39
|
const objectToTest = this.initReturn || this.handler || {};
|
|
42
40
|
return objectToTest.controlsDescendantBindings;
|
|
43
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a handler instance from the `origin`, which may be:
|
|
44
|
+
*
|
|
45
|
+
* 1. an object (becomes LegacyBindingHandler)
|
|
46
|
+
* 2. a function (becomes LegacyBindingHandler with `init: function`)
|
|
47
|
+
*
|
|
48
|
+
* If given an object (the only kind supported in knockout 3.x and before), it
|
|
49
|
+
* shall draw the `init`, `update`, and `allowVirtualElements` properties
|
|
50
|
+
*/
|
|
44
51
|
static getOrCreateFor(key, handler) {
|
|
45
52
|
if (legacyBindingMap.has(handler)) {
|
|
46
53
|
return legacyBindingMap.get(handler);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/LegacyBindingHandler.ts"],
|
|
4
|
-
"sourcesContent": ["
|
|
5
|
-
"mappings": ";
|
|
4
|
+
"sourcesContent": ["import { virtualElements, options } from '@tko/utils'\nimport { BindingHandler } from './BindingHandler'\n\n/**\n * We have no guarantees, for users employing legacy bindings,\n * that it has not been changed with a modification like\n *\n * ko.bindingHandlers[name] = { init: ...}\n *\n * ... so we have to keep track by way of a map.\n */\nconst PossibleWeakMap = options.global.WeakMap || Map\nconst legacyBindingMap = new PossibleWeakMap()\n\nexport class LegacyBindingHandler extends BindingHandler {\n get handler(): any {\n // Needed to prevent tsc error for using this.handler\n // is overriden in factory functions. Any must be used for return type\n return undefined\n }\n initReturn: any\n onError: (step: string, error: unknown) => void\n constructor(params: any) {\n super(params)\n const handler = this.handler\n this.onError = params.onError\n\n if (typeof handler.dispose === 'function') {\n this.addDisposable(handler)\n }\n\n try {\n this.initReturn = handler.init && handler.init(...this.legacyArgs)\n } catch (e) {\n params.onError('init', e)\n }\n }\n\n onValueChange(): void {\n const handler = this.handler\n if (typeof handler.update !== 'function') {\n return\n }\n try {\n handler.update(...this.legacyArgs)\n } catch (e) {\n this.onError('update', e)\n }\n }\n\n get legacyArgs(): any[] {\n return [this.$element, this.valueAccessor, this.allBindings, this.$data, this.$context]\n }\n\n override get controlsDescendants(): boolean {\n const objectToTest = this.initReturn || this.handler || {}\n return objectToTest.controlsDescendantBindings\n }\n\n /**\n * Create a handler instance from the `origin`, which may be:\n *\n * 1. an object (becomes LegacyBindingHandler)\n * 2. a function (becomes LegacyBindingHandler with `init: function`)\n *\n * If given an object (the only kind supported in knockout 3.x and before), it\n * shall draw the `init`, `update`, and `allowVirtualElements` properties\n */\n static getOrCreateFor(key: string | undefined, handler: any): any {\n if (legacyBindingMap.has(handler)) {\n return legacyBindingMap.get(handler)\n }\n const newLegacyHandler = this.createFor(key, handler)\n legacyBindingMap.set(handler, newLegacyHandler)\n return newLegacyHandler\n }\n\n static createFor(key: string | undefined, handler: any): any {\n if (typeof handler === 'function') {\n const [initFn, disposeFn] = [handler, handler.dispose]\n return class extends LegacyBindingHandler {\n override get handler() {\n const init = initFn.bind(this)\n const dispose = disposeFn ? disposeFn.bind(this) : null\n return { init, dispose }\n }\n static get after() {\n return handler.after\n }\n static override get allowVirtualElements() {\n return handler.allowVirtualElements || virtualElements.allowedBindings[key!]\n }\n }\n }\n\n if (typeof handler === 'object') {\n return class extends LegacyBindingHandler {\n override get handler() {\n return handler\n }\n static get after() {\n return handler.after\n }\n static override get allowVirtualElements() {\n return handler.allowVirtualElements || virtualElements.allowedBindings[key!]\n }\n }\n }\n\n throw new Error('The given handler is not an appropriate type.')\n }\n}\n"],
|
|
5
|
+
"mappings": ";;AAAA,SAAS,iBAAiB,eAAe;AACzC,SAAS,sBAAsB;AAU/B,MAAM,kBAAkB,QAAQ,OAAO,WAAW;AAClD,MAAM,mBAAmB,IAAI,gBAAgB;AAEtC,aAAM,6BAA6B,eAAe;AAAA,EACvD,IAAI,UAAe;AAGjB,WAAO;AAAA,EACT;AAAA,EAGA,YAAY,QAAa;AACvB,UAAM,MAAM;AACZ,UAAM,UAAU,KAAK;AACrB,SAAK,UAAU,OAAO;AAEtB,QAAI,OAAO,QAAQ,YAAY,YAAY;AACzC,WAAK,cAAc,OAAO;AAAA,IAC5B;AAEA,QAAI;AACF,WAAK,aAAa,QAAQ,QAAQ,QAAQ,KAAK,GAAG,KAAK,UAAU;AAAA,IACnE,SAAS,GAAG;AACV,aAAO,QAAQ,QAAQ,CAAC;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,gBAAsB;AACpB,UAAM,UAAU,KAAK;AACrB,QAAI,OAAO,QAAQ,WAAW,YAAY;AACxC;AAAA,IACF;AACA,QAAI;AACF,cAAQ,OAAO,GAAG,KAAK,UAAU;AAAA,IACnC,SAAS,GAAG;AACV,WAAK,QAAQ,UAAU,CAAC;AAAA,IAC1B;AAAA,EACF;AAAA,EAEA,IAAI,aAAoB;AACtB,WAAO,CAAC,KAAK,UAAU,KAAK,eAAe,KAAK,aAAa,KAAK,OAAO,KAAK,QAAQ;AAAA,EACxF;AAAA,EAEA,IAAa,sBAA+B;AAC1C,UAAM,eAAe,KAAK,cAAc,KAAK,WAAW,CAAC;AACzD,WAAO,aAAa;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,eAAe,KAAyB,SAAmB;AAChE,QAAI,iBAAiB,IAAI,OAAO,GAAG;AACjC,aAAO,iBAAiB,IAAI,OAAO;AAAA,IACrC;AACA,UAAM,mBAAmB,KAAK,UAAU,KAAK,OAAO;AACpD,qBAAiB,IAAI,SAAS,gBAAgB;AAC9C,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,UAAU,KAAyB,SAAmB;AAC3D,QAAI,OAAO,YAAY,YAAY;AACjC,YAAM,CAAC,QAAQ,SAAS,IAAI,CAAC,SAAS,QAAQ,OAAO;AACrD,aAAO,cAAc,qBAAqB;AAAA,QACxC,IAAa,UAAU;AACrB,gBAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,gBAAM,UAAU,YAAY,UAAU,KAAK,IAAI,IAAI;AACnD,iBAAO,EAAE,MAAM,QAAQ;AAAA,QACzB;AAAA,QACA,WAAW,QAAQ;AACjB,iBAAO,QAAQ;AAAA,QACjB;AAAA,QACA,WAAoB,uBAAuB;AACzC,iBAAO,QAAQ,wBAAwB,gBAAgB,gBAAgB,GAAI;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AAEA,QAAI,OAAO,YAAY,UAAU;AAC/B,aAAO,cAAc,qBAAqB;AAAA,QACxC,IAAa,UAAU;AACrB,iBAAO;AAAA,QACT;AAAA,QACA,WAAW,QAAQ;AACjB,iBAAO,QAAQ;AAAA,QACjB;AAAA,QACA,WAAoB,uBAAuB;AACzC,iBAAO,QAAQ,wBAAwB,gBAAgB,gBAAgB,GAAI;AAAA,QAC7E;AAAA,MACF;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/applyBindings.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
// @tko/bind 🥊 4.0.0
|
|
1
|
+
// @tko/bind 🥊 4.0.0 ESM
|
|
2
|
+
"use strict";
|
|
2
3
|
import {
|
|
3
4
|
extend,
|
|
4
5
|
objectMap,
|
|
@@ -10,37 +11,27 @@ import {
|
|
|
10
11
|
arrayForEach,
|
|
11
12
|
options
|
|
12
13
|
} from "@tko/utils";
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
} from "
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
} from "
|
|
19
|
-
import {
|
|
20
|
-
dataFor,
|
|
21
|
-
bindingContext,
|
|
22
|
-
boundElementDomDataKey,
|
|
23
|
-
contextSubscribeSymbol
|
|
24
|
-
} from "./bindingContext";
|
|
25
|
-
import {
|
|
26
|
-
bindingEvent
|
|
27
|
-
} from "./bindingEvent";
|
|
28
|
-
import {
|
|
29
|
-
BindingResult
|
|
30
|
-
} from "./BindingResult";
|
|
31
|
-
import {
|
|
32
|
-
LegacyBindingHandler
|
|
33
|
-
} from "./LegacyBindingHandler";
|
|
14
|
+
import { dependencyDetection } from "@tko/observable";
|
|
15
|
+
import { computed } from "@tko/computed";
|
|
16
|
+
import { dataFor, bindingContext, boundElementDomDataKey, contextSubscribeSymbol } from "./bindingContext";
|
|
17
|
+
import { bindingEvent } from "./bindingEvent";
|
|
18
|
+
import { BindingResult } from "./BindingResult";
|
|
19
|
+
import { LegacyBindingHandler } from "./LegacyBindingHandler";
|
|
34
20
|
const bindingDoesNotRecurseIntoElementTypes = {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
21
|
+
// Don't want bindings that operate on text nodes to mutate <script> and <textarea> contents,
|
|
22
|
+
// because it's unexpected and a potential XSS issue.
|
|
23
|
+
// Also bindings should not operate on <template> elements since this breaks in Internet Explorer
|
|
24
|
+
// and because such elements' contents are always intended to be bound in a different context
|
|
25
|
+
// from where they appear in the document.
|
|
26
|
+
script: true,
|
|
27
|
+
textarea: true,
|
|
28
|
+
template: true
|
|
38
29
|
};
|
|
39
30
|
function getBindingProvider() {
|
|
40
31
|
return options.bindingProviderInstance.instance || options.bindingProviderInstance;
|
|
41
32
|
}
|
|
42
33
|
function isProviderForNode(provider, node) {
|
|
43
|
-
const nodeTypes = provider.FOR_NODE_TYPES || [
|
|
34
|
+
const nodeTypes = provider.FOR_NODE_TYPES || [Node.ELEMENT_NODE, Node.TEXT_NODE, Node.COMMENT_NODE];
|
|
44
35
|
return nodeTypes.includes(node.nodeType);
|
|
45
36
|
}
|
|
46
37
|
function asProperHandlerClass(handler, bindingKey) {
|
|
@@ -91,11 +82,11 @@ function nodeOrChildHasBindings(node) {
|
|
|
91
82
|
return hasBindings(node) || [...node.childNodes].some((c) => nodeOrChildHasBindings(c));
|
|
92
83
|
}
|
|
93
84
|
function applyBindingsToNodeAndDescendantsInternal(bindingContext2, nodeVerified, asyncBindingsApplied) {
|
|
94
|
-
|
|
85
|
+
const isElement = nodeVerified.nodeType === Node.ELEMENT_NODE;
|
|
95
86
|
if (isElement) {
|
|
96
87
|
virtualElements.normaliseVirtualElementDomStructure(nodeVerified);
|
|
97
88
|
}
|
|
98
|
-
|
|
89
|
+
const shouldApplyBindings = isElement || hasBindings(nodeVerified);
|
|
99
90
|
const { shouldBindDescendants } = shouldApplyBindings ? applyBindingsToNodeInternal(nodeVerified, null, bindingContext2, asyncBindingsApplied) : { shouldBindDescendants: true };
|
|
100
91
|
if (shouldBindDescendants && !bindingDoesNotRecurseIntoElementTypes[tagNameLower(nodeVerified)]) {
|
|
101
92
|
applyBindingsToDescendantsInternal(bindingContext2, nodeVerified, asyncBindingsApplied);
|
|
@@ -104,7 +95,7 @@ function applyBindingsToNodeAndDescendantsInternal(bindingContext2, nodeVerified
|
|
|
104
95
|
function* topologicalSortBindings(bindings, $component) {
|
|
105
96
|
const results = [];
|
|
106
97
|
const bindingsConsidered = {};
|
|
107
|
-
const cyclicDependencyStack =
|
|
98
|
+
const cyclicDependencyStack = new Array();
|
|
108
99
|
objectForEach(bindings, function pushBinding(bindingKey) {
|
|
109
100
|
if (!bindingsConsidered[bindingKey]) {
|
|
110
101
|
const binding = getBindingHandlerFromComponent(bindingKey, $component) || getBindingHandler(bindingKey);
|
|
@@ -118,7 +109,9 @@ function* topologicalSortBindings(bindings, $component) {
|
|
|
118
109
|
return;
|
|
119
110
|
}
|
|
120
111
|
if (arrayIndexOf(cyclicDependencyStack, bindingDependencyKey) !== -1) {
|
|
121
|
-
throw Error(
|
|
112
|
+
throw Error(
|
|
113
|
+
"Cannot combine the following bindings, because they have a cyclic dependency: " + cyclicDependencyStack.join(", ")
|
|
114
|
+
);
|
|
122
115
|
} else {
|
|
123
116
|
pushBinding(bindingDependencyKey);
|
|
124
117
|
}
|
|
@@ -154,30 +147,32 @@ function applyBindingsToNodeInternal(node, sourceBindings, bindingContext2, asyn
|
|
|
154
147
|
if (!alreadyBound) {
|
|
155
148
|
bindingInfo.context = bindingContext2;
|
|
156
149
|
}
|
|
157
|
-
|
|
150
|
+
let bindings = null;
|
|
151
|
+
let bindingsUpdater = null;
|
|
158
152
|
if (sourceBindings && typeof sourceBindings !== "function") {
|
|
159
153
|
bindings = sourceBindings;
|
|
160
154
|
} else {
|
|
161
155
|
const provider = getBindingProvider();
|
|
162
156
|
const getBindings = provider.getBindingAccessors;
|
|
163
157
|
if (isProviderForNode(provider, node)) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
bindingContext2[contextSubscribeSymbol]
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
158
|
+
bindingsUpdater = computed(
|
|
159
|
+
function() {
|
|
160
|
+
bindings = sourceBindings ? sourceBindings(bindingContext2, node) : getBindings.call(provider, node, bindingContext2);
|
|
161
|
+
if (bindings && bindingContext2[contextSubscribeSymbol]) {
|
|
162
|
+
bindingContext2[contextSubscribeSymbol]();
|
|
163
|
+
}
|
|
164
|
+
return bindings;
|
|
165
|
+
},
|
|
166
|
+
null,
|
|
167
|
+
{ disposeWhenNodeIsRemoved: node }
|
|
168
|
+
);
|
|
171
169
|
if (!bindings || !bindingsUpdater.isActive()) {
|
|
172
170
|
bindingsUpdater = null;
|
|
173
171
|
}
|
|
174
172
|
}
|
|
175
173
|
}
|
|
176
|
-
|
|
174
|
+
let bindingHandlerThatControlsDescendantBindings;
|
|
177
175
|
if (bindings) {
|
|
178
|
-
let allBindings = function() {
|
|
179
|
-
return objectMap(bindingsUpdater ? bindingsUpdater() : bindings, evaluateValueAccessor);
|
|
180
|
-
};
|
|
181
176
|
const $component = bindingContext2.$component || {};
|
|
182
177
|
const allBindingHandlers = {};
|
|
183
178
|
domData.set(node, "bindingHandlers", allBindingHandlers);
|
|
@@ -189,24 +184,32 @@ function applyBindingsToNodeInternal(node, sourceBindings, bindingContext2, asyn
|
|
|
189
184
|
return valueAccessor(optionalValue);
|
|
190
185
|
}
|
|
191
186
|
} : (bindingKey) => bindings[bindingKey];
|
|
187
|
+
const allBindings = function() {
|
|
188
|
+
return objectMap(bindingsUpdater ? bindingsUpdater() : bindings, evaluateValueAccessor);
|
|
189
|
+
};
|
|
192
190
|
allBindings.has = (key) => key in bindings;
|
|
193
191
|
allBindings.get = (key) => bindings[key] && evaluateValueAccessor(getValueAccessor(key));
|
|
194
192
|
if (bindingEvent.childrenComplete in bindings) {
|
|
195
|
-
bindingEvent.subscribe(
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
193
|
+
bindingEvent.subscribe(
|
|
194
|
+
node,
|
|
195
|
+
bindingEvent.childrenComplete,
|
|
196
|
+
() => {
|
|
197
|
+
const callback = evaluateValueAccessor(bindings[bindingEvent.childrenComplete]);
|
|
198
|
+
if (!callback) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const nodes = virtualElements.childNodes(node);
|
|
202
|
+
if (nodes.length) {
|
|
203
|
+
callback(nodes, dataFor(nodes[0]));
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
null
|
|
207
|
+
);
|
|
205
208
|
}
|
|
206
209
|
const bindingsGenerated = topologicalSortBindings(bindings, $component);
|
|
207
210
|
const nodeAsyncBindingPromises = /* @__PURE__ */ new Set();
|
|
208
211
|
for (const [key, BindingHandlerClass] of bindingsGenerated) {
|
|
209
|
-
|
|
212
|
+
const reportBindingError = function(during, errorCaptured) {
|
|
210
213
|
onBindingError({
|
|
211
214
|
during,
|
|
212
215
|
errorCaptured,
|
|
@@ -218,26 +221,30 @@ function applyBindingsToNodeInternal(node, sourceBindings, bindingContext2, asyn
|
|
|
218
221
|
valueAccessor: getValueAccessor(key)
|
|
219
222
|
});
|
|
220
223
|
};
|
|
221
|
-
if (node.nodeType ===
|
|
224
|
+
if (node.nodeType === Node.COMMENT_NODE && !BindingHandlerClass.allowVirtualElements) {
|
|
222
225
|
throw new Error(`The binding '${key}' cannot be used with virtual elements`);
|
|
223
226
|
}
|
|
224
227
|
try {
|
|
225
|
-
const bindingHandler = dependencyDetection.ignore(
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
228
|
+
const bindingHandler = dependencyDetection.ignore(
|
|
229
|
+
() => new BindingHandlerClass({
|
|
230
|
+
allBindings,
|
|
231
|
+
$element: node,
|
|
232
|
+
$context: bindingContext2,
|
|
233
|
+
onError: reportBindingError,
|
|
234
|
+
valueAccessor(...v) {
|
|
235
|
+
return getValueAccessor(key)(...v);
|
|
236
|
+
}
|
|
237
|
+
})
|
|
238
|
+
);
|
|
234
239
|
if (bindingHandler.onValueChange) {
|
|
235
240
|
dependencyDetection.ignore(() => bindingHandler.computed("onValueChange"));
|
|
236
241
|
}
|
|
237
242
|
allBindingHandlers[key] = bindingHandler;
|
|
238
243
|
if (bindingHandler.controlsDescendants) {
|
|
239
244
|
if (bindingHandlerThatControlsDescendantBindings !== void 0) {
|
|
240
|
-
throw new Error(
|
|
245
|
+
throw new Error(
|
|
246
|
+
"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."
|
|
247
|
+
);
|
|
241
248
|
}
|
|
242
249
|
bindingHandlerThatControlsDescendantBindings = key;
|
|
243
250
|
}
|
|
@@ -246,7 +253,8 @@ function applyBindingsToNodeInternal(node, sourceBindings, bindingContext2, asyn
|
|
|
246
253
|
nodeAsyncBindingPromises.add(bindingHandler.bindingCompleted);
|
|
247
254
|
}
|
|
248
255
|
} catch (err) {
|
|
249
|
-
|
|
256
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
257
|
+
reportBindingError("creation", error);
|
|
250
258
|
}
|
|
251
259
|
}
|
|
252
260
|
triggerDescendantsComplete(node, bindings, nodeAsyncBindingPromises);
|
|
@@ -274,10 +282,15 @@ function getBindingContext(viewModelOrBindingContext, extendContextCallback) {
|
|
|
274
282
|
return viewModelOrBindingContext && viewModelOrBindingContext instanceof bindingContext ? viewModelOrBindingContext : new bindingContext(viewModelOrBindingContext, void 0, void 0, extendContextCallback);
|
|
275
283
|
}
|
|
276
284
|
export function applyBindingAccessorsToNode(node, bindings, viewModelOrBindingContext, asyncBindingsApplied) {
|
|
277
|
-
if (node.nodeType ===
|
|
285
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
278
286
|
virtualElements.normaliseVirtualElementDomStructure(node);
|
|
279
287
|
}
|
|
280
|
-
return applyBindingsToNodeInternal(
|
|
288
|
+
return applyBindingsToNodeInternal(
|
|
289
|
+
node,
|
|
290
|
+
bindings,
|
|
291
|
+
getBindingContext(viewModelOrBindingContext),
|
|
292
|
+
asyncBindingsApplied
|
|
293
|
+
);
|
|
281
294
|
}
|
|
282
295
|
export function applyBindingsToNode(node, bindings, viewModelOrBindingContext) {
|
|
283
296
|
const asyncBindingsApplied = /* @__PURE__ */ new Set();
|
|
@@ -288,24 +301,21 @@ export function applyBindingsToNode(node, bindings, viewModelOrBindingContext) {
|
|
|
288
301
|
}
|
|
289
302
|
export function applyBindingsToDescendants(viewModelOrBindingContext, rootNode) {
|
|
290
303
|
const asyncBindingsApplied = /* @__PURE__ */ new Set();
|
|
291
|
-
|
|
292
|
-
|
|
304
|
+
const bindingContext2 = getBindingContext(viewModelOrBindingContext);
|
|
305
|
+
if (rootNode.nodeType === Node.ELEMENT_NODE || rootNode.nodeType === Node.COMMENT_NODE) {
|
|
293
306
|
applyBindingsToDescendantsInternal(bindingContext2, rootNode, asyncBindingsApplied);
|
|
294
307
|
return new BindingResult({ asyncBindingsApplied, rootNode, bindingContext: bindingContext2 });
|
|
295
308
|
}
|
|
296
|
-
return new BindingResult({ asyncBindingsApplied, rootNode });
|
|
309
|
+
return new BindingResult({ asyncBindingsApplied, rootNode, bindingContext: bindingContext2 });
|
|
297
310
|
}
|
|
298
311
|
export function applyBindings(viewModelOrBindingContext, rootNode, extendContextCallback) {
|
|
299
312
|
const asyncBindingsApplied = /* @__PURE__ */ new Set();
|
|
300
|
-
if (!options.jQuery === void 0 && options.jQuery) {
|
|
301
|
-
options.jQuery = options.jQuery;
|
|
302
|
-
}
|
|
303
313
|
if (!rootNode) {
|
|
304
314
|
rootNode = window.document.body;
|
|
305
315
|
if (!rootNode) {
|
|
306
316
|
throw Error("ko.applyBindings: could not find window.document.body; has the document been loaded?");
|
|
307
317
|
}
|
|
308
|
-
} else if (rootNode.nodeType !==
|
|
318
|
+
} else if (rootNode.nodeType !== Node.ELEMENT_NODE && rootNode.nodeType !== Node.COMMENT_NODE) {
|
|
309
319
|
throw Error("ko.applyBindings: first parameter should be your view model; second parameter should be a DOM node");
|
|
310
320
|
}
|
|
311
321
|
const rootContext = getBindingContext(viewModelOrBindingContext, extendContextCallback);
|
|
@@ -313,7 +323,7 @@ export function applyBindings(viewModelOrBindingContext, rootNode, extendContext
|
|
|
313
323
|
return Promise.all(asyncBindingsApplied);
|
|
314
324
|
}
|
|
315
325
|
function onBindingError(spec) {
|
|
316
|
-
|
|
326
|
+
let error;
|
|
317
327
|
if (spec.bindingKey) {
|
|
318
328
|
error = spec.errorCaptured;
|
|
319
329
|
spec.message = 'Unable to process binding "' + spec.bindingKey + '" in binding "' + spec.bindingKey + '"\nMessage: ' + (error.message ? error.message : error);
|
|
@@ -324,7 +334,12 @@ function onBindingError(spec) {
|
|
|
324
334
|
extend(error, spec);
|
|
325
335
|
} catch (e) {
|
|
326
336
|
spec.stack = error.stack;
|
|
327
|
-
|
|
337
|
+
const message = error.message || String(error);
|
|
338
|
+
const originalName = error.name;
|
|
339
|
+
error = new Error(message);
|
|
340
|
+
if (originalName && originalName !== "Error") {
|
|
341
|
+
error.name = originalName;
|
|
342
|
+
}
|
|
328
343
|
extend(error, spec);
|
|
329
344
|
}
|
|
330
345
|
options.onError(error);
|