討論 » 開發

Hook into jQuery existing events

§
發表於:2015-03-31
編輯: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?

woxxom管理員
§
發表於:2015-03-31
編輯: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.

§
發表於:2015-03-31
編輯: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);
woxxom管理員
§
發表於:2015-03-31
編輯: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.

§
發表於:2015-04-01
編輯: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.

§
發表於: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');
}
§
發表於:2015-04-01

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

§
發表於: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.

發表回覆

登入以回復

长期地址
遇到问题?请前往 GitHub 提 Issues。