28

I've written a simple Greasemonkey script, and I'm trying to create a "config" page for this script (like the one that is used for Google Chrome extensions. ) Would there be any way to create a config page for a userscript, like the "options" pages for Google Chrome extensions? There isn't any way to include an .html page as part of a Greasemonkey script (as far as I know), so I'm looking for other options.

// ==UserScript==
// @name       Redirector
// @namespace  http://use.i.E.your.homepage/
// @version    0.1
// @description  enter something useful
// @match      http://*/*
// @copyright  2012+, You
// @run-at document-start
// ==/UserScript==

redirectToPage("http://www.youtube.com/", "http://www.google.com");

function redirectToPage(page1, page2){
if(window.location.href.indexOf(page1) != -1){
    window.location.href = page2;
}
}
Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • Perhaps I could use the "about:blank" page, for example: `about:blank#redirector-config`. Would this work? (I'll need to test it and find out. :) ) – Anderson Green Jan 29 '13 at 23:58

5 Answers5

33

There are a few libraries which provide config pages for userscripts:

1) GM_config

Example GM_config dialog

2) MonkeyConfig

Example MonkeyConfig dialog

3) GM_registerMenuCommand Submenu JS Module


The usage varies per library, but typically you grant the permissions they need such as GM_getValue and GM_setValue, and require the library via the @require directive, e.g.:

// ==UserScript==
// @name          My Userscript
// @description   An example userscript with a config page
// @version       0.0.1
// @require       https://www.example.com/lib/myconfig.js
// @grant         GM_getValue
// @grant         GM_setValue
// @grant         GM_addStyle
// @grant         GM_registerMenuCommand
// ==/UserScript==

const config = new MyConfig({ ... })

You then register a menu command which opens the config page/dialog, e.g.:

GM_registerMenuCommand('Configure My Userscript!', () => {
    config.open()
})

In the case of MonkeyConfig, it can register the command for you:

const config = new MonkeyConfig({
    title: 'Configure My Userscript!',
    menuCommand: true,
    // ...
})

For advanced uses, the configurator may allow listeners to be registered for the close/cancel/save events, as well as providing control over the CSS, and other options. Detailed instructions can be found on the GM_config wiki and the MonkeyConfig homepage.

chocolateboy
  • 1,693
  • 1
  • 19
  • 21
  • 1
    Thanks for the useful and comprehensive answer. Just used `GM_config` for the first time. I was favorably impressed with how easy this was to set up. – Dan Lenski Oct 30 '20 at 05:56
8

If you are using it for chrome, then it isn't Greasemonkey but Tampermonkey.

You may consider using GM_getResourceText, paste your html to pastebin.com (or similar) and add the link as one of @resource to the metadata block. At least, I know it works to Greasemonkey.

For example:

// @resource configHtml http://pastebin.com/raw.php?i=2RjKfwJQ

// ... some DOM node that you will append to the current page
node.innerHTML = GM_getResourceText("configHtml");
w35l3y
  • 8,613
  • 3
  • 39
  • 51
2

Use a parameter to the page you're already including, and if that's set then clear the whole document: http://page.my.script.runs.on/?configPage=true

if(getUrlParameter("configPage") === "true") {
    $(document).empty
}
sicotron
  • 245
  • 2
  • 9
  • 1
    `$(document).empty` doesn’t do anything. Why even rely on jQuery, or is this pseudo-code? Using built-in methods: `document.body.replaceChildren([]);`. Instead of `getUrlParameter("configPage")`, `new URL(location.href).searchParams.get("configPage")` can be used. – Sebastian Simon Oct 25 '20 at 12:49
1

This is much needed but for now combination of 2 approaches should work.

1) For personal use I just have a bunch of variables at the top of the script. The problem here is that if anyone else uses my script an update ends up erasing his preferences.

2) Have a configuration page on your website. While this works wonderfully websites get deleted all the time. There is no good reason for a script to depend on a website to work.

If you do both those things the user can edit the preferences in the script when the scripts website vanishes.

Here is an example where undesired functionality is // commented out.

http://go-here.nl/gm/wikipedia-clean-up.php

Good luck and enjoy

user40521
  • 1,997
  • 20
  • 8
1

this userscript don't use any external libs. with modification you can make good UI.

// ==UserScript==
// @name         UI development
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       ManojBhakarPCM
// @match        https://www.google.com/
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    function ui_create(contentss){
        var div = document.createElement('div');
        //var contentss = "<h1>TESTsssss</h1>";
        div.innerHTML = '<div id="mbpcm_modal" style="position: fixed;z-index: 1;left: 0;top: 0;width: 100%;height: 100%;overflow: auto;display:none;"><div id="mbpcm_content" style="background-color: pink;margin: 15% auto;padding: 20px;border: 1px solid black;width: 20%;box-shadow:20px 20px 30px 2px gray;border-radius:7px;"><span id="mbpcm_close" style="float: right;font-size:25px;cursor: pointer;">&times;</span>'+ contentss +'</div></div>';
        document.body.appendChild(div);
        var modal = document.getElementById("mbpcm_modal");
        var close = document.getElementById("mbpcm_close");
        close.onclick = function(){modal.style.display = "none";}
    }
    function ui_add_opener(parent,classs,stylee){
        var btn = document.createElement("button");
        btn.setAttribute("class",classs);
        btn.setAttribute("style",stylee);
        btn.setAttribute("id","mbpcm_ui_opener");
        btn.innerHTML = "Settings";
        parent.appendChild(btn);
        var modal = document.getElementById("mbpcm_modal");
        var btnn = document.getElementById("mbpcm_ui_opener");
        btnn.onclick = function(){modal.style.display = "block";}
    }
    function ui_addElement(el,cls,styl,val,innerHtml){
        var modal = document.getElementById("mbpcm_content");
        var e = document.createElement(el);
        e.setAttribute("class",cls);
        e.setAttribute("style",styl);
        e.setAttribute("value",val);
        e.innerHTML = innerHtml;
        modal.appendChild(e);
        return e;
    }

    ui_create("<h1>Title</h1><span>discription</span><br>");
    ui_add_opener(document.getElementById("gbw"),"RNmpXc","nothing");
    ui_addElement("button","modal","none","none","TestButton").onclick = function(){alert("hellow ji ");}
    ui_addElement("br","","","","");
    ui_addElement("button","none","none","none","TestButton").onclick = function(){alert("How are you");}
    ui_addElement("button","none","none","none","TestButton").onclick = function(){alert("Kaise ho");}
})();
MbPCM
  • 457
  • 5
  • 12