Búsqueda de sitios web

javascript - ¿Cómo controlar la profundidad del (i)frame en la que se inyectan los scripts de contenido en una extensión de Chrome?


Al crear el archivo de manifiesto para una extensión de Chrome, existe una opción all_frames que permite que los scripts de contenido se inyecten en el marco/iframe superior o en todos.

Quiero que este comportamiento se detenga en un nivel específico (por ejemplo, 2). ¿Hay alguna manera de especificarlo, preferiblemente en el manifiesto? ¿O al menos con un truco en el script actual?

La pregunta puede traducirse a: "¿Es posible saber qué tan profundo está un marco dentro de un documento HTML?"

Respuesta #1

No puedes especificar la profundidad de los marcos en el manifiesto.
Pero, si los iframes tienen URL diferentes, puedes ejecutar diferentes scripts de contenido en ellos (teniendo más de una entrada en el array content_scripts en el manifiesto).

Un script de contenido puede determinar programáticamente la profundidad de un (i)frame con un código como este:

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);
}

Puedes probar esto en esta página en jsBin, si creas una extensión como sigue:

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);
}

Tenga en cuenta que las extensiones de Chrome actualmente solo se ejecutarán en iframes con un atributo src, y solo cuando la URL cumpla con los requisitos de coincidencia y glob del manifiesto.