by Giorgio Maone » Thu May 20, 2010 4:48 pm
Just to recap, now we got 3 types of surrogates:
- "Inclusion" surrogates, which run in place of the external scripts which are blocked and whose URL matches the "sources" preference.
- "Page" surrogates (@), whose "sources" preference, matching the page's URL itself instead of a script source, is prefixed with an "@" character and which run before HTML parsing starts (i.e. you don't have any DOM node yet). This is useful to replace standard JavaScript/DOM objects before they get used by inlined scripts. If you need to run after the DOM is completed, you can attach a "DOMContentLoaded" listener (or a "load" listener if you need every subrequest, e.g. for images or frames, to have been completed as well).
- "Fallback" surrogates (!). Like the "Page" surrogates their "source" preference matches the page's URL, but
- their "source" preference is prefixed with an "!" character
- they run only if JavaScript is disabled for this page
- they run on DOM completion (i.e. in a "DOMContentLoaded" listener) by default, as a convenience since in a script-disabled page the only useful things you can do are manipulating DOM nodes and attaching UI events
This kind of surrogates are very similar to GreaseMonkey scripts, both because of the "late" time they run at and because they're ran in a sandbox (with the content window seen as the global object, though), rather than in the page's context.
So types 1 & 2 run when the page can run scripts, type 3 when page can't.
What the OP was trying to do can be accomplished in two ways, both using type 2 (Page, @) surrogates:
-
This one replaces the function as soon as the DOM loads (more or less as suggested by al_9x).
Code: Select all
user_pref("noscript.surrogate.test.replacement", "addEventListener('DOMContentLoaded', function(ev) { window.test=function(){alert('changed')}, true)");
user_pref("noscript.surrogate.test.sources", "@^file:");
-
This one creates the function before HTML parsing start, makes the getter for the "test" window property return it and defines an empty getter to smoothly prevent "test" from being rewritten. Albeit a bit more complex, it has the advantage that the replacement function will be called also by early inline scripts.
Code: Select all
user_pref("noscript.surrogate.test.replacement", "__defineGetter__('test', function(){return function(){alert('changed')}});__defineSetter__('test', function(){});");
user_pref("noscript.surrogate.test.sources", "@^file:");
Just to recap, now we got 3 types of surrogates:
[list=1]
[*][b]"Inclusion" surrogates[/b], which run in place of the external scripts [i]which are blocked and whose URL matches the "sources" preference[/i].
[*][b]"Page" surrogates[/b] (@), whose "sources" preference, matching the page's URL itself instead of a script source, is prefixed with an "@" character and which run [i]before HTML parsing starts[/i] (i.e. you don't have any DOM node yet). This is useful to replace standard JavaScript/DOM objects before they get used by inlined scripts. If you need to run after the DOM is completed, you can attach a "DOMContentLoaded" listener (or a "load" listener if you need every subrequest, e.g. for images or frames, to have been completed as well).
[*][b]"Fallback" surrogates[/b] (!). Like the "Page" surrogates their "source" preference matches the page's URL, but
[list]
[*]their "source" preference is prefixed with an "!" character
[*]they run only if JavaScript is disabled for this page
[*]they run on DOM completion (i.e. in a "DOMContentLoaded" listener) by default, as a convenience since in a script-disabled page the only useful things you can do are manipulating DOM nodes and attaching UI events[/list]
This kind of surrogates are very similar to GreaseMonkey scripts, both because of the "late" time they run at and because they're ran in a sandbox (with the content window seen as the global object, though), rather than in the page's context.[/list]
So types 1 & 2 run when the page can run scripts, type 3 when page can't.
What the OP was trying to do can be accomplished in two ways, both using type 2 (Page, @) surrogates:
[list=1]
[*]
This one replaces the function as soon as the DOM loads (more or less as suggested by al_9x).
[code]
user_pref("noscript.surrogate.test.replacement", "addEventListener('DOMContentLoaded', function(ev) { window.test=function(){alert('changed')}, true)");
user_pref("noscript.surrogate.test.sources", "@^file:");
[/code]
[*]
This one creates the function before HTML parsing start, makes the getter for the "test" window property return it and defines an empty getter to smoothly prevent "test" from being rewritten. Albeit a bit more complex, it has the advantage that the replacement function will be called also by early inline scripts.
[code]
user_pref("noscript.surrogate.test.replacement", "__defineGetter__('test', function(){return function(){alert('changed')}});__defineSetter__('test', function(){});");
user_pref("noscript.surrogate.test.sources", "@^file:");
[/code][/list]