Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[web-profiler-bundle] Debug toolbar javascript stacks event listeners #37073

Copy link
Copy link
Closed
@Seikyo

Description

@Seikyo
Issue body actions

Description

When the debug toolbar is enabled each ajax request add two event listeners to the document.

It seems that in base_js.html.twig the method addEventListener is called within the renderAjaxRequests method which is called on each ajax call. This bind new event listeners on each ajax request to the document.

Not sure if it should be feature request or bug report as this is not critical but I was searching why event listeners where stacking and it took me some time to find it.

name     : symfony/web-profiler-bundle
descrip. : Symfony WebProfilerBundle
keywords : 
versions : * v5.0.8

web-profiler-bundle/Resources/views/Profiler/base_js.html.twig

var renderAjaxRequests = function() {
    ()

    addEventListener(document.querySelector('.sf-toolbar-ajax-clear'), 'click', function() {
        requestStack = [];
        renderAjaxRequests();
        successStreak = 4;
        document.querySelector('.sf-toolbar-ajax-request-list').innerHTML = '';
    });
}

Suggestion

I have not fully understood how the toolbar javascript works but moving the addEventListener call on the loadToolbar method after the intial renderAjaxRequests should do the trick. The renderAjaxRequests does not create / remove any html but only work with classes and internal attributes so it seems it should be ok.

Moving it under the loadToolbar removes the event listeners stacking and the ajax call toolbar seems to be ok but I did not test this thoroughly and only with Chrome.

loadToolbar: function(token, newToken) {
    newToken = (newToken || token);
    this.load(
        ()
        renderAjaxRequests();
        addEventListener(document.querySelector('.sf-toolbar-ajax-clear'), 'click', function() {
            requestStack = [];
            renderAjaxRequests();
            successStreak = 4;
            document.querySelector('.sf-toolbar-ajax-request-list').innerHTML = '';
        });
    )
}

Example

Here is the code used to monitor event listeners :

event-tracker.js

window.eventListenerList = [];

Element.prototype.originalAddEventListener = Element.prototype.addEventListener;
Element.prototype.addEventListener = function (type, listener, capture) {
    this.eventListenerList = this.eventListenerList || [];
    this.eventListenerList[type] = this.eventListenerList[type] || [];

    capture = capture || false;
    this.originalAddEventListener(type, listener, capture);


    const event = {
        listener: listener,
        useCapture: capture,
    };
    this.eventListenerList[type].push(event);
    window.eventListenerList.push(event);
};

Element.prototype.getEventListeners = function () {
    this.eventListenerList = this.eventListenerList || {};
    return this.eventListenerList;
};

Element.prototype.originalRemoveEventListener = Element.prototype.removeEventListener;
Element.prototype.removeEventListener = function (type, listener, capture) {
    capture = capture || false;
    this.originalRemoveEventListener(type, listener, capture);

    const event = {
        listener: listener,
        useCapture: capture,
    };

    this.eventListenerList[type] = this.eventListenerList.filter(e => e !== event);
    window.eventListenerList = window.eventListenerList.filter(e => e !== event);
};

On any template using twig with profiler enabled with only the above javascript added :
(input) = type in console and validate

Chrome console

// List page initial event listeners
(input) window.eventListenerList
(5) [{}, {}, {}, {}, {}]

// Do an ajax request and display event listeners again
(input) fetch('https://google.com');
(input) window.eventListenerList
(7) [{}, {}, {}, {}, {}, {}, {}]

// New event listeners informations
(input) window.eventListenerList[6].listener
ƒ () {                requestStack = [];                renderAjaxRequests();                successStreak = 4;                document.querySelector('.sf-toolbar-ajax-request-list').innerHTML = '';   
(input) window.eventListenerList[5].listener
ƒ () {                requestStack = [];                renderAjaxRequests();                successStreak = 4;                document.querySelector('.sf-toolbar-ajax-request-list').innerHTML = '';   

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.