From ff0d118f287c40884b618f8b057934f0b99d71b3 Mon Sep 17 00:00:00 2001 From: Will Harney <62956339+wjhsf@users.noreply.github.com> Date: Thu, 19 Dec 2024 14:44:38 -0500 Subject: [PATCH] fix: only call callback when needed @W-17420330 (#5064) * fix: only call callback when needed @W-17420330 * chore: simplify test * fix: use correct class check --- packages/@lwc/engine-core/src/framework/main.ts | 1 + .../src/apis/build-custom-element-constructor.ts | 6 +++++- .../component/lifecycle-callbacks/index.spec.js | 14 ++++++++++++++ .../lifecycle-callbacks/x/details/details.html | 10 ++++++++++ .../lifecycle-callbacks/x/details/details.js | 5 +++++ 5 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.html create mode 100644 packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.js diff --git a/packages/@lwc/engine-core/src/framework/main.ts b/packages/@lwc/engine-core/src/framework/main.ts index c7ecba9c99..fee61e3f23 100644 --- a/packages/@lwc/engine-core/src/framework/main.ts +++ b/packages/@lwc/engine-core/src/framework/main.ts @@ -31,6 +31,7 @@ export { registerTemplate } from './secure-template'; export { registerDecorators } from './decorators/register'; // Mics. internal APIs ----------------------------------------------------------------------------- +export { BaseBridgeElement } from './base-bridge-element'; export { unwrap } from './membrane'; export { sanitizeAttribute } from './secure-template'; export { getComponentDef, isComponentConstructor } from './def'; diff --git a/packages/@lwc/engine-dom/src/apis/build-custom-element-constructor.ts b/packages/@lwc/engine-dom/src/apis/build-custom-element-constructor.ts index 83adaa2608..69bd97842b 100644 --- a/packages/@lwc/engine-dom/src/apis/build-custom-element-constructor.ts +++ b/packages/@lwc/engine-dom/src/apis/build-custom-element-constructor.ts @@ -17,6 +17,7 @@ import { runFormDisabledCallback, runFormResetCallback, runFormStateRestoreCallback, + BaseBridgeElement, } from '@lwc/engine-core'; import { isNull } from '@lwc/shared'; import { renderer } from '../renderer'; @@ -121,7 +122,10 @@ export function buildCustomElementConstructor(Ctor: ComponentConstructor): HTMLE } attributeChangedCallback(name: string, oldValue: any, newValue: any) { - attributeChangedCallback.call(this, name, oldValue, newValue); + if (this instanceof BaseBridgeElement) { + // W-17420330 + attributeChangedCallback.call(this, name, oldValue, newValue); + } } formAssociatedCallback(form: HTMLFormElement | null) { diff --git a/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/index.spec.js b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/index.spec.js index 79f7ee8588..48b6f2d306 100644 --- a/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/index.spec.js +++ b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/index.spec.js @@ -10,6 +10,7 @@ import TimingParent from 'timing/parent'; import TimingParentLight from 'timing/parentLight'; import ReorderingList from 'reordering/list'; import ReorderingListLight from 'reordering/listLight'; +import Details from 'x/details'; function resetTimingBuffer() { window.timingBuffer = []; @@ -422,3 +423,16 @@ describe('dispatchEvent from connectedCallback/disconnectedCallback', () => { expect(globalDisconnected).toBe(false); // never received due to disconnection }); }); + +describe('attributeChangedCallback', () => { + it('W-17420330 - only fires for registered component', async () => { + const root = createElement('x-details', { is: Details }); + document.body.appendChild(root); + await Promise.resolve(); + + const details = root.shadowRoot.querySelector('details'); + const cb = Details.CustomElementConstructor.prototype.attributeChangedCallback; + cb.call(details, 'open', '', 'open'); + expect(details.getAttribute('open')).toBeNull(); + }); +}); diff --git a/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.html b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.html new file mode 100644 index 0000000000..2acc02de3d --- /dev/null +++ b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.html @@ -0,0 +1,10 @@ + diff --git a/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.js b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.js new file mode 100644 index 0000000000..8c861d75cf --- /dev/null +++ b/packages/@lwc/integration-karma/test/component/lifecycle-callbacks/x/details/details.js @@ -0,0 +1,5 @@ +import { LightningElement, api } from 'lwc'; + +export default class Details extends LightningElement { + @api open; +}