1

I have a contentscript that essentially does a console.log to indicate that it has been injected into a page, and my manifest.json has all_frames set to true.

As a result, if I go to http://www.reddit.com/r/videos I see a message per frame and if I click on a video, I will also see a message coming from a script injected into the video's iframe. This indicates to me that if the page is dynamically modified to include an iframe, the contentscript will be injected into it.

When I go to http://www.html5video.org, I only get a message from one frame, but if I look at the DOM I see that there is an iframe for the video so I would expect my contentscript to be injected into it, but it is not.

My ultimate goal is to get a selector for the video on the page and I would expect to be able to do so by injecting code that looks for it into the iframe.

Help is appreciated.

Jared Sohn
  • 443
  • 5
  • 17

1 Answers1

4

I suspect that Chrome will inject your content scripts into an IFRAME that is part of the original page source which is the case with the reddit.com example - the IFRAMEs are part of the original page so Chrome can and will inject into those. For the html5video link the IFRAME is not part of the original source. However, if you inspect the elements you can see the IFRAME which suggests to me that the IFRAME has been dynamically loaded to the DOM. I see the same behaviour with an extension I have written so it seems consistent.

If you need to inject into the IFRAME then perhaps you can hook the DOM creation event and take the action you require:

document.addEventListener('DOMNodeInserted', onNodeInserted, false);

UPDATE:

What about this for http://html5video.org/ - using the following content_script code I can get the IFRAME and then VIDEO tag. Note: This approach/concept should also work pretty well too for Reddit.

content_script.js

console.log("content script for: " + document.title);

var timer;

document.addEventListener('DOMNodeInserted', onNodeInserted, false);

function onNodeInserted(e)
{
    if(timer) clearTimeout(timer);
    timer = setTimeout("doSomething()", 250);
}

function doSomething()
{
    $media = $(".mwEmbedKalturaIframe");
    console.log($media);
    $video = $media.contents().find("video");
    console.log($video);
}

manifest.json

{
  // Required
  "name": "Foo Extension",
  "version": "0.0.1",

  // Recommended
  "description": "A plain text description",
  "icons": { "48": "foo.png" },
  //"default_locale": "en",

  // Pick one (or none)
  "browser_action": {
    "default_icon": "Foo.png", // optional
    "default_title": "Foo Extension"      // optional; shown in tooltip
    },

  "permissions": [ "http://*/", "https://*/", "tabs" ],

  "content_scripts": [
    {
      "matches": ["http://*/*", "https://*/*"],
      "js": ["jquery-1.7.1.min.js", "content_script.js" ],
      "run_at": "document_idle",
      "all_frames": true
    }
    ]
}

See also: jQuery/JavaScript: accessing contents of an iframe

Community
  • 1
  • 1
RidingTheRails
  • 1,105
  • 1
  • 12
  • 22
  • The only IFRAME present in the reddit example prior to clicking is for the ads. The IFRAME for each media element is created dynamically when you click on the 'play video' button; I don't see a difference. I don't think adding the eventlistener would work because I need to access the content inside the IFRAME, which I think I can only do by having the contentscript injected inside of it. (I believe I've seen a bug report on crbug that states that you can't see the contents of IFRAMES within a page from the parent in the contentscript.) – Jared Sohn Feb 27 '12 at 09:00
  • Also, my contentscript opens a port connection to the background page so I have the ability to rerun my contentscript via a command on the popup menu. Just doing a JQuery search for – Jared Sohn Feb 27 '12 at 09:07
  • Sorry for the delay; was on vacation. Your code worked for me which convinces me that I should be able to convert your code into a general solution for my application. Also will investigate why the code I wrote earlier didn't work but your code does. – Jared Sohn Apr 06 '12 at 22:55
  • Update: If you look at the contents of the DOM mutation event, it is actually caused due to a twitter widget rather than the iframe loading. Basically, the reason why my code works okay for reddit.com/r/videos is that the iframes are for different sites so my content script gets injected into it but on html5video.org, it is on the same site so the contentscript is not injected. The real problem was that I was searching the page for video via code like this: $(document).find("video").each( function(i) { actOnVideo(this); }); when (continued...) – Jared Sohn Apr 24 '12 at 23:00
  • when I need to include like this: $(document).find("iframe").each(function(i){ $(this).contents().find("video").each( function(j) { actOnVideo(this) });});}); so that the selector is able to find instances where the video tag shows up within an iframe. Also, I need to do this recursively in case there are stacked iframes. – Jared Sohn Apr 24 '12 at 23:02
  • Interesting to know that the mutation event was from the twitter widget. Sounds like you've got a good solution going and what you said in the last comment looks good. Thanks for sharing the update. – RidingTheRails Apr 25 '12 at 09:24
  • Update: I think my earlier reasoning about which iframes the contentscript gets injected into was incorrect. If you go to gmail.com, you'll see that there are three embeds (uploader, chat sound, and something media-related) and each exists in a different same-domain iframe. At the moment I am noticing that my contentscript is injected into the uploader and the media ones but not the chat sound one. (Although if I restart the extension after the page is loaded, it injects into the chat sound one as well.) – Jared Sohn Jun 01 '12 at 05:15
  • I've read elsewhere that contentscripts are injected into all iframes except for those which have no source or have the source set to about:blank. This would explain why it wouldn't inject into html5video.org, but it doesn't explain why I am experiencing issues with the chat sound on gmail. I'm currently thinking that the issue might be that the chat sound iframe is dynamically created (while the others aren't), although my understanding is that it will still inject contentscripts into those tabs (like it does on reddit/r/videos.) – Jared Sohn Jun 01 '12 at 05:15