@fluffjs/fluff 0.1.9 → 0.1.11
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/package.json +1 -1
- package/runtime/FluffBase.d.ts +2 -0
- package/runtime/FluffBase.js +94 -10
- package/runtime/FluffElementImpl.d.ts +1 -1
- package/runtime/FluffElementImpl.js +4 -1
- package/runtime/tests/TestPropertyUnwrapChildComponent.d.ts +10 -0
- package/runtime/tests/TestPropertyUnwrapChildComponent.js +19 -0
- package/runtime/tests/TestPropertyUnwrapContainerClass.d.ts +4 -0
- package/runtime/tests/TestPropertyUnwrapContainerClass.js +4 -0
- package/runtime/tests/TestPropertyUnwrapParentComponent.d.ts +9 -0
- package/runtime/tests/TestPropertyUnwrapParentComponent.js +19 -0
- package/runtime/tests/TestWatchNestedPropertyChildComponent.d.ts +13 -0
- package/runtime/tests/TestWatchNestedPropertyChildComponent.js +30 -0
- package/runtime/tests/TestWatchNestedPropertyChildComponent2.d.ts +3 -0
- package/runtime/tests/TestWatchNestedPropertyChildComponent2.js +3 -0
- package/runtime/tests/TestWatchNestedPropertyContainerClass.d.ts +4 -0
- package/runtime/tests/TestWatchNestedPropertyContainerClass.js +4 -0
- package/runtime/tests/TestWatchNestedPropertyParentComponent.d.ts +9 -0
- package/runtime/tests/TestWatchNestedPropertyParentComponent.js +19 -0
- package/runtime/tests/TestWatchNestedPropertyParentComponent2.d.ts +3 -0
- package/runtime/tests/TestWatchNestedPropertyParentComponent2.js +3 -0
package/package.json
CHANGED
package/runtime/FluffBase.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export declare abstract class FluffBase extends HTMLElement {
|
|
|
28
28
|
protected __getCompiledExprFn(exprId: number): ExpressionFn;
|
|
29
29
|
protected __getCompiledHandlerFn(handlerId: number): HandlerFn;
|
|
30
30
|
protected __subscribeToExpressionInScope(deps: PropertyChain[] | undefined, scope: Scope, callback: () => void, subscriptions?: Subscription[]): void;
|
|
31
|
+
private __subscribeToPropertyChain;
|
|
32
|
+
private __subscribeToNestedChain;
|
|
31
33
|
protected __getReactivePropFromScope(propName: string, scope: Scope): Property<unknown> | undefined;
|
|
32
34
|
protected __setChildProperty(el: Element, propName: string, value: unknown): void;
|
|
33
35
|
private __applyPropertyBindingWithScope;
|
package/runtime/FluffBase.js
CHANGED
|
@@ -77,21 +77,105 @@ export class FluffBase extends HTMLElement {
|
|
|
77
77
|
__subscribeToExpressionInScope(deps, scope, callback, subscriptions) {
|
|
78
78
|
if (!deps)
|
|
79
79
|
return;
|
|
80
|
+
const addSub = (sub) => {
|
|
81
|
+
if (subscriptions) {
|
|
82
|
+
subscriptions.push(sub);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.__baseSubscriptions.push(sub);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
80
88
|
for (const dep of deps) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
if (Array.isArray(dep)) {
|
|
90
|
+
this.__subscribeToPropertyChain(dep, scope, callback, addSub);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
const reactiveProp = this.__getReactivePropFromScope(dep, scope);
|
|
94
|
+
if (reactiveProp) {
|
|
95
|
+
addSub(reactiveProp.onChange.subscribe(callback));
|
|
87
96
|
}
|
|
88
|
-
else {
|
|
89
|
-
|
|
97
|
+
else if (!(dep in scope.locals) && !(dep in scope.host)) {
|
|
98
|
+
console.warn(`Binding dependency "${dep}" not found on component ${scope.host.constructor.name}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
__subscribeToPropertyChain(chain, scope, callback, addSub) {
|
|
104
|
+
if (chain.length === 0)
|
|
105
|
+
return;
|
|
106
|
+
const [first, ...rest] = chain;
|
|
107
|
+
const reactiveProp = this.__getReactivePropFromScope(first, scope);
|
|
108
|
+
if (reactiveProp) {
|
|
109
|
+
if (rest.length === 0) {
|
|
110
|
+
addSub(reactiveProp.onChange.subscribe(callback));
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
let nestedSubs = [];
|
|
114
|
+
const resubscribeNested = () => {
|
|
115
|
+
for (const sub of nestedSubs) {
|
|
116
|
+
sub.unsubscribe();
|
|
117
|
+
}
|
|
118
|
+
nestedSubs = [];
|
|
119
|
+
const currentValue = reactiveProp.getValue();
|
|
120
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
121
|
+
this.__subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
122
|
+
nestedSubs.push(sub);
|
|
123
|
+
addSub(sub);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
callback();
|
|
127
|
+
};
|
|
128
|
+
addSub(reactiveProp.onChange.subscribe(resubscribeNested));
|
|
129
|
+
const currentValue = reactiveProp.getValue();
|
|
130
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
131
|
+
this.__subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
132
|
+
nestedSubs.push(sub);
|
|
133
|
+
addSub(sub);
|
|
134
|
+
});
|
|
90
135
|
}
|
|
91
136
|
}
|
|
92
|
-
|
|
93
|
-
|
|
137
|
+
}
|
|
138
|
+
else if (!(first in scope.locals) && !(first in scope.host)) {
|
|
139
|
+
console.warn(`Binding dependency "${first}" not found on component ${scope.host.constructor.name}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
__subscribeToNestedChain(obj, chain, callback, addSub) {
|
|
143
|
+
if (chain.length === 0 || obj === null || obj === undefined)
|
|
144
|
+
return;
|
|
145
|
+
const [first, ...rest] = chain;
|
|
146
|
+
const prop = Reflect.get(obj, first);
|
|
147
|
+
if (prop instanceof Property) {
|
|
148
|
+
if (rest.length === 0) {
|
|
149
|
+
addSub(prop.onChange.subscribe(callback));
|
|
94
150
|
}
|
|
151
|
+
else {
|
|
152
|
+
let nestedSubs = [];
|
|
153
|
+
const resubscribeNested = () => {
|
|
154
|
+
for (const sub of nestedSubs) {
|
|
155
|
+
sub.unsubscribe();
|
|
156
|
+
}
|
|
157
|
+
nestedSubs = [];
|
|
158
|
+
const currentValue = prop.getValue();
|
|
159
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
160
|
+
this.__subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
161
|
+
nestedSubs.push(sub);
|
|
162
|
+
addSub(sub);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
callback();
|
|
166
|
+
};
|
|
167
|
+
addSub(prop.onChange.subscribe(resubscribeNested));
|
|
168
|
+
const currentValue = prop.getValue();
|
|
169
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
170
|
+
this.__subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
171
|
+
nestedSubs.push(sub);
|
|
172
|
+
addSub(sub);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
else if (rest.length > 0 && prop !== null && prop !== undefined) {
|
|
178
|
+
this.__subscribeToNestedChain(prop, rest, callback, addSub);
|
|
95
179
|
}
|
|
96
180
|
}
|
|
97
181
|
__getReactivePropFromScope(propName, scope) {
|
|
@@ -15,7 +15,7 @@ export declare abstract class FluffElement extends FluffBase {
|
|
|
15
15
|
constructor();
|
|
16
16
|
connectedCallback(): void;
|
|
17
17
|
disconnectedCallback(): void;
|
|
18
|
-
$watch: (_properties: string[], callback: () => void) => Subscription;
|
|
18
|
+
$watch: (_properties: string[], callback: (changed: string) => void) => Subscription;
|
|
19
19
|
__processBindingsOnElementPublic(el: HTMLElement, scope: Scope, subscriptions?: Subscription[]): void;
|
|
20
20
|
protected abstract __render(): void;
|
|
21
21
|
protected __setupBindings(): void;
|
|
@@ -62,7 +62,7 @@ export class FluffElement extends FluffBase {
|
|
|
62
62
|
this.__baseSubscriptions = [];
|
|
63
63
|
}
|
|
64
64
|
$watch = (_properties, callback) => {
|
|
65
|
-
callback();
|
|
65
|
+
callback('');
|
|
66
66
|
return {
|
|
67
67
|
unsubscribe: () => {
|
|
68
68
|
}
|
|
@@ -187,6 +187,9 @@ export class FluffElement extends FluffBase {
|
|
|
187
187
|
this.__bindOutputOnElement(el, outputName, handler);
|
|
188
188
|
}
|
|
189
189
|
__setChildProperty(el, propName, value) {
|
|
190
|
+
if (value instanceof Property) {
|
|
191
|
+
value = value.getValue();
|
|
192
|
+
}
|
|
190
193
|
if (el instanceof HTMLElement && el.hasAttribute('x-fluff-component')) {
|
|
191
194
|
const tagName = el.tagName.toLowerCase();
|
|
192
195
|
if (customElements.get(tagName) === undefined) {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export declare let testPropertyUnwrapReceivedValue: number | null;
|
|
4
|
+
export declare function resetTestPropertyUnwrapReceivedValue(): void;
|
|
5
|
+
export declare class TestPropertyUnwrapChildComponent extends FluffElement {
|
|
6
|
+
__property: Property<number | null>;
|
|
7
|
+
get property(): number | null;
|
|
8
|
+
set property(val: number | null);
|
|
9
|
+
protected __render(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export let testPropertyUnwrapReceivedValue = null;
|
|
4
|
+
export function resetTestPropertyUnwrapReceivedValue() {
|
|
5
|
+
testPropertyUnwrapReceivedValue = null;
|
|
6
|
+
}
|
|
7
|
+
export class TestPropertyUnwrapChildComponent extends FluffElement {
|
|
8
|
+
__property = new Property({ initialValue: null, propertyName: 'property' });
|
|
9
|
+
get property() {
|
|
10
|
+
return this.__property.getValue();
|
|
11
|
+
}
|
|
12
|
+
set property(val) {
|
|
13
|
+
testPropertyUnwrapReceivedValue = val;
|
|
14
|
+
this.__property.setValue(val);
|
|
15
|
+
}
|
|
16
|
+
__render() {
|
|
17
|
+
this.__getShadowRoot().innerHTML = '<span></span>';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { TestPropertyUnwrapContainerClass } from './TestPropertyUnwrapContainerClass.js';
|
|
4
|
+
export declare class TestPropertyUnwrapParentComponent extends FluffElement {
|
|
5
|
+
__hostClass: Property<TestPropertyUnwrapContainerClass>;
|
|
6
|
+
get hostClass(): TestPropertyUnwrapContainerClass;
|
|
7
|
+
set hostClass(val: TestPropertyUnwrapContainerClass);
|
|
8
|
+
protected __render(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { TestPropertyUnwrapContainerClass } from './TestPropertyUnwrapContainerClass.js';
|
|
4
|
+
export class TestPropertyUnwrapParentComponent extends FluffElement {
|
|
5
|
+
__hostClass = new Property({ initialValue: new TestPropertyUnwrapContainerClass(), propertyName: 'hostClass' });
|
|
6
|
+
get hostClass() {
|
|
7
|
+
const val = this.__hostClass.getValue();
|
|
8
|
+
if (!val) {
|
|
9
|
+
throw new Error('hostClass is null');
|
|
10
|
+
}
|
|
11
|
+
return val;
|
|
12
|
+
}
|
|
13
|
+
set hostClass(val) {
|
|
14
|
+
this.__hostClass.setValue(val);
|
|
15
|
+
}
|
|
16
|
+
__render() {
|
|
17
|
+
this.__getShadowRoot().innerHTML = '<test-prop-unwrap-child data-lid="l0"></test-prop-unwrap-child>';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export declare let testWatchNestedPropertyCallCount: number;
|
|
4
|
+
export declare let testWatchNestedPropertyLastValue: number | null;
|
|
5
|
+
export declare function resetTestWatchNestedPropertyState(): void;
|
|
6
|
+
export declare class TestWatchNestedPropertyChildComponent extends FluffElement {
|
|
7
|
+
__property: Property<number | null>;
|
|
8
|
+
get property(): number | null;
|
|
9
|
+
set property(val: number | null);
|
|
10
|
+
constructor();
|
|
11
|
+
onPropertyChange(): void;
|
|
12
|
+
protected __render(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export let testWatchNestedPropertyCallCount = 0;
|
|
4
|
+
export let testWatchNestedPropertyLastValue = null;
|
|
5
|
+
export function resetTestWatchNestedPropertyState() {
|
|
6
|
+
testWatchNestedPropertyCallCount = 0;
|
|
7
|
+
testWatchNestedPropertyLastValue = null;
|
|
8
|
+
}
|
|
9
|
+
export class TestWatchNestedPropertyChildComponent extends FluffElement {
|
|
10
|
+
__property = new Property({ initialValue: null, propertyName: 'property' });
|
|
11
|
+
get property() {
|
|
12
|
+
return this.__property.getValue();
|
|
13
|
+
}
|
|
14
|
+
set property(val) {
|
|
15
|
+
this.__property.setValue(val);
|
|
16
|
+
}
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.__baseSubscriptions.push(this.__property.onChange.subscribe(() => {
|
|
20
|
+
this.onPropertyChange();
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
onPropertyChange() {
|
|
24
|
+
testWatchNestedPropertyCallCount++;
|
|
25
|
+
testWatchNestedPropertyLastValue = this.property;
|
|
26
|
+
}
|
|
27
|
+
__render() {
|
|
28
|
+
this.__getShadowRoot().innerHTML = '<span></span>';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { TestWatchNestedPropertyContainerClass } from './TestWatchNestedPropertyContainerClass.js';
|
|
4
|
+
export declare class TestWatchNestedPropertyParentComponent extends FluffElement {
|
|
5
|
+
__hostClass: Property<TestWatchNestedPropertyContainerClass>;
|
|
6
|
+
get hostClass(): TestWatchNestedPropertyContainerClass;
|
|
7
|
+
set hostClass(val: TestWatchNestedPropertyContainerClass);
|
|
8
|
+
protected __render(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { TestWatchNestedPropertyContainerClass } from './TestWatchNestedPropertyContainerClass.js';
|
|
4
|
+
export class TestWatchNestedPropertyParentComponent extends FluffElement {
|
|
5
|
+
__hostClass = new Property({ initialValue: new TestWatchNestedPropertyContainerClass(), propertyName: 'hostClass' });
|
|
6
|
+
get hostClass() {
|
|
7
|
+
const val = this.__hostClass.getValue();
|
|
8
|
+
if (!val) {
|
|
9
|
+
throw new Error('hostClass is null');
|
|
10
|
+
}
|
|
11
|
+
return val;
|
|
12
|
+
}
|
|
13
|
+
set hostClass(val) {
|
|
14
|
+
this.__hostClass.setValue(val);
|
|
15
|
+
}
|
|
16
|
+
__render() {
|
|
17
|
+
this.__getShadowRoot().innerHTML = '<test-watch-nested-child data-lid="l0"></test-watch-nested-child>';
|
|
18
|
+
}
|
|
19
|
+
}
|