Skip to content

Conversation

@songjiz
Copy link

@songjiz songjiz commented May 27, 2025

This PR fixes a potential TypeError: this.element.contains is not a function error in ElementObserver. This error can occur if a child element shadows the native contains method.

To resolve this, the PR replaces this.element.contains(element) with HTMLElement.prototype.contains.call(this.element, element) in the elementIsActive method. This ensures that the native contains method is always called, regardless of any naming conflicts.

For example, consider the following HTML:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script type="module">
      import {
        Application,
        Controller,
      } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js";
      window.Stimulus = Application.start();

      function debounce(fn, delay = 1000) {
        let timeoutId = null;

        return (...args) => {
          clearTimeout(timeoutId);
          timeoutId = setTimeout(() => fn.apply(this, args), delay);
        };
      }

      Stimulus.register(
        "form",
        class extends Controller {
          initialize() {
            this.submit = debounce(this.submit.bind(this), 300);
          }

          submit() {
            this.element.requestSubmit();
          }
        },
      );
    </script>
  </head>
  <body>
    <form action="/search" method="get" data-controller="form">
      <input type="search" name="contains" data-action="form#submit" />
    </form>
  </body>
</html>

In this case, the <input name="contains"> shadows the native contains method on the <form> element, leading to a TypeError: this.element.contains is not a function error at runtime.

@songjiz songjiz force-pushed the fix-element-observer-contains-type-error branch from dfed9ca to 757bd81 Compare May 27, 2025 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant