1

I'm working on a FireFox extension that listens to onStateChange. When the current document has been loaded it should insert a script to the page and it should be able to call the script on a button event.

Now I am able to add a button to all webpages by using:

nsCOMPtr<nsIDOMElement> NewInputElementTest;
rv = htmlDoc->CreateElement(NS_LITERAL_STRING("input"),getter_AddRefs(NewInputElementTest));

rv = NewInputElementTest->SetAttribute(NS_LITERAL_STRING("type"),NS_LITERAL_STRING("button"));

rv = NewInputElementTest->SetAttribute(NS_LITERAL_STRING("value"),NS_LITERAL_STRING("hummer"));

rv = body->AppendChild(NewInputElementTest,getter_AddRefs(AddedNewInputElement2));

The button is displayed correctly.


I wish to use the same procedure to add a SCRIPT to the page, like so:

rv = htmlDoc->CreateElement(NS_LITERAL_STRING("script"),getter_AddRefs(NewInputElement));
rv = NewInputElement->SetAttribute(NS_LITERAL_STRING("type"),NS_LITERAL_STRING("text/javascript"));
rv = NewInputElement->SetAttribute(NS_LITERAL_STRING("text"),NS_LITERAL_STRING("alert('hello world!')"));
rv = body->AppendChild(NewInputElement,getter_AddRefs(AddedNewInputElement));

All functions return success, but no script is added to the page. No alert is displayed, and if i insert a function and call it from the button.onclick then the FireFox log displayes that the function is not available.

If I use the exact same procedure from a javascript inside the html page, then it works find and the alert pops up.

Do I need to do anything to enable the script from my extension or why is the script not available from the button or anywhere else?

elnino
  • 41
  • 1
  • 1
  • 2
  • possible duplicate of [How to inject javascript into page, from a Firefox add-on, and run it?](http://stackoverflow.com/questions/2879669/how-to-inject-javascript-into-page-from-a-firefox-add-on-and-run-it) – user2284570 Nov 09 '14 at 23:14

2 Answers2

2

I hate to say it after you created a bunch of code, but check out Greasemonkey: https://addons.mozilla.org/en-US/firefox/addon/748

It'll probably handle a lot of your work for you.

Oren Mazor
  • 4,437
  • 2
  • 29
  • 28
  • Seems like using greasemonkey would require that that addon is already installed. Is there no way of adding my own script using my already loaded addon? – elnino Nov 03 '09 at 12:39
  • @OrenMazor : **I very dislike the greasmonkey idea.** They script is loaded only when the page finished to load. On many sites, the page load can never end so the script is never launched *(this is greasmonkey design)*. It is important to put more ***grained control*** and Opera folks [understood it](http://www.opera.com/docs/userjs/examples/#loadingscripts) in the past *(They no longer does)*. Users can really get mad if they need to wait up to 50 mins. – user2284570 Nov 09 '14 at 22:54
1

Yes, sounds like you're tryin to re-invent the wheel. Use Greasemonkey as Oren suggested.

Here is a Greasemonkey script that I use to load external JS framework (Prototype and Scriptaculous in this case) load any number of external files (js and css) into a page.

// ==UserScript==
// @name           External Loader
// @namespace      http://ifelse.org
// @description    Loads external JS and CSS
// @include        http://*.yoursitedomainetc.com/*
// ==/UserScript==

var hasPrototype  = ('Prototype' in unsafeWindow);
var hasEffects    = ('Effect'    in unsafeWindow);

function _require(url, isCSS) {
    if (isCSS) {
        var script = document.createElement('link');
        script.setAttribute('type', 'text/css');
        script.setAttribute('rel',  'stylesheet');
        script.setAttribute('href', url);
    } else {
        var script = document.createElement('script');
        script.setAttribute('type',    'text/javascript');
        script.setAttribute('charset', 'UTF-8');
        script.src = url;
    }
    document.getElementsByTagName('head')[0].appendChild(script);
}

//  Load prototype; shouldn't get here because it is already on the page
if ( !hasPrototype ) {
    _require('http://path.com/to/prototype/1.6.0.2/prototype.js');
}

//  Load scriptaculous effects if it's not already loaded
if ( !hasEffects ) {
    _require('http://path.com/to/scriptaculous/1.8.1/effects.js');
}

//  Add greasemonkey ajax object
//  Copies format of Prototype Ajax.Request to
//  Allow to easily swap out at a later point (i.e. no longer FF plugin)
unsafeWindow.Remote = new Object;
unsafeWindow.Remote.Ajax = function(url, options) {
    if (options.onCreate) {
        options["onCreate"]();
    }

    var request = {
        method: options.method || 'get',
        url: url + ('?' + unsafeWindow.Object.toQueryString(options.parameters) || ''),
        onload: function(response) {
            if (response.status == 200)
            options["onComplete"](response);
            options["onSuccess"]();
        },
        onerror: options.onFailure || null
    };
    window.setTimeout(GM_xmlhttpRequest, 0, request);
};

//  Load these External files
_require('http://path/to/anything/and/dont/cache/it.js' + '?cache=' + (new Date()).getTime());
_require('http://paht/to/something/else.css', true);
}
donohoe
  • 13,867
  • 4
  • 37
  • 59
  • Thanks for the help. Im new to this, perhaps you can help me further. I need to load a script from another application or a script located on the disc, not from a URL is this a problem? Also does users of my application / script require having greasemonkey installed beforehand? The attached script, where do i put it in order for it to load when any page is done loading? A little more detail for a newbie would be great:) i'll check out the greasemonekey in the meantime:) Thanks. – elnino Nov 03 '09 at 12:37
  • If you know the specific script or code to include and don't need to load it remotely, then you could replace the script above with its content and have it run instead. Users would normally need to install greasemonkey and the script to run, but you can also compile greasemonkey scripts into Firefox Plugins. http://arantius.com/misc/greasemonkey/script-compiler – donohoe Nov 03 '09 at 14:47
  • So let me get this straight. I need to create an extension that will load a file ie. c:\myscript.js and insert this script into any webpage that FireFox visits. Is this possible by creating a GreaseMonkey script and compiling it into an xpi file? And once i have an xpi file what do i do with it? Thank you. – elnino Nov 04 '09 at 08:55
  • The XPI file is the Firefox extension, which you and users can add to Firefox like you would any other extension. – donohoe Nov 04 '09 at 16:11
  • The _require function worked fine when executed directly from a Firefox extension (using a `contentDocument` for a particular tab rather than the `document`). – Brian Jul 13 '12 at 15:14
  • @donohoe : **I very dislike the greasmonkey idea.** They script is loaded only when the page finished to load. On many sites, the page load can never end so the script is never launched *(this is greasmonkey design)*. It is important to put more grained control and Opera folks [understood it](http://www.opera.com/docs/userjs/examples/#loadingscripts) in the past *(They no longer does)*. – user2284570 Nov 09 '14 at 22:56