From 6eb7b5f62f7dad233a9b3ebb373bde6a82fe6e76 Mon Sep 17 00:00:00 2001 From: sebkolind Date: Mon, 27 May 2024 15:33:47 +0200 Subject: [PATCH] wip --- src/__tests__/attributes.test.ts | 8 ++++++++ src/__tests__/main.test.ts | 32 -------------------------------- src/__tests__/tags.test.ts | 8 ++++++++ src/attributes.ts | 8 ++++++-- src/tags.ts | 2 ++ src/types.ts | 8 ++++++-- src/walker.ts | 6 ++++++ 7 files changed, 36 insertions(+), 36 deletions(-) delete mode 100644 src/__tests__/main.test.ts diff --git a/src/__tests__/attributes.test.ts b/src/__tests__/attributes.test.ts index 1fb664dc..3d66c0ba 100644 --- a/src/__tests__/attributes.test.ts +++ b/src/__tests__/attributes.test.ts @@ -34,4 +34,12 @@ describe('attributes.ts', () => { expect(el.value).toBe('test'); }); + + test("doesn't add `mounted` as an attribute", () => { + const el = document.createElement('div'); + + addAttribute(el, 'mounted', 'test'); + + expect(el.hasAttribute('mounted')).toBe(false); + }); }); diff --git a/src/__tests__/main.test.ts b/src/__tests__/main.test.ts deleted file mode 100644 index 8c2109b9..00000000 --- a/src/__tests__/main.test.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { Component, mount, tags } from '../main'; - -describe('main', () => { - test('`null` element', () => { - const el = document.querySelector('.not-defined'); - - expect(mount(el, {} as Component)).toBe(undefined); - }); - - test('setting an unknown state property', () => { - const el = document.createElement('div'); - - expect(() => - mount(el, { - state: { count: 0 }, - view: ({ state }) => - tags.div('', { mounted: () => state['unknown']++ }), - }), - ).toThrow(); - }); - - test('setting a state property to the same value', () => { - const el = document.createElement('div'); - - expect(() => - mount(el, { - state: { count: 0 }, - view: ({ state }) => tags.div('', { mounted: () => (state.count = 0) }), - }), - ).not.toThrow(); - }); -}); diff --git a/src/__tests__/tags.test.ts b/src/__tests__/tags.test.ts index be9ea4c0..147b21c5 100644 --- a/src/__tests__/tags.test.ts +++ b/src/__tests__/tags.test.ts @@ -68,4 +68,12 @@ describe('tags.ts', () => { expect(el.$tent.attributes['data-bar']).toBe('baz'); expect(el.$tent.attributes['onClick']).toBe(fn); }); + + test('mounted', () => { + const fn = jest.fn(); + const el = createTag(['div', 'test', { mounted: fn }]); + + expect(fn).toHaveBeenCalledTimes(1); + expect(fn).toHaveBeenCalledWith({ el }); + }); }); diff --git a/src/attributes.ts b/src/attributes.ts index 1529e2ea..bafe1db5 100644 --- a/src/attributes.ts +++ b/src/attributes.ts @@ -1,10 +1,14 @@ -import { type TentNode, type Attrs } from './types'; +import { type TentNode, type Attrs, type TagAttrsValues } from './types'; function addAttribute( el: TentNode | HTMLElement, key: string, - value: string | boolean | number, + value: TagAttrsValues, ) { + if (key === 'mounted') { + return; + } + if (typeof value === 'boolean') { if (value) { el.setAttribute(key, ''); diff --git a/src/tags.ts b/src/tags.ts index 0edfee30..c8ca138c 100644 --- a/src/tags.ts +++ b/src/tags.ts @@ -26,6 +26,8 @@ function createTag(context: Context) { el.append(typeof children === 'number' ? children.toString() : children); } + attributes?.mounted?.({ el }); + return el; } diff --git a/src/types.ts b/src/types.ts index fc6e1466..c16b87de 100644 --- a/src/types.ts +++ b/src/types.ts @@ -23,9 +23,13 @@ export type TentNode = Node & }; export type Children = string | number | TentNode | (Node | string | Context)[]; -export type Context = [string, Children, object | undefined]; +export type Context = [string, Children, TagAttrs | undefined]; +export type TagAttrsValues = string | boolean | number | Function; +type TagAttrs = Record & { + mounted?: ({ el }: { el: TentNode }) => void; +}; export type Tags = Record< string, - (children: Children, attrs?: object) => TentNode + (children: Children, attrs?: TagAttrs) => TentNode >; diff --git a/src/walker.ts b/src/walker.ts index a68a739a..fc3dd298 100644 --- a/src/walker.ts +++ b/src/walker.ts @@ -19,6 +19,12 @@ function walker(oldNode: TentNode, newNode: TentNode) { return; } + if (oldNode.$tent == null || newNode.$tent == null) { + oldNode.replaceWith(newNode); + + return; + } + // Remove attributes that are not present in the new node for (const key in oldNode.$tent.attributes) { if (newNode.$tent.attributes[key] == null) {