dragonmnl
dragonmnl

Reputation: 15548

How can I click on a button when it becomes visible in Gmail?

I have written a Tampermonkey script to auto-click on the little arrow of gmail "send as" when the composer window is open.

"send as" arrow

Two things don't seem to work:

  1. The observer will resolve the promise only once (so it seems this will work only once, for the first time the composer window is open). I have tried to remove observer.disconnect(); but it won't help.
  2. The .click() itself is not working (not even from regular Chrome console when calling element.click()).

Is there a way to make this work?

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  some script
// @author       You
// @match        http*://mail.google.com/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant        none
// ==/UserScript==

(function() {
    async function waitForElement(selector) {
        return new Promise(resolve => {
            if (document.querySelector(selector)) {
                return resolve(document.querySelector(selector));
            }

            const observer = new MutationObserver(mutations => {
                if (document.querySelector(selector)) {
                    resolve(document.querySelector(selector));
                    observer.disconnect();
                }
            });

            observer.observe(document.body, {
                childList: true,
                subtree: true
            });
        });
    }

    waitForElement('.nH.Hd[role=dialog]').then(button => {
        console.log('Compose window is open');
        console.log(button.querySelector('.J-J5-Ji.J-JN-M-I-JG'));

        const downEvt = new MouseEvent("mousedown");
        button.dispatchEvent(downEvt);
    })
})();

Upvotes: 0

Views: 354

Answers (1)

double-beep
double-beep

Reputation: 5504

Do consider making the selectors more stable - the ones you use are bound to change.

The script below uses waitForKeyElements, a utility developed by Brock Adams. The third parameter (false) continues to search for new elements even after the first one has been found.

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  some script
// @author       You
// @match        http*://mail.google.com/*
// @require      https://gist.githubusercontent.com/BrockA/2625891/raw/waitForKeyElements.js
// @require      https://code.jquery.com/jquery-3.6.3.min.js
// @grant        none
// ==/UserScript==
/* globals waitForKeyElements */

(function() {
    waitForKeyElements('.nH.Hd[role=dialog] .J-J5-Ji.J-JN-M-I-JG', element => {
        const downEvt = new MouseEvent("mousedown");
        const parent = element[0].parentElement;

        // for stability
        if (!parent.innerText.includes("one of your emails")) return;

        parent.dispatchEvent(downEvt);
    }, false);
})();

Upvotes: 1

Related Questions