@microsoft/fast-element 1.10.2 → 2.0.0-beta.3
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/.eslintrc.json +1 -12
- package/CHANGELOG.json +387 -1
- package/CHANGELOG.md +74 -2
- package/README.md +2 -2
- package/dist/dts/components/attributes.d.ts +4 -1
- package/dist/dts/components/controller.d.ts +12 -11
- package/dist/dts/components/fast-definitions.d.ts +10 -2
- package/dist/dts/components/fast-element.d.ts +12 -5
- package/dist/dts/context.d.ts +157 -0
- package/dist/dts/debug.d.ts +1 -0
- package/dist/dts/hooks.d.ts +20 -0
- package/dist/dts/index.d.ts +16 -15
- package/dist/dts/index.debug.d.ts +2 -0
- package/dist/dts/index.rollup.d.ts +2 -0
- package/dist/dts/index.rollup.debug.d.ts +3 -0
- package/dist/dts/interfaces.d.ts +145 -0
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +207 -0
- package/dist/dts/observation/behavior.d.ts +4 -4
- package/dist/dts/observation/notifier.d.ts +18 -18
- package/dist/dts/observation/observable.d.ts +56 -18
- package/dist/dts/observation/splice-strategies.d.ts +13 -0
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/platform.d.ts +18 -67
- package/dist/dts/polyfills.d.ts +8 -0
- package/dist/dts/styles/css-directive.d.ts +43 -5
- package/dist/dts/styles/css.d.ts +19 -3
- package/dist/dts/styles/element-styles.d.ts +42 -62
- package/dist/dts/templating/binding-signal.d.ts +38 -0
- package/dist/dts/templating/binding-two-way.d.ts +56 -0
- package/dist/dts/templating/binding.d.ts +233 -65
- package/dist/dts/templating/children.d.ts +18 -15
- package/dist/dts/templating/compiler.d.ts +46 -28
- package/dist/dts/templating/dom.d.ts +41 -0
- package/dist/dts/templating/html-directive.d.ts +181 -43
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +45 -29
- package/dist/dts/templating/ref.d.ts +6 -12
- package/dist/dts/templating/repeat.d.ts +26 -14
- package/dist/dts/templating/slotted.d.ts +13 -14
- package/dist/dts/templating/template.d.ts +27 -21
- package/dist/dts/templating/view.d.ts +15 -22
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
- package/dist/dts/utilities.d.ts +40 -0
- package/dist/esm/components/attributes.js +25 -24
- package/dist/esm/components/controller.js +77 -57
- package/dist/esm/components/fast-definitions.js +16 -22
- package/dist/esm/components/fast-element.js +10 -2
- package/dist/esm/context.js +159 -0
- package/dist/esm/debug.js +30 -0
- package/dist/esm/hooks.js +32 -0
- package/dist/esm/index.debug.js +2 -0
- package/dist/esm/index.js +19 -14
- package/dist/esm/index.rollup.debug.js +3 -0
- package/dist/esm/index.rollup.js +2 -0
- package/dist/esm/interfaces.js +8 -1
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +269 -0
- package/dist/esm/observation/notifier.js +27 -35
- package/dist/esm/observation/observable.js +93 -68
- package/dist/esm/observation/{array-change-records.js → splice-strategies.js} +136 -62
- package/dist/esm/observation/update-queue.js +67 -0
- package/dist/esm/platform.js +36 -42
- package/dist/esm/polyfills.js +85 -0
- package/dist/esm/styles/css-directive.js +29 -13
- package/dist/esm/styles/css.js +27 -40
- package/dist/esm/styles/element-styles.js +65 -104
- package/dist/esm/templating/binding-signal.js +84 -0
- package/dist/esm/templating/binding-two-way.js +82 -0
- package/dist/esm/templating/binding.js +306 -153
- package/dist/esm/templating/children.js +33 -23
- package/dist/esm/templating/compiler.js +236 -152
- package/dist/esm/templating/dom.js +49 -0
- package/dist/esm/templating/html-directive.js +128 -40
- package/dist/esm/templating/markup.js +75 -0
- package/dist/esm/templating/node-observation.js +50 -45
- package/dist/esm/templating/ref.js +7 -16
- package/dist/esm/templating/repeat.js +39 -36
- package/dist/esm/templating/slotted.js +23 -20
- package/dist/esm/templating/template.js +51 -95
- package/dist/esm/templating/view.js +44 -43
- package/dist/esm/templating/when.js +2 -1
- package/dist/esm/utilities.js +139 -0
- package/dist/fast-element.api.json +11789 -5377
- package/dist/fast-element.d.ts +1178 -530
- package/dist/fast-element.debug.js +3722 -0
- package/dist/fast-element.debug.min.js +1 -0
- package/dist/fast-element.js +3484 -4033
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +2699 -0
- package/docs/api-report.md +472 -219
- package/docs/fast-element-2-changes.md +15 -0
- package/docs/guide/declaring-templates.md +4 -4
- package/docs/guide/defining-elements.md +2 -2
- package/docs/guide/next-steps.md +2 -2
- package/docs/guide/observables-and-state.md +1 -1
- package/docs/guide/using-directives.md +1 -1
- package/karma.conf.cjs +6 -17
- package/package.json +63 -15
- package/dist/dts/dom.d.ts +0 -112
- package/dist/dts/observation/array-change-records.d.ts +0 -48
- package/dist/dts/observation/array-observer.d.ts +0 -9
- package/dist/esm/dom.js +0 -207
- package/dist/esm/observation/array-observer.js +0 -177
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
const marker = `fast-${Math.random().toString(36).substring(2, 8)}`;
|
|
2
|
+
const interpolationStart = `${marker}{`;
|
|
3
|
+
const interpolationEnd = `}${marker}`;
|
|
4
|
+
const interpolationEndLength = interpolationEnd.length;
|
|
5
|
+
let id = 0;
|
|
6
|
+
/** @internal */
|
|
7
|
+
export const nextId = () => `${marker}-${++id}`;
|
|
8
|
+
/**
|
|
9
|
+
* Common APIs related to markup generation.
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export const Markup = Object.freeze({
|
|
13
|
+
/**
|
|
14
|
+
* Creates a placeholder string suitable for marking out a location *within*
|
|
15
|
+
* an attribute value or HTML content.
|
|
16
|
+
* @param index - The directive index to create the placeholder for.
|
|
17
|
+
* @remarks
|
|
18
|
+
* Used internally by binding directives.
|
|
19
|
+
*/
|
|
20
|
+
interpolation: (id) => `${interpolationStart}${id}${interpolationEnd}`,
|
|
21
|
+
/**
|
|
22
|
+
* Creates a placeholder that manifests itself as an attribute on an
|
|
23
|
+
* element.
|
|
24
|
+
* @param attributeName - The name of the custom attribute.
|
|
25
|
+
* @param index - The directive index to create the placeholder for.
|
|
26
|
+
* @remarks
|
|
27
|
+
* Used internally by attribute directives such as `ref`, `slotted`, and `children`.
|
|
28
|
+
*/
|
|
29
|
+
attribute: (id) => `${nextId()}="${interpolationStart}${id}${interpolationEnd}"`,
|
|
30
|
+
/**
|
|
31
|
+
* Creates a placeholder that manifests itself as a marker within the DOM structure.
|
|
32
|
+
* @param index - The directive index to create the placeholder for.
|
|
33
|
+
* @remarks
|
|
34
|
+
* Used internally by structural directives such as `repeat`.
|
|
35
|
+
*/
|
|
36
|
+
comment: (id) => `<!--${interpolationStart}${id}${interpolationEnd}-->`,
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Common APIs related to content parsing.
|
|
40
|
+
* @public
|
|
41
|
+
*/
|
|
42
|
+
export const Parser = Object.freeze({
|
|
43
|
+
/**
|
|
44
|
+
* Parses text content or HTML attribute content, separating out the static strings
|
|
45
|
+
* from the directives.
|
|
46
|
+
* @param value - The content or attribute string to parse.
|
|
47
|
+
* @param factories - A list of directives to search for in the string.
|
|
48
|
+
* @returns A heterogeneous array of static strings interspersed with
|
|
49
|
+
* directives or null if no directives are found in the string.
|
|
50
|
+
*/
|
|
51
|
+
parse(value, factories) {
|
|
52
|
+
const parts = value.split(interpolationStart);
|
|
53
|
+
if (parts.length === 1) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
const result = [];
|
|
57
|
+
for (let i = 0, ii = parts.length; i < ii; ++i) {
|
|
58
|
+
const current = parts[i];
|
|
59
|
+
const index = current.indexOf(interpolationEnd);
|
|
60
|
+
let literal;
|
|
61
|
+
if (index === -1) {
|
|
62
|
+
literal = current;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
const factoryId = current.substring(0, index);
|
|
66
|
+
result.push(factories[factoryId]);
|
|
67
|
+
literal = current.substring(index + interpolationEndLength);
|
|
68
|
+
}
|
|
69
|
+
if (literal !== "") {
|
|
70
|
+
result.push(literal);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
@@ -1,72 +1,77 @@
|
|
|
1
|
-
import { Observable } from "../observation/observable.js";
|
|
2
1
|
import { emptyArray } from "../platform.js";
|
|
2
|
+
import { StatelessAttachedAttributeDirective, } from "./html-directive.js";
|
|
3
|
+
const selectElements = (value) => value.nodeType === 1;
|
|
3
4
|
/**
|
|
4
5
|
* Creates a function that can be used to filter a Node array, selecting only elements.
|
|
5
6
|
* @param selector - An optional selector to restrict the filter to.
|
|
6
7
|
* @public
|
|
7
8
|
*/
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return value.nodeType === 1 && value.matches(selector);
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
return function (value, index, array) {
|
|
15
|
-
return value.nodeType === 1;
|
|
16
|
-
};
|
|
17
|
-
}
|
|
9
|
+
export const elements = (selector) => selector
|
|
10
|
+
? value => value.nodeType === 1 && value.matches(selector)
|
|
11
|
+
: selectElements;
|
|
18
12
|
/**
|
|
19
13
|
* A base class for node observation.
|
|
20
|
-
* @
|
|
14
|
+
* @public
|
|
15
|
+
* @remarks
|
|
16
|
+
* Internally used by the SlottedDirective and the ChildrenDirective.
|
|
21
17
|
*/
|
|
22
|
-
export class
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
* @param options - The options to use in configuring node observation.
|
|
27
|
-
*/
|
|
28
|
-
constructor(target, options) {
|
|
29
|
-
this.target = target;
|
|
30
|
-
this.options = options;
|
|
31
|
-
this.source = null;
|
|
18
|
+
export class NodeObservationDirective extends StatelessAttachedAttributeDirective {
|
|
19
|
+
constructor() {
|
|
20
|
+
super(...arguments);
|
|
21
|
+
this.sourceProperty = `${this.id}-s`;
|
|
32
22
|
}
|
|
33
23
|
/**
|
|
34
24
|
* Bind this behavior to the source.
|
|
35
25
|
* @param source - The source to bind to.
|
|
36
26
|
* @param context - The execution context that the binding is operating within.
|
|
27
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
37
28
|
*/
|
|
38
|
-
bind(source) {
|
|
39
|
-
const
|
|
40
|
-
this.
|
|
41
|
-
this.source
|
|
42
|
-
this.
|
|
43
|
-
if (this.shouldUpdate) {
|
|
44
|
-
this.observe();
|
|
45
|
-
}
|
|
29
|
+
bind(source, context, targets) {
|
|
30
|
+
const target = targets[this.nodeId];
|
|
31
|
+
target[this.sourceProperty] = source;
|
|
32
|
+
this.updateTarget(source, this.computeNodes(target));
|
|
33
|
+
this.observe(target);
|
|
46
34
|
}
|
|
47
35
|
/**
|
|
48
36
|
* Unbinds this behavior from the source.
|
|
49
37
|
* @param source - The source to unbind from.
|
|
38
|
+
* @param context - The execution context that the binding is operating within.
|
|
39
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
50
40
|
*/
|
|
51
|
-
unbind() {
|
|
52
|
-
this.
|
|
53
|
-
this.source
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
}
|
|
41
|
+
unbind(source, context, targets) {
|
|
42
|
+
const target = targets[this.nodeId];
|
|
43
|
+
this.updateTarget(source, emptyArray);
|
|
44
|
+
this.disconnect(target);
|
|
45
|
+
target[this.sourceProperty] = null;
|
|
57
46
|
}
|
|
58
|
-
/**
|
|
59
|
-
|
|
60
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Gets the data source for the target.
|
|
49
|
+
* @param target - The target to get the source for.
|
|
50
|
+
* @returns The source.
|
|
51
|
+
*/
|
|
52
|
+
getSource(target) {
|
|
53
|
+
return target[this.sourceProperty];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Updates the source property with the computed nodes.
|
|
57
|
+
* @param source - The source object to assign the nodes property to.
|
|
58
|
+
* @param value - The nodes to assign to the source object property.
|
|
59
|
+
*/
|
|
60
|
+
updateTarget(source, value) {
|
|
61
|
+
source[this.options.property] = value;
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Computes the set of nodes that should be assigned to the source property.
|
|
65
|
+
* @param target - The target to compute the nodes for.
|
|
66
|
+
* @returns The computed nodes.
|
|
67
|
+
* @remarks
|
|
68
|
+
* Applies filters if provided.
|
|
69
|
+
*/
|
|
70
|
+
computeNodes(target) {
|
|
71
|
+
let nodes = this.getNodes(target);
|
|
72
|
+
if ("filter" in this.options) {
|
|
65
73
|
nodes = nodes.filter(this.options.filter);
|
|
66
74
|
}
|
|
67
75
|
return nodes;
|
|
68
76
|
}
|
|
69
|
-
updateTarget(value) {
|
|
70
|
-
this.source[this.options.property] = value;
|
|
71
|
-
}
|
|
72
77
|
}
|
|
@@ -1,25 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HTMLDirective, StatelessAttachedAttributeDirective, } from "./html-directive.js";
|
|
2
2
|
/**
|
|
3
3
|
* The runtime behavior for template references.
|
|
4
4
|
* @public
|
|
5
5
|
*/
|
|
6
|
-
export class
|
|
7
|
-
/**
|
|
8
|
-
* Creates an instance of RefBehavior.
|
|
9
|
-
* @param target - The element to reference.
|
|
10
|
-
* @param propertyName - The name of the property to assign the reference to.
|
|
11
|
-
*/
|
|
12
|
-
constructor(target, propertyName) {
|
|
13
|
-
this.target = target;
|
|
14
|
-
this.propertyName = propertyName;
|
|
15
|
-
}
|
|
6
|
+
export class RefDirective extends StatelessAttachedAttributeDirective {
|
|
16
7
|
/**
|
|
17
8
|
* Bind this behavior to the source.
|
|
18
9
|
* @param source - The source to bind to.
|
|
19
10
|
* @param context - The execution context that the binding is operating within.
|
|
11
|
+
* @param targets - The targets that behaviors in a view can attach to.
|
|
20
12
|
*/
|
|
21
|
-
bind(source) {
|
|
22
|
-
source[this.
|
|
13
|
+
bind(source, context, targets) {
|
|
14
|
+
source[this.options] = targets[this.nodeId];
|
|
23
15
|
}
|
|
24
16
|
/**
|
|
25
17
|
* Unbinds this behavior from the source.
|
|
@@ -28,11 +20,10 @@ export class RefBehavior {
|
|
|
28
20
|
/* eslint-disable-next-line @typescript-eslint/no-empty-function */
|
|
29
21
|
unbind() { }
|
|
30
22
|
}
|
|
23
|
+
HTMLDirective.define(RefDirective);
|
|
31
24
|
/**
|
|
32
25
|
* A directive that observes the updates a property with a reference to the element.
|
|
33
26
|
* @param propertyName - The name of the property to assign the reference to.
|
|
34
27
|
* @public
|
|
35
28
|
*/
|
|
36
|
-
export
|
|
37
|
-
return new AttachedBehaviorHTMLDirective("fast-ref", RefBehavior, propertyName);
|
|
38
|
-
}
|
|
29
|
+
export const ref = (propertyName) => new RefDirective(propertyName);
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isFunction } from "../interfaces.js";
|
|
2
2
|
import { Observable, } from "../observation/observable.js";
|
|
3
|
-
import { enableArrayObservation } from "../observation/array-observer.js";
|
|
4
3
|
import { emptyArray } from "../platform.js";
|
|
5
|
-
import {
|
|
4
|
+
import { ArrayObserver } from "../observation/arrays.js";
|
|
5
|
+
import { Markup } from "./markup.js";
|
|
6
|
+
import { HTMLDirective, } from "./html-directive.js";
|
|
6
7
|
import { HTMLView } from "./view.js";
|
|
7
8
|
const defaultRepeatOptions = Object.freeze({
|
|
8
9
|
positioning: false,
|
|
@@ -12,10 +13,7 @@ function bindWithoutPositioning(view, items, index, context) {
|
|
|
12
13
|
view.bind(items[index], context);
|
|
13
14
|
}
|
|
14
15
|
function bindWithPositioning(view, items, index, context) {
|
|
15
|
-
|
|
16
|
-
childContext.index = index;
|
|
17
|
-
childContext.length = items.length;
|
|
18
|
-
view.bind(items[index], childContext);
|
|
16
|
+
view.bind(items[index], context.createItemContext(index, items.length));
|
|
19
17
|
}
|
|
20
18
|
/**
|
|
21
19
|
* A behavior that renders a template for each item in an array.
|
|
@@ -40,7 +38,7 @@ export class RepeatBehavior {
|
|
|
40
38
|
this.views = [];
|
|
41
39
|
this.items = null;
|
|
42
40
|
this.itemsObserver = null;
|
|
43
|
-
this.
|
|
41
|
+
this.context = void 0;
|
|
44
42
|
this.childContext = void 0;
|
|
45
43
|
this.bindView = bindWithoutPositioning;
|
|
46
44
|
this.itemsBindingObserver = Observable.binding(itemsBinding, this, isItemsBindingVolatile);
|
|
@@ -56,12 +54,10 @@ export class RepeatBehavior {
|
|
|
56
54
|
*/
|
|
57
55
|
bind(source, context) {
|
|
58
56
|
this.source = source;
|
|
59
|
-
this.
|
|
60
|
-
this.childContext =
|
|
61
|
-
this.
|
|
62
|
-
this.
|
|
63
|
-
this.items = this.itemsBindingObserver.observe(source, this.originalContext);
|
|
64
|
-
this.template = this.templateBindingObserver.observe(source, this.originalContext);
|
|
57
|
+
this.context = context;
|
|
58
|
+
this.childContext = context.createChildContext(source);
|
|
59
|
+
this.items = this.itemsBindingObserver.observe(source, this.context);
|
|
60
|
+
this.template = this.templateBindingObserver.observe(source, this.context);
|
|
65
61
|
this.observeItems(true);
|
|
66
62
|
this.refreshAllViews();
|
|
67
63
|
}
|
|
@@ -76,20 +72,27 @@ export class RepeatBehavior {
|
|
|
76
72
|
this.itemsObserver.unsubscribe(this);
|
|
77
73
|
}
|
|
78
74
|
this.unbindAllViews();
|
|
79
|
-
this.itemsBindingObserver.
|
|
80
|
-
this.templateBindingObserver.
|
|
75
|
+
this.itemsBindingObserver.dispose();
|
|
76
|
+
this.templateBindingObserver.dispose();
|
|
81
77
|
}
|
|
82
|
-
/**
|
|
78
|
+
/**
|
|
79
|
+
* Handles changes in the array, its items, and the repeat template.
|
|
80
|
+
* @param source - The source of the change.
|
|
81
|
+
* @param args - The details about what was changed.
|
|
82
|
+
*/
|
|
83
83
|
handleChange(source, args) {
|
|
84
84
|
if (source === this.itemsBinding) {
|
|
85
|
-
this.items = this.itemsBindingObserver.observe(this.source, this.
|
|
85
|
+
this.items = this.itemsBindingObserver.observe(this.source, this.context);
|
|
86
86
|
this.observeItems();
|
|
87
87
|
this.refreshAllViews();
|
|
88
88
|
}
|
|
89
89
|
else if (source === this.templateBinding) {
|
|
90
|
-
this.template = this.templateBindingObserver.observe(this.source, this.
|
|
90
|
+
this.template = this.templateBindingObserver.observe(this.source, this.context);
|
|
91
91
|
this.refreshAllViews(true);
|
|
92
92
|
}
|
|
93
|
+
else if (args[0].reset) {
|
|
94
|
+
this.refreshAllViews();
|
|
95
|
+
}
|
|
93
96
|
else {
|
|
94
97
|
this.updateViews(args);
|
|
95
98
|
}
|
|
@@ -110,8 +113,8 @@ export class RepeatBehavior {
|
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
updateViews(splices) {
|
|
113
|
-
const childContext = this.childContext;
|
|
114
116
|
const views = this.views;
|
|
117
|
+
const childContext = this.childContext;
|
|
115
118
|
const totalRemoved = [];
|
|
116
119
|
const bindView = this.bindView;
|
|
117
120
|
let removeDelta = 0;
|
|
@@ -143,22 +146,20 @@ export class RepeatBehavior {
|
|
|
143
146
|
}
|
|
144
147
|
if (this.options.positioning) {
|
|
145
148
|
for (let i = 0, ii = views.length; i < ii; ++i) {
|
|
146
|
-
|
|
147
|
-
currentContext.length = ii;
|
|
148
|
-
currentContext.index = i;
|
|
149
|
+
views[i].context.updatePosition(i, ii);
|
|
149
150
|
}
|
|
150
151
|
}
|
|
151
152
|
}
|
|
152
153
|
refreshAllViews(templateChanged = false) {
|
|
153
154
|
const items = this.items;
|
|
154
|
-
const childContext = this.childContext;
|
|
155
155
|
const template = this.template;
|
|
156
156
|
const location = this.location;
|
|
157
157
|
const bindView = this.bindView;
|
|
158
|
+
const childContext = this.childContext;
|
|
158
159
|
let itemsLength = items.length;
|
|
159
160
|
let views = this.views;
|
|
160
161
|
let viewsLength = views.length;
|
|
161
|
-
if (itemsLength === 0 || templateChanged) {
|
|
162
|
+
if (itemsLength === 0 || templateChanged || !this.options.recycle) {
|
|
162
163
|
// all views need to be removed
|
|
163
164
|
HTMLView.disposeContiguousBatch(views);
|
|
164
165
|
viewsLength = 0;
|
|
@@ -205,7 +206,7 @@ export class RepeatBehavior {
|
|
|
205
206
|
* A directive that configures list rendering.
|
|
206
207
|
* @public
|
|
207
208
|
*/
|
|
208
|
-
export class RepeatDirective
|
|
209
|
+
export class RepeatDirective {
|
|
209
210
|
/**
|
|
210
211
|
* Creates an instance of RepeatDirective.
|
|
211
212
|
* @param itemsBinding - The binding that provides the array to render.
|
|
@@ -213,27 +214,29 @@ export class RepeatDirective extends HTMLDirective {
|
|
|
213
214
|
* @param options - Options used to turn on special repeat features.
|
|
214
215
|
*/
|
|
215
216
|
constructor(itemsBinding, templateBinding, options) {
|
|
216
|
-
super();
|
|
217
217
|
this.itemsBinding = itemsBinding;
|
|
218
218
|
this.templateBinding = templateBinding;
|
|
219
219
|
this.options = options;
|
|
220
|
-
|
|
221
|
-
* Creates a placeholder string based on the directive's index within the template.
|
|
222
|
-
* @param index - The index of the directive within the template.
|
|
223
|
-
*/
|
|
224
|
-
this.createPlaceholder = DOM.createBlockPlaceholder;
|
|
225
|
-
enableArrayObservation();
|
|
220
|
+
ArrayObserver.enable();
|
|
226
221
|
this.isItemsBindingVolatile = Observable.isVolatileBinding(itemsBinding);
|
|
227
222
|
this.isTemplateBindingVolatile = Observable.isVolatileBinding(templateBinding);
|
|
228
223
|
}
|
|
224
|
+
/**
|
|
225
|
+
* Creates a placeholder string based on the directive's index within the template.
|
|
226
|
+
* @param index - The index of the directive within the template.
|
|
227
|
+
*/
|
|
228
|
+
createHTML(add) {
|
|
229
|
+
return Markup.comment(add(this));
|
|
230
|
+
}
|
|
229
231
|
/**
|
|
230
232
|
* Creates a behavior for the provided target node.
|
|
231
233
|
* @param target - The node instance to create the behavior for.
|
|
232
234
|
*/
|
|
233
|
-
createBehavior(
|
|
234
|
-
return new RepeatBehavior(
|
|
235
|
+
createBehavior(targets) {
|
|
236
|
+
return new RepeatBehavior(targets[this.nodeId], this.itemsBinding, this.isItemsBindingVolatile, this.templateBinding, this.isTemplateBindingVolatile, this.options);
|
|
235
237
|
}
|
|
236
238
|
}
|
|
239
|
+
HTMLDirective.define(RepeatDirective);
|
|
237
240
|
/**
|
|
238
241
|
* A directive that enables list rendering.
|
|
239
242
|
* @param itemsBinding - The array to render.
|
|
@@ -243,7 +246,7 @@ export class RepeatDirective extends HTMLDirective {
|
|
|
243
246
|
* @public
|
|
244
247
|
*/
|
|
245
248
|
export function repeat(itemsBinding, templateOrTemplateBinding, options = defaultRepeatOptions) {
|
|
246
|
-
const templateBinding =
|
|
249
|
+
const templateBinding = isFunction(templateOrTemplateBinding)
|
|
247
250
|
? templateOrTemplateBinding
|
|
248
251
|
: () => templateOrTemplateBinding;
|
|
249
252
|
return new RepeatDirective(itemsBinding, templateBinding, options);
|
|
@@ -1,37 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { isString } from "../interfaces.js";
|
|
2
|
+
import { HTMLDirective } from "./html-directive.js";
|
|
3
|
+
import { NodeObservationDirective } from "./node-observation.js";
|
|
4
|
+
const slotEvent = "slotchange";
|
|
3
5
|
/**
|
|
4
6
|
* The runtime behavior for slotted node observation.
|
|
5
7
|
* @public
|
|
6
8
|
*/
|
|
7
|
-
export class
|
|
8
|
-
/**
|
|
9
|
-
* Creates an instance of SlottedBehavior.
|
|
10
|
-
* @param target - The slot element target to observe.
|
|
11
|
-
* @param options - The options to use when observing the slot.
|
|
12
|
-
*/
|
|
13
|
-
constructor(target, options) {
|
|
14
|
-
super(target, options);
|
|
15
|
-
}
|
|
9
|
+
export class SlottedDirective extends NodeObservationDirective {
|
|
16
10
|
/**
|
|
17
11
|
* Begins observation of the nodes.
|
|
12
|
+
* @param target - The target to observe.
|
|
18
13
|
*/
|
|
19
|
-
observe() {
|
|
20
|
-
|
|
14
|
+
observe(target) {
|
|
15
|
+
target.addEventListener(slotEvent, this);
|
|
21
16
|
}
|
|
22
17
|
/**
|
|
23
18
|
* Disconnects observation of the nodes.
|
|
19
|
+
* @param target - The target to unobserve.
|
|
24
20
|
*/
|
|
25
|
-
disconnect() {
|
|
26
|
-
|
|
21
|
+
disconnect(target) {
|
|
22
|
+
target.removeEventListener(slotEvent, this);
|
|
27
23
|
}
|
|
28
24
|
/**
|
|
29
|
-
* Retrieves the nodes that should be assigned to the
|
|
25
|
+
* Retrieves the raw nodes that should be assigned to the source property.
|
|
26
|
+
* @param target - The target to get the node to.
|
|
30
27
|
*/
|
|
31
|
-
getNodes() {
|
|
32
|
-
return
|
|
28
|
+
getNodes(target) {
|
|
29
|
+
return target.assignedNodes(this.options);
|
|
30
|
+
}
|
|
31
|
+
/** @internal */
|
|
32
|
+
handleEvent(event) {
|
|
33
|
+
const target = event.currentTarget;
|
|
34
|
+
this.updateTarget(this.getSource(target), this.computeNodes(target));
|
|
33
35
|
}
|
|
34
36
|
}
|
|
37
|
+
HTMLDirective.define(SlottedDirective);
|
|
35
38
|
/**
|
|
36
39
|
* A directive that observes the `assignedNodes()` of a slot and updates a property
|
|
37
40
|
* whenever they change.
|
|
@@ -39,8 +42,8 @@ export class SlottedBehavior extends NodeObservationBehavior {
|
|
|
39
42
|
* @public
|
|
40
43
|
*/
|
|
41
44
|
export function slotted(propertyOrOptions) {
|
|
42
|
-
if (
|
|
45
|
+
if (isString(propertyOrOptions)) {
|
|
43
46
|
propertyOrOptions = { property: propertyOrOptions };
|
|
44
47
|
}
|
|
45
|
-
return new
|
|
48
|
+
return new SlottedDirective(propertyOrOptions);
|
|
46
49
|
}
|