Discussions » Development

Hook into jQuery existing events

§
Posted: 2015-03-31
Edited: 2015-03-31

Hook into jQuery existing events

Before GreaseMonkey changed it's sandbox policy (read: Firefox did, and GM didn't make it backwards compatible), I had small peace of code that worked great when hooking into jQuery events on a website:

unsafeWindow.$(document).on("pjax:end", function(){ 
    console.log('test 1'); 
});

For a few months this doesn't work anymore and I'm still looking for a solution to make it work again.

I know that the logic still works on the page when I manually run above code (without unsafeWindow) in the Developer Tools.

I have tried the following:

unsafeWindow.$('body').on("pjax:end", function(){
    console.log('test 2');
});
unsafeWindow.$(unsafeWindow.document).on("pjax:end", function(){
    console.log('test 3');
});
unsafeWindow.$(unsafeWindow.document.body).on("pjax:end", function(){
    console.log('test 4');
});

I also tried including (@require) jQuery into the script and dropping the unsafeWindow from above code.

Nothing works, anyone got an solution?

wOxxOmMod
§
Posted: 2015-03-31
Edited: 2015-03-31

Sandbox escape, huh. I'd try to inject some html into the document with js in some of onevent attributes that would be fired no matter what. Or a <script>. As for communicating with the main script... maybe that same element's attributes could be used, you'd just need to attach a MutationObserver with {attributes:true} on both sides.

§
Posted: 2015-03-31
Edited: 2015-03-31

Thnx for your response. Actually it's for some scripts I have build for Github. But Github has a very strict content security policy (CSP), so injecting won't work;

Content-Security-Policy:default-src *; script-src assets-cdn.github.com collector-cdn.github.com; [...]

I'll give MutationObserver another try.

Edit: I tried the following script injections without success:

var script = document.querySelector("head").appendChild(document.createElement("script"));
script.type = "text/javascript";
script.textContent = 'alert("test");';
var script2= document.querySelector("body").appendChild(document.createElement("script"));
script2.type = "text/javascript";
script2.textContent = 'alert("test2");';
var script3 = document.createElement('script');
script3.setAttribute('type', 'application/javascript');
script3.innerHTML = 'alert("test3");';
document.documentElement.appendChild(script3);
document.documentElement.removeChild(script3);
wOxxOmMod
§
Posted: 2015-03-31
Edited: 2015-03-31

I guess my idea was stupid, otherwise it wouldn't be so hard for Greasemonkey developers to implement a workaround. Seems like your only option is to try making an addon with injected content scripts. Not sure this will work, though, since modern browsers tend to separate the code environments as much as possible.

§
Posted: 2015-04-01
Edited: 2015-04-01

Your reply wasn't stupid; I forgot about MutationObserver which will work. It's just not an simple and foolproof solution like the original code was.

§
Posted: 2015-04-01

I also tried hooking into the pushState without success:

document.addEventListener('history.pushState', function() {
    console.log('history.pushState');
}, false);
window.onpopstate = function() {
    console.log('onpopstate 1');
}
unsafeWindow.onpopstate = function() {
    console.log('onpopstate 2');
}
§
Posted: 2015-04-01

unsafeWindow.$(document).on("pjax:end", exportFunction(function(){
console.log('test 1');
}, unsafeWindow));

§
Posted: 2015-04-01

Thank you so much! Your code let me to the following userscripts: https://gist.github.com/jerone/e38e8637887559870d84 One for @grant none and one used with an @grant option.

Post reply

Sign in to post a reply.