HamsterScript – a micro-library for TamperMonkey

The following is just some thoughts and findings I’ve had on creating a micro-library for personal use for TamperMonkey/Userscripts. The library is not published yet as it is still a proof of concept/learning exercise and a little messy currently


This content originally appeared on DEV Community and was authored by DEV Community

The following is just some thoughts and findings I've had on creating a micro-library for personal use for TamperMonkey/Userscripts. The library is not published yet as it is still a proof of concept/learning exercise and a little messy currently

TamperMonkey Intro

Something I've recently started goofing around with is TamperMonkey, a browser extension that allows you to "install and create userscripts, which are JavaScript programs that can be used to modify web pages".

I enjoy automating and hacking things together and TamperMonkey scratches that itch for me. Browser extensions are very powerful but sometimes you just need to restyle a webpage or inject a little bit of JS. A few scripts I've created recently that I found myself using daily are:

  • Display crime stats for properties on Rightmove (i've been looking at houses a lot lately)
  • Add a hyperlink on every GitHub PR to a "short lived environment" & a link to JIRA tickets
  • Autopopulating web forms for misc dev tools from a GitHub PR
  • Enrich websites I'm developing with detailed debugging information (e.g Session helpers, visible commit_ref, links to logging for the logged in user, cloud tools, links to CMS and CRM entries, envconfigs at a glance). Can be very useful when testers, product owners, etc are running into issues on dev environments.

Why Create A Library Though?

I find myself constantly copy/pasting boilerplate code for new scripts or re-writing from memory and introducing bugs. Want to insert an element? You'll need a lot of lines of code for this:

var textEl = document.createElement('p')
textEl.innerText = "foo";
textEl.className = "";
textEl.onclick = populate;
logo.appendChild(textEl);
// or
someOtherElement.parentNode.appendChild();
// or this monstrosity
textEl.insertBefore(someOtherElement, textEl.firstChild);
// or some other ways

And the same applies for making fetch requests. fetch blocks most requests due to CORS. So you'll need to use GM_xmlhttpRequest instead. But that doesn't use promises because xmlhttpRequest is ancient. So you'll probably want to wrap in a Promise. Then you'll need to parse the response. Then some other stuff. I've needed to copy/paste or change the following for multiple scripts now:

// The following header is required to make cross origin requests:
// @grant GM_xmlhttpRequest

async function parseWebsite(postcode) {
    const url = `https://www.ilivehere.co.uk/check-my-postcode/${postcode}`;

    const response = await Request(url); // Request is defined below
    const html = response.responseText;
    var parser = new DOMParser();

    // Parse the text
    var doc = parser.parseFromString(html, "text/html");
    const number = doc.querySelector('.ilivehere-rating-number').textContent;
    return number;
}

// Wrap xmlRequest in a Promise
function Request(url, opt={}) {
    Object.assign(opt, {
        url,
        timeout: 2000,
        responseType: 'json'
    })

    return new Promise((resolve, reject) => {
        opt.onerror = opt.ontimeout = reject
        opt.onload = resolve

        GM_xmlhttpRequest(opt)
    })
}

Another example - reading a cookie. Unfortunately there's no document.readCookie("foo") so I find myself copy/pasting this and other 'utility' functions across Userscripts:

const getCookie = (name)=> {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}

HamsterScript Intro

Assuming you've made it this far, thanks for sticking around. I decided to create HamsterScript for two reasons:

  • Make it slightly easier to create future Userscripts by using a library with a set of easy to use, common helper functions
  • Create a "cheatsheet" for personal Userscript knowledge

HamsterScript Usage

Installing a library is really simple in a Userscript. Heck, you could even include Vue or jQuery if you wanted too!

// @name         [HamsterScript Example]
...
// @grant        GM_xmlhttpRequest
// @require      <placeholder>/hamsterscript-latest.min.js
...
(async function() {
    'use strict';

    const doc = await hamster.fetchDom("<some-url>");
    const stats = doc.querySelector('.body-band-highlight').childNodes[1].textContent;
        const newBtn = hamster.insert({tag: "p", text}, `[itemprop="streetAddress"]`);
})

Only 3 lines of code for my most common use case. The same in vanilla JS is 20+ lines. Understandably you may lose some readability (what does hamster.fetchDom actually do?). Well as I previously mentioned, the goal of this library is to create a cheatsheet and abstract common functions into a reusable library! You can see what hamster.fetchDom does in the HamsterScript docs OR on GitHub, along with a full explanation and alternative methods

Findings

I doubt anybody will ever come across or use this framework but it's been a fun little exercise for a few reasons:

  • Learnt JSDoc and generating documentation
  • Found out about multiple TamperMonkey APIs and other scripts like waitForKeyElements
  • Comparing the "before" and "after" of using HamsterScript (in one case, 95 lines was simplified to 55 lines)
  • Creating pipelines from scratch to minify and deploy my library

Future Steps

  • Think about versioning my library
  • Hosting multiple versions on a CDN along with multiple versions of documentation
  • Prevent breaking changes


This content originally appeared on DEV Community and was authored by DEV Community


Print Share Comment Cite Upload Translate Updates
APA

DEV Community | Sciencx (2022-03-14T01:29:40+00:00) HamsterScript – a micro-library for TamperMonkey. Retrieved from https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/

MLA
" » HamsterScript – a micro-library for TamperMonkey." DEV Community | Sciencx - Monday March 14, 2022, https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/
HARVARD
DEV Community | Sciencx Monday March 14, 2022 » HamsterScript – a micro-library for TamperMonkey., viewed ,<https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/>
VANCOUVER
DEV Community | Sciencx - » HamsterScript – a micro-library for TamperMonkey. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/
CHICAGO
" » HamsterScript – a micro-library for TamperMonkey." DEV Community | Sciencx - Accessed . https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/
IEEE
" » HamsterScript – a micro-library for TamperMonkey." DEV Community | Sciencx [Online]. Available: https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/. [Accessed: ]
rf:citation
» HamsterScript – a micro-library for TamperMonkey | DEV Community | Sciencx | https://www.scien.cx/2022/03/14/hamsterscript-a-micro-library-for-tampermonkey/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.