My comments are interspersed.
--- On Mon, 7/20/09, BD <[email protected]> wrote: > From: BD <[email protected]> > Subject: [greasemonkey-users] Re: change an external web page within a web app > To: [email protected] > Date: Monday, July 20, 2009, 1:14 PM > > The GmScript instance running in the parent > cannot access the iframe (and vice versa), but the GmScript > instance running in the iframe can access the iframe. You just need > to get the two GmScript instances talking to each other. And > your GmScript needs to know if it is running in the parent, and > what to do then, or in the iframe, and what to do in that case. > > I wasn't thinking about this specific scenario, but, > since it's the SAME script, both of them can access the same > data space using the built-in GM_setValue() and GM_getValue() > functions. > > So the parent instance can tell the iframe instance what to > do by some sort of a communication data exchange protocol. > (that you have to design and implement) That's what the > example code below is trying to show. > > It's a master-slave or slave-slave scenario, depending > if you want one-way or two-way communication and control. > You would probably have to set up some sort of a timer so > that the iframe (and the parent if you want two-way, or > one-way for 'complex' comm) checks some value > using GET every 1/100 of a second, or whatever, that the This is the standard, polling solution. > parent has set using SET, and then some action occurs. > And if you want multiple occurrences of communication, > the iframe has to set that value to blank > (or use another value for ready/not ready) so that the > parent knows the action has occurred and the iframe is > ready for another message. (and/or that the iframe has > sent a message back to the parent) > > It's typical, (relatively) simple protocol communication > between two entities. You might need some way to know > when both are ready for communication, because the set/get > values could have old state data values in them, so it > can get a little complex in that sense. Or, if > there are multiple pages with the script being run, you > need multiple values so that they don't stomp on each > other, and confuse each other, so that needs to be taken > into account. In addition, you should also consider that the same web page may be started up multiple times (ie. multiple instances of the same web page). Now when an iframe responds, which parent should be responsible. It's not an impossible situation, but you should be careful in your thinking. > Afaik, that is the only way to achieve what you want. There is a non polling, event driven solution, which is aesthetically a much cleaner way to go. I've never seen this mentioned mentioned (at least on this list). That means, specifically, that there is a way to get around (without violating) the standard cross-domain prohibition when both sides want very much to cooperate with each other. At least in FF 1.5. However, I don't remember thinking that there were any implied security issues with the GM specific method. > It will take a little programming and logic and design. > It would be nice if someone made something like this > as kind of a drop-in module that people could > use, and maybe someone has, although I would bet that it > isn't particularly popular thing to do. You might find code > examples out in the community somewhere. I've posted specific usage examples of the standard technique in the past (though they were not a drop in module kind of thing). Search under my handle in this list (probably two years ago), and you may be able to dig them up. Csaba Gabor from Vienna > daremind wrote: > > Thanks for the detailed reply. It's all good stuff. > > however, i just want to reiterate one major issue that the > trick didn't solve: the content of the iframe is from > another domain. that means the src is set to > be http://www.google.com/ while the parent web > app is from http://mydomain/. so the GM > script can't access anything > inside the iframe. the only solution i get so far is to > try setting > up some proxy within my domain to pull the content on my > server side > and display it in the iframe. but then the other > site/domain can XSS > my site if they want to... > > > > thanks, > -hui > > > On Jul 18, 2:45 pm, cc <[email protected]> > wrote: > > > You need to split the logic in your script into > two parts (generally > speaking), and check whether the current instance is > running inside the > iframe by looking at document.location.href to see if > it's e.g.http://www.google.com/, or whatever. If it > matches the URL of whatever > you have inside the iframe, then the script is currently > running inside > the iframe. In that case, you do whatever DOM manipulations > you need to, > and you use the tricks we've mentioned to pass data > back and forth if > necessary -- for example, if you need to get information > from the script > instance running on the "outside", you might use > GM_setValue on the > "outside" script, and GM_getValue on the iframe > script. > > See, GM will run the same script, in different instances, > on multiple > pages at (theoretically) the same time -- you can load a > page with > iframes, have GM run script(s) on it, then as the iframes > load, GM will > run whatever scripts apply to *them*. That's the key > point here -- you > need to make sure that whatever code you need to run inside > the iframe > is set to only run if the inside-iframe check passes. And, > of course, > the "outside" script probably only needs to run > if the inside-iframe > check /doesn't/ pass. > > Does that make sense? > > Pseudo-code (not tested): > > if > (document.location.href.indexOf("http://www.example.com/path/to/iframed/web/app/") > === 0) { > // Yep, we're inside the iframe -- > matched path at beginning of string, too > while (!GM_getValue("info_ready", > false)) { > // HACK: Stupid CPU-intensive > polling while we wait for things to clear up > // TODO: switch to using > window.setInterval > // TODO: allow cancellation, if > that makes sense, or timeouts > } > > // Hey, we're ready to go do whatever it > is we need! > var info = GM_getValue("info", > ""); > /* ... insert code here to manipulate DOM > from inside iframe.... */} else { > > /* ... do whatever it is you do when > you're not inside the iframe.... */ > // Pass info in > GM_setValue("info", "GM rocks > -- just FYI"); > GM_setValue("info_ready", true); > > } > daremind wrote: > > > Thanks, guys. there's a problem that i > loaded other site's pages into > my iframe. that caused i got permission denied when trying > to access > the DOM of the contained web page. It doesn't > seem i can get around > this permission issue. > > > > Johan, I tried your suggestions. > > > > my domain of the web app is "http://localhost/" > say the domain of the web page I included in an iframe is > "http:// > www.google.com/" > > > > I have @include-d both domains in my GM scripts. > > > > my GM script looks like this: > .... > .... > if ('mybrowser' != window.name) return; > .... > var iframeEl = > document.getElementById('mybrowser'); > var doc; > if ( iframeEl.contentDocument ) { // DOM > doc = iframeEl.contentDocument; > } > > > > var allLinks; > allLinks = doc.getElementsByTagName('a'); > // try to modify the css of all the links... > ... > .... > > > > here's what happened: > > > > 1. the window.name doesn't return anything, > it's empty. > > > > 2. i got "Error: Permission denied to call > method > HTMLDocument.getElementsByTagName" when > executing: allLinks = > doc.getElementsByTagName('a'); This is caused > by doc is not > accessible. I can access its parent the iframeEl > element though. > > > > so looks like we have no way to invoke GM on the > iframe that contains > external site's content. correct? > > > > thanks much. > > > > On Jul 18, 3:22 am, Johan Sundström <[email protected]> > wrote: > > > On Fri, Jul 17, 2009 at 07:36, daremind<[email protected]> > wrote: > > In the web app, I will have a portion of the > web page that acts like a > web browser. in the web browser, I can load any web > page from another > site. And then I'll add some javascript effects > onto this web page. > > > > What i'm doing inside this browser-like > portion of the page can be > done with grease monkey user script. however, the issue is > whether > this doable at all. More specifically: > > > > > > > > What is this portion of the page? if I > use an Iframe, i have domain > permission issue so javascript can't modify it's > content. If i use > some div's, i need to parse like a browser to pull over > js, css, etc. > which is a mess. > > > > > > > If it's an iframe, and your GM script can > do its work inside of the > iframe without access to anything outside of that iframe, > it's a piece > of cake; just make the iframe, point it to the url you want > to show > and augment and make a GM script that @include:s that url > (or perhaps > all URLs). Also, I'd suggest putting a name=mybrowser > attribute on > that iframe. > > > In the GM script, start with an "if > ('mybrowser' != window.name) > return;" to make sure you're executing in the > iframe context and > nowhere else. > > Then modify its DOM any way you please. > > > Is there some type of plugin that I can use > to create such as area > inside a web page so that i can use grease monkey user > script on its > content? or am i trying to do something grease monkey > already did. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "greasemonkey-users" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/greasemonkey-users?hl=en -~----------~----~----~----~------~----~------~--~---
