0

I have the following situation:

  • A website gets data from another html-file("news.html") which gets called every 10s or so
  • I want to manipulate the data from the news.html

I thought I could set up a greasemonkey script which manipulates the news.html and thus also the main website. However this assumption was wrong: When I open the news.html in my browser, the news are manipulated (in terms of data - just to clarify this), but when I visit the main website the news don't get manipulated.

I think that greasemonkey does not work when the website is not opened "directly" in the browser, but with ajax/jQuery/....

Is there any known workaround for this?

Thanks in advance!

Franz
  • 49
  • 6
  • It's not at all clear from your wording, but is it possible that you haven't included code in your greasemonkey script to trigger it to run (such as `document.addEventListener("DOMContentLoaded", function() { // your script here }`? – Daniel Beck Feb 01 '16 at 18:15
  • I think the greasemonkey script starts as soon as the URL matches the pattern which is specified in the @include-Tag in the userscript-file, isn't it? So I think this is not neccessary. – Franz Feb 01 '16 at 18:35
  • Been a long time since I played with greasemonkey, but I believe the script is injected when the URL matches, but that doesn't necessarily cause it to be invoked (or perhaps it's invoked before the DOM is ready to be manipulated.) See http://stackoverflow.com/questions/20729895/how-to-auto-trigger-my-greasemonkey-script-every-time-i-open-a-page for example – Daniel Beck Feb 01 '16 at 18:41
  • ah, never mind, that was close but not quite it. See full answer below. – Daniel Beck Feb 01 '16 at 18:50
  • You need to be much more specific. Also, Make an MCVE and/or link to the target page. – Brock Adams Feb 01 '16 at 21:52
  • 1
    Ok. This is actually really a duplicate. Next time I will be more specific :) Thanks for helping me! – Franz Feb 01 '16 at 23:27

2 Answers2

0

You can't change files that are on a server with greasemonkey unless the API for some reason leaves that exposed. Whatever you are changing is just local to you.

Mitchell Ingram
  • 686
  • 2
  • 11
  • 23
  • Oh yes, I know :) But the changes aren't even local when I use the main page – Franz Feb 01 '16 at 18:10
  • Because you are getting a new file when you visit the main page, you aren't actually changing anything with gresemonkey except for whatever is in the DOM. When you reload or go anywhere else, that is blown away. – Mitchell Ingram Feb 01 '16 at 18:14
  • OK. Got it. But why can't I manipulate a website which gets requested by the main website? The mainwebsite uses ajax to load another file (namely: news.html) and I'd like to manipulate this file. I thought I could do this by adding the file to the @ include-Tag of my userscript (// @ include http://url.xyz/news.html). And I thought my userscript would then be applied to this url whenever it gets loaded in the browser. Maybe this clarified my issue a bit? :) – Franz Feb 01 '16 at 18:37
  • Greasemonkey only modifies the page it is on, you would have to go to news.html to modify that. – Mitchell Ingram Feb 01 '16 at 20:04
0

For simple pages, it's safest to wrap your greasemonkey scripts in at least an unload handler: According to the "Authoring" page at http://greasemonkey.mozdev.org/authoring.html,

User scripts are executed after the DOM is fully loaded, but before onload occurs. This means that your scripts can begin immediately and don't need to wait for onload. However, replacing large parts of the DOM (e.g. using innerHTML or outerHTML) at this early stage of rendering is known to cause Firefox some trouble. In this case, you'll have more success if you call your code in response to the load event instead:

window.addEventListener("load", function(e) {
  document.innerHTML = "Hello, world!";
}, false);

However, if the "main site" is constructing itself via a secondary ajax call to news.html, that won't be enough, because the data you want to manipulate won't be in the DOM yet when your script runs on the main site. You'll need to delay your script's execution until after the main site has finished doing its thing, so that when you try to do your thing there'll be the thing there for you to do your thing to. So to speak.

Have your script observe the DOM and wait to run until after news.html has been injected into the main site, or be lazy and start it after a sufficiently-long setTimeout.

(A clarification based on discussion in comments: Greasemonkey will only act on the site that was actually loaded in the browser; it will not act directly on every XHR request that site makes, even if that url was @included in the script. So if site "foo.com" ajax-injects content from "bar.com/news.html", and the browser loaded "foo.com", greasemonkey will not directly modify the "bar.com/news.html" request foo.com made; it can only work with the DOM that foo.com constructs based on what it got from news.html.)

Daniel Beck
  • 20,653
  • 5
  • 38
  • 53