Estoy publicando esta pregunta aquí, ya que no puedo publicarla en los foros oficiales de extensión de Chromium (o hay una tremenda demora hasta que se modera). Tengo que verificar en la extensión de Chromium si hay un oyente de un tipo de evento específico adjunto a un elemento HTML arbitrario. En Firefox que podría utilizar el siguiente servicio para obtener esta información:¿Cómo averiguar qué tipos de escucha de eventos se unen a un elemento HTML específico en la extensión de Chrome?
var listenerService = Components.classes["@mozilla.org/eventlistenerservice;1"]
.getService(Components.interfaces.nsIEventListenerService);
var infos = listenerService.getListenerInfoFor(element, {});
var types = [];
for (var i = 0; i < infos.length; ++i) {
var info = infos[i].QueryInterface(Components.interfaces.nsIEventListenerInfo);
types.push(info.type);
}
Como veo en Chromium no hay API similar. Por lo tanto, he probado el siguiente técnica (que fue sugerido here):
He creado guión events_spy.js
:
(function(original) {
Element.prototype.addEventListener = function(type, listener, useCapture) {
if (typeof (this._handlerTypes) == 'undefined') {
this._handlerTypes = {};
}
this._handlerTypes[type] = true;
return original.apply(this, arguments);
}
})(Element.prototype.addEventListener);
(function(original) {
Element.prototype.removeEventListener = function(type, listener,useCapture) {
if (typeof (this._handlerTypes) != 'undefined') {
delete this._handlerTypes[type];
}
return original.apply(this, arguments);
}
})(Element.prototype.removeEventListener);
Declaro este script en manifest.json
de la siguiente manera:
"content_scripts" : [{
"matches" : [ "http://*/*", "https://*/*" ],
"js" : [ "content/events_spy.js" ],
"run_at" : "document_start",
"all_frames" : true
},
...
]
entonces, pongo a prueba mi extensión en la página HTML siguiente:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<a id="test" href="#">Click here</a>
<script type="application/javascript">
document.getElementById("test").addEventListener("click", function()
{ alert("clicked"); }, false);
</script>
</body>
</html>
Por desgracia, esto no funciona - no puedo ver que depurador se detiene en el interior de mi función personalizada addEventListener()
. ¿Qué estoy haciendo mal?
Gracias!
EDITAR: Solución final (sucio), gracias a @kdzwinel
var injectedJS = "\
(function(original) { \
Element.prototype.addEventListener = function(type, listener, useCapture) { \
var attr = this.getAttribute('_handlerTypes'); \
var types = attr ? attr.split(',') : []; \
var found = false; \
for (var i = 0; i < types.length; ++i) { \
if (types[i] == type) { \
found = true; \
break; \
} \
} \
if (!found) { \
types.push(type); \
} \
this.setAttribute('_handlerTypes', types.join(',')); \
return original.apply(this, arguments); \
} \
})(Element.prototype.addEventListener); \
\
(function(original) { \
Element.prototype.removeEventListener = function(type, listener, useCapture) { \
var attr = this.getAttribute('_handlerTypes'); \
var types = attr ? attr.split(',') : []; \
var removed = false; \
for (var i = 0; i < types.length; ++i) { \
if (types[i] == type) { \
types.splice(i, 1); \
removed = true; \
break; \
} \
} \
if (removed) { \
this.setAttribute('_handlerTypes', types.join(',')); \
} \
return original.apply(this, arguments); \
} \
})(Element.prototype.removeEventListener); \
";
var script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(injectedJS));
document.documentElement.appendChild(script);
elemento
Cada HTML que tiene un detectores de eventos asociados tendrán un atributo especial "_handlerTypes", que contiene una lista separada por comas de los acontecimientos . ¡Y este atributo es accesible desde el script de contenido de la extensión de Chrome!
Muchas gracias por la actualización de su solución! –