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

Commit 50a59c0

Browse filesBrowse files
feature #26655 [WebProfilerBundle] Make WDT follow ajax requests if header set (jeffreymb)
This PR was squashed before being merged into the 4.1-dev branch (closes #26655). Discussion ---------- [WebProfilerBundle] Make WDT follow ajax requests if header set Replaces #22509. I accidentally closed that PR and couldn't get GitHub to recognize when I added more commits to the branch in my fork. | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes <!-- don't forget updating src/**/CHANGELOG.md files --> | BC breaks? | no | Deprecations? | no <!-- don't forget updating UPGRADE-*.md files --> | Tests pass? | yes (There are no tests that I could find) | Fixed tickets | #15456 | License | MIT | Doc PR | symfony/symfony-docs#... <!--highly recommended for new features--> When the header of an ajax response contains the `Symfony-Debug-Toolbar-Replace` header with a value of '1' it will automatically update the toolbar with the toolbar with the debug info from the ajax request. The bulk of the code in the `loadToolbar` function in the `base_js.html.twig` file is moved from the `toolbar_js.html.twig` file and slightly refactored to use the internal functions instead of making external calls. I take no credit/blame for this code. 😉 If this could make it into 4.1 there are multiple people that would be very happy! Commits ------- e4e591b [WebProfilerBundle] Make WDT follow ajax requests if header set
2 parents 5b6df6f + e4e591b commit 50a59c0
Copy full SHA for 50a59c0

File tree

3 files changed

+141
-110
lines changed
Filter options

3 files changed

+141
-110
lines changed

‎src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ CHANGELOG
55
-----
66

77
* added information about orphaned events
8+
* made the toolbar auto-update with info from ajax reponses when they set the
9+
`Symfony-Debug-Toolbar-Replace header` to `1`
810

911
4.0.0
1012
-----

‎src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/base_js.html.twig
+138Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@
8383
if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) {
8484
stackElement.profilerUrl = ret[1];
8585
}
86+
if (ret = allHeaders.match(/^Symfony-Debug-Toolbar-Replace:\s+(.*)$/im)) {
87+
stackElement.toolbarReplaceFinished = false;
88+
stackElement.toolbarReplace = '1' === ret[1];
89+
}
8690
};
8791
8892
var successStreak = 4;
@@ -185,6 +189,19 @@
185189
if (!request.DOMNode) {
186190
return;
187191
}
192+
193+
if (request.toolbarReplace && !request.toolbarReplaceFinished && request.profile) {
194+
/* Flag as complete because finishAjaxRequest can be called multiple times. */
195+
request.toolbarReplaceFinished = true;
196+
/* Search up through the DOM to find the toolbar's container ID. */
197+
for (var elem = request.DOMNode; elem && elem !== document; elem = elem.parentNode) {
198+
if (elem.id.match(/^sfwdt/)) {
199+
Sfjs.loadToolbar(elem.id.replace(/^sfwdt/, ''), request.profile);
200+
break;
201+
}
202+
}
203+
}
204+
188205
pendingRequests--;
189206
var row = request.DOMNode;
190207
/* Unpack the children from the row */
@@ -285,6 +302,8 @@
285302
stackElement.statusCode = r.status;
286303
stackElement.profile = r.headers.get('x-debug-token');
287304
stackElement.profilerUrl = r.headers.get('x-debug-token-link');
305+
stackElement.toolbarReplaceFinished = false;
306+
stackElement.toolbarReplace = '1' === r.headers.get('Symfony-Debug-Toolbar-Replace');
288307
finishAjaxRequest(idx);
289308
}, function (e){
290309
stackElement.error = true;
@@ -372,12 +391,15 @@
372391
el.innerHTML = xhr.responseText;
373392
el.setAttribute('data-sfurl', url);
374393
removeClass(el, 'loading');
394+
var pending = pendingRequests;
375395
for (var i = 0; i < requestStack.length; i++) {
376396
startAjaxRequest(i);
377397
if (requestStack[i].duration) {
378398
finishAjaxRequest(i);
379399
}
380400
}
401+
/* Revert the pending state in case there was a start called without a finish above. */
402+
pendingRequests = pending;
381403
(onSuccess || noop)(xhr, el);
382404
},
383405
function(xhr) { (onError || noop)(xhr, el); },
@@ -389,6 +411,122 @@
389411
return this;
390412
},
391413
414+
loadToolbar: function(token, newToken) {
415+
newToken = (newToken || token);
416+
this.load(
417+
'sfwdt' + token,
418+
'{{ path("_wdt", { "token": "xxxxxx" }) }}'.replace(/xxxxxx/, newToken),
419+
function(xhr, el) {
420+
421+
/* Evaluate embedded scripts inside the toolbar */
422+
var i, scripts = [].slice.call(el.querySelectorAll('script'));
423+
424+
for (i = 0; i < scripts.length; ++i) {
425+
eval(scripts[i].firstChild.nodeValue);
426+
}
427+
428+
el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none';
429+
430+
if (el.style.display == 'none') {
431+
return;
432+
}
433+
434+
if (getPreference('toolbar/displayState') == 'none') {
435+
document.getElementById('sfToolbarMainContent-' + newToken).style.display = 'none';
436+
document.getElementById('sfToolbarClearer-' + newToken).style.display = 'none';
437+
document.getElementById('sfMiniToolbar-' + newToken).style.display = 'block';
438+
} else {
439+
document.getElementById('sfToolbarMainContent-' + newToken).style.display = 'block';
440+
document.getElementById('sfToolbarClearer-' + newToken).style.display = 'block';
441+
document.getElementById('sfMiniToolbar-' + newToken).style.display = 'none';
442+
}
443+
444+
/* Handle toolbar-info position */
445+
var toolbarBlocks = [].slice.call(el.querySelectorAll('.sf-toolbar-block'));
446+
for (i = 0; i < toolbarBlocks.length; ++i) {
447+
toolbarBlocks[i].onmouseover = function () {
448+
var toolbarInfo = this.querySelectorAll('.sf-toolbar-info')[0];
449+
var pageWidth = document.body.clientWidth;
450+
var elementWidth = toolbarInfo.offsetWidth;
451+
var leftValue = (elementWidth + this.offsetLeft) - pageWidth;
452+
var rightValue = (elementWidth + (pageWidth - this.offsetLeft)) - pageWidth;
453+
454+
/* Reset right and left value, useful on window resize */
455+
toolbarInfo.style.right = '';
456+
toolbarInfo.style.left = '';
457+
458+
if (elementWidth > pageWidth) {
459+
toolbarInfo.style.left = 0;
460+
}
461+
else if (leftValue > 0 && rightValue > 0) {
462+
toolbarInfo.style.right = (rightValue * -1) + 'px';
463+
} else if (leftValue < 0) {
464+
toolbarInfo.style.left = 0;
465+
} else {
466+
toolbarInfo.style.right = '0px';
467+
}
468+
};
469+
}
470+
addEventListener(document.getElementById('sfToolbarHideButton-' + newToken), 'click', function (event) {
471+
event.preventDefault();
472+
473+
var p = this.parentNode;
474+
p.style.display = 'none';
475+
(p.previousElementSibling || p.previousSibling).style.display = 'none';
476+
document.getElementById('sfMiniToolbar-' + newToken).style.display = 'block';
477+
setPreference('toolbar/displayState', 'none');
478+
});
479+
addEventListener(document.getElementById('sfToolbarMiniToggler-' + newToken), 'click', function (event) {
480+
event.preventDefault();
481+
482+
var elem = this.parentNode;
483+
if (elem.style.display == 'none') {
484+
document.getElementById('sfToolbarMainContent-' + newToken).style.display = 'none';
485+
document.getElementById('sfToolbarClearer-' + newToken).style.display = 'none';
486+
elem.style.display = 'block';
487+
} else {
488+
document.getElementById('sfToolbarMainContent-' + newToken).style.display = 'block';
489+
document.getElementById('sfToolbarClearer-' + newToken).style.display = 'block';
490+
elem.style.display = 'none'
491+
}
492+
493+
setPreference('toolbar/displayState', 'block');
494+
});
495+
renderAjaxRequests();
496+
addEventListener(document.querySelector('.sf-toolbar-block-ajax > .sf-toolbar-icon'), 'click', function (event) {
497+
event.preventDefault();
498+
499+
toggleClass(this.parentNode, 'hover');
500+
});
501+
502+
var dumpInfo = document.querySelector('.sf-toolbar-block-dump .sf-toolbar-info');
503+
if (null !== dumpInfo) {
504+
addEventListener(dumpInfo, 'sfbeforedumpcollapse', function () {
505+
dumpInfo.style.minHeight = dumpInfo.getBoundingClientRect().height+'px';
506+
});
507+
addEventListener(dumpInfo, 'mouseleave', function () {
508+
dumpInfo.style.minHeight = '';
509+
});
510+
}
511+
},
512+
function(xhr) {
513+
if (xhr.status !== 0) {
514+
var sfwdt = document.getElementById('sfwdt' + token);
515+
sfwdt.innerHTML = '\
516+
<div class="sf-toolbarreset">\
517+
<div class="sf-toolbar-icon"><svg width="26" height="28" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 26 28" enable-background="new 0 0 26 28" xml:space="preserve"><path fill="#FFFFFF" d="M13 0C5.8 0 0 5.8 0 13c0 7.2 5.8 13 13 13c7.2 0 13-5.8 13-13C26 5.8 20.2 0 13 0z M20 7.5 c-0.6 0-1-0.3-1-0.9c0-0.2 0-0.4 0.2-0.6c0.1-0.3 0.2-0.3 0.2-0.4c0-0.3-0.5-0.4-0.7-0.4c-2 0.1-2.5 2.7-2.9 4.8l-0.2 1.1 c1.1 0.2 1.9 0 2.4-0.3c0.6-0.4-0.2-0.8-0.1-1.3C18 9.2 18.4 9 18.7 8.9c0.5 0 0.8 0.5 0.8 1c0 0.8-1.1 2-3.3 1.9 c-0.3 0-0.5 0-0.7-0.1L15 14.1c-0.4 1.7-0.9 4.1-2.6 6.2c-1.5 1.8-3.1 2.1-3.8 2.1c-1.3 0-2.1-0.6-2.2-1.6c0-0.9 0.8-1.4 1.3-1.4 c0.7 0 1.2 0.5 1.2 1.1c0 0.5-0.2 0.6-0.4 0.7c-0.1 0.1-0.3 0.2-0.3 0.4c0 0.1 0.1 0.3 0.4 0.3c0.5 0 0.9-0.3 1.2-0.5 c1.3-1 1.7-2.9 2.4-6.2l0.1-0.8c0.2-1.1 0.5-2.3 0.8-3.5c-0.9-0.7-1.4-1.5-2.6-1.8c-0.8-0.2-1.3 0-1.7 0.4C8.4 10 8.6 10.7 9 11.1 l0.7 0.7c0.8 0.9 1.3 1.7 1.1 2.7c-0.3 1.6-2.1 2.8-4.3 2.1c-1.9-0.6-2.2-1.9-2-2.7c0.2-0.6 0.7-0.8 1.2-0.6 c0.5 0.2 0.7 0.8 0.6 1.3c0 0.1 0 0.1-0.1 0.3C6 15 5.9 15.2 5.9 15.3c-0.1 0.4 0.4 0.7 0.8 0.8c0.8 0.3 1.7-0.2 1.9-0.9 c0.2-0.6-0.2-1.1-0.4-1.2l-0.8-0.9c-0.4-0.4-1.2-1.5-0.8-2.8c0.2-0.5 0.5-1 0.9-1.4c1-0.7 2-0.8 3-0.6c1.3 0.4 1.9 1.2 2.8 1.9 c0.5-1.3 1.1-2.6 2-3.8c0.9-1 2-1.7 3.3-1.8C20 4.8 21 5.4 21 6.3C21 6.7 20.8 7.5 20 7.5z"/></svg></div>\
518+
An error occurred while loading the web debug toolbar. <a href="{{ path("_profiler_home") }}' + newToken + '>Open the web profiler.</a>\
519+
</div>\
520+
';
521+
sfwdt.setAttribute('class', 'sf-toolbar sf-error-toolbar');
522+
}
523+
},
524+
{ maxTries: 5 }
525+
);
526+
527+
return this;
528+
},
529+
392530
toggle: function(selector, elOn, elOff) {
393531
var tmp = elOn.style.display,
394532
el = document.getElementById(selector);

‎src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar_js.html.twig
+1-110Lines changed: 1 addition & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -5,115 +5,6 @@
55
</style>
66
<script{% if csp_script_nonce %} nonce="{{ csp_script_nonce }}"{% endif %}>/*<![CDATA[*/
77
(function () {
8-
Sfjs.load(
9-
'sfwdt{{ token }}',
10-
'{{ path("_wdt", { "token": token }) }}',
11-
function(xhr, el) {
12-
13-
/* Evaluate embedded scripts inside the toolbar */
14-
var i, scripts = [].slice.call(el.querySelectorAll('script'));
15-
16-
for (i = 0; i < scripts.length; ++i) {
17-
eval(scripts[i].firstChild.nodeValue);
18-
}
19-
20-
el.style.display = -1 !== xhr.responseText.indexOf('sf-toolbarreset') ? 'block' : 'none';
21-
22-
if (el.style.display == 'none') {
23-
return;
24-
}
25-
26-
if (Sfjs.getPreference('toolbar/displayState') == 'none') {
27-
document.getElementById('sfToolbarMainContent-{{ token }}').style.display = 'none';
28-
document.getElementById('sfToolbarClearer-{{ token }}').style.display = 'none';
29-
document.getElementById('sfMiniToolbar-{{ token }}').style.display = 'block';
30-
} else {
31-
document.getElementById('sfToolbarMainContent-{{ token }}').style.display = 'block';
32-
document.getElementById('sfToolbarClearer-{{ token }}').style.display = 'block';
33-
document.getElementById('sfMiniToolbar-{{ token }}').style.display = 'none';
34-
}
35-
36-
/* Handle toolbar-info position */
37-
var toolbarBlocks = [].slice.call(el.querySelectorAll('.sf-toolbar-block'));
38-
for (i = 0; i < toolbarBlocks.length; ++i) {
39-
toolbarBlocks[i].onmouseover = function () {
40-
var toolbarInfo = this.querySelectorAll('.sf-toolbar-info')[0];
41-
var pageWidth = document.body.clientWidth;
42-
var elementWidth = toolbarInfo.offsetWidth;
43-
var leftValue = (elementWidth + this.offsetLeft) - pageWidth;
44-
var rightValue = (elementWidth + (pageWidth - this.offsetLeft)) - pageWidth;
45-
46-
/* Reset right and left value, useful on window resize */
47-
toolbarInfo.style.right = '';
48-
toolbarInfo.style.left = '';
49-
50-
if (elementWidth > pageWidth) {
51-
toolbarInfo.style.left = 0;
52-
}
53-
else if (leftValue > 0 && rightValue > 0) {
54-
toolbarInfo.style.right = (rightValue * -1) + 'px';
55-
} else if (leftValue < 0) {
56-
toolbarInfo.style.left = 0;
57-
} else {
58-
toolbarInfo.style.right = '0px';
59-
}
60-
};
61-
}
62-
Sfjs.addEventListener(document.getElementById('sfToolbarHideButton-{{ token }}'), 'click', function (event) {
63-
event.preventDefault();
64-
65-
var p = this.parentNode;
66-
p.style.display = 'none';
67-
(p.previousElementSibling || p.previousSibling).style.display = 'none';
68-
document.getElementById('sfMiniToolbar-{{ token }}').style.display = 'block';
69-
Sfjs.setPreference('toolbar/displayState', 'none');
70-
});
71-
Sfjs.addEventListener(document.getElementById('sfToolbarMiniToggler-{{ token }}'), 'click', function (event) {
72-
event.preventDefault();
73-
74-
var elem = this.parentNode;
75-
if (elem.style.display == 'none') {
76-
document.getElementById('sfToolbarMainContent-{{ token }}').style.display = 'none';
77-
document.getElementById('sfToolbarClearer-{{ token }}').style.display = 'none';
78-
elem.style.display = 'block';
79-
} else {
80-
document.getElementById('sfToolbarMainContent-{{ token }}').style.display = 'block';
81-
document.getElementById('sfToolbarClearer-{{ token }}').style.display = 'block';
82-
elem.style.display = 'none'
83-
}
84-
85-
Sfjs.setPreference('toolbar/displayState', 'block');
86-
});
87-
Sfjs.renderAjaxRequests();
88-
Sfjs.addEventListener(document.querySelector('.sf-toolbar-block-ajax > .sf-toolbar-icon'), 'click', function (event) {
89-
event.preventDefault();
90-
91-
Sfjs.toggleClass(this.parentNode, 'hover');
92-
});
93-
94-
var dumpInfo = document.querySelector('.sf-toolbar-block-dump .sf-toolbar-info');
95-
if (null !== dumpInfo) {
96-
Sfjs.addEventListener(dumpInfo, 'sfbeforedumpcollapse', function () {
97-
dumpInfo.style.minHeight = dumpInfo.getBoundingClientRect().height+'px';
98-
});
99-
Sfjs.addEventListener(dumpInfo, 'mouseleave', function () {
100-
dumpInfo.style.minHeight = '';
101-
});
102-
}
103-
},
104-
function(xhr) {
105-
if (xhr.status !== 0) {
106-
var sfwdt = document.getElementById('sfwdt{{ token }}');
107-
sfwdt.innerHTML = '\
108-
<div class="sf-toolbarreset">\
109-
<div class="sf-toolbar-icon"><svg width="26" height="28" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 26 28" enable-background="new 0 0 26 28" xml:space="preserve"><path fill="#FFFFFF" d="M13 0C5.8 0 0 5.8 0 13c0 7.2 5.8 13 13 13c7.2 0 13-5.8 13-13C26 5.8 20.2 0 13 0z M20 7.5 c-0.6 0-1-0.3-1-0.9c0-0.2 0-0.4 0.2-0.6c0.1-0.3 0.2-0.3 0.2-0.4c0-0.3-0.5-0.4-0.7-0.4c-2 0.1-2.5 2.7-2.9 4.8l-0.2 1.1 c1.1 0.2 1.9 0 2.4-0.3c0.6-0.4-0.2-0.8-0.1-1.3C18 9.2 18.4 9 18.7 8.9c0.5 0 0.8 0.5 0.8 1c0 0.8-1.1 2-3.3 1.9 c-0.3 0-0.5 0-0.7-0.1L15 14.1c-0.4 1.7-0.9 4.1-2.6 6.2c-1.5 1.8-3.1 2.1-3.8 2.1c-1.3 0-2.1-0.6-2.2-1.6c0-0.9 0.8-1.4 1.3-1.4 c0.7 0 1.2 0.5 1.2 1.1c0 0.5-0.2 0.6-0.4 0.7c-0.1 0.1-0.3 0.2-0.3 0.4c0 0.1 0.1 0.3 0.4 0.3c0.5 0 0.9-0.3 1.2-0.5 c1.3-1 1.7-2.9 2.4-6.2l0.1-0.8c0.2-1.1 0.5-2.3 0.8-3.5c-0.9-0.7-1.4-1.5-2.6-1.8c-0.8-0.2-1.3 0-1.7 0.4C8.4 10 8.6 10.7 9 11.1 l0.7 0.7c0.8 0.9 1.3 1.7 1.1 2.7c-0.3 1.6-2.1 2.8-4.3 2.1c-1.9-0.6-2.2-1.9-2-2.7c0.2-0.6 0.7-0.8 1.2-0.6 c0.5 0.2 0.7 0.8 0.6 1.3c0 0.1 0 0.1-0.1 0.3C6 15 5.9 15.2 5.9 15.3c-0.1 0.4 0.4 0.7 0.8 0.8c0.8 0.3 1.7-0.2 1.9-0.9 c0.2-0.6-0.2-1.1-0.4-1.2l-0.8-0.9c-0.4-0.4-1.2-1.5-0.8-2.8c0.2-0.5 0.5-1 0.9-1.4c1-0.7 2-0.8 3-0.6c1.3 0.4 1.9 1.2 2.8 1.9 c0.5-1.3 1.1-2.6 2-3.8c0.9-1 2-1.7 3.3-1.8C20 4.8 21 5.4 21 6.3C21 6.7 20.8 7.5 20 7.5z"/></svg></div>\
110-
An error occurred while loading the web debug toolbar. <a href="{{ path("_profiler", { "token": token }) }}">Open the web profiler.</a>\
111-
</div>\
112-
';
113-
sfwdt.setAttribute('class', 'sf-toolbar sf-error-toolbar');
114-
}
115-
},
116-
{ maxTries: 5 }
117-
);
8+
Sfjs.loadToolbar('{{ token }}');
1189
})();
11910
/*]]>*/</script>

0 commit comments

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