Search code examples
javascriptuserscripts

Remove part of title of website via userscript


I try to code a userscript that removes everything from the title of a website (flash browsergame) but the countdown that appears when starting an action.

I'm new to Javascript and need some help.

UPDATE

The regexp problem is solved but I still need some help getting this script to "monitor" the title so everytime it's changes by the game the script runs again.

The main title looks like this:

Shakes & Fidget - The Game (buffed buffed)

As soon as an action is started a countdown is added to the beginning so the title changes to

02:26 - Shakes & Fidget - The Game (buffed buffed)

I want the title to show the countdown only.

I searched the net and found different ways to do this but none of them works for me.

Here is what I currently have:

// ==UserScript==
// @name       Shakes & Fidget Buffed title shortener
// @namespace  http://släcker.de
// @version    0.1
// @description  Removes the page title of Shakes & Fidget to only display left time if it exists
// @include        *.sfgame.*
// @exclude        www.sfgame.*
// @exclude        sfgame.*
// @copyright  2013+, slaecker
// ==/UserScript==

var regex = [^0-9:]

function cleanTitle() { 
    var oldTitle = document.title; 
    var oldTitleRX = oldTitle.match(regex);
    document.title = oldTitle.replace(oldTitleRX,""); 
    return oldTitle; 
} 


cleanTitle()

The Javascript console shows errors concerning the regex. I tried to escape the characters but the errors are the same:

env: ERROR: Syntax error @ 'Shakes & Fidget Buffed title shortener'!
Unexpected token ^
SyntaxError: Unexpected token ^
    at Window.Function (<anonymous>)
    at L (eval at <anonymous> (eval at <anonymous> (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/content.js:51:21)), <anonymous>:156:21)
    at n (eval at <anonymous> (eval at <anonymous> (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/content.js:51:21)), <anonymous>:384:2)
    at R (eval at <anonymous> (eval at <anonymous> (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/content.js:51:21)), <anonymous>:388:86)
    at Q (eval at <anonymous> (eval at <anonymous> (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/content.js:51:21)), <anonymous>:194:40)
Uncaught SyntaxError: Unexpected token ^
L
n
R
Q

It has to be a regex match because the containing string "(buffed buffed)" changes (it shows the server name).

Another problem is that the script should "monitor" the title because it changes everytime a new action is started or finished but my script only runs once (tested it without regex).

Thanks in advance for your help,

slaecker


Solution

  • For the regex, use:

    document.title = document.title.replace (/[^0-9:]/g, "");
    

    To detect title changes, use MutationObservers, a new HTML5 feature that is implemented in both Google Chrome and Firefox (The two main browsers).

    This complete script will work:

    // ==UserScript==
    // @name        Shakes & Fidget Buffed title shortener
    // @namespace   http://släcker.de
    // @version     0.1
    // @description  Removes the page title of Shakes & Fidget to only display left time if it exists
    // @include     *.sfgame.*
    // @exclude     www.sfgame.*
    // @exclude     sfgame.*
    // @copyright   2013+, slaecker, Stack Overflow
    // @grant       GM_addStyle
    // ==/UserScript==
    /*- The @grant directive is needed to work around a design change
        introduced in GM 1.0.   It restores the sandbox.
    */
    
    var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
    var myObserver       = new MutationObserver (titleChangeDetector);
    var obsConfig        = {
        //-- Subtree needed.
        childList: true, characterData: true, subtree: true
    };
    
    myObserver.observe (document, obsConfig);
    
    function titleChangeHandler () {
        this.weInitiatedChange      = this.weInitiatedChange || false;
        if (this.weInitiatedChange) {
            this.weInitiatedChange  = false;
            //-- No further action needed
        }
        else {
            this.weInitiatedChange  = true;
            document.title = document.title.replace (/[^0-9:]/g, "");
        }
    }
    
    function titleChangeDetector (mutationRecords) {
    
        mutationRecords.forEach ( function (mutation) {
            //-- Sensible, Firefox
            if (    mutation.type                       == "childList"
                &&  mutation.target.nodeName            == "TITLE"
            ) {
                titleChangeHandler ();
            }
            //-- WTF, Chrome
            else if (mutation.type                      == "characterData"
                &&  mutation.target.parentNode.nodeName == "TITLE"
            ) {
                titleChangeHandler ();
            }
        } );
    }
    
    //-- Probably best to wait for first title change, but uncomment the next line if desired.
    //titleChangeHandler ();
    

    If you are using some other browser (state that in the question), then fallback to using setInterval().