Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to control the (i)frame depth, that content scripts are injected, in a Chrome extension?

When creating the manifest file for a Chrome extension there is an option all_frames that allows the content scripts to be injected in the top frame/iframe, or in all.

I want this behavior to stop at some specific level (e.g.,2 ). Is there a way to specify it, preferably on the manifest? or at least with a hack in the actual script?

The question may be translated to: "Is it possible to know how deep a frame is inside an HTML document?

like image 968
zabetak Avatar asked Apr 12 '13 21:04

zabetak


1 Answers

You cannot specify frame depth in the manifest.
But, if the iframes have different URL's you can run different content scripts against them (By having more than one entry in the content_scripts array, in the manifest).

A content script can programmatically determine an (i)frame's depth with code like this:

getFrameDepth (window.self);

function getFrameDepth (winToID) {
    if (winToID === window.top) {
        return 0;
    }
    else if (winToID.parent === window.top) {
        return 1;
    }

    return 1 + getFrameDepth (winToID.parent);
}



You can test this against this page at jsBin, if you create an extension as follows:

manifest.json:

{
    "manifest_version": 2,
    "content_scripts":  [ {
        "all_frames":       true,
        "js":               [   "iframe foo.js" ],
        "matches":          [   "http://jsbin.com/enivux/*",
                                "http://jsbin.com/anomic/*",
                                "http://jsbin.com/ogaxoq/*",
                                "http://jsbin.com/ihegaq/*"
                            ]
    } ],
    "description":      "Detecting where an iframe is in the hierarchy",
    "name":             "(i)frame Level identification",
    "version":      "   1"
}


iframe foo.js:

var frameDepth  = getFrameDepth (window.self);
var bodyColors  = ["white", "pink", "lime", "cyan"]

document.body.style.background = bodyColors[frameDepth];

function getFrameDepth (winToID) {
    if (winToID === window.top) {
        return 0;
    }
    else if (winToID.parent === window.top) {
        return 1;
    }

    return 1 + getFrameDepth (winToID.parent);
}



Note that Chrome extensions will currently only run on iframes with a src attribute, and only when the URL meets the match and glob requirements of the manifest.

like image 65
Brock Adams Avatar answered Oct 17 '22 17:10

Brock Adams