Zamieszczam tutaj to pytanie, ponieważ nie mogę go opublikować na oficjalnych forach rozszerzeń Chromium (lub jest to straszne opóźnienie, dopóki nie zostanie on moderowany). Muszę sprawdzić rozszerzenie Chromium, czy odbiornik określonego typu zdarzenia jest dołączony do dowolnego elementu HTML. W Firefoksie można używać następujące usługi, aby uzyskać te informacje:Jak dowiedzieć się, jakie typy detektorów zdarzeń są dołączone do określonego elementu HTML w rozszerzeniu 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);
}
Jak widzę w Chromium nie ma podobny interfejs API. Dlatego starałem się następujące techniki (który został zaproponowany here):
Mam utworzonego skryptu 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);
Oświadczam ten skrypt w manifest.json
następująco:
"content_scripts" : [{
"matches" : [ "http://*/*", "https://*/*" ],
"js" : [ "content/events_spy.js" ],
"run_at" : "document_start",
"all_frames" : true
},
...
]
Następnie testuję rozszerzenie na następującą stronę HTML:
<!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>
Niestety, to nie działa - nie widzę, że debugger zatrzymuje się wewnątrz mojej niestandardowej funkcji addEventListener()
. Co ja robię źle?
Dzięki!
EDIT: Finał (brudny) rozwiązanie, dzięki @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);
elementem
Każdy HTML, który ma załączony detektory zdarzeń będzie miało szczególny atrybut „_handlerTypes”, który zawiera listę oddzielonych przecinkami wydarzeń . A ten atrybut jest dostępny ze skryptu treści rozszerzenia Chrome!
Dzięki bardzo za aktualizację z rozwiązania! –