Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions src/parser/parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ describe('Parser', () => {
expect(template).toEqual(`<div>${num}</div>`);
});

it('renders 0 for { value: 0 } expressions', () => {
const expr = { value: 0 };
const template = rml`<div>${expr}</div>`;
expect(template).toEqual('<div>0</div>');
});

it('handles -0 as "0"', () => {
// Don't ask why, it's a JavaScript quirk
const num = -0;
Expand Down Expand Up @@ -558,29 +564,36 @@ describe('Parser', () => {
describe('Any sink', () => {

describe('When a BehaviorSubject (.value) is passed', () => {

describe('When an implicit sink is used', () => {

it('sets the value inline', () => {
const bs = new BehaviorSubject(123)
const template = rml`<div>${bs}</div>`;

expect(template).toMatch(/<div.*>123<\/div>/);
});

});

describe('When an explicit sink is used', () => {

it('sets the value inline', () => {
const bs = new BehaviorSubject(123)
const template = rml`<div>${InnerText(bs)}</div>`;

expect(template).toMatch(/<div.*>123<\/div>/);
});
});

describe('Content', () => {
it('renders 0 when an object has a .value of 0', () => {
const zeroValueObject = { value: 0 };
const template = rml`<div>${zeroValueObject}</div>`;
expect(template).toEqual('<div>0</div>');
});
});

describe('Attributes', () => {
it('renders 0 in an attribute when an object has a .value of 0', () => {
const zeroValueObject = { value: 0 };
const template = rml`<input value="${zeroValueObject}">`;
expect(template).toEqual(`<input value="0">`);
});
});
});

});
Expand Down
31 changes: 21 additions & 10 deletions src/parser/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,20 @@ const getEventName = (eventAttributeString: RMLEventAttributeName): [RMLEventNam
* <input type="number" value="${number}">
* `;
* };
* ```
*
* ## Example
*
* ```ts
* import { rml } from 'rimmel';
*
* const Component = () => {
if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
acc = accPlusString +(expression ?? '');
} else if (
expression && typeof expression === 'object' &&
'value' in expression &&
(typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
) {
// Render the value property of objects, including 0
acc = accPlusString + (expression.value ?? '');
} else {
//other existing logic for different expression types
}
}

* const data = fetch('/api').then(res => res.text());
*
* return rml`
Expand Down Expand Up @@ -127,8 +133,13 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
const printableExpressionType = typeof (expression ?? '');

if(['string', 'number', 'boolean'].includes(printableExpressionType)) {
// Static expressions, no data binding. Just concatenate and move on
acc = accPlusString +(expression ?? '');
} else if (
expression && typeof expression === 'object' &&
'value' in expression &&
(typeof expression.value === 'string' || typeof expression.value === 'number' || typeof expression.value === 'boolean')
) {
acc = accPlusString + (expression.value ?? '');
} else if(eventName) {
// Event Source
// so feed it to an Rx Subject | Observer | Handler Function | POJO | Array
Expand Down Expand Up @@ -268,7 +279,7 @@ export function rml(strings: TemplateStringsArray, ...expressions: RMLTemplateEx
addRef(ref, isSinkBindingConfiguration(_source) ? _source : InnerHTML(_source));
acc = acc
+(existingRef ? string : string.replace(/\s*>\s*$/, ` ${RESOLVE_ATTRIBUTE}="${ref}">`))
+(initialValue || '')
+(initialValue ?? '')
;

} else if(/>?\s*[^<]*$/m.test(string) && /^\s*[^<]*\s*<?/m.test(nextString)) {
Expand Down