mirror of
https://github.com/zoriya/v10.git
synced 2026-08-16 02:45:09 +00:00
fix(html): avoid menu item value render loop (#1791)
This commit is contained in:
@@ -335,12 +335,24 @@ export function observeMenuViewContent(content: HTMLElement, onChange: () => voi
|
||||
});
|
||||
}
|
||||
|
||||
const observer = new MutationObserver(scheduleChange);
|
||||
const observer = new MutationObserver((records) => {
|
||||
const changed = records.some((record) => {
|
||||
if (record.type !== 'attributes') return true;
|
||||
|
||||
const name = record.attributeName;
|
||||
if (!name) return true;
|
||||
|
||||
return record.oldValue !== (record.target as Element).getAttribute(name);
|
||||
});
|
||||
|
||||
if (changed) scheduleChange();
|
||||
});
|
||||
|
||||
observer.observe(content, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeOldValue: true,
|
||||
attributeFilter: MENU_VIEW_LAYOUT_ATTRS,
|
||||
});
|
||||
|
||||
|
||||
@@ -172,11 +172,21 @@ describe('menu-viewport-transition', () => {
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(2);
|
||||
|
||||
cleanup();
|
||||
item.setAttribute('data-availability', 'unavailable');
|
||||
item.setAttribute('data-availability', 'available');
|
||||
await waitForMutationFrame();
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(2);
|
||||
|
||||
item.setAttribute('data-availability', 'unavailable');
|
||||
await waitForMutationFrame();
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(3);
|
||||
|
||||
cleanup();
|
||||
item.setAttribute('data-availability', 'available');
|
||||
await waitForMutationFrame();
|
||||
|
||||
expect(onChange).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
|
||||
it('toggles menu viewport data attributes for active and exiting phases', () => {
|
||||
|
||||
@@ -17,6 +17,9 @@ export class MenuItemValueElement extends MediaElement {
|
||||
protected override update(_changed: PropertyValues): void {
|
||||
super.update(_changed);
|
||||
|
||||
this.textContent = this.#ctx.value?.label ?? '';
|
||||
const label = this.#ctx.value?.label ?? '';
|
||||
if (this.textContent !== label) {
|
||||
this.textContent = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,6 +172,26 @@ describe('MenuItemValueElement', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('does not rewrite an unchanged label', async () => {
|
||||
const { value } = setup(createPlaybackRateStore({ playbackRate: 1.5 }), 'playback-rate');
|
||||
|
||||
await value.updateComplete;
|
||||
await waitForAssertion(() => {
|
||||
expect(value.textContent).toBe('1.5×');
|
||||
});
|
||||
|
||||
const mutations: MutationRecord[] = [];
|
||||
const observer = new MutationObserver((records) => mutations.push(...records));
|
||||
observer.observe(value, { childList: true, characterData: true, subtree: true });
|
||||
|
||||
value.requestUpdate();
|
||||
await value.updateComplete;
|
||||
await nextFrame();
|
||||
observer.disconnect();
|
||||
|
||||
expect(mutations).toHaveLength(0);
|
||||
});
|
||||
|
||||
it('renders Off when captions are disabled', async () => {
|
||||
const { value } = setup(
|
||||
createTextTrackStore({
|
||||
|
||||
Reference in New Issue
Block a user