@fluffjs/fluff 0.2.3 → 0.3.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/bundle.min.js +1 -0
- package/decorators/Component.d.ts +0 -8
- package/decorators/Component.js +0 -11
- package/decorators/Input.d.ts +1 -1
- package/decorators/InputOutputHelper.d.ts +2 -1
- package/decorators/InputOutputHelper.js +3 -1
- package/decorators/Output.d.ts +1 -1
- package/decorators/Pipe.d.ts +1 -0
- package/decorators/Pipe.js +1 -1
- package/decorators/Reactive.d.ts +2 -1
- package/decorators/Reactive.js +1 -1
- package/index.d.ts +2 -1
- package/index.js +1 -1
- package/interfaces/FluffHostElement.d.ts +13 -3
- package/interfaces/ReactiveOptions.d.ts +6 -0
- package/interfaces/ReactiveOptions.js +1 -0
- package/package.json +1 -1
- package/runtime/FluffBase.d.ts +12 -1
- package/runtime/FluffBase.js +70 -22
- package/runtime/FluffElementImpl.d.ts +9 -21
- package/runtime/FluffElementImpl.js +48 -149
- package/runtime/ForController.js +1 -2
- package/runtime/IfController.js +1 -2
- package/runtime/MarkerConfigGuards.d.ts +0 -2
- package/runtime/MarkerConfigGuards.js +0 -3
- package/runtime/MarkerController.d.ts +1 -9
- package/runtime/MarkerController.js +28 -144
- package/runtime/MarkerManager.d.ts +2 -1
- package/runtime/MarkerManager.js +1 -2
- package/runtime/MarkerManagerInterface.d.ts +3 -1
- package/runtime/SwitchController.js +1 -2
- package/runtime/TextController.d.ts +0 -1
- package/runtime/TextController.js +5 -19
- package/runtime/tests/TestChildTasksListComponent.js +2 -2
- package/runtime/tests/TestForComponent.js +2 -2
- package/runtime/tests/TestForReinsertBindsInputParentComponent.js +2 -2
- package/runtime/tests/TestForTextMarkerCollisionNoTrackParentComponent.js +2 -2
- package/runtime/tests/TestForTextMarkerCollisionParentComponent.js +2 -2
- package/runtime/tests/TestForUnsubscribeNestedParentComponent.js +2 -2
- package/runtime/tests/TestGetterReactivityComponent.js +2 -2
- package/runtime/tests/TestHarness.d.ts +9 -0
- package/runtime/tests/TestHarness.js +29 -0
- package/runtime/tests/TestIfReinsertBindsInputChildComponent.js +2 -2
- package/runtime/tests/TestIfReinsertBindsInputParentComponent.js +2 -2
- package/runtime/tests/TestIfUnsubscribeNestedParentComponent.js +2 -2
- package/runtime/tests/TestInterpolationNestedPropertyComponentBase.js +2 -2
- package/runtime/tests/TestLateDefineForComponent.js +2 -2
- package/runtime/tests/TestNullInputTextComponent.js +2 -2
- package/runtime/tests/TestOutputBindingParentComponent.js +2 -2
- package/runtime/tests/TestParentBindsTasksComponent.js +2 -2
- package/runtime/tests/TestSwitchReinsertBindsInputChildComponent.js +2 -2
- package/runtime/tests/TestSwitchReinsertBindsInputParentComponent.js +2 -2
- package/runtime/tests/TestSwitchUnsubscribeNestedParentComponent.js +2 -2
- package/runtime/tests/TestTemplateNestedMarkersComponent.js +2 -2
- package/runtime/tests/TestUnsubscribeNestedGrandchildComponent.js +2 -2
- package/runtime/tests/createPipeUnwrapTestComponent.js +2 -2
- package/runtime/tests/createPropertyUnwrapNativeTestComponents.d.ts +4 -0
- package/runtime/tests/createPropertyUnwrapNativeTestComponents.js +23 -0
- package/runtime/tests/createTestInterpolationPipeComponent.js +2 -2
- package/runtime/tests/createTestInterpolationPipeWithArgsComponent.js +2 -2
- package/runtime/tests/typeguards.d.ts +21 -0
- package/runtime/tests/typeguards.js +48 -0
- package/utils/Property.d.ts +8 -2
- package/utils/Property.js +48 -8
- package/utils/DomUtils.d.ts +0 -3
- package/utils/DomUtils.js +0 -6
|
@@ -17,9 +17,9 @@ export class TestChildTasksListComponent extends FluffElement {
|
|
|
17
17
|
<div class="item"></div>
|
|
18
18
|
</template>
|
|
19
19
|
`;
|
|
20
|
-
this.__setMarkerConfigs(
|
|
20
|
+
this.__setMarkerConfigs([
|
|
21
21
|
[0, { type: 'for', iterator: 'task', iterableExprId: 2, deps: ['tasks'], hasEmpty: false }]
|
|
22
|
-
])
|
|
22
|
+
]);
|
|
23
23
|
}
|
|
24
24
|
__setupBindings() {
|
|
25
25
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -10,9 +10,9 @@ export class TestForComponent extends FluffElement {
|
|
|
10
10
|
<test-for-child data-lid="l0"></test-for-child>
|
|
11
11
|
</template>
|
|
12
12
|
`;
|
|
13
|
-
this.__setMarkerConfigs(
|
|
13
|
+
this.__setMarkerConfigs([
|
|
14
14
|
[0, { type: 'for', iterator: 'item', iterableExprId: 0, deps: ['items'], hasEmpty: false }]
|
|
15
|
-
])
|
|
15
|
+
]);
|
|
16
16
|
}
|
|
17
17
|
__setupBindings() {
|
|
18
18
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -42,9 +42,9 @@ export class TestForReinsertBindsInputParentComponent extends FluffElement {
|
|
|
42
42
|
<div class="empty">empty</div>
|
|
43
43
|
</template>
|
|
44
44
|
`;
|
|
45
|
-
this.__setMarkerConfigs(
|
|
45
|
+
this.__setMarkerConfigs([
|
|
46
46
|
[0, { type: 'for', iterator: 'item', iterableExprId: 0, deps: ['items'], hasEmpty: true }]
|
|
47
|
-
])
|
|
47
|
+
]);
|
|
48
48
|
const bindings = {
|
|
49
49
|
l0: [{ n: 'stats', b: 'property', e: 1, d: ['stats'] }]
|
|
50
50
|
};
|
|
@@ -17,10 +17,10 @@ export class TestForTextMarkerCollisionNoTrackParentComponent extends FluffEleme
|
|
|
17
17
|
<span class="tag"><!--fluff:text:9--><!--/fluff:text:9--></span>
|
|
18
18
|
</template>
|
|
19
19
|
`;
|
|
20
|
-
this.__setMarkerConfigs(
|
|
20
|
+
this.__setMarkerConfigs([
|
|
21
21
|
[0, { type: 'for', iterator: 'tag', iterableExprId: 0, deps: ['tags'], hasEmpty: false }],
|
|
22
22
|
[9, { type: 'text', exprId: 1, deps: ['tag'] }]
|
|
23
|
-
])
|
|
23
|
+
]);
|
|
24
24
|
}
|
|
25
25
|
__setupBindings() {
|
|
26
26
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -28,7 +28,7 @@ export class TestForTextMarkerCollisionParentComponent extends FluffElement {
|
|
|
28
28
|
<span class="tag"><!--fluff:text:9--><!--/fluff:text:9--></span>
|
|
29
29
|
</template>
|
|
30
30
|
`;
|
|
31
|
-
this.__setMarkerConfigs(
|
|
31
|
+
this.__setMarkerConfigs([
|
|
32
32
|
[0, { type: 'for', iterator: 'tag', iterableExprId: 0, deps: ['tags'], trackBy: 'tag', hasEmpty: false }],
|
|
33
33
|
[
|
|
34
34
|
9,
|
|
@@ -39,7 +39,7 @@ export class TestForTextMarkerCollisionParentComponent extends FluffElement {
|
|
|
39
39
|
pipes: [{ name: 'lowercase', argExprIds: [] }, { name: 'capitalize', argExprIds: [] }]
|
|
40
40
|
}
|
|
41
41
|
]
|
|
42
|
-
])
|
|
42
|
+
]);
|
|
43
43
|
}
|
|
44
44
|
__setupBindings() {
|
|
45
45
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -20,9 +20,9 @@ export class TestForUnsubscribeNestedParentComponent extends TestUnsubscribeNest
|
|
|
20
20
|
<div class="empty">empty</div>
|
|
21
21
|
</template>
|
|
22
22
|
`;
|
|
23
|
-
this.__setMarkerConfigs(
|
|
23
|
+
this.__setMarkerConfigs([
|
|
24
24
|
[0, { type: 'for', iterator: 'item', iterableExprId: 0, deps: ['items'], hasEmpty: true }]
|
|
25
|
-
])
|
|
25
|
+
]);
|
|
26
26
|
const bindings = {
|
|
27
27
|
l0: [{ n: 'stats', b: 'property', e: 1, d: ['stats'] }]
|
|
28
28
|
};
|
|
@@ -16,9 +16,9 @@ export class TestGetterReactivityComponent extends FluffElement {
|
|
|
16
16
|
this.__getShadowRoot().innerHTML = `
|
|
17
17
|
<div class="count"><!--fluff:text:0--><!--/fluff:text:0--></div>
|
|
18
18
|
`;
|
|
19
|
-
this.__setMarkerConfigs(
|
|
19
|
+
this.__setMarkerConfigs([
|
|
20
20
|
[0, { type: 'text', exprId: 0, deps: ['items'], pipes: [] }]
|
|
21
|
-
])
|
|
21
|
+
]);
|
|
22
22
|
}
|
|
23
23
|
__setupBindings() {
|
|
24
24
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ExpressionFn, type HandlerFn } from '../FluffBase.js';
|
|
2
|
+
export declare class TestHarness {
|
|
3
|
+
static setExpressionTable(expressions: ExpressionFn[], handlers: HandlerFn[]): void;
|
|
4
|
+
static resetExpressionTable(): void;
|
|
5
|
+
static defineCustomElement(tag: string, ctor: CustomElementConstructor): void;
|
|
6
|
+
static mount(tag: string): HTMLElement;
|
|
7
|
+
static tick(count?: number): Promise<void>;
|
|
8
|
+
static waitForTimeout(): Promise<void>;
|
|
9
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { FluffBase } from '../FluffBase.js';
|
|
2
|
+
export class TestHarness {
|
|
3
|
+
static setExpressionTable(expressions, handlers) {
|
|
4
|
+
FluffBase.__setExpressionTable(expressions, handlers);
|
|
5
|
+
}
|
|
6
|
+
static resetExpressionTable() {
|
|
7
|
+
FluffBase.__setExpressionTable([], []);
|
|
8
|
+
}
|
|
9
|
+
static defineCustomElement(tag, ctor) {
|
|
10
|
+
if (!customElements.get(tag)) {
|
|
11
|
+
customElements.define(tag, ctor);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
static mount(tag) {
|
|
15
|
+
const el = document.createElement(tag);
|
|
16
|
+
document.body.appendChild(el);
|
|
17
|
+
return el;
|
|
18
|
+
}
|
|
19
|
+
static async tick(count = 1) {
|
|
20
|
+
for (let i = 0; i < count; i++) {
|
|
21
|
+
await Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
static async waitForTimeout() {
|
|
25
|
+
await new Promise((resolve) => {
|
|
26
|
+
setTimeout(resolve, 0);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -28,9 +28,9 @@ export class TestIfReinsertBindsInputChildComponent extends FluffElement {
|
|
|
28
28
|
this.__getShadowRoot().innerHTML = `
|
|
29
29
|
<div class="total"><!--fluff:text:0--><!--/fluff:text:0--></div>
|
|
30
30
|
`;
|
|
31
|
-
this.__setMarkerConfigs(
|
|
31
|
+
this.__setMarkerConfigs([
|
|
32
32
|
[0, { type: 'text', exprId: 2, deps: ['stats'], pipes: [] }]
|
|
33
|
-
])
|
|
33
|
+
]);
|
|
34
34
|
}
|
|
35
35
|
__setupBindings() {
|
|
36
36
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -39,9 +39,9 @@ export class TestIfReinsertBindsInputParentComponent extends FluffElement {
|
|
|
39
39
|
<test-if-reinsert-binds-input-child x-fluff-component data-lid="l0"></test-if-reinsert-binds-input-child>
|
|
40
40
|
</template>
|
|
41
41
|
`;
|
|
42
|
-
this.__setMarkerConfigs(
|
|
42
|
+
this.__setMarkerConfigs([
|
|
43
43
|
[0, { type: 'if', branches: [{ exprId: 0, deps: ['show'] }] }]
|
|
44
|
-
])
|
|
44
|
+
]);
|
|
45
45
|
const bindings = {
|
|
46
46
|
l0: [{ n: 'stats', b: 'property', e: 1, d: ['stats'] }]
|
|
47
47
|
};
|
|
@@ -17,9 +17,9 @@ export class TestIfUnsubscribeNestedParentComponent extends TestUnsubscribeNeste
|
|
|
17
17
|
<test-unsubscribe-nested-child x-fluff-component data-lid="l0"></test-unsubscribe-nested-child>
|
|
18
18
|
</template>
|
|
19
19
|
`;
|
|
20
|
-
this.__setMarkerConfigs(
|
|
20
|
+
this.__setMarkerConfigs([
|
|
21
21
|
[0, { type: 'if', branches: [{ exprId: 0, deps: ['show'] }] }]
|
|
22
|
-
])
|
|
22
|
+
]);
|
|
23
23
|
const bindings = {
|
|
24
24
|
l0: [{ n: 'stats', b: 'property', e: 1, d: ['stats'] }]
|
|
25
25
|
};
|
|
@@ -19,9 +19,9 @@ export class TestInterpolationNestedPropertyComponentBase extends FluffElement {
|
|
|
19
19
|
}
|
|
20
20
|
__render() {
|
|
21
21
|
this.__getShadowRoot().innerHTML = '<!--fluff:text:0--><!--/fluff:text:0-->';
|
|
22
|
-
this.__setMarkerConfigs(
|
|
22
|
+
this.__setMarkerConfigs([
|
|
23
23
|
[0, { type: 'text', exprId: 0, deps: [['hostClass', 'childProp']], pipes: [] }]
|
|
24
|
-
])
|
|
24
|
+
]);
|
|
25
25
|
}
|
|
26
26
|
__setupBindings() {
|
|
27
27
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -14,9 +14,9 @@ export class TestLateDefineForComponent extends FluffElement {
|
|
|
14
14
|
<late-define-for-child x-fluff-component="" data-lid="l0"></late-define-for-child>
|
|
15
15
|
</template>
|
|
16
16
|
`;
|
|
17
|
-
this.__setMarkerConfigs(
|
|
17
|
+
this.__setMarkerConfigs([
|
|
18
18
|
[0, { type: 'for', iterator: 'column', iterableExprId: 0, deps: ['columns'], hasEmpty: false }]
|
|
19
|
-
])
|
|
19
|
+
]);
|
|
20
20
|
}
|
|
21
21
|
__setupBindings() {
|
|
22
22
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -25,10 +25,10 @@ export class TestNullInputTextComponent extends FluffElement {
|
|
|
25
25
|
</template>
|
|
26
26
|
<template data-fluff-branch="test-null-input-text-0-1"></template>
|
|
27
27
|
`;
|
|
28
|
-
this.__setMarkerConfigs(
|
|
28
|
+
this.__setMarkerConfigs([
|
|
29
29
|
[0, { type: 'if', branches: [{ exprId: 0, deps: ['isEditing'] }, { exprId: undefined, deps: [] }] }],
|
|
30
30
|
[1, { type: 'text', exprId: 1, deps: ['task'], pipes: [] }]
|
|
31
|
-
])
|
|
31
|
+
]);
|
|
32
32
|
}
|
|
33
33
|
__setupBindings() {
|
|
34
34
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -23,9 +23,9 @@ export class TestOutputBindingParentComponent extends FluffElement {
|
|
|
23
23
|
<test-output-binding-child x-fluff-component data-lid="l0"></test-output-binding-child>
|
|
24
24
|
</template>
|
|
25
25
|
`;
|
|
26
|
-
this.__setMarkerConfigs(
|
|
26
|
+
this.__setMarkerConfigs([
|
|
27
27
|
[0, { type: 'if', branches: [{ exprId: 0, deps: ['show'] }] }]
|
|
28
|
-
])
|
|
28
|
+
]);
|
|
29
29
|
const bindings = {
|
|
30
30
|
l0: [{ n: 'edit', b: 'event', h: 0, d: ['onChildEdit'] }]
|
|
31
31
|
};
|
|
@@ -11,9 +11,9 @@ export class TestParentBindsTasksComponent extends FluffElement {
|
|
|
11
11
|
<test-child-tasks-list x-fluff-component="" data-lid="l0"></test-child-tasks-list>
|
|
12
12
|
</template>
|
|
13
13
|
`;
|
|
14
|
-
this.__setMarkerConfigs(
|
|
14
|
+
this.__setMarkerConfigs([
|
|
15
15
|
[0, { type: 'for', iterator: 'child', iterableExprId: 0, deps: ['childList'], hasEmpty: false }]
|
|
16
|
-
])
|
|
16
|
+
]);
|
|
17
17
|
}
|
|
18
18
|
__setupBindings() {
|
|
19
19
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -28,9 +28,9 @@ export class TestSwitchReinsertBindsInputChildComponent extends FluffElement {
|
|
|
28
28
|
this.__getShadowRoot().innerHTML = `
|
|
29
29
|
<div class="total"><!--fluff:text:0--><!--/fluff:text:0--></div>
|
|
30
30
|
`;
|
|
31
|
-
this.__setMarkerConfigs(
|
|
31
|
+
this.__setMarkerConfigs([
|
|
32
32
|
[0, { type: 'text', exprId: 4, deps: ['stats'], pipes: [] }]
|
|
33
|
-
])
|
|
33
|
+
]);
|
|
34
34
|
}
|
|
35
35
|
__setupBindings() {
|
|
36
36
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -42,7 +42,7 @@ export class TestSwitchReinsertBindsInputParentComponent extends FluffElement {
|
|
|
42
42
|
<test-switch-reinsert-binds-input-child x-fluff-component data-lid="l1"></test-switch-reinsert-binds-input-child>
|
|
43
43
|
</template>
|
|
44
44
|
`;
|
|
45
|
-
this.__setMarkerConfigs(
|
|
45
|
+
this.__setMarkerConfigs([
|
|
46
46
|
[
|
|
47
47
|
0, {
|
|
48
48
|
type: 'switch', expressionExprId: 0, deps: ['mode'], cases: [
|
|
@@ -51,7 +51,7 @@ export class TestSwitchReinsertBindsInputParentComponent extends FluffElement {
|
|
|
51
51
|
]
|
|
52
52
|
}
|
|
53
53
|
]
|
|
54
|
-
])
|
|
54
|
+
]);
|
|
55
55
|
const bindings = {
|
|
56
56
|
l0: [{ n: 'stats', b: 'property', e: 3, d: ['stats'] }],
|
|
57
57
|
l1: [{ n: 'stats', b: 'property', e: 3, d: ['stats'] }]
|
|
@@ -20,7 +20,7 @@ export class TestSwitchUnsubscribeNestedParentComponent extends TestUnsubscribeN
|
|
|
20
20
|
<div class="placeholder">placeholder</div>
|
|
21
21
|
</template>
|
|
22
22
|
`;
|
|
23
|
-
this.__setMarkerConfigs(
|
|
23
|
+
this.__setMarkerConfigs([
|
|
24
24
|
[
|
|
25
25
|
0, {
|
|
26
26
|
type: 'switch', expressionExprId: 0, deps: ['mode'], cases: [
|
|
@@ -29,7 +29,7 @@ export class TestSwitchUnsubscribeNestedParentComponent extends TestUnsubscribeN
|
|
|
29
29
|
]
|
|
30
30
|
}
|
|
31
31
|
]
|
|
32
|
-
])
|
|
32
|
+
]);
|
|
33
33
|
const bindings = {
|
|
34
34
|
l0: [{ n: 'stats', b: 'property', e: 3, d: ['stats'] }]
|
|
35
35
|
};
|
|
@@ -27,10 +27,10 @@ export class TestTemplateNestedMarkersComponent extends FluffElement {
|
|
|
27
27
|
<div class="fallback">Fallback</div>
|
|
28
28
|
</template>
|
|
29
29
|
`;
|
|
30
|
-
this.__setMarkerConfigs(
|
|
30
|
+
this.__setMarkerConfigs([
|
|
31
31
|
[0, { type: 'if', branches: [{ exprId: 0, deps: ['show'] }, { exprId: undefined, deps: [] }] }],
|
|
32
32
|
[1, { type: 'text', exprId: 1, deps: ['text'], pipes: [] }]
|
|
33
|
-
])
|
|
33
|
+
]);
|
|
34
34
|
}
|
|
35
35
|
__setupBindings() {
|
|
36
36
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -28,9 +28,9 @@ export class TestUnsubscribeNestedGrandchildComponent extends FluffElement {
|
|
|
28
28
|
this.__getShadowRoot().innerHTML = `
|
|
29
29
|
<div class="total"><!--fluff:text:0--><!--/fluff:text:0--></div>
|
|
30
30
|
`;
|
|
31
|
-
this.__setMarkerConfigs(
|
|
31
|
+
this.__setMarkerConfigs([
|
|
32
32
|
[0, { type: 'text', exprId: 5, deps: ['stats'], pipes: [] }]
|
|
33
|
-
])
|
|
33
|
+
]);
|
|
34
34
|
}
|
|
35
35
|
__setupBindings() {
|
|
36
36
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -19,9 +19,9 @@ export function createPipeUnwrapTestComponent(state) {
|
|
|
19
19
|
};
|
|
20
20
|
__render() {
|
|
21
21
|
this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
|
|
22
|
-
this.__setMarkerConfigs(
|
|
22
|
+
this.__setMarkerConfigs([
|
|
23
23
|
[0, { type: 'text', exprId: 0, deps: ['testProp'], pipes: [{ name: 'capture', argExprIds: [] }] }]
|
|
24
|
-
])
|
|
24
|
+
]);
|
|
25
25
|
}
|
|
26
26
|
__setupBindings() {
|
|
27
27
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare function createClassBindingTestComponent(): CustomElementConstructor;
|
|
2
|
+
export declare function createStyleBindingTestComponent(): CustomElementConstructor;
|
|
3
|
+
export declare function createPropertyBindingTestComponent(): CustomElementConstructor;
|
|
4
|
+
export declare function createAttributeBindingTestComponent(): CustomElementConstructor;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FluffElement } from '../FluffElement.js';
|
|
2
|
+
function createTestComponent(html) {
|
|
3
|
+
return class extends FluffElement {
|
|
4
|
+
__render() {
|
|
5
|
+
this.__getShadowRoot().innerHTML = html;
|
|
6
|
+
}
|
|
7
|
+
__setupBindings() {
|
|
8
|
+
this.__processBindings();
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function createClassBindingTestComponent() {
|
|
13
|
+
return createTestComponent('<div data-lid="l0">test</div>');
|
|
14
|
+
}
|
|
15
|
+
export function createStyleBindingTestComponent() {
|
|
16
|
+
return createTestComponent('<div data-lid="l0">test</div>');
|
|
17
|
+
}
|
|
18
|
+
export function createPropertyBindingTestComponent() {
|
|
19
|
+
return createTestComponent('<button data-lid="l0">test</button>');
|
|
20
|
+
}
|
|
21
|
+
export function createAttributeBindingTestComponent() {
|
|
22
|
+
return createTestComponent('<div data-lid="l0">test</div>');
|
|
23
|
+
}
|
|
@@ -22,9 +22,9 @@ export function createTestInterpolationPipeComponent() {
|
|
|
22
22
|
};
|
|
23
23
|
__render() {
|
|
24
24
|
this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
|
|
25
|
-
this.__setMarkerConfigs(
|
|
25
|
+
this.__setMarkerConfigs([
|
|
26
26
|
[0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'uppercase', argExprIds: [] }] }]
|
|
27
|
-
])
|
|
27
|
+
]);
|
|
28
28
|
}
|
|
29
29
|
__setupBindings() {
|
|
30
30
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -22,9 +22,9 @@ export function createTestInterpolationPipeWithArgsComponent() {
|
|
|
22
22
|
};
|
|
23
23
|
__render() {
|
|
24
24
|
this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
|
|
25
|
-
this.__setMarkerConfigs(
|
|
25
|
+
this.__setMarkerConfigs([
|
|
26
26
|
[0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'truncate', argExprIds: [1] }] }]
|
|
27
|
-
])
|
|
27
|
+
]);
|
|
28
28
|
}
|
|
29
29
|
__setupBindings() {
|
|
30
30
|
this.__initializeMarkers(MarkerManager);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Property } from '../../utils/Property.js';
|
|
1
2
|
import type { TestLateDefineForColumn } from './TestLateDefineForComponent.js';
|
|
2
3
|
import type { TestTask } from './TestNullInputTextComponent.js';
|
|
3
4
|
export declare function hasItem(t: unknown): t is {
|
|
@@ -18,3 +19,23 @@ export declare function hasValue(t: unknown): t is {
|
|
|
18
19
|
export declare function hasTaskId(e: unknown): e is {
|
|
19
20
|
taskId: number;
|
|
20
21
|
};
|
|
22
|
+
export declare function hasItemSelected(obj: unknown): obj is {
|
|
23
|
+
item: {
|
|
24
|
+
selected: Property<boolean>;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export declare function hasItemColor(obj: unknown): obj is {
|
|
28
|
+
item: {
|
|
29
|
+
color: Property<string>;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export declare function hasItemDisabled(obj: unknown): obj is {
|
|
33
|
+
item: {
|
|
34
|
+
disabled: Property<boolean>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
export declare function hasItemValue(obj: unknown): obj is {
|
|
38
|
+
item: {
|
|
39
|
+
value: Property<string>;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
@@ -16,3 +16,51 @@ export function hasValue(t) {
|
|
|
16
16
|
export function hasTaskId(e) {
|
|
17
17
|
return e !== null && typeof e === 'object' && 'taskId' in e && typeof e.taskId === 'number';
|
|
18
18
|
}
|
|
19
|
+
export function hasItemSelected(obj) {
|
|
20
|
+
if (obj === null || typeof obj !== 'object')
|
|
21
|
+
return false;
|
|
22
|
+
if (!('item' in obj))
|
|
23
|
+
return false;
|
|
24
|
+
const { item } = obj;
|
|
25
|
+
if (item === null || typeof item !== 'object')
|
|
26
|
+
return false;
|
|
27
|
+
if (!('selected' in item))
|
|
28
|
+
return false;
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
export function hasItemColor(obj) {
|
|
32
|
+
if (obj === null || typeof obj !== 'object')
|
|
33
|
+
return false;
|
|
34
|
+
if (!('item' in obj))
|
|
35
|
+
return false;
|
|
36
|
+
const { item } = obj;
|
|
37
|
+
if (item === null || typeof item !== 'object')
|
|
38
|
+
return false;
|
|
39
|
+
if (!('color' in item))
|
|
40
|
+
return false;
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
export function hasItemDisabled(obj) {
|
|
44
|
+
if (obj === null || typeof obj !== 'object')
|
|
45
|
+
return false;
|
|
46
|
+
if (!('item' in obj))
|
|
47
|
+
return false;
|
|
48
|
+
const { item } = obj;
|
|
49
|
+
if (item === null || typeof item !== 'object')
|
|
50
|
+
return false;
|
|
51
|
+
if (!('disabled' in item))
|
|
52
|
+
return false;
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
export function hasItemValue(obj) {
|
|
56
|
+
if (obj === null || typeof obj !== 'object')
|
|
57
|
+
return false;
|
|
58
|
+
if (!('item' in obj))
|
|
59
|
+
return false;
|
|
60
|
+
const { item } = obj;
|
|
61
|
+
if (item === null || typeof item !== 'object')
|
|
62
|
+
return false;
|
|
63
|
+
if (!('value' in item))
|
|
64
|
+
return false;
|
|
65
|
+
return true;
|
|
66
|
+
}
|
package/utils/Property.d.ts
CHANGED
|
@@ -9,12 +9,17 @@ export declare class Property<T> {
|
|
|
9
9
|
private value?;
|
|
10
10
|
private committed;
|
|
11
11
|
private _isChanging;
|
|
12
|
-
private readonly _propName?;
|
|
13
12
|
private _parentProperty?;
|
|
14
13
|
private _parentSubscription?;
|
|
14
|
+
private _commitTriggerSub?;
|
|
15
|
+
private _pendingCommitValue?;
|
|
16
|
+
private _options?;
|
|
15
17
|
constructor(options: {
|
|
16
|
-
initialValue
|
|
18
|
+
initialValue?: T;
|
|
17
19
|
propertyName?: string;
|
|
20
|
+
direction?: Direction;
|
|
21
|
+
commitTrigger?: Property<unknown>;
|
|
22
|
+
linkHandler?: (prop: Property<T>) => void;
|
|
18
23
|
} | T);
|
|
19
24
|
prop(): Property<T> | undefined;
|
|
20
25
|
setValue(val: T | Property<T>, inbound?: boolean, commit?: boolean): void;
|
|
@@ -22,6 +27,7 @@ export declare class Property<T> {
|
|
|
22
27
|
private setValueInternal;
|
|
23
28
|
private pushToParent;
|
|
24
29
|
private clearParentLink;
|
|
30
|
+
setCommitTrigger(trigger: Property<unknown>): void;
|
|
25
31
|
reset(): void;
|
|
26
32
|
triggerChange(direction?: Direction): void;
|
|
27
33
|
subscribe(direction: Direction, cb: (val: T) => void): Subscription;
|
package/utils/Property.js
CHANGED
|
@@ -20,16 +20,19 @@ export class Property {
|
|
|
20
20
|
value;
|
|
21
21
|
committed = true;
|
|
22
22
|
_isChanging = false;
|
|
23
|
-
_propName;
|
|
24
23
|
_parentProperty;
|
|
25
24
|
_parentSubscription;
|
|
25
|
+
_commitTriggerSub;
|
|
26
|
+
_pendingCommitValue;
|
|
27
|
+
_options;
|
|
26
28
|
constructor(options) {
|
|
27
29
|
if (this.isOptionsObject(options)) {
|
|
30
|
+
this._options = options;
|
|
28
31
|
if (options.initialValue !== undefined) {
|
|
29
32
|
this.value = options.initialValue;
|
|
30
33
|
}
|
|
31
|
-
if (options.
|
|
32
|
-
this.
|
|
34
|
+
if (options.commitTrigger !== undefined) {
|
|
35
|
+
this.setCommitTrigger(options.commitTrigger);
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
else {
|
|
@@ -41,16 +44,22 @@ export class Property {
|
|
|
41
44
|
}
|
|
42
45
|
setValue(val, inbound = false, commit = true) {
|
|
43
46
|
if (val instanceof Property) {
|
|
47
|
+
const linkHandler = this._options?.linkHandler;
|
|
48
|
+
if (linkHandler) {
|
|
49
|
+
linkHandler(val);
|
|
50
|
+
}
|
|
44
51
|
this.linkToParent(val);
|
|
45
52
|
return;
|
|
46
53
|
}
|
|
47
54
|
if (this._isChanging) {
|
|
48
|
-
|
|
55
|
+
const propName = this._options?.propertyName;
|
|
56
|
+
console.error((propName ? propName + ': ' : '') + 'Binding loop detected: setValue called while change is in progress');
|
|
49
57
|
return;
|
|
50
58
|
}
|
|
51
59
|
const changed = val !== this.value && safeStringify(val) !== safeStringify(this.value);
|
|
52
|
-
if (!changed)
|
|
60
|
+
if (!changed && !(commit && !this.committed)) {
|
|
53
61
|
return;
|
|
62
|
+
}
|
|
54
63
|
this._isChanging = true;
|
|
55
64
|
try {
|
|
56
65
|
this.value = val;
|
|
@@ -62,7 +71,7 @@ export class Property {
|
|
|
62
71
|
this.committed = true;
|
|
63
72
|
this.onInboundChange.emit(val);
|
|
64
73
|
}
|
|
65
|
-
else if (commit
|
|
74
|
+
else if (commit) {
|
|
66
75
|
this.committed = true;
|
|
67
76
|
if (this.value !== undefined) {
|
|
68
77
|
this.onOutboundChange.emit(this.value);
|
|
@@ -83,7 +92,8 @@ export class Property {
|
|
|
83
92
|
root = root._parentProperty;
|
|
84
93
|
}
|
|
85
94
|
this._parentProperty = root;
|
|
86
|
-
this.
|
|
95
|
+
const direction = this._options?.direction ?? Direction.Any;
|
|
96
|
+
this._parentSubscription = root.subscribe(direction, (val) => {
|
|
87
97
|
this.setValueInternal(val, true);
|
|
88
98
|
});
|
|
89
99
|
const currentValue = root.getValue();
|
|
@@ -112,11 +122,22 @@ export class Property {
|
|
|
112
122
|
pushToParent(val) {
|
|
113
123
|
if (!this._parentProperty)
|
|
114
124
|
return;
|
|
125
|
+
const commitTrigger = this._options?.commitTrigger;
|
|
126
|
+
if (commitTrigger) {
|
|
127
|
+
const shouldCommit = Boolean(commitTrigger.getValue());
|
|
128
|
+
if (!shouldCommit) {
|
|
129
|
+
this._pendingCommitValue = { value: val };
|
|
130
|
+
this._parentProperty.setValue(val, false, false);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
this._pendingCommitValue = undefined;
|
|
134
|
+
}
|
|
115
135
|
const sub = this._parentSubscription;
|
|
116
136
|
this._parentSubscription = undefined;
|
|
117
137
|
sub?.unsubscribe();
|
|
118
138
|
this._parentProperty.setValue(val);
|
|
119
|
-
|
|
139
|
+
const direction = this._options?.direction ?? Direction.Any;
|
|
140
|
+
this._parentSubscription = this._parentProperty.subscribe(direction, (v) => {
|
|
120
141
|
this.setValueInternal(v, true);
|
|
121
142
|
});
|
|
122
143
|
}
|
|
@@ -127,6 +148,25 @@ export class Property {
|
|
|
127
148
|
}
|
|
128
149
|
this._parentProperty = undefined;
|
|
129
150
|
}
|
|
151
|
+
setCommitTrigger(trigger) {
|
|
152
|
+
if (this._commitTriggerSub) {
|
|
153
|
+
this._commitTriggerSub.unsubscribe();
|
|
154
|
+
this._commitTriggerSub = undefined;
|
|
155
|
+
}
|
|
156
|
+
this._options ??= {};
|
|
157
|
+
this._options.commitTrigger = trigger;
|
|
158
|
+
this._commitTriggerSub = trigger.onChange.subscribe((val) => {
|
|
159
|
+
if (!val)
|
|
160
|
+
return;
|
|
161
|
+
if (!this._parentProperty)
|
|
162
|
+
return;
|
|
163
|
+
if (!this._pendingCommitValue)
|
|
164
|
+
return;
|
|
165
|
+
const pending = this._pendingCommitValue.value;
|
|
166
|
+
this._pendingCommitValue = undefined;
|
|
167
|
+
this._parentProperty.setValue(pending, false, true);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
130
170
|
reset() {
|
|
131
171
|
this.clearParentLink();
|
|
132
172
|
}
|
package/utils/DomUtils.d.ts
DELETED