Я публикую этот вопрос здесь, так как не могу опубликовать его на официальных форумах по расширению Chromium (или есть огромная задержка, пока он не модерируется). Я должен проверить в расширении Chromium, есть ли прослушиватель определенного типа события, прикрепленный к произвольному элементу HTML. В Firefox я мог использовать следующий сервис для получения этой информации:
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);
}
Как я вижу в Chromium, аналогичного API нет. Поэтому я попробовал
следующий метод (который был предложен здесь ):
Я создал скрипт 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);
Я объявляю этот скрипт в manifest.json
следующим образом:
"content_scripts" : [{
"matches" : [ "http://*/*", "https://*/*" ],
"js" : [ "content/events_spy.js" ],
"run_at" : "document_start",
"all_frames" : true
},
...
]
Затем я проверяю свое расширение на следующей 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>
К сожалению, это не работает - я не вижу, что отладчик останавливается
внутри моей пользовательской функции addEventListener()
. Что я делаю не так?
Спасибо!
EDIT : окончательное (грязное) решение благодаря @ 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);
Каждый элемент HTML, к которому прикреплены прослушиватели событий, будет иметь специальный атрибут "_handlerTypes", который содержит список событий, разделенных запятыми. И этот атрибут доступен из скрипта содержимого расширения Chrome!