Skip to content

Commit

Permalink
fix(ssr): make "for" attribute watcher SSR compatible
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 536858733
  • Loading branch information
Elliott Marquez authored and copybara-github committed May 31, 2023
1 parent 60fe02e commit f47bdc3
Showing 1 changed file with 19 additions and 15 deletions.
34 changes: 19 additions & 15 deletions internal/controller/attachable-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import {ReactiveController, ReactiveControllerHost} from 'lit';
import {ReactiveController, ReactiveControllerHost, isServer} from 'lit';

/**
* An element that can be attached to an associated controlling element.
Expand Down Expand Up @@ -73,19 +73,23 @@ interface AttachableControllerHost extends ReactiveControllerHost, HTMLElement {
[ATTACHABLE_CONTROLLER]?: AttachableController;
}

/**
* A global `MutationObserver` that reacts to `for` attribute changes on
* `Attachable` elements. If the `for` attribute changes, the controller will
* re-attach to the new referenced element.
*/
const FOR_ATTRIBUTE_OBSERVER = new MutationObserver(records => {
for (const record of records) {
// When a control's `for` attribute changes, inform its
// `AttachableController` to update to a new control.
(record.target as AttachableControllerHost)[ATTACHABLE_CONTROLLER]
?.hostConnected();
}
});
let FOR_ATTRIBUTE_OBSERVER: MutationObserver|undefined;

if (!isServer) {
/**
* A global `MutationObserver` that reacts to `for` attribute changes on
* `Attachable` elements. If the `for` attribute changes, the controller will
* re-attach to the new referenced element.
*/
FOR_ATTRIBUTE_OBSERVER = new MutationObserver(records => {
for (const record of records) {
// When a control's `for` attribute changes, inform its
// `AttachableController` to update to a new control.
(record.target as AttachableControllerHost)[ATTACHABLE_CONTROLLER]
?.hostConnected();
}
});
}

/**
* A controller that provides an implementation for `Attachable` elements.
Expand Down Expand Up @@ -150,7 +154,7 @@ export class AttachableController implements ReactiveController, Attachable {
(prev: HTMLElement|null, next: HTMLElement|null) => void) {
host.addController(this);
host[ATTACHABLE_CONTROLLER] = this;
FOR_ATTRIBUTE_OBSERVER.observe(host, {attributeFilter: ['for']});
FOR_ATTRIBUTE_OBSERVER?.observe(host, {attributeFilter: ['for']});
}

attach(control: HTMLElement) {
Expand Down

0 comments on commit f47bdc3

Please sign in to comment.