1

I have an array that looks something like this in the file menu.html on the local address http://127.0.0.1/menu.html :

<script language='javascript'>
<!-- hide
var options = new Array('blue',
                           'a',
                           'm',
                           '1',
                           '1',
                           '0',
                           '1'
                          );

   // change value of blue to green before execution of the function below.

   createMenu(options);

// done hiding -->
    </script>

I want to change the value of blue to green before createMenu(options) is executed using .

I tried to create the a new user script that includes http://127.0.0.1/*

with the contents

// ==UserScript==
// @name        scriptname
// @namespace   namespace
// @description makes password blue
// @include     http://127.0.0.1/*
// @version     1
// @grant       none
// ==/UserScript==

unsafeWindow.options = new Array('green',
                               'a',
                               'm',
                               '1',
                               '1',
                               '0',
                               '1'
                              );

But this code does not work as intended.

Does anyone know how the value can be changed in the array options from blue to green?

I am using unsafeWindow since I am not concerned about the security for this user script.

2 Answers 2

1

First, a couple of points. You can dispense with hiding your JavaScript -- people coded that way years ago because they needed to. Nowadays browsers generally recognize JavaScript so hiding it is unnecessary. Secondly, if you wish to include a JavaScript file into your GreaseMonkey script, you need to put that JavaScript in its own .js file; including an HTML file is not going to achieve your goal. So, here is one way that you might include a JavaScript file into a GreaseMonkey script as well as change option blue to green before CreateMenuOptions() executes:

test_gm.js:

var options = new Array('blue',
                           'a',
                           'm',
                           '1',
                           '1',
                           '0',
                           '1'
                          );

function CreateMenuOptions(opts) {
  document.getElementsByTagName("body")[0].style.background = opts[0];
}

(GreaseMonkey) blue2green.user.js:

// ==UserScript==
// @name        Blue2Green
// @namespace   http://localhost/hayageek.com
// @include     *
// @version     1
// @grant       none
// @require     http://localhost/exp/test_gm.js
// ==/UserScript==

options[0] = "green";
CreateMenuOptions(options);

Note that the .js file is included in the GreaseMonkey script using @require. The @include is used to specify where the .user.js file may augment one or more webpages by having the .user.js file itself execute and affect the current webpage.

Lastly, also note that this strategy did not require using "unsafeWindow" which should be a last resort per the GreaseMonkey Manual:API

Sign up to request clarification or add additional context in comments.

2 Comments

Your points are useful but you didn't solve the problem. He defines an array and uses it in a call in the HTML website. What he actually wants is to change the definition of that array via userscript.
@Tomáš Zato: The OP seeks to change the value of an element, not the array definition as per his words "I want to change the value of blue to green before createMenu(options) is executed". The solution I provide accomplishes this goal.
0

tl;dr JSFiddle

You have three options. I'll sort them based on how hacky they are, the least hacky solution first:

1. Override createMenu()

This one is simple.

// Save old version of the function
var old_createMenu = window.createMenu;
window.createMenu = function(options) {
    // Change first value of the array
    options[0] = "green";
    // call the original function
    old_createMenu(options);
}

2. Override new Array() constructor

Only works when new Array() is used, does not work for [] array literal! I do not recommend this unless necesary:

var oldArray = Array;
Array = function() {
    if(arguments.length>0 && arguments[0]=="blue") {
        arguments[0] = "green";
        // Put back old constructor
        Array = oldArray;
    }
    // create array of arguments which must be prepended with null
    var args = [];
    args.push.apply(args, arguments);
    args.unshift(null);
    return new (Function.prototype.bind.apply(oldArray, args));
}

3. Set setter on window.options

Only works when window.options is used, does not work with var options!

The idea here is to guard window.options and whenever someone tries to set a new array, modify it:

var options_secret = [];
Object.defineProperty(window, "options", {
    get: function() {return options_secret;},
    set: function(new_value) {
        if(new_value.length>0 && new_value[0]=="blue")
            new_value[0] = "green";
        options_secret = new_value;
    }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.