I used this snippet to illustrate my undestanding of how scurity scopes work. jQuery is taken from unsafeWindow, and thus runs with page level of privilege. The code itself is run in script scope, so empty array and anonymous function are also created in script scope. That's why page-defined jQuery fails to access them.
You're using script-scope jQuery, so it should work just fine in my scenario. As for yours... say again: 1. Where and how is click handler installed? 2. Where and how is .click() called? 2014-07-17 16:23 GMT+04:00 Daniel Wynalda <[email protected]>: > I think what I'm having trouble with is understanding the use of cloneInto. > > You mentioned this code: > $.each( > cloneInto([], unsafeWindow), > exportFunction(function(){}, unsafeWindow) > ); > > But I don't understand it. Is this suppose to replace the .each() inside > jQuery? > > The .each seems to be running fine and I get the content that I expect > with jquery (the text is visible, as is the .onClick routine that is in the > code). What I can't do is actually click the element (perhaps because it > has an onclick and that is in the page scope??) > > > On Thursday, July 17, 2014 5:46:48 AM UTC-4, TheVindicar wrote: > >> Let me guess, you're trying to use jQuery provided by target page? >> Following code will fail: >> >> var $ = unsafeWindow.jQuery; >> $.each([], function(){}); >> >> Since $.each() is a function from page scope, and array and function are >> both in more priviledged script scope, jQuery will fail to access their >> properties (like Array.length and Function.call). >> There are two ways to work around it. Either you can export everything >> you need explicitly (though strings and numbers don't have to be exported): >> >> $.each( >> cloneInto([], unsafeWindow), >> exportFunction(function(){}, unsafeWindow) >> ); >> >> Or you can run the page-modifying code entirely inside the page scope via >> script tag injection: >> >> function RunInPage(func) { >> var s = document.createElement("script"); >> s.textContent = "(" + func + ")();"; >> document.body.appendChild(s); >> setTimeout(function(){document.body.removeChild(s)}, 0); >> } >> RunInPage(function(){ >> //you can use page-scope code (like jQuery if the page uses it) >> here freely - entirety of this script is run in page scope. >> var $ = window.jQuery; $.each([], function(){}); >> }); >> >> >> The latter method is much easier if you don't need to make priviledged >> calls from the page scope (i.e. you don't have an event handler that calls >> GM_setValue(), don't use GM_xmlHttpRequest(), and so on). One drawback is >> that you can't use closures with it. Following code will give you >> 'undefined': >> >> var my_settings = {settings : GM_getValue( 'settings', 'default' )}; >> RunInPage(function(){ >> alert(my_settings); >> }); >> >> It seems that a good way to pass values into page scope would be this: >> >> var my_settings = {settings : GM_getValue( 'settings', 'default' )} >> unsafeWindow.my_settings = cloneInto(my_settings, unsafeWindow); >> RunInPage(function(){ >> alert(window.my_settings); >> }); >> >> >> Mind that settings object better not include any functions. >> >> >> 2014-07-16 20:03 GMT+04:00 Daniel Wynalda <[email protected]>: >> >> If possible could you post an example of how you used cloneInto() in your >>> greasemonkey script to inject something? My scripts also broke with >>> greasemonkey 2.0 deployment and they are all failing inside jQuery so I >>> don't know what to do to try to fix them. Simple things like: >>> >>> $(this).click(); >>> >>> no longer work -- and Firefox is giving this error: >>> Permission denied to access property 'length'. >>> >>> I know it's finding the item (I have logged the content). It works fine >>> in Greasemonkey 1.5. I am guessing this has something to do with the >>> scope changes - but I have no idea how to work around them. I'm not trying >>> to inject anything into the web page. I'm just trying to click a DIV >>> element.... >>> >>> >>> >>> On Tuesday, July 15, 2014 7:53:50 AM UTC-4, TheVindicar wrote: >>> >>>> Well, I solved it in a different manner. I run everything I can in >>>> script scope, load settings into an object, then export that object into >>>> unsafeWindow via cloneInto() and run the rest in page scope via script tag >>>> injection. >>>> It works for simple scripts that don't need to call priviledged calls >>>> from pages scope. If you do need it, you might want to use >>>> addEventListener()/postMessage() combo. >>>> >>>> >>>> 2014-07-15 3:33 GMT+04:00 Dr Sr <[email protected]>: >>>> >>>>> Same here, half a dozen scripts broken. The easiest way is to use "@grant >>>>> none <http://wiki.greasespot.net/@grant>", so your script runs in the >>>>> page context and can carry on as before. Replace "unsafeWindow" with >>>>> "window". You lose access to all the GM_ calls, but if you're only using >>>>> GM_getValue()/setValue() anyway, see the compatibility shim in the above >>>>> link for a drop-in replacement that uses localStorage. >>>>> >>>>> On Sunday, July 13, 2014 12:57:16 AM UTC+12, TheVindicar wrote: >>>>>> >>>>>> Where can I read about writing scripts in accordance with new API? >>>>>> Since now I can't even iterate over page-defined jQuery collection using >>>>>> script-defined callback, every single one of my scripts is broken. >>>>>> >>>>>> Pretty much all of them use the same scheme: >>>>>> 1. load settings into object via GM_getValue() >>>>>> 2. find and modify some DOM nodes according to the settings >>>>>> 3. (optionally) replace some functions in the target page with my own >>>>>> versions >>>>>> >>>>>> Now I fail to understand how do I do that using cloneInto() and >>>>>> exportFunction(). The fact Firefox shows wrong line number in error >>>>>> message >>>>>> doesn't help either. >>>>>> >>>>> -- >>>>> You received this message because you are subscribed to a topic in the >>>>> Google Groups "greasemonkey-users" group. >>>>> To unsubscribe from this topic, visit https://groups.google.com/d/to >>>>> pic/greasemonkey-users/SXfpyvcQofQ/unsubscribe. >>>>> To unsubscribe from this group and all its topics, send an email to >>>>> [email protected]. >>>>> To post to this group, send email to [email protected]. >>>>> >>>>> Visit this group at http://groups.google.com/group/greasemonkey-users. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- >>> You received this message because you are subscribed to a topic in the >>> Google Groups "greasemonkey-users" group. >>> To unsubscribe from this topic, visit https://groups.google.com/d/ >>> topic/greasemonkey-users/SXfpyvcQofQ/unsubscribe. >>> To unsubscribe from this group and all its topics, send an email to >>> [email protected]. >>> To post to this group, send email to [email protected]. >>> Visit this group at http://groups.google.com/group/greasemonkey-users. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> -- > You received this message because you are subscribed to a topic in the > Google Groups "greasemonkey-users" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/greasemonkey-users/SXfpyvcQofQ/unsubscribe > . > To unsubscribe from this group and all its topics, send an email to > [email protected]. > To post to this group, send email to [email protected]. > Visit this group at http://groups.google.com/group/greasemonkey-users. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "greasemonkey-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/greasemonkey-users. For more options, visit https://groups.google.com/d/optout.
