Fix: A potential TypeError due to shadowed contains in ElementObserve by songjiz · Pull Request #842 · hotwired/stimulus
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.
<!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.