Search code examples
javascripttampermonkey

tampermonkey script run accross multiple pages


This is an example what I would like to do. Whenever we are on target url i.e. stackoverflow to appear a sticky footer on the bottom with buttons. One of the buttons to type something in search, submit the form. After this it waits for page to load and do something the page that just loaded, i.e. click on the first link.

I found out this is not possible by just running a click after the submit because the frames of the page change or something like that, how would it be possible to do this with tampermonkey.

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://stackoverflow.com/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    $('body').append('<div id="test"><p><button onclick="myFunction()">Click me</button></p></div>');
    $('body').append(
        `<script type="text/javascript">
             function myFunction() {
                 // page 1
                 document.querySelector('#search > div > input').value="tampermonkey";
                 document.forms[0].submit();

                 // page 2 (DOEST WORK)
                 document.querySelector('#question-summary-29592068 > div.summary > div.result-link > h3 > a');
             }
         </script>`
    );

    $('#test').css({'position': 'fixed',
                   'left': '0',
                   'bottom': '0',
                   'width': '100%',
                   'background-color': 'red',
                   'color': 'white',
                   'text-align': 'center',
                   'z-index':'1'
                  });

})();

Solution

  • The part listed as not working fails because when the form is submitted the page changes but the code doesn't continue once on page 2. This could be solved by having one Userscript that has 2 parts and logic to detect whether the script is running on page 1 or 2. One part could create the footer and submit the form; another performs all necessary actions on page 2 (such as clicking the first link).

    The current script doesn't run on the search results page since the @match field is only set up for the Stack Overflow homepage (https://stackoverflow.com/). The metadata could be changed to include both https://stackoverflow.com/ and https://stackoverflow.com/search?* like this:

    // @match        https://stackoverflow.com/
    // @match        https://stackoverflow.com/search?*
    

    These 2 patches would fix the script allowing it to create the footer, submit the form, and access the form's results in one script. The updated script with patches might look like this:

    // ==UserScript==
    // @name         New Userscript
    // @namespace    http://tampermonkey.net/
    // @version      0.1
    // @description  try to take over the world!
    // @author       You
    // @match        https://stackoverflow.com/
    // @match        https://stackoverflow.com/search?*
    // @grant        none
    // ==/UserScript==
    
    (function() {
        'use strict';
    
        if (location.pathname === '/') { // Part 1. Check if on the homepage and perform all actions
            console.log('Homepage!');
    
            $('body').append('<div id="test"><p><button onclick="myFunction()">Click me</button></p></div>');
            $('body').append(
                `<script type="text/javascript">
                     function myFunction() {
                         // page 1
                         document.querySelector('#search > div > input').value="tampermonkey";
                         document.forms[0].submit();
                     }
                </script>`
            );
    
            $('#test').css({
                'position': 'fixed',
                'left': '0',
                'bottom': '0',
                'width': '100%',
                'background-color': 'red',
                'color': 'white',
                'text-align': 'center',
                'z-index':'1'
            });
        }else if (location.pathname.startsWith('search')) { // Part 2. Check if on the search page and perform all actions
            console.log('Search page!')
    
            document.querySelector('#question-summary-29592068 > div.summary > div.result-link > h3 > a');
        }
    }());