donobu
Version:
Create browser automations with an LLM agent and replay them as Playwright scripts.
63 lines (57 loc) • 2.01 kB
JavaScript
(() => {
const clickableElements = new Set();
const originalAddEventListener = EventTarget.prototype.addEventListener;
const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
const pointerEvents = [
'click',
'mousedown',
'pointerdown',
'mouseup',
'pointerup',
'touchstart',
];
// Helper function to check if an element is in shadow DOM
const isInShadowDOM = (element) => {
return element.getRootNode() instanceof ShadowRoot;
};
EventTarget.prototype.addEventListener = function (type, listener, options) {
if (pointerEvents.includes(type) && this !== window && this !== document) {
clickableElements.add(this);
// If this element is in shadow DOM, we need to ensure it's accessible
if (isInShadowDOM(this)) {
const shadowRoot = this.getRootNode();
if (shadowRoot.host) {
clickableElements.add(shadowRoot.host); // Add the shadow host as well
}
}
}
return originalAddEventListener.call(this, type, listener, options);
};
EventTarget.prototype.removeEventListener = function (
type,
listener,
options,
) {
if (pointerEvents.includes(type) && this !== window && this !== document) {
clickableElements.delete(this);
}
return originalRemoveEventListener.call(this, type, listener, options);
};
// Modified to also return elements from shadow DOM
window.donobuGetClickableElements = () => {
const allClickableElements = [];
clickableElements.forEach((element) => {
allClickableElements.push(element);
// If element is a shadow host, get clickable elements from its shadow root
if (element.shadowRoot) {
const shadowElements = element.shadowRoot.querySelectorAll('*');
shadowElements.forEach((shadowEl) => {
if (clickableElements.has(shadowEl)) {
allClickableElements.push(shadowEl);
}
});
}
});
return allClickableElements;
};
})();