Skip to content

Commit 46cf081

Browse files
authored
Allow each without block params (#86)
* feat: allow each without block params * +
1 parent 78d709b commit 46cf081

File tree

6 files changed

+73
-21
lines changed

6 files changed

+73
-21
lines changed

plugins/converter.test.ts

+36-6
Original file line numberDiff line numberDiff line change
@@ -302,14 +302,26 @@ describe.each([
302302
});
303303
describe('special ember composition helpers', () => {
304304
test('its properly converted', () => {
305-
expect($t<ASTv1.MustacheStatement>(`{{component @cmp 123 name=hash}}`)).toEqual(
306-
`$:() => $:${SYMBOLS.COMPONENT_HELPER}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
305+
expect(
306+
$t<ASTv1.MustacheStatement>(`{{component @cmp 123 name=hash}}`),
307+
).toEqual(
308+
`$:() => $:${
309+
SYMBOLS.COMPONENT_HELPER
310+
}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
307311
);
308-
expect($t<ASTv1.MustacheStatement>(`{{helper @cmp 123 name=hash}}`)).toEqual(
309-
`$:() => $:${SYMBOLS.HELPER_HELPER}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
312+
expect(
313+
$t<ASTv1.MustacheStatement>(`{{helper @cmp 123 name=hash}}`),
314+
).toEqual(
315+
`$:() => $:${
316+
SYMBOLS.HELPER_HELPER
317+
}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
310318
);
311-
expect($t<ASTv1.MustacheStatement>(`{{modifier @cmp 123 name=hash}}`)).toEqual(
312-
`$:() => $:${SYMBOLS.MODIFIER_HELPER}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
319+
expect(
320+
$t<ASTv1.MustacheStatement>(`{{modifier @cmp 123 name=hash}}`),
321+
).toEqual(
322+
`$:() => $:${
323+
SYMBOLS.MODIFIER_HELPER
324+
}([$:this[$args].cmp,123],{name: ${$glimmerCompat('hash')}})`,
313325
);
314326
});
315327
});
@@ -633,6 +645,24 @@ describe.each([
633645
});
634646
});
635647
describe('each condition', () => {
648+
test('it support block-less case', () => {
649+
const converted = $t<ASTv1.BlockStatement>(
650+
`{{#each smf}}<div></div>{{/each}}`,
651+
);
652+
expect(converted).toEqual<HBSControlExpression>(
653+
$control({
654+
type: 'each',
655+
condition: $glimmerCompat('$:smf'),
656+
blockParams: [],
657+
children: [$node({ tag: 'div' })],
658+
}),
659+
);
660+
expect($s(converted)).toEqual(
661+
`$_each(${$glimmerCompat(
662+
'smf',
663+
)}, ($noop,$index,ctx0) => [$_tag('div', $_edp, [], ctx0)], null, this)`,
664+
);
665+
});
636666
test('it adds unstable child wrapper for simple multi-nodes', () => {
637667
const converted = $t<ASTv1.BlockStatement>(
638668
`{{#each foo as |bar|}}<div></div><span></span>{{/each}}`,

plugins/converter.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import type { Flags } from './flags';
2020
const SPECIAL_HELPERS = [
2121
SYMBOLS.HELPER_HELPER,
2222
SYMBOLS.MODIFIER_HELPER,
23-
SYMBOLS.COMPONENT_HELPER
23+
SYMBOLS.COMPONENT_HELPER,
2424
];
2525

2626
function patchNodePath(node: ASTv1.MustacheStatement | ASTv1.SubExpression) {
@@ -137,9 +137,7 @@ export function convert(
137137
.map((p) => serializeParam(p))
138138
.join(',')}],${toObject(hash)})`;
139139
} else {
140-
return `$:${fnPath}(${params
141-
.map((p) => serializeParam(p))
142-
.join(',')})`;
140+
return `$:${fnPath}(${params.map((p) => serializeParam(p)).join(',')})`;
143141
}
144142
/*
145143
params.map(el => {

plugins/utils.ts

+3
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,9 @@ export function serializeNode(
362362
newCtxName,
363363
)}], ${ctxName})`;
364364
} else if (key === '@each') {
365+
if (paramNames.length === 0) {
366+
paramNames.push('$noop');
367+
}
365368
if (paramNames.length === 1) {
366369
// @todo - add compiler param to mark there is no index here
367370
// likely we need to import $getIndex function and pass it as a param for each constructor

src/tests/integration/each-test.gts

+14
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,20 @@ module('Integration | InternalComponent | each', function (hooks) {
1212
users = cell([{ name: cell('Uef') }, { name: cell('Bi') }]);
1313
});
1414

15+
test('it support iteration without block params', async function (assert) {
16+
const list = new Array(10).fill(undefined);
17+
await render(
18+
<template>
19+
<ul>
20+
{{#each list}}
21+
<li></li>
22+
{{/each}}
23+
</ul>
24+
</template>,
25+
);
26+
assert.dom('li').exists({ count: 10 });
27+
});
28+
1529
test('it runs async element destructors for Components with context', async function (assert) {
1630
const animationDelay = 100;
1731
const items = cell([{ id: '1' }, { id: '2' }]);

src/utils/dom.ts

+15-11
Original file line numberDiff line numberDiff line change
@@ -61,20 +61,22 @@ export function $_componentHelper(params: any, hash: any) {
6161
args[key] = hash[key];
6262
});
6363
return new componentFn(...arguments);
64-
}
64+
};
6565
}
6666
export function $_modifierHelper(params: any, hash: any) {
6767
const modifierFn = params.shift();
6868
// @ts-expect-error undefined
6969
if (EmberFunctionalModifiers.has(modifierFn)) {
70-
function wrappedModifier (node: any, _params: any, _hash: any) {
70+
function wrappedModifier(node: any, _params: any, _hash: any) {
7171
console.log('callingWrapperModifier', {
72-
params, _params,
73-
hash, _hash
74-
})
72+
params,
73+
_params,
74+
hash,
75+
_hash,
76+
});
7577
return $_maybeModifier(modifierFn, node, [...params, ..._params], {
7678
...hash,
77-
..._hash
79+
..._hash,
7880
});
7981
}
8082
// @ts-expect-error undefined
@@ -89,14 +91,16 @@ export function $_helperHelper(params: any, hash: any) {
8991
console.log('helper-helper', params, hash);
9092
// @ts-expect-error undefined
9193
if (EmberFunctionalHelpers.has(helperFn)) {
92-
function wrappedHelper (_params: any, _hash: any) {
94+
function wrappedHelper(_params: any, _hash: any) {
9395
console.log('callingWrapperHelper', {
94-
params, _params,
95-
hash, _hash
96-
})
96+
params,
97+
_params,
98+
hash,
99+
_hash,
100+
});
97101
return $_maybeHelper(helperFn, [...params, ..._params], {
98102
...hash,
99-
..._hash
103+
..._hash,
100104
});
101105
}
102106
// @ts-expect-error undefined

src/utils/list.ts

+3
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ class BasicListComponent<T extends { id: number }> {
117117
const map: WeakMap<T, string> = new WeakMap();
118118
this.keyForItem = (item: T) => {
119119
if (IS_DEV_MODE) {
120+
if (typeof item === 'undefined' || item === null) {
121+
return Math.random().toString(36).slice(2);
122+
}
120123
if (isPrimitive(item)) {
121124
console.warn(`Iteration over primitives is not supported yet`);
122125
return String(item);

0 commit comments

Comments
 (0)