Skip to content

Commit

Permalink
Fix setting data- attributes during render.
Browse files Browse the repository at this point in the history
  • Loading branch information
edoardocavazza committed Jan 8, 2024
1 parent dff9576 commit 815dd18
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 51 deletions.
35 changes: 7 additions & 28 deletions src/render.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Realm } from '@chialab/quantum';
import { isComponent, type ComponentConstructor, type ComponentInstance } from './Component';
import { isComponent, type ComponentInstance } from './Component';
import { css } from './css';
import { getPropertyDescriptor, isArray } from './helpers';
import { HooksManager, type HooksState } from './Hooks';
Expand All @@ -17,7 +17,6 @@ import {
type Template,
type TreeProperties,
} from './JSX';
import { getProperty } from './property';

/**
* A symbol for node render context.
Expand Down Expand Up @@ -165,14 +164,12 @@ const isWritableProperty = (element: Node, propertyKey: string) => {
* @param propertyKey The property key to update.
* @param value The new value.
* @param oldValue The old value.
* @param constructor The constructor of the node.
*/
const setProperty = <T extends Node | HTMLElement, P extends string & keyof T>(
node: T,
propertyKey: P,
value: T[P] | undefined,
oldValue?: T[P],
constructor?: ComponentConstructor
oldValue?: T[P]
) => {
const isInputValue =
(propertyKey === 'checked' || propertyKey === 'value') && (node as HTMLElement).tagName === 'INPUT';
Expand Down Expand Up @@ -246,21 +243,6 @@ const setProperty = <T extends Node | HTMLElement, P extends string & keyof T>(

if (isReference || wasReference || isInputValue || isProtoProperty) {
(node as unknown as Record<string, unknown>)[propertyKey] = value;
} else if (constructor) {
const observedAttributes = constructor.observedAttributes;
if (!observedAttributes?.includes(propertyKey)) {
if (isWritableProperty(node, propertyKey)) {
(node as unknown as Record<string, unknown>)[propertyKey] = value;
}
} else {
const property = getProperty(node as ComponentInstance, propertyKey as keyof ComponentInstance);
if (property?.fromAttribute) {
(node as unknown as Record<string, unknown>)[propertyKey] = (property.fromAttribute as Function).call(
node,
value as string
);
}
}
}

if (!isProtoProperty) {
Expand Down Expand Up @@ -500,6 +482,7 @@ const renderTemplate = (
}

const node = templateContext.node;
const isComponentNode = isComponent(node);
if (key != null) {
templateContext.key = key;
fragment.keys = (fragment.keys || new Map()).set(key, templateContext);
Expand All @@ -511,9 +494,7 @@ const renderTemplate = (
| (KeyedProperties & TreeProperties & EventProperties & ElementProperties);
templateContext.properties = properties;

let constructor: ComponentConstructor | undefined;
if (isComponent(node)) {
constructor = (node as ComponentInstance).constructor as ComponentConstructor;
if (isComponentNode) {
node.collectUpdatesStart();
}

Expand All @@ -524,8 +505,7 @@ const renderTemplate = (
node,
propertyKey as keyof Node,
undefined,
oldProperties[propertyKey as keyof typeof oldProperties] as Node[keyof Node],
constructor
oldProperties[propertyKey as keyof typeof oldProperties] as Node[keyof Node]
);
}
}
Expand All @@ -537,13 +517,12 @@ const renderTemplate = (
node,
propertyKey as keyof Node,
properties[propertyKey as keyof typeof properties] as Node[keyof Node],
oldProperties?.[propertyKey as keyof typeof oldProperties] as Node[keyof Node],
constructor
oldProperties?.[propertyKey as keyof typeof oldProperties] as Node[keyof Node]
);
}
}

if (constructor) {
if (isComponentNode) {
(node as ComponentInstance).collectUpdatesEnd();
}

Expand Down
37 changes: 14 additions & 23 deletions test/render.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,11 +383,11 @@ describe(
}
);

DNA.render(DNA.h(name, { number: '2' }), wrapper);
expect(wrapper.querySelector(name).number).toBe(2);
const elem = DNA.render(DNA.h(name, { number: '2' }), wrapper);
expect(elem.number).toBe(2);
});

it('should assign not observed attributes', () => {
it('should assign properties and attributes to component', () => {
const name = getComponentName();
DNA.define(
name,
Expand All @@ -402,27 +402,18 @@ describe(
}
);

DNA.render(DNA.h(name, { string: '2' }), wrapper);
expect(wrapper.querySelector(name).string).toBe('2');
});

it('should assign not string attribute', () => {
const name = getComponentName();
DNA.define(
name,
class TestElement extends DNA.Component {
static get properties() {
return {
number: {
type: Number,
},
};
}
}
const elem = DNA.render(
DNA.h(name, { 'number': 2, 'string': '2', 'object': {}, 'data-test': '3' }),
wrapper
);

DNA.render(DNA.h(name, { number: 2 }), wrapper);
expect(wrapper.querySelector(name).number).toBe(2);
expect(elem.number).toBe(2);
expect(elem.string).toBeUndefined();
expect(elem.getAttribute('string')).toBe('2');
expect(elem.object).toBeTypeOf('object');
expect(elem.getAttribute('object')).toBeNull();
expect(elem['data-test']).toBeUndefined();
expect(elem.getAttribute('data-test')).toBe('3');
expect(elem.dataset.test).toBe('3');
});

it('should update add and remove classes', () => {
Expand Down

0 comments on commit 815dd18

Please sign in to comment.