bernte
bernte

Reputation: 1184

Greasemonkey script gives error on wrong inputs

I have a Greasemonkey script with logic like this:

  1. Unless the logged-in user is in the privileged group (JOHN, LUKE, JEFF, MAX, ANDY), disable the <input> with name="prio".

  2. If not a privileged user, block select values from <input name="dest">.
    Specifically, block "12" or "22" and write an error message.


The script works fine but has a bug:

When I insert text in an other input field or I change a select field and press Enter, the submit stops and I receive an error message in the console:

Error: destInput[0] has no properties Source File: file:///E:/FirefoxPortable2.x/Data/profile/extensions/%7Be4a8a97b-f2ed-450b-b12d-ee082ba24781%7D/components/greasemonkey.js Line: 379

var err = this.findError(script, line - lineFinder.lineNumber - 1);

I think the rule with the name="dest" is working on all input fields and select fields? But i want the rule for the "dest" input only.

Here is my script code:

// ==UserScript==
// @name           _SO Block submit on custom FF2 page.
// @namespace      PC
// @include        file:///D:/temp/foo%20SO/task*
// @include        file:///D:/temp/foo%20SO/fixture*
// @include        file:///D:/temp/foo%20SO/pallet*
// ==/UserScript==

GM_log ("Script start.");

unsafeWindow._oldSubmit  = unsafeWindow.document.forms[0].submit;
unsafeWindow.document.forms[0].submit = function () {
    GM_log ("Submit function fired.");

    var destInput   = document.getElementsByName ("dest");
    if ( ! destInput  ||  destInput.length == 0) {
        //unsafeWindow._oldSubmit ();
    }

    var destValue   = destInput[0].value;
    if (    /^\s*$/.test (destValue)
            ||  excludedDestinations.indexOf (destValue) > -1
    ) {
        GM_log ("Submit should be blocked! (1)");
    }
    else {
        //unsafeWindow._oldSubmit ();
    }
};


//--- Make sure this list of names is all uppercase.
var usersWhoCanSetPriority  = ['JOHN', 'LUKE', 'JEFF', 'MAX', 'ANDY'];
var excludedDestinations    = ['12', '22'];

var bDisablePrio    = true;
var tdNodes         = document.getElementsByTagName ("TD");
for (var J = tdNodes.length - 1;  J >= 0;  --J) {
    var tdNode      = tdNodes[J];
    if (tdNode.className == "user") {
        var userName        = tdNode.textContent.replace (
            /^(?:.|\n|\r)+\(User:\s+([^)]+)\)(?:.|\n|\r)+$/i, "$1"
        ).toUpperCase ();
        if (usersWhoCanSetPriority.indexOf (userName) > -1) {
            bDisablePrio = false;
        }
    }
}

if (bDisablePrio) {
    var oldInput    = document.getElementsByName ("prio");
    if (oldInput  &&  oldInput.length) {
        oldInput[0].setAttribute ("disabled", "disabled");
    }

    var destInput   = document.getElementsByName ("dest");
    if (destInput  &&  destInput.length) {
        destInput[0].addEventListener (
            "change",
            function (zEvent) {
                bCheckdestinationValue (destInput[0]);
                GM_log ("Change handler fired.");
            },
            false
        );

        destInput[0].form.addEventListener (
            "submit",
            function (zEvent) {
                GM_log ("Submit handler fired.");
                var destValue   = destInput[0].value;
                if (    /^\s*$/.test (destValue)
                        ||  excludedDestinations.indexOf (destValue) > -1
                ) {
                    //--- Stop the submit
                    zEvent.preventDefault ();
                    //zEvent.stopPropagation ();
                    GM_log ("Submit should be blocked! (2)");
                    return false;
                }
            },
            true
        );
    }
}

function bCheckdestinationValue (destInputNd) {
    //--- Returns true if value is bad.
    if (excludedDestinations.indexOf (destInputNd.value) > -1) {
        destInputNd.value = ''; // Blank input

        //--- Add or show Error message.
        var destErrNode = document.getElementById ("gmDestErrorDisp");
        if (destErrNode) {
            destErrNode.style.display = "inline";
        }
        else {
            destErrNode             = document.createElement ('b');
            destErrNode.id          = "gmDestErrorDisp";
            destErrNode.style.color = "red";
            destErrNode.textContent = "12 and 22 are forbidden";
            destInputNd.parentNode.appendChild (destErrNode);
        }
        return true;
    }
    else {
        var destErrNode = document.getElementById ("gmDestErrorDisp");
        if (destErrNode) {
            destErrNode.style.display = "none";
        }
    }
    return false;
}

Here is an old working version on jsFiddle for a better understanding.

PS: the pastebin code (unsafeWindow..) is the only working version on my old system. The system runs FF 2.0.0.11 and Greasemonkey 0.8 and It can't be updated.

Is there a way to remove the bug? :D

Upvotes: 0

Views: 180

Answers (1)

Brock Adams
Brock Adams

Reputation: 93473

Change the forms[0].submit code to:

if (unsafeWindow.document.forms[0]) {
    unsafeWindow._oldSubmit  = unsafeWindow.document.forms[0].submit;
    unsafeWindow.document.forms[0].submit = function () {
        GM_log ("Submit function fired.");

        var destInput   = document.getElementsByName ("dest");
        if ( ! destInput  ||  destInput.length == 0) {
            unsafeWindow._oldSubmit ();
        }
        else {
            var destValue   = destInput[0].value;
            if (    /^\s*$/.test (destValue)
                    ||  excludedDestinations.indexOf (destValue) > -1
            ) {
                GM_log ("Submit should be blocked! (1)");
            }
            else {
                unsafeWindow._oldSubmit ();
            }
        }
    };
}

It does a proper job of making sure things exist before using them.

Also, uncomment this line:

//zEvent.stopPropagation ();

Upvotes: 1

Related Questions