Dev: Catch event listeners

This commit is contained in:
surunzi
2016-05-20 20:28:39 +08:00
parent 5f96530189
commit 1a9de88660
7 changed files with 176 additions and 3 deletions

View File

@@ -3,6 +3,7 @@ import CssStore from './CssStore.es6'
import Highlight from './Highlight.es6'
import Select from './Select.es6'
import util from '../lib/util'
import config from '../lib/config.es6'
export default class Elements extends Tool
{
@@ -17,6 +18,7 @@ export default class Elements extends Tool
this._rmDefComputedStyle = true;
this._highlightElement = false;
this._selectElement = false;
this._events = {};
}
init($el, parent)
{
@@ -32,6 +34,7 @@ export default class Elements extends Tool
this._highlight = new Highlight(this._parent.$parent);
this._select = new Select();
this._bindEvent();
this._initConfig();
this._setEl(this._htmlEl);
}
show()
@@ -40,6 +43,77 @@ export default class Elements extends Tool
this._render();
}
overrideEventTarget()
{
var winEventProto = window.EventTarget.prototype;
var origAddEvent = this._origAddEvent = winEventProto.addEventListener,
origRmEvent = this._origRmEvent = winEventProto.removeEventListener;
var self = this;
winEventProto.addEventListener = function (type, listener, useCapture)
{
var id = this.erudaEventId = this.erudaEventId || util.uniqId('event');
self._addEvent(id, type, listener, useCapture);
origAddEvent.apply(this, arguments);
};
winEventProto.removeEventListener = function (type, listener, useCapture)
{
var id = this.erudaEventId;
if (id) self._rmEvent(id, type, listener, useCapture);
origRmEvent.apply(this, arguments);
};
}
restoreEventTarget()
{
var winEventProto = window.EventTarget.prototype;
if (this._origAddEvent) winEventProto.addEventListener = this._origAddEvent;
if (this._origRmEvent) winEventProto.removeEventListener = this._origRmEvent;
}
destroy()
{
super.destroy();
this.restoreEventTarget();
}
_addEvent(id, type, listener, useCapture = false)
{
if (!util.isFn(listener) && !util.isBool(useCapture)) return;
var events = this._events;
events[id] = events[id] || {};
events[id][type] = events[id][type] || [];
events[id][type].push({
listener: listener,
listenerStr: listener.toString(),
useCapture: useCapture
});
}
_rmEvent(id, type, listener, useCapture = false)
{
if (!util.isFn(listener) && !util.isBool(useCapture)) return;
var events = this._events;
if (!(events[id] && events[id][type])) return;
var listeners = events[id][type];
for (let i = 0, len = listener.length; i < len; i++)
{
if (listener[i].listener === listener)
{
listeners.splice(i, 1);
break;
}
}
if (listener.length === 0) delete events[id][type];
}
_back()
{
if (this._curEl === this._htmlEl) return;
@@ -167,6 +241,13 @@ export default class Elements extends Tool
ret.attributes = formatAttr(attributes);
ret.name = formatElName({tagName, id, className, attributes});
var eventId = el.erudaEventId;
if (eventId)
{
var listeners = this._events[eventId];
if (util.keys(listeners).length !== 0) ret.listeners = listeners;
}
if (needNoStyle(tagName)) return ret;
var computedStyle = cssStore.getComputedStyle();
@@ -186,6 +267,27 @@ export default class Elements extends Tool
this._highlight[this._highlightElement ? 'show' : 'hide']();
this._$showArea.html(this._tpl(this._getData()));
}
_initConfig()
{
var cfg = this.config = config.create('eruda-elements');
cfg.set(util.defaults(cfg.get(), {overrideEventTarget: true}));
if (cfg.get('overrideEventTarget')) this.overrideEventTarget();
cfg.on('change', (key, val) =>
{
switch (key)
{
case 'overrideEventTarget': return val ? this.overrideEventTarget(): this.restoreEventTarget();
}
});
var settings = this._parent.get('settings');
settings.text('Elements')
.add(cfg, 'overrideEventTarget', 'Show Event Listeners')
.separator();
}
}
var isElExist = val => util.isEl(val) && val.parentNode;

View File

@@ -64,3 +64,20 @@
</div>
</div>
{{/if}}
{{#if listeners}}
<div class="eruda-listeners eruda-section">
<h2>Event Listeners</h2>
<div class="eruda-listener-wrapper">
{{#each listeners}}
<div class="eruda-listener">
<div class="eruda-listener-type">{{@key}}</div>
<ul class="eruda-listener-content">
{{#each .}}
<li class="{{#if useCapture}}eruda-capture{{/if}}">{{listenerStr}}</li>
{{/each}}
</ul>
</div>
{{/each}}
</div>
</div>
{{/if}}

View File

@@ -80,7 +80,7 @@
background: #fff;
font-size: 12px;
.style-wrapper {
padding: 10px;
padding: $common-padding;
.style-rules {
box-shadow: $box-shadow;
border: 1px solid $gray;
@@ -99,6 +99,33 @@
}
}
}
.listeners {
background: #fff;
font-size: 12px;
.listener-wrapper {
padding: $common-padding;
.listener {
box-shadow: $box-shadow;
margin-bottom: 10px;
background: #fff;
.listener-type {
padding: $common-padding;
background: $blue;
color: #fff;
}
.listener-content li {
padding: $common-padding;
border: 1px solid $gray;
border-top: none;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
&.capture {
background: $gray-light;
}
}
}
}
}
.bottom-bar {
height: 40px;
background: #fff;

View File

@@ -148,6 +148,10 @@ export default class Sources extends Tool
}
_renderHttp()
{
var val = this._data.val;
val.hasResTxt = (val.resTxt.trim() !== '');
this._$el.html(this._httpTpl(this._data.val));
}
_renderCode()

View File

@@ -13,5 +13,7 @@
</tbody>
</table>
</div>
<pre class="eruda-response">{{resTxt}}</pre>
{{#if hasResTxt}}
<pre class="eruda-response">{{resTxt}}</pre>
{{/if}}
</div>

0
test/empty.json Normal file
View File

View File

@@ -25,6 +25,23 @@
</div>
<button>Test</button>
<script>
document.body.addEventListener('click', function ()
{
console.log('test');
}, false);
var test = document.getElementById('test-element');
test.addEventListener('click', function ()
{
console.log('test2');
}, false);
test.addEventListener('click', function ()
{
console.log('This is something really really cool!!!!! Laaaaaaaaaa!!!!!!!!!!!!!!!');
}, true);
test.addEventListener('touchstart', function ()
{
console.log('test3');
}, false);
function req(url)
{
var xhr = new XMLHttpRequest();
@@ -35,11 +52,15 @@
setTimeout(function ()
{
req('http://localhost:3000/test/style.css');
}, 2000);
}, 1000);
setTimeout(function ()
{
req('http://localhost:3000/test/data.json');
}, 2000);
setTimeout(function ()
{
req('http://localhost:3000/test/empty.json');
}, 3000);
</script>
</div>
</body>