@microsoft/fast-element 1.10.5 → 2.0.0-beta.10
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 +629 -6
- package/CHANGELOG.md +152 -5
- package/dist/dts/components/attributes.d.ts +14 -1
- package/dist/dts/components/{controller.d.ts → element-controller.d.ts} +32 -32
- package/dist/dts/components/fast-definitions.d.ts +51 -11
- package/dist/dts/components/fast-element.d.ts +18 -23
- package/dist/dts/context.d.ts +157 -0
- package/dist/{esm/observation/behavior.js → dts/debug.d.ts} +0 -0
- package/dist/dts/di/di.d.ts +899 -0
- package/dist/dts/index.d.ts +17 -16
- 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 +176 -0
- package/dist/dts/metadata.d.ts +25 -0
- package/dist/dts/observation/arrays.d.ts +207 -0
- package/dist/dts/observation/notifier.d.ts +18 -18
- package/dist/dts/observation/observable.d.ts +117 -34
- package/dist/dts/observation/update-queue.d.ts +40 -0
- package/dist/dts/pending-task.d.ts +20 -0
- package/dist/dts/platform.d.ts +23 -66
- package/dist/dts/polyfills.d.ts +8 -0
- package/dist/dts/state/exports.d.ts +3 -0
- package/dist/dts/state/reactive.d.ts +8 -0
- package/dist/dts/state/state.d.ts +141 -0
- package/dist/dts/state/visitor.d.ts +6 -0
- package/dist/dts/state/watch.d.ts +10 -0
- package/dist/dts/styles/css-directive.d.ts +44 -6
- package/dist/dts/styles/css.d.ts +19 -3
- package/dist/dts/styles/element-styles.d.ts +49 -63
- package/dist/dts/styles/host.d.ts +68 -0
- package/dist/dts/templating/binding-signal.d.ts +21 -0
- package/dist/dts/templating/binding-two-way.d.ts +39 -0
- package/dist/dts/templating/binding.d.ts +101 -70
- 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 +239 -45
- package/dist/dts/templating/markup.d.ts +48 -0
- package/dist/dts/templating/node-observation.d.ts +45 -30
- package/dist/dts/templating/ref.d.ts +6 -20
- package/dist/dts/templating/render.d.ts +272 -0
- package/dist/dts/templating/repeat.d.ts +36 -33
- package/dist/dts/templating/slotted.d.ts +13 -14
- package/dist/dts/templating/template.d.ts +28 -22
- package/dist/dts/templating/view.d.ts +82 -24
- package/dist/dts/templating/when.d.ts +3 -3
- package/dist/dts/testing/exports.d.ts +3 -0
- package/dist/dts/testing/fakes.d.ts +4 -0
- package/dist/dts/testing/fixture.d.ts +84 -0
- package/dist/dts/testing/timeout.d.ts +7 -0
- package/dist/{tsdoc-metadata.json → dts/tsdoc-metadata.json} +1 -1
- package/dist/dts/utilities.d.ts +22 -0
- package/dist/esm/components/attributes.js +38 -28
- package/dist/esm/components/{controller.js → element-controller.js} +150 -140
- package/dist/esm/components/fast-definitions.js +48 -46
- package/dist/esm/components/fast-element.js +31 -12
- package/dist/esm/context.js +163 -0
- package/dist/esm/debug.js +61 -0
- package/dist/esm/di/di.js +1435 -0
- package/dist/esm/index.debug.js +2 -0
- package/dist/esm/index.js +20 -14
- package/dist/esm/index.rollup.debug.js +3 -0
- package/dist/esm/index.rollup.js +2 -0
- package/dist/esm/interfaces.js +12 -1
- package/dist/esm/metadata.js +60 -0
- package/dist/esm/observation/arrays.js +570 -0
- package/dist/esm/observation/notifier.js +27 -35
- package/dist/esm/observation/observable.js +116 -149
- package/dist/esm/observation/update-queue.js +67 -0
- package/dist/esm/pending-task.js +16 -0
- package/dist/esm/platform.js +60 -42
- package/dist/esm/polyfills.js +85 -0
- package/dist/esm/state/exports.js +3 -0
- package/dist/esm/state/reactive.js +34 -0
- package/dist/esm/state/state.js +148 -0
- package/dist/esm/state/visitor.js +28 -0
- package/dist/esm/state/watch.js +36 -0
- package/dist/esm/styles/css-directive.js +29 -13
- package/dist/esm/styles/css.js +29 -42
- package/dist/esm/styles/element-styles.js +79 -104
- package/dist/esm/styles/host.js +1 -0
- package/dist/esm/templating/binding-signal.js +83 -0
- package/dist/esm/templating/binding-two-way.js +103 -0
- package/dist/esm/templating/binding.js +189 -159
- package/dist/esm/templating/children.js +33 -23
- package/dist/esm/templating/compiler.js +258 -152
- package/dist/esm/templating/dom.js +49 -0
- package/dist/esm/templating/html-directive.js +193 -36
- package/dist/esm/templating/markup.js +75 -0
- package/dist/esm/templating/node-observation.js +51 -45
- package/dist/esm/templating/ref.js +8 -25
- package/dist/esm/templating/render.js +391 -0
- package/dist/esm/templating/repeat.js +83 -79
- package/dist/esm/templating/slotted.js +23 -20
- package/dist/esm/templating/template.js +51 -93
- package/dist/esm/templating/view.js +125 -46
- package/dist/esm/templating/when.js +6 -4
- package/dist/esm/testing/exports.js +3 -0
- package/dist/esm/testing/fakes.js +76 -0
- package/dist/esm/testing/fixture.js +86 -0
- package/dist/esm/testing/timeout.js +24 -0
- package/dist/esm/utilities.js +44 -0
- package/dist/fast-element.api.json +12153 -5373
- package/dist/fast-element.d.ts +1448 -696
- package/dist/fast-element.debug.js +4107 -0
- package/dist/fast-element.debug.min.js +1 -0
- package/dist/fast-element.js +3817 -4029
- package/dist/fast-element.min.js +1 -1
- package/dist/fast-element.untrimmed.d.ts +2814 -0
- package/docs/api-report.md +567 -254
- package/docs/fast-element-2-changes.md +15 -0
- package/karma.conf.cjs +6 -17
- package/package.json +76 -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/dts/observation/behavior.d.ts +0 -19
- package/dist/esm/dom.js +0 -207
- package/dist/esm/observation/array-change-records.js +0 -326
- package/dist/esm/observation/array-observer.js +0 -177
|
@@ -1,39 +1,34 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import
|
|
1
|
+
import type { Disposable } from "../interfaces.js";
|
|
2
|
+
import { ExecutionContext, SourceLifetime } from "../observation/observable.js";
|
|
3
|
+
import type { ViewBehaviorFactory, ViewBehaviorTargets, ViewController } from "./html-directive.js";
|
|
3
4
|
/**
|
|
4
5
|
* Represents a collection of DOM nodes which can be bound to a data source.
|
|
5
6
|
* @public
|
|
6
7
|
*/
|
|
7
|
-
export interface View {
|
|
8
|
+
export interface View<TSource = any, TParent = any> extends Disposable {
|
|
8
9
|
/**
|
|
9
10
|
* The execution context the view is running within.
|
|
10
11
|
*/
|
|
11
|
-
readonly context: ExecutionContext
|
|
12
|
+
readonly context: ExecutionContext<TParent>;
|
|
12
13
|
/**
|
|
13
14
|
* The data that the view is bound to.
|
|
14
15
|
*/
|
|
15
|
-
readonly source:
|
|
16
|
+
readonly source: TSource | null;
|
|
16
17
|
/**
|
|
17
18
|
* Binds a view's behaviors to its binding source.
|
|
18
19
|
* @param source - The binding source for the view's binding behaviors.
|
|
19
|
-
* @param context - The execution context to run the view within.
|
|
20
20
|
*/
|
|
21
|
-
bind(source:
|
|
21
|
+
bind(source: TSource, context?: ExecutionContext<TParent>): void;
|
|
22
22
|
/**
|
|
23
23
|
* Unbinds a view's behaviors from its binding source and context.
|
|
24
24
|
*/
|
|
25
25
|
unbind(): void;
|
|
26
|
-
/**
|
|
27
|
-
* Removes the view and unbinds its behaviors, disposing of DOM nodes afterward.
|
|
28
|
-
* Once a view has been disposed, it cannot be inserted or bound again.
|
|
29
|
-
*/
|
|
30
|
-
dispose(): void;
|
|
31
26
|
}
|
|
32
27
|
/**
|
|
33
28
|
* A View representing DOM nodes specifically for rendering the view of a custom element.
|
|
34
29
|
* @public
|
|
35
30
|
*/
|
|
36
|
-
export interface ElementView extends View {
|
|
31
|
+
export interface ElementView<TSource = any, TParent = any> extends View<TSource, TParent> {
|
|
37
32
|
/**
|
|
38
33
|
* Appends the view's DOM nodes to the referenced node.
|
|
39
34
|
* @param node - The parent node to append the view's DOM nodes to.
|
|
@@ -44,7 +39,7 @@ export interface ElementView extends View {
|
|
|
44
39
|
* A view representing a range of DOM nodes which can be added/removed ad hoc.
|
|
45
40
|
* @public
|
|
46
41
|
*/
|
|
47
|
-
export interface SyntheticView extends View {
|
|
42
|
+
export interface SyntheticView<TSource = any, TParent = any> extends View<TSource, TParent> {
|
|
48
43
|
/**
|
|
49
44
|
* The first DOM node in the range of nodes that make up the view.
|
|
50
45
|
*/
|
|
@@ -63,27 +58,86 @@ export interface SyntheticView extends View {
|
|
|
63
58
|
* The nodes are not disposed and the view can later be re-inserted.
|
|
64
59
|
*/
|
|
65
60
|
remove(): void;
|
|
66
|
-
/**
|
|
67
|
-
* Removes the view and unbinds its behaviors, disposing of DOM nodes afterward.
|
|
68
|
-
* Once a view has been disposed, it cannot be inserted or bound again.
|
|
69
|
-
*/
|
|
70
|
-
dispose(): void;
|
|
71
61
|
}
|
|
72
62
|
/**
|
|
73
63
|
* The standard View implementation, which also implements ElementView and SyntheticView.
|
|
74
64
|
* @public
|
|
75
65
|
*/
|
|
76
|
-
export declare class HTMLView implements ElementView, SyntheticView {
|
|
66
|
+
export declare class HTMLView<TSource = any, TParent = any> implements ElementView<TSource, TParent>, SyntheticView<TSource, TParent>, ExecutionContext<TParent> {
|
|
77
67
|
private fragment;
|
|
68
|
+
private factories;
|
|
69
|
+
readonly targets: ViewBehaviorTargets;
|
|
78
70
|
private behaviors;
|
|
71
|
+
private unbindables;
|
|
79
72
|
/**
|
|
80
73
|
* The data that the view is bound to.
|
|
81
74
|
*/
|
|
82
|
-
source:
|
|
75
|
+
source: TSource | null;
|
|
76
|
+
/**
|
|
77
|
+
* Indicates whether the controller is bound.
|
|
78
|
+
*/
|
|
79
|
+
isBound: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Indicates how the source's lifetime relates to the controller's lifetime.
|
|
82
|
+
*/
|
|
83
|
+
readonly sourceLifetime: SourceLifetime;
|
|
83
84
|
/**
|
|
84
85
|
* The execution context the view is running within.
|
|
85
86
|
*/
|
|
86
|
-
context: ExecutionContext
|
|
87
|
+
context: ExecutionContext<TParent>;
|
|
88
|
+
/**
|
|
89
|
+
* The index of the current item within a repeat context.
|
|
90
|
+
*/
|
|
91
|
+
index: number;
|
|
92
|
+
/**
|
|
93
|
+
* The length of the current collection within a repeat context.
|
|
94
|
+
*/
|
|
95
|
+
length: number;
|
|
96
|
+
/**
|
|
97
|
+
* The parent data source within a nested context.
|
|
98
|
+
*/
|
|
99
|
+
readonly parent: TParent;
|
|
100
|
+
/**
|
|
101
|
+
* The parent execution context when in nested context scenarios.
|
|
102
|
+
*/
|
|
103
|
+
readonly parentContext: ExecutionContext<TParent>;
|
|
104
|
+
/**
|
|
105
|
+
* The current event within an event handler.
|
|
106
|
+
*/
|
|
107
|
+
get event(): Event;
|
|
108
|
+
/**
|
|
109
|
+
* Indicates whether the current item within a repeat context
|
|
110
|
+
* has an even index.
|
|
111
|
+
*/
|
|
112
|
+
get isEven(): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Indicates whether the current item within a repeat context
|
|
115
|
+
* has an odd index.
|
|
116
|
+
*/
|
|
117
|
+
get isOdd(): boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Indicates whether the current item within a repeat context
|
|
120
|
+
* is the first item in the collection.
|
|
121
|
+
*/
|
|
122
|
+
get isFirst(): boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Indicates whether the current item within a repeat context
|
|
125
|
+
* is somewhere in the middle of the collection.
|
|
126
|
+
*/
|
|
127
|
+
get isInMiddle(): boolean;
|
|
128
|
+
/**
|
|
129
|
+
* Indicates whether the current item within a repeat context
|
|
130
|
+
* is the last item in the collection.
|
|
131
|
+
*/
|
|
132
|
+
get isLast(): boolean;
|
|
133
|
+
/**
|
|
134
|
+
* Returns the typed event detail of a custom event.
|
|
135
|
+
*/
|
|
136
|
+
eventDetail<TDetail>(): TDetail;
|
|
137
|
+
/**
|
|
138
|
+
* Returns the typed event target of the event.
|
|
139
|
+
*/
|
|
140
|
+
eventTarget<TTarget extends EventTarget>(): TTarget;
|
|
87
141
|
/**
|
|
88
142
|
* The first DOM node in the range of nodes that make up the view.
|
|
89
143
|
*/
|
|
@@ -97,7 +151,7 @@ export declare class HTMLView implements ElementView, SyntheticView {
|
|
|
97
151
|
* @param fragment - The html fragment that contains the nodes for this view.
|
|
98
152
|
* @param behaviors - The behaviors to be applied to this view.
|
|
99
153
|
*/
|
|
100
|
-
constructor(fragment: DocumentFragment,
|
|
154
|
+
constructor(fragment: DocumentFragment, factories: ReadonlyArray<ViewBehaviorFactory>, targets: ViewBehaviorTargets);
|
|
101
155
|
/**
|
|
102
156
|
* Appends the view's DOM nodes to the referenced node.
|
|
103
157
|
* @param node - The parent node to append the view's DOM nodes to.
|
|
@@ -118,16 +172,20 @@ export declare class HTMLView implements ElementView, SyntheticView {
|
|
|
118
172
|
* Once a view has been disposed, it cannot be inserted or bound again.
|
|
119
173
|
*/
|
|
120
174
|
dispose(): void;
|
|
175
|
+
onUnbind(behavior: {
|
|
176
|
+
unbind(controller: ViewController<TSource, TParent>): any;
|
|
177
|
+
}): void;
|
|
121
178
|
/**
|
|
122
179
|
* Binds a view's behaviors to its binding source.
|
|
123
180
|
* @param source - The binding source for the view's binding behaviors.
|
|
124
181
|
* @param context - The execution context to run the behaviors within.
|
|
125
182
|
*/
|
|
126
|
-
bind(source:
|
|
183
|
+
bind(source: TSource, context?: ExecutionContext<TParent>): void;
|
|
127
184
|
/**
|
|
128
185
|
* Unbinds a view's behaviors from its binding source.
|
|
129
186
|
*/
|
|
130
187
|
unbind(): void;
|
|
188
|
+
private evaluateUnbindables;
|
|
131
189
|
/**
|
|
132
190
|
* Efficiently disposes of a contiguous range of synthetic view instances.
|
|
133
191
|
* @param views - A contiguous range of views to be disposed.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Expression } from "../observation/observable.js";
|
|
2
2
|
import type { CaptureType, SyntheticViewTemplate } from "./template.js";
|
|
3
3
|
/**
|
|
4
4
|
* A directive that enables basic conditional rendering in a template.
|
|
5
|
-
* @param
|
|
5
|
+
* @param condition - The condition to test for rendering.
|
|
6
6
|
* @param templateOrTemplateBinding - The template or a binding that gets
|
|
7
7
|
* the template to render when the condition is true.
|
|
8
8
|
* @public
|
|
9
9
|
*/
|
|
10
|
-
export declare function when<TSource = any, TReturn = any>(
|
|
10
|
+
export declare function when<TSource = any, TReturn = any, TParent = any>(condition: Expression<TSource, TReturn, TParent> | boolean, templateOrTemplateBinding: SyntheticViewTemplate<TSource, TParent> | Expression<TSource, SyntheticViewTemplate<TSource, TParent>, TParent>): CaptureType<TSource, TParent>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { Constructable } from "../interfaces.js";
|
|
2
|
+
import { ViewTemplate } from "../templating/template.js";
|
|
3
|
+
import type { HTMLView } from "../templating/view.js";
|
|
4
|
+
/**
|
|
5
|
+
* Options used to customize the creation of the test fixture.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export interface FixtureOptions {
|
|
9
|
+
/**
|
|
10
|
+
* The document to run the fixture in.
|
|
11
|
+
* @defaultValue `globalThis.document`
|
|
12
|
+
*/
|
|
13
|
+
document?: Document;
|
|
14
|
+
/**
|
|
15
|
+
* The parent element to append the fixture to.
|
|
16
|
+
* @defaultValue An instance of `HTMLDivElement`.
|
|
17
|
+
*/
|
|
18
|
+
parent?: HTMLElement;
|
|
19
|
+
/**
|
|
20
|
+
* The data source to bind the HTML to.
|
|
21
|
+
* @defaultValue An empty object.
|
|
22
|
+
*/
|
|
23
|
+
source?: any;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A test fixture.
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export interface Fixture<TElement = HTMLElement> {
|
|
30
|
+
/**
|
|
31
|
+
* The document the fixture is running in.
|
|
32
|
+
*/
|
|
33
|
+
document: Document;
|
|
34
|
+
/**
|
|
35
|
+
* The template the fixture was created from.
|
|
36
|
+
*/
|
|
37
|
+
template: ViewTemplate;
|
|
38
|
+
/**
|
|
39
|
+
* The view that was created from the fixture's template.
|
|
40
|
+
*/
|
|
41
|
+
view: HTMLView;
|
|
42
|
+
/**
|
|
43
|
+
* The parent element that the view was appended to.
|
|
44
|
+
* @remarks
|
|
45
|
+
* This element will be appended to the DOM only
|
|
46
|
+
* after {@link Fixture.connect} has been called.
|
|
47
|
+
*/
|
|
48
|
+
parent: HTMLElement;
|
|
49
|
+
/**
|
|
50
|
+
* The first element in the {@link Fixture.view}.
|
|
51
|
+
*/
|
|
52
|
+
element: TElement;
|
|
53
|
+
/**
|
|
54
|
+
* Adds the {@link Fixture.parent} to the DOM, causing the
|
|
55
|
+
* connect lifecycle to begin.
|
|
56
|
+
* @remarks
|
|
57
|
+
* Yields control to the caller one Microtask later, in order to
|
|
58
|
+
* ensure that the DOM has settled.
|
|
59
|
+
*/
|
|
60
|
+
connect: () => Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Removes the {@link Fixture.parent} from the DOM, causing the
|
|
63
|
+
* disconnect lifecycle to begin.
|
|
64
|
+
* @remarks
|
|
65
|
+
* Yields control to the caller one Microtask later, in order to
|
|
66
|
+
* ensure that the DOM has settled.
|
|
67
|
+
*/
|
|
68
|
+
disconnect: () => Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Creates a random, unique name suitable for use as a Custom Element name.
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export declare function uniqueElementName(prefix?: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* Creates a test fixture suitable for testing custom elements, templates, and bindings.
|
|
77
|
+
* @param templateNameOrType An HTML template or single element name to create the fixture for.
|
|
78
|
+
* @param options Enables customizing fixture creation behavior.
|
|
79
|
+
* @remarks
|
|
80
|
+
* Yields control to the caller one Microtask later, in order to
|
|
81
|
+
* ensure that the DOM has settled.
|
|
82
|
+
* @public
|
|
83
|
+
*/
|
|
84
|
+
export declare function fixture<TElement = HTMLElement>(templateNameOrType: ViewTemplate | string | Constructable<TElement>, options?: FixtureOptions): Promise<Fixture<TElement>>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Retrieves the "composed parent" element of a node, ignoring DOM tree boundaries.
|
|
3
|
+
* When the parent of a node is a shadow-root, it will return the host
|
|
4
|
+
* element of the shadow root. Otherwise it will return the parent node or null if
|
|
5
|
+
* no parent node exists.
|
|
6
|
+
* @param element - The element for which to retrieve the composed parent
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare function composedParent<T extends HTMLElement>(element: T): HTMLElement | null;
|
|
11
|
+
/**
|
|
12
|
+
* Determines if the reference element contains the test element in a "composed" DOM tree that
|
|
13
|
+
* ignores shadow DOM boundaries.
|
|
14
|
+
*
|
|
15
|
+
* Returns true of the test element is a descendent of the reference, or exist in
|
|
16
|
+
* a shadow DOM that is a logical descendent of the reference. Otherwise returns false.
|
|
17
|
+
* @param reference - The element to test for containment against.
|
|
18
|
+
* @param test - The element being tested for containment.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export declare function composedContains(reference: HTMLElement, test: HTMLElement): boolean;
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { Observable } from "../observation/observable.js";
|
|
2
|
-
import {
|
|
2
|
+
import { isString } from "../interfaces.js";
|
|
3
|
+
import { Updates } from "../observation/update-queue.js";
|
|
4
|
+
import { DOM } from "../templating/dom.js";
|
|
5
|
+
import { createMetadataLocator } from "../platform.js";
|
|
6
|
+
const booleanMode = "boolean";
|
|
7
|
+
const reflectMode = "reflect";
|
|
8
|
+
/**
|
|
9
|
+
* Metadata used to configure a custom attribute's behavior.
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export const AttributeConfiguration = Object.freeze({
|
|
13
|
+
/**
|
|
14
|
+
* Locates all attribute configurations associated with a type.
|
|
15
|
+
*/
|
|
16
|
+
locate: createMetadataLocator(),
|
|
17
|
+
});
|
|
3
18
|
/**
|
|
4
19
|
* A {@link ValueConverter} that converts to and from `boolean` values.
|
|
5
20
|
* @remarks
|
|
@@ -11,16 +26,22 @@ export const booleanConverter = {
|
|
|
11
26
|
return value ? "true" : "false";
|
|
12
27
|
},
|
|
13
28
|
fromView(value) {
|
|
14
|
-
|
|
29
|
+
return value === null ||
|
|
15
30
|
value === void 0 ||
|
|
16
31
|
value === "false" ||
|
|
17
32
|
value === false ||
|
|
18
|
-
value === 0
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return true;
|
|
33
|
+
value === 0
|
|
34
|
+
? false
|
|
35
|
+
: true;
|
|
22
36
|
},
|
|
23
37
|
};
|
|
38
|
+
function toNumber(value) {
|
|
39
|
+
if (value === null || value === undefined) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const number = value * 1;
|
|
43
|
+
return isNaN(number) ? null : number;
|
|
44
|
+
}
|
|
24
45
|
/**
|
|
25
46
|
* A {@link ValueConverter} that converts to and from `number` values.
|
|
26
47
|
* @remarks
|
|
@@ -30,19 +51,10 @@ export const booleanConverter = {
|
|
|
30
51
|
*/
|
|
31
52
|
export const nullableNumberConverter = {
|
|
32
53
|
toView(value) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
const number = value * 1;
|
|
37
|
-
return isNaN(number) ? null : number.toString();
|
|
38
|
-
},
|
|
39
|
-
fromView(value) {
|
|
40
|
-
if (value === null || value === undefined) {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
const number = value * 1;
|
|
44
|
-
return isNaN(number) ? null : number;
|
|
54
|
+
const output = toNumber(value);
|
|
55
|
+
return output ? output.toString() : output;
|
|
45
56
|
},
|
|
57
|
+
fromView: toNumber,
|
|
46
58
|
};
|
|
47
59
|
/**
|
|
48
60
|
* An implementation of {@link Accessor} that supports reactivity,
|
|
@@ -60,7 +72,7 @@ export class AttributeDefinition {
|
|
|
60
72
|
* @param converter - A {@link ValueConverter} that integrates with the property getter/setter
|
|
61
73
|
* to convert values to and from a DOM string.
|
|
62
74
|
*/
|
|
63
|
-
constructor(Owner, name, attribute = name.toLowerCase(), mode =
|
|
75
|
+
constructor(Owner, name, attribute = name.toLowerCase(), mode = reflectMode, converter) {
|
|
64
76
|
this.guards = new Set();
|
|
65
77
|
this.Owner = Owner;
|
|
66
78
|
this.name = name;
|
|
@@ -70,7 +82,7 @@ export class AttributeDefinition {
|
|
|
70
82
|
this.fieldName = `_${name}`;
|
|
71
83
|
this.callbackName = `${name}Changed`;
|
|
72
84
|
this.hasCallback = this.callbackName in Owner.prototype;
|
|
73
|
-
if (mode ===
|
|
85
|
+
if (mode === booleanMode && converter === void 0) {
|
|
74
86
|
this.converter = booleanConverter;
|
|
75
87
|
}
|
|
76
88
|
}
|
|
@@ -117,15 +129,15 @@ export class AttributeDefinition {
|
|
|
117
129
|
if (guards.has(element) || mode === "fromView") {
|
|
118
130
|
return;
|
|
119
131
|
}
|
|
120
|
-
|
|
132
|
+
Updates.enqueue(() => {
|
|
121
133
|
guards.add(element);
|
|
122
134
|
const latestValue = element[this.fieldName];
|
|
123
135
|
switch (mode) {
|
|
124
|
-
case
|
|
136
|
+
case reflectMode:
|
|
125
137
|
const converter = this.converter;
|
|
126
138
|
DOM.setAttribute(element, this.attribute, converter !== void 0 ? converter.toView(latestValue) : latestValue);
|
|
127
139
|
break;
|
|
128
|
-
case
|
|
140
|
+
case booleanMode:
|
|
129
141
|
DOM.setBooleanAttribute(element, this.attribute, latestValue);
|
|
130
142
|
break;
|
|
131
143
|
}
|
|
@@ -140,7 +152,7 @@ export class AttributeDefinition {
|
|
|
140
152
|
*/
|
|
141
153
|
static collect(Owner, ...attributeLists) {
|
|
142
154
|
const attributes = [];
|
|
143
|
-
attributeLists.push(Owner
|
|
155
|
+
attributeLists.push(AttributeConfiguration.locate(Owner));
|
|
144
156
|
for (let i = 0, ii = attributeLists.length; i < ii; ++i) {
|
|
145
157
|
const list = attributeLists[i];
|
|
146
158
|
if (list === void 0) {
|
|
@@ -148,7 +160,7 @@ export class AttributeDefinition {
|
|
|
148
160
|
}
|
|
149
161
|
for (let j = 0, jj = list.length; j < jj; ++j) {
|
|
150
162
|
const config = list[j];
|
|
151
|
-
if (
|
|
163
|
+
if (isString(config)) {
|
|
152
164
|
attributes.push(new AttributeDefinition(Owner, config));
|
|
153
165
|
}
|
|
154
166
|
else {
|
|
@@ -170,9 +182,7 @@ export function attr(configOrTarget, prop) {
|
|
|
170
182
|
// - @attr({...opts})
|
|
171
183
|
config.property = $prop;
|
|
172
184
|
}
|
|
173
|
-
|
|
174
|
-
($target.constructor.attributes = []);
|
|
175
|
-
attributes.push(config);
|
|
185
|
+
AttributeConfiguration.locate($target.constructor).push(config);
|
|
176
186
|
}
|
|
177
187
|
if (arguments.length > 1) {
|
|
178
188
|
// Non invocation:
|