Watch grid DOM for id changes.

This commit is contained in:
Dermot Duffy
2023-09-04 18:40:13 -07:00
parent e830db1a77
commit cd84e490a8
2 changed files with 51 additions and 9 deletions
+2
View File
@@ -1,3 +1,5 @@
// TODO: Live non-grid -> live grid -> timeline is different from when the timeline is dragged.
import { import {
CSSResultGroup, CSSResultGroup,
html, html,
+49 -9
View File
@@ -1,5 +1,5 @@
import Masonry from 'masonry-layout'; import Masonry from 'masonry-layout';
import { beforeEach, describe, expect, it, vi } from 'vitest'; import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
import { mock } from 'vitest-mock-extended'; import { mock } from 'vitest-mock-extended';
import { MediaLoadedInfo } from '../../src/types'; import { MediaLoadedInfo } from '../../src/types';
import { import {
@@ -12,6 +12,7 @@ import {
ResizeObserverMock, ResizeObserverMock,
createSlot, createSlot,
createSlotHost, createSlotHost,
requestAnimationFrameMock,
} from '../test-utils'; } from '../test-utils';
vi.mock('lodash-es/throttle', () => ({ vi.mock('lodash-es/throttle', () => ({
@@ -60,14 +61,16 @@ const createController = (host: HTMLElement, options?: MediaGridConstructorOptio
return new MediaGridController(host, options); return new MediaGridController(host, options);
}; };
const triggerMutationObserver = (): void => { const triggerMutationObserver = (hostOrCell: 'cell' | 'host'): void => {
const mutationObserverTrigger = vi.mocked(global.MutationObserver).mock.calls[0][0]; const mutationObserverTrigger = vi.mocked(global.MutationObserver).mock.calls[
hostOrCell === 'host' ? 0 : 1
][0];
mutationObserverTrigger([], mock<MutationObserver>()); mutationObserverTrigger([], mock<MutationObserver>());
}; };
const triggerResizeObserver = (cellOrHost: 'cell' | 'host'): void => { const triggerResizeObserver = (hostOrCell: 'cell' | 'host'): void => {
const resizeObserverTrigger = vi.mocked(global.ResizeObserver).mock.calls[ const resizeObserverTrigger = vi.mocked(global.ResizeObserver).mock.calls[
cellOrHost === 'cell' ? 0 : 1 hostOrCell === 'host' ? 0 : 1
][0]; ][0];
resizeObserverTrigger([], mock<ResizeObserver>()); resizeObserverTrigger([], mock<ResizeObserver>());
}; };
@@ -79,6 +82,10 @@ describe('MediaGridController', () => {
height: 20, height: 20,
}; };
beforeAll(() => {
window.requestAnimationFrame = requestAnimationFrameMock;
});
beforeEach(() => { beforeEach(() => {
vi.clearAllMocks(); vi.clearAllMocks();
vi.stubGlobal('MutationObserver', MutationObserverMock); vi.stubGlobal('MutationObserver', MutationObserverMock);
@@ -311,7 +318,7 @@ describe('MediaGridController', () => {
const newChildren = createChildren(['one', 'two', 'three']); const newChildren = createChildren(['one', 'two', 'three']);
newChildren.forEach((child) => parent.appendChild(child)); newChildren.forEach((child) => parent.appendChild(child));
triggerMutationObserver(); triggerMutationObserver('host');
expect(controller.getGridContents()).toEqual( expect(controller.getGridContents()).toEqual(
new Map([ new Map([
@@ -323,6 +330,33 @@ describe('MediaGridController', () => {
expect(controller.getSelected()).toBeNull(); expect(controller.getSelected()).toBeNull();
}); });
it('should re-calculate children when id attribute changes', () => {
const children = createChildren(['one', 'two', 'three'], 'test-id');
const parent = createParent({ children: children });
const controller = createController(parent, {
selected: 'one',
idAttribute: 'test-id',
});
expect(controller.getSelected()).toBe('one');
expect(controller.getGridSize()).toBe(3);
children[0].setAttribute('test-id', 'alpha');
children[1].setAttribute('test-id', 'beta');
children[2].setAttribute('test-id', 'gamma');
triggerMutationObserver('cell');
expect(controller.getGridContents()).toEqual(
new Map([
['alpha', children[0]],
['beta', children[1]],
['gamma', children[2]],
]),
);
expect(controller.getSelected()).toBeNull();
});
it('should replace children of a slot when they change', () => { it('should replace children of a slot when they change', () => {
const children = createChildren(); const children = createChildren();
const slot = createSlot(); const slot = createSlot();
@@ -372,7 +406,9 @@ describe('MediaGridController', () => {
columnWidth: 246, columnWidth: 246,
}), }),
); );
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe('246px'); expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
'246px',
);
}); });
it('should respect exact columns', () => { it('should respect exact columns', () => {
@@ -459,7 +495,9 @@ describe('MediaGridController', () => {
columnWidth: 246, columnWidth: 246,
}), }),
); );
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe('246px'); expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
'246px',
);
// Clear mock state. // Clear mock state.
vi.mocked(Masonry).mockClear(); vi.mocked(Masonry).mockClear();
@@ -476,7 +514,9 @@ describe('MediaGridController', () => {
columnWidth: 667, columnWidth: 667,
}), }),
); );
expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe('667px'); expect(parent.style.getPropertyValue('--frigate-card-grid-column-size')).toBe(
'667px',
);
expect(masonry.layout).toBeCalled(); expect(masonry.layout).toBeCalled();
// Clear mock state. // Clear mock state.