Here's an example script (reduced to the bare minimum). It can be found online at http://hithuntheal.com/x.user.js
// ==UserScript== // @name TEST CLICK BUTTON // @namespace http://hithuntheal.com/x.user.js // @description Hitlist hunt heal and level combined // @grant GM_setValue // @grant GM_getValue // @grant GM_log // @grant GM_xmlhttpRequest // @grant unsafeWindow // @grant window // @include *hithuntheal.com/* // @icon http://www.hithuntheal.com/hhhicon.ico // @require http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js // ==/UserScript== var thisx=window.location.href; setTimeout(function() { if (thisx.indexOf('tamoki')>0) { //alert('metamoki'); jQuery(".formInputButton").each(function(index) { //alert(index+": found formInputButton"+$(this).attr('value')); var thisvalue=$(this).attr('value'); if (thisvalue="Finish Job") { alert('found button !'); $(this).click(); } }); } }, 3000); It acts upon the following webpage and should click the button. http://hithuntheal.com/x.php But it doesn't click the button. It gets an error in greasemonkey. If I make the script run with //@grant none then it runs just fine -- but then I can't use GM_setValue/GM_getValue -- and I need them because the actual script works across multiple domains using Greasemonkey's local storage. I tried using some GM_setValue and GM_getValue routines that use local storage but that doesn't work across domains... On Thursday, July 17, 2014 12:51:59 PM UTC-4, TheVindicar wrote: > > 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] <javascript:> > >: > >> 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] <javascript:>. >> To post to this group, send email to [email protected] >> <javascript:>. >> 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.
