There is a third-party site with an embedded iframe from a different domain.
domain1.com:
<html>
  ...
    <iframe src="domain2.com/?...">...</iframe>
  ...
</html>
All I need to do is run a user script inside the iframe. I do not need any communication between the iframe and it's embedding page. I use Greasemonkey 4.11 in Firefox 103.0.
There are a few closely related questions and also some answers:
- Apply a Greasemonkey/Tampermonkey userscript to an iframe
- Userscript to bypass same-origin policy for accessing nested iframes
- Greasemonkey script for page with cross-domain iframe
However, I have a hard time understanding how these questions and answers apply to the orthogonal issues of:
- Same or different origin of the iframe
- Interaction between the iframe and it's embedding page
- Loading time of the iframe
- Greasemonkey version, specifically >= 4 vs. <4.
Nevertheless I tried out what I thought might work, but it didn't.
Apparantly, this is supposed to work in Greasemonkey < 4:
Edit: Confirmed to work with Tampermonkey in Chrome and with Violentmonkey in Firefox.
// ==UserScript==
// @name     foo1
// @version  1
// @grant    none
// @match    https://domain1.com
// @match    https://domain2.com/*
// ==/UserScript==
setInterval(() => {
  if (window.top === window.self) {
    // Works:
    console.log("top")
  }
  else {
    // Unreachable:
    console.log("iframe")
  }
  
}, 3000)
And this is supposed to work in Greasemonkey >=4, but it doesn't seem to work with a different domain:
// ==UserScript==
// @name     foo2
// @version  1
// @grant    none
// @match    https://domain1.com
// @match    https://domain2.com/*
// @require https://git.io/waitForKeyElements.js
// ==/UserScript==
waitForKeyElements("iframe", function(elem) {
  setInterval(() => {
    // Works:
    console.log(elem.contentWindow)
    try {
      // Throws SecurityError:
      // Permission denied to access property "document" on 
      // cross-origin object
      console.log(elem.contentWindow.document)
    } catch (e) {
      console.log("ERROR " + e);
    }
  }, 3000)
});
