@fluffjs/fluff 0.1.13 → 0.1.15
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/decorators/Pipe.d.ts +5 -1
- package/decorators/Pipe.js +9 -0
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/runtime/FluffBase.d.ts +10 -0
- package/runtime/FluffBase.js +23 -1
- package/runtime/FluffElementImpl.d.ts +1 -0
- package/runtime/FluffElementImpl.js +4 -0
- package/runtime/MarkerController.d.ts +2 -0
- package/runtime/MarkerController.js +88 -7
- package/runtime/TextController.js +6 -3
- package/runtime/tests/TestForTextMarkerCollisionParentComponent.js +3 -1
- package/runtime/tests/TestInterpolationNestedPropertyComponentBase.d.ts +10 -0
- package/runtime/tests/TestInterpolationNestedPropertyComponentBase.js +30 -0
- package/runtime/tests/TestInterpolationNestedPropertyContainerClass.d.ts +4 -0
- package/runtime/tests/TestInterpolationNestedPropertyContainerClass.js +4 -0
- package/runtime/tests/TestPropertyBindingPipeChildComponent.d.ts +10 -0
- package/runtime/tests/TestPropertyBindingPipeChildComponent.js +19 -0
- package/runtime/tests/TestPropertyBindingPipeParentComponent.d.ts +9 -0
- package/runtime/tests/TestPropertyBindingPipeParentComponent.js +19 -0
- package/runtime/tests/TestPropertyUnwrapParentComponent.js +4 -1
- package/runtime/tests/TestWatchNestedPropertyParentComponent.js +4 -1
- package/runtime/tests/createPropertyBindingPipeChildComponent.d.ts +2 -0
- package/runtime/tests/createPropertyBindingPipeChildComponent.js +5 -0
- package/runtime/tests/createPropertyBindingPipeParentComponent.d.ts +2 -0
- package/runtime/tests/createPropertyBindingPipeParentComponent.js +5 -0
- package/runtime/tests/createTestInterpolationNestedPropertyComponent.d.ts +2 -0
- package/runtime/tests/createTestInterpolationNestedPropertyComponent.js +5 -0
- package/runtime/tests/createTestInterpolationPipeComponent.d.ts +8 -0
- package/runtime/tests/createTestInterpolationPipeComponent.js +35 -0
- package/runtime/tests/createTestInterpolationPipeWithArgsComponent.d.ts +2 -0
- package/runtime/tests/createTestInterpolationPipeWithArgsComponent.js +35 -0
- package/runtime/tests/typeguards.d.ts +20 -0
- package/runtime/tests/typeguards.js +18 -0
package/decorators/Pipe.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
interface PipeInstance {
|
|
2
|
+
transform: (value: unknown, ...args: unknown[]) => unknown;
|
|
3
|
+
}
|
|
4
|
+
type PipeConstructor = (new () => PipeInstance) & {
|
|
2
5
|
__pipeName?: string;
|
|
3
6
|
};
|
|
7
|
+
export declare function getPipeTransform(name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
|
|
4
8
|
export declare function Pipe(name: string): <T extends PipeConstructor>(target: T) => T;
|
|
5
9
|
export interface PipeTransform<TArgs extends unknown[] = unknown[], TReturn = unknown> {
|
|
6
10
|
transform: (value: unknown, ...args: TArgs) => TReturn;
|
package/decorators/Pipe.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
+
const pipeRegistry = new Map();
|
|
2
|
+
export function getPipeTransform(name) {
|
|
3
|
+
const PipeClass = pipeRegistry.get(name);
|
|
4
|
+
if (!PipeClass)
|
|
5
|
+
return undefined;
|
|
6
|
+
const instance = new PipeClass();
|
|
7
|
+
return (value, ...args) => instance.transform(value, ...args);
|
|
8
|
+
}
|
|
1
9
|
export function Pipe(name) {
|
|
2
10
|
return function (target) {
|
|
3
11
|
target.__pipeName = name;
|
|
12
|
+
pipeRegistry.set(name, target);
|
|
4
13
|
return target;
|
|
5
14
|
};
|
|
6
15
|
}
|
package/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { HostBinding } from './decorators/HostBinding.js';
|
|
|
4
4
|
export { HostListener } from './decorators/HostListener.js';
|
|
5
5
|
export { Input } from './decorators/Input.js';
|
|
6
6
|
export { Output } from './decorators/Output.js';
|
|
7
|
-
export { Pipe } from './decorators/Pipe.js';
|
|
7
|
+
export { getPipeTransform, Pipe } from './decorators/Pipe.js';
|
|
8
8
|
export type { PipeTransform } from './decorators/Pipe.js';
|
|
9
9
|
export { Reactive } from './decorators/Reactive.js';
|
|
10
10
|
export { ViewChild } from './decorators/ViewChild.js';
|
package/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { HostBinding } from './decorators/HostBinding.js';
|
|
|
3
3
|
export { HostListener } from './decorators/HostListener.js';
|
|
4
4
|
export { Input } from './decorators/Input.js';
|
|
5
5
|
export { Output } from './decorators/Output.js';
|
|
6
|
-
export { Pipe } from './decorators/Pipe.js';
|
|
6
|
+
export { getPipeTransform, Pipe } from './decorators/Pipe.js';
|
|
7
7
|
export { Reactive } from './decorators/Reactive.js';
|
|
8
8
|
export { ViewChild } from './decorators/ViewChild.js';
|
|
9
9
|
export { Watch } from './decorators/Watch.js';
|
package/package.json
CHANGED
package/runtime/FluffBase.d.ts
CHANGED
|
@@ -12,6 +12,10 @@ export interface BindingInfo {
|
|
|
12
12
|
t?: string;
|
|
13
13
|
d?: PropertyChain[];
|
|
14
14
|
s?: string;
|
|
15
|
+
p?: {
|
|
16
|
+
n: string;
|
|
17
|
+
a: number[];
|
|
18
|
+
}[];
|
|
15
19
|
}
|
|
16
20
|
export declare abstract class FluffBase extends HTMLElement {
|
|
17
21
|
static __e: ExpressionFn[];
|
|
@@ -27,6 +31,12 @@ export declare abstract class FluffBase extends HTMLElement {
|
|
|
27
31
|
protected __applyBindingWithScope(el: HTMLElement, binding: BindingInfo, scope: Scope, subscriptions?: Subscription[]): void;
|
|
28
32
|
protected __getCompiledExprFn(exprId: number): ExpressionFn;
|
|
29
33
|
protected __getCompiledHandlerFn(handlerId: number): HandlerFn;
|
|
34
|
+
protected __applyPipes(value: unknown, pipes: {
|
|
35
|
+
n: string;
|
|
36
|
+
a: number[];
|
|
37
|
+
}[], locals: Record<string, unknown>): unknown;
|
|
38
|
+
private __applyPipe;
|
|
39
|
+
protected __getPipeFn(_name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
|
|
30
40
|
protected __subscribeToExpressionInScope(deps: PropertyChain[] | undefined, scope: Scope, callback: () => void, subscriptions?: Subscription[]): void;
|
|
31
41
|
private __subscribeToPropertyChain;
|
|
32
42
|
private __subscribeToNestedChain;
|
package/runtime/FluffBase.js
CHANGED
|
@@ -74,6 +74,25 @@ export class FluffBase extends HTMLElement {
|
|
|
74
74
|
}
|
|
75
75
|
return fn;
|
|
76
76
|
}
|
|
77
|
+
__applyPipes(value, pipes, locals) {
|
|
78
|
+
let result = value;
|
|
79
|
+
for (const pipe of pipes) {
|
|
80
|
+
result = this.__applyPipe(pipe.n, result, pipe.a, locals);
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
__applyPipe(name, value, argExprIds, locals) {
|
|
85
|
+
const pipeFn = this.__getPipeFn(name);
|
|
86
|
+
if (!pipeFn) {
|
|
87
|
+
console.warn(`Pipe "${name}" not found`);
|
|
88
|
+
return value;
|
|
89
|
+
}
|
|
90
|
+
const args = argExprIds.map(id => this.__getCompiledExprFn(id)(this, locals));
|
|
91
|
+
return pipeFn(value, ...args);
|
|
92
|
+
}
|
|
93
|
+
__getPipeFn(_name) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
77
96
|
__subscribeToExpressionInScope(deps, scope, callback, subscriptions) {
|
|
78
97
|
if (!deps)
|
|
79
98
|
return;
|
|
@@ -222,7 +241,10 @@ export class FluffBase extends HTMLElement {
|
|
|
222
241
|
throw new Error(`Binding for ${binding.n} is missing exprId`);
|
|
223
242
|
}
|
|
224
243
|
const fn = this.__getCompiledExprFn(binding.e);
|
|
225
|
-
|
|
244
|
+
let value = fn(this, scope.locals);
|
|
245
|
+
if (binding.p && binding.p.length > 0) {
|
|
246
|
+
value = this.__applyPipes(value, binding.p, scope.locals);
|
|
247
|
+
}
|
|
226
248
|
this.__setChildProperty(el, binding.n, value);
|
|
227
249
|
}
|
|
228
250
|
catch (e) {
|
|
@@ -21,6 +21,7 @@ export declare abstract class FluffElement extends FluffBase {
|
|
|
21
21
|
protected __setupBindings(): void;
|
|
22
22
|
protected __addSubscription(sub: Subscription): void;
|
|
23
23
|
protected __pipe(name: string, value: unknown, ...args: unknown[]): unknown;
|
|
24
|
+
protected __getPipeFn(name: string): ((value: unknown, ...args: unknown[]) => unknown) | undefined;
|
|
24
25
|
protected __getShadowRoot(): ShadowRoot;
|
|
25
26
|
protected __setMarkerConfigs(configJson: string): void;
|
|
26
27
|
protected __initializeMarkers(MarkerManagerClass: new (host: FluffElement, shadowRoot: ShadowRoot) => MarkerManagerInterface): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { getPipeTransform } from '../decorators/Pipe.js';
|
|
1
2
|
import { DomUtils } from '../utils/DomUtils.js';
|
|
2
3
|
import { Property } from '../utils/Property.js';
|
|
3
4
|
import { Publisher } from '../utils/Publisher.js';
|
|
@@ -86,6 +87,9 @@ export class FluffElement extends FluffBase {
|
|
|
86
87
|
}
|
|
87
88
|
return pipe(value, ...args);
|
|
88
89
|
}
|
|
90
|
+
__getPipeFn(name) {
|
|
91
|
+
return this.__pipes[name] ?? getPipeTransform(name);
|
|
92
|
+
}
|
|
89
93
|
__getShadowRoot() {
|
|
90
94
|
return this._shadowRoot;
|
|
91
95
|
}
|
|
@@ -31,6 +31,8 @@ export declare abstract class MarkerController {
|
|
|
31
31
|
protected getScope(): Scope;
|
|
32
32
|
protected collectLocalsFromScope(scope: Scope): Record<string, unknown>;
|
|
33
33
|
protected subscribeTo(deps: PropertyChain[], callback: () => void): void;
|
|
34
|
+
private subscribeToPropertyChain;
|
|
35
|
+
private subscribeToNestedChain;
|
|
34
36
|
protected getReactivePropFromScope(propName: string, scope: Scope): Property<unknown> | undefined;
|
|
35
37
|
protected createChildScope(locals: Record<string, unknown>): Scope;
|
|
36
38
|
protected clearContentBetweenMarkersWithCleanup(bindingsSubscriptions: Subscription[]): void;
|
|
@@ -82,14 +82,95 @@ export class MarkerController {
|
|
|
82
82
|
subscribeTo(deps, callback) {
|
|
83
83
|
const scope = this.getScope();
|
|
84
84
|
for (const dep of deps) {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
continue;
|
|
88
|
-
const reactiveProp = this.getReactivePropFromScope(propName, scope);
|
|
89
|
-
if (reactiveProp) {
|
|
90
|
-
const sub = reactiveProp.onChange.subscribe(callback);
|
|
91
|
-
this.subscriptions.push(sub);
|
|
85
|
+
if (Array.isArray(dep)) {
|
|
86
|
+
this.subscribeToPropertyChain(dep, scope, callback);
|
|
92
87
|
}
|
|
88
|
+
else {
|
|
89
|
+
if (dep.startsWith('['))
|
|
90
|
+
continue;
|
|
91
|
+
const reactiveProp = this.getReactivePropFromScope(dep, scope);
|
|
92
|
+
if (reactiveProp) {
|
|
93
|
+
const sub = reactiveProp.onChange.subscribe(callback);
|
|
94
|
+
this.subscriptions.push(sub);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
subscribeToPropertyChain(chain, scope, callback) {
|
|
100
|
+
if (chain.length === 0)
|
|
101
|
+
return;
|
|
102
|
+
const [first, ...rest] = chain;
|
|
103
|
+
if (first.startsWith('['))
|
|
104
|
+
return;
|
|
105
|
+
const reactiveProp = this.getReactivePropFromScope(first, scope);
|
|
106
|
+
if (reactiveProp) {
|
|
107
|
+
if (rest.length === 0) {
|
|
108
|
+
this.subscriptions.push(reactiveProp.onChange.subscribe(callback));
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
let nestedSubs = [];
|
|
112
|
+
const resubscribeNested = () => {
|
|
113
|
+
for (const sub of nestedSubs) {
|
|
114
|
+
sub.unsubscribe();
|
|
115
|
+
}
|
|
116
|
+
nestedSubs = [];
|
|
117
|
+
const currentValue = reactiveProp.getValue();
|
|
118
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
119
|
+
this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
120
|
+
nestedSubs.push(sub);
|
|
121
|
+
this.subscriptions.push(sub);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
callback();
|
|
125
|
+
};
|
|
126
|
+
this.subscriptions.push(reactiveProp.onChange.subscribe(resubscribeNested));
|
|
127
|
+
const currentValue = reactiveProp.getValue();
|
|
128
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
129
|
+
this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
130
|
+
nestedSubs.push(sub);
|
|
131
|
+
this.subscriptions.push(sub);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
subscribeToNestedChain(obj, chain, callback, addSub) {
|
|
138
|
+
if (chain.length === 0 || obj === null || obj === undefined)
|
|
139
|
+
return;
|
|
140
|
+
const [first, ...rest] = chain;
|
|
141
|
+
const prop = Reflect.get(obj, first);
|
|
142
|
+
if (prop instanceof Property) {
|
|
143
|
+
if (rest.length === 0) {
|
|
144
|
+
addSub(prop.onChange.subscribe(callback));
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
let nestedSubs = [];
|
|
148
|
+
const resubscribeNested = () => {
|
|
149
|
+
for (const sub of nestedSubs) {
|
|
150
|
+
sub.unsubscribe();
|
|
151
|
+
}
|
|
152
|
+
nestedSubs = [];
|
|
153
|
+
const currentValue = prop.getValue();
|
|
154
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
155
|
+
this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
156
|
+
nestedSubs.push(sub);
|
|
157
|
+
addSub(sub);
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
callback();
|
|
161
|
+
};
|
|
162
|
+
addSub(prop.onChange.subscribe(resubscribeNested));
|
|
163
|
+
const currentValue = prop.getValue();
|
|
164
|
+
if (currentValue !== null && currentValue !== undefined) {
|
|
165
|
+
this.subscribeToNestedChain(currentValue, rest, callback, (sub) => {
|
|
166
|
+
nestedSubs.push(sub);
|
|
167
|
+
addSub(sub);
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
else if (rest.length > 0 && prop !== null && prop !== undefined) {
|
|
173
|
+
this.subscribeToNestedChain(prop, rest, callback, addSub);
|
|
93
174
|
}
|
|
94
175
|
}
|
|
95
176
|
getReactivePropFromScope(propName, scope) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { getPipeTransform } from '../decorators/Pipe.js';
|
|
2
|
+
import { Property } from '../utils/Property.js';
|
|
1
3
|
import { MarkerController } from './MarkerController.js';
|
|
2
4
|
export class TextController extends MarkerController {
|
|
3
5
|
config;
|
|
@@ -13,6 +15,9 @@ export class TextController extends MarkerController {
|
|
|
13
15
|
const pipes = this.config.pipes ?? [];
|
|
14
16
|
const update = () => {
|
|
15
17
|
let result = this.evaluateExpr(this.config.exprId);
|
|
18
|
+
if (result instanceof Property) {
|
|
19
|
+
result = result.getValue();
|
|
20
|
+
}
|
|
16
21
|
for (const pipe of pipes) {
|
|
17
22
|
result = this.applyPipe(pipe.name, result, pipe.argExprIds);
|
|
18
23
|
}
|
|
@@ -40,9 +45,7 @@ export class TextController extends MarkerController {
|
|
|
40
45
|
}
|
|
41
46
|
applyPipe(name, value, args) {
|
|
42
47
|
const pipes = this.host.__pipes;
|
|
43
|
-
|
|
44
|
-
return value;
|
|
45
|
-
const pipeFn = pipes[name];
|
|
48
|
+
const pipeFn = pipes?.[name] ?? getPipeTransform(name);
|
|
46
49
|
if (!pipeFn) {
|
|
47
50
|
console.warn(`Pipe "${name}" not found`);
|
|
48
51
|
return value;
|
|
@@ -3,6 +3,7 @@ import { FluffElement } from '../FluffElementImpl.js';
|
|
|
3
3
|
import { MarkerManager } from '../MarkerManager.js';
|
|
4
4
|
export class TestForTextMarkerCollisionParentComponent extends FluffElement {
|
|
5
5
|
__tags = new Property({ initialValue: ['docs', 'api'], propertyName: 'tags' });
|
|
6
|
+
// TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
|
|
6
7
|
__pipes = {
|
|
7
8
|
lowercase: (v) => String(v)
|
|
8
9
|
.toLowerCase(),
|
|
@@ -29,7 +30,8 @@ export class TestForTextMarkerCollisionParentComponent extends FluffElement {
|
|
|
29
30
|
`;
|
|
30
31
|
this.__setMarkerConfigs(JSON.stringify([
|
|
31
32
|
[0, { type: 'for', iterator: 'tag', iterableExprId: 0, deps: ['tags'], trackBy: 'tag', hasEmpty: false }],
|
|
32
|
-
[
|
|
33
|
+
[
|
|
34
|
+
9,
|
|
33
35
|
{
|
|
34
36
|
type: 'text',
|
|
35
37
|
exprId: 1,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { TestInterpolationNestedPropertyContainerClass } from './TestInterpolationNestedPropertyContainerClass.js';
|
|
4
|
+
export declare abstract class TestInterpolationNestedPropertyComponentBase extends FluffElement {
|
|
5
|
+
__hostClass: Property<TestInterpolationNestedPropertyContainerClass>;
|
|
6
|
+
get hostClass(): TestInterpolationNestedPropertyContainerClass;
|
|
7
|
+
set hostClass(val: TestInterpolationNestedPropertyContainerClass);
|
|
8
|
+
protected __render(): void;
|
|
9
|
+
protected __setupBindings(): void;
|
|
10
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
import { MarkerManager } from '../MarkerManager.js';
|
|
4
|
+
import { TestInterpolationNestedPropertyContainerClass } from './TestInterpolationNestedPropertyContainerClass.js';
|
|
5
|
+
export class TestInterpolationNestedPropertyComponentBase extends FluffElement {
|
|
6
|
+
__hostClass = new Property({
|
|
7
|
+
initialValue: new TestInterpolationNestedPropertyContainerClass(),
|
|
8
|
+
propertyName: 'hostClass'
|
|
9
|
+
});
|
|
10
|
+
get hostClass() {
|
|
11
|
+
const val = this.__hostClass.getValue();
|
|
12
|
+
if (!val) {
|
|
13
|
+
throw new Error('hostClass is null');
|
|
14
|
+
}
|
|
15
|
+
return val;
|
|
16
|
+
}
|
|
17
|
+
set hostClass(val) {
|
|
18
|
+
this.__hostClass.setValue(val);
|
|
19
|
+
}
|
|
20
|
+
__render() {
|
|
21
|
+
this.__getShadowRoot().innerHTML = '<!--fluff:text:0--><!--/fluff:text:0-->';
|
|
22
|
+
this.__setMarkerConfigs(JSON.stringify([
|
|
23
|
+
[0, { type: 'text', exprId: 0, deps: [['hostClass', 'childProp']], pipes: [] }]
|
|
24
|
+
]));
|
|
25
|
+
}
|
|
26
|
+
__setupBindings() {
|
|
27
|
+
this.__initializeMarkers(MarkerManager);
|
|
28
|
+
super.__setupBindings();
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export declare let testPropertyBindingPipeReceivedValue: unknown;
|
|
4
|
+
export declare function resetTestPropertyBindingPipeReceivedValue(): void;
|
|
5
|
+
export declare class TestPropertyBindingPipeChildComponent extends FluffElement {
|
|
6
|
+
__value: Property<unknown>;
|
|
7
|
+
get value(): unknown;
|
|
8
|
+
set value(val: unknown);
|
|
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 testPropertyBindingPipeReceivedValue = undefined;
|
|
4
|
+
export function resetTestPropertyBindingPipeReceivedValue() {
|
|
5
|
+
testPropertyBindingPipeReceivedValue = undefined;
|
|
6
|
+
}
|
|
7
|
+
export class TestPropertyBindingPipeChildComponent extends FluffElement {
|
|
8
|
+
__value = new Property({ initialValue: undefined, propertyName: 'value' });
|
|
9
|
+
get value() {
|
|
10
|
+
return this.__value.getValue();
|
|
11
|
+
}
|
|
12
|
+
set value(val) {
|
|
13
|
+
this.__value.setValue(val);
|
|
14
|
+
testPropertyBindingPipeReceivedValue = val;
|
|
15
|
+
}
|
|
16
|
+
__render() {
|
|
17
|
+
this.__getShadowRoot().innerHTML = '<span>child</span>';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export declare class TestPropertyBindingPipeParentComponent extends FluffElement {
|
|
4
|
+
__amount: Property<number>;
|
|
5
|
+
get amount(): number;
|
|
6
|
+
set amount(val: number);
|
|
7
|
+
__pipes: Record<string, (v: unknown, ...args: unknown[]) => unknown>;
|
|
8
|
+
protected __render(): void;
|
|
9
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElement.js';
|
|
3
|
+
export class TestPropertyBindingPipeParentComponent extends FluffElement {
|
|
4
|
+
__amount = new Property({ initialValue: 100, propertyName: 'amount' });
|
|
5
|
+
get amount() {
|
|
6
|
+
return this.__amount.getValue() ?? 0;
|
|
7
|
+
}
|
|
8
|
+
set amount(val) {
|
|
9
|
+
this.__amount.setValue(val);
|
|
10
|
+
}
|
|
11
|
+
// TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
|
|
12
|
+
__pipes = {
|
|
13
|
+
double: (v) => (typeof v === 'number' ? v * 2 : 0),
|
|
14
|
+
addSuffix: (v, suffix) => `${String(v)}${String(suffix)}`
|
|
15
|
+
};
|
|
16
|
+
__render() {
|
|
17
|
+
this.__getShadowRoot().innerHTML = '<test-child data-lid="l0"></test-child>';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -2,7 +2,10 @@ import { Property } from '../../utils/Property.js';
|
|
|
2
2
|
import { FluffElement } from '../FluffElement.js';
|
|
3
3
|
import { TestPropertyUnwrapContainerClass } from './TestPropertyUnwrapContainerClass.js';
|
|
4
4
|
export class TestPropertyUnwrapParentComponent extends FluffElement {
|
|
5
|
-
__hostClass = new Property({
|
|
5
|
+
__hostClass = new Property({
|
|
6
|
+
initialValue: new TestPropertyUnwrapContainerClass(),
|
|
7
|
+
propertyName: 'hostClass'
|
|
8
|
+
});
|
|
6
9
|
get hostClass() {
|
|
7
10
|
const val = this.__hostClass.getValue();
|
|
8
11
|
if (!val) {
|
|
@@ -2,7 +2,10 @@ import { Property } from '../../utils/Property.js';
|
|
|
2
2
|
import { FluffElement } from '../FluffElement.js';
|
|
3
3
|
import { TestWatchNestedPropertyContainerClass } from './TestWatchNestedPropertyContainerClass.js';
|
|
4
4
|
export class TestWatchNestedPropertyParentComponent extends FluffElement {
|
|
5
|
-
__hostClass = new Property({
|
|
5
|
+
__hostClass = new Property({
|
|
6
|
+
initialValue: new TestWatchNestedPropertyContainerClass(),
|
|
7
|
+
propertyName: 'hostClass'
|
|
8
|
+
});
|
|
6
9
|
get hostClass() {
|
|
7
10
|
const val = this.__hostClass.getValue();
|
|
8
11
|
if (!val) {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElementImpl.js';
|
|
3
|
+
export interface TestInterpolationPipeComponentInstance extends FluffElement {
|
|
4
|
+
message: string;
|
|
5
|
+
__message: Property<string>;
|
|
6
|
+
}
|
|
7
|
+
export type TestInterpolationPipeComponentConstructor = new () => TestInterpolationPipeComponentInstance;
|
|
8
|
+
export declare function createTestInterpolationPipeComponent(): TestInterpolationPipeComponentConstructor;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElementImpl.js';
|
|
3
|
+
import { MarkerManager } from '../MarkerManager.js';
|
|
4
|
+
export function createTestInterpolationPipeComponent() {
|
|
5
|
+
class TestComponent extends FluffElement {
|
|
6
|
+
__message = new Property({ initialValue: 'hello world', propertyName: 'message' });
|
|
7
|
+
get message() {
|
|
8
|
+
return this.__message.getValue() ?? '';
|
|
9
|
+
}
|
|
10
|
+
set message(val) {
|
|
11
|
+
this.__message.setValue(val);
|
|
12
|
+
}
|
|
13
|
+
// TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
|
|
14
|
+
__pipes = {
|
|
15
|
+
uppercase: (v) => String(v)
|
|
16
|
+
.toUpperCase(),
|
|
17
|
+
truncate: (v, length) => {
|
|
18
|
+
const str = String(v);
|
|
19
|
+
const len = typeof length === 'number' ? length : 10;
|
|
20
|
+
return str.length > len ? str.slice(0, len) + '...' : str;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
__render() {
|
|
24
|
+
this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
|
|
25
|
+
this.__setMarkerConfigs(JSON.stringify([
|
|
26
|
+
[0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'uppercase', argExprIds: [] }] }]
|
|
27
|
+
]));
|
|
28
|
+
}
|
|
29
|
+
__setupBindings() {
|
|
30
|
+
this.__initializeMarkers(MarkerManager);
|
|
31
|
+
super.__setupBindings();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return TestComponent;
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Property } from '../../utils/Property.js';
|
|
2
|
+
import { FluffElement } from '../FluffElementImpl.js';
|
|
3
|
+
import { MarkerManager } from '../MarkerManager.js';
|
|
4
|
+
export function createTestInterpolationPipeWithArgsComponent() {
|
|
5
|
+
class TestComponentWithArgs extends FluffElement {
|
|
6
|
+
__message = new Property({ initialValue: 'hello world', propertyName: 'message' });
|
|
7
|
+
get message() {
|
|
8
|
+
return this.__message.getValue() ?? '';
|
|
9
|
+
}
|
|
10
|
+
set message(val) {
|
|
11
|
+
this.__message.setValue(val);
|
|
12
|
+
}
|
|
13
|
+
// TEST STUB: In real apps, __pipes is generated by the CLI in CodeGenerator.ts
|
|
14
|
+
__pipes = {
|
|
15
|
+
uppercase: (v) => String(v)
|
|
16
|
+
.toUpperCase(),
|
|
17
|
+
truncate: (v, length) => {
|
|
18
|
+
const str = String(v);
|
|
19
|
+
const len = typeof length === 'number' ? length : 10;
|
|
20
|
+
return str.length > len ? str.slice(0, len) + '...' : str;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
__render() {
|
|
24
|
+
this.__getShadowRoot().innerHTML = '<span><!--fluff:text:0--><!--/fluff:text:0--></span>';
|
|
25
|
+
this.__setMarkerConfigs(JSON.stringify([
|
|
26
|
+
[0, { type: 'text', exprId: 0, deps: ['message'], pipes: [{ name: 'truncate', argExprIds: [1] }] }]
|
|
27
|
+
]));
|
|
28
|
+
}
|
|
29
|
+
__setupBindings() {
|
|
30
|
+
this.__initializeMarkers(MarkerManager);
|
|
31
|
+
super.__setupBindings();
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return TestComponentWithArgs;
|
|
35
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { TestLateDefineForColumn } from './TestLateDefineForComponent.js';
|
|
2
|
+
import type { TestTask } from './TestNullInputTextComponent.js';
|
|
3
|
+
export declare function hasItem(t: unknown): t is {
|
|
4
|
+
item: unknown;
|
|
5
|
+
};
|
|
6
|
+
export declare function hasItemName(t: unknown): t is {
|
|
7
|
+
itemName: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function hasTask(t: unknown): t is {
|
|
10
|
+
task: TestTask;
|
|
11
|
+
};
|
|
12
|
+
export declare function isLateDefineForColumn(l: unknown): l is {
|
|
13
|
+
column: TestLateDefineForColumn;
|
|
14
|
+
};
|
|
15
|
+
export declare function hasValue(t: unknown): t is {
|
|
16
|
+
value: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function hasTaskId(e: unknown): e is {
|
|
19
|
+
taskId: number;
|
|
20
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function hasItem(t) {
|
|
2
|
+
return t !== null && typeof t === 'object' && 'item' in t;
|
|
3
|
+
}
|
|
4
|
+
export function hasItemName(t) {
|
|
5
|
+
return t !== null && typeof t === 'object' && 'itemName' in t && typeof t.itemName === 'string';
|
|
6
|
+
}
|
|
7
|
+
export function hasTask(t) {
|
|
8
|
+
return t !== null && typeof t === 'object' && 'task' in t;
|
|
9
|
+
}
|
|
10
|
+
export function isLateDefineForColumn(l) {
|
|
11
|
+
return l !== null && typeof l === 'object' && 'column' in l;
|
|
12
|
+
}
|
|
13
|
+
export function hasValue(t) {
|
|
14
|
+
return t !== null && typeof t === 'object' && 'value' in t && typeof t.value === 'string';
|
|
15
|
+
}
|
|
16
|
+
export function hasTaskId(e) {
|
|
17
|
+
return e !== null && typeof e === 'object' && 'taskId' in e && typeof e.taskId === 'number';
|
|
18
|
+
}
|