|
1 |
| -{# This file is duplicated in WebProfilerBundle/Resources/views/Profiler/base_js.html.twig. |
2 |
| - If you make any change in this file, do the same change in the other file. #} |
| 1 | +{# This file is based on WebProfilerBundle/Resources/views/Profiler/base_js.html.twig. |
| 2 | + If you make any change in this file, verify the same change is needed in the other file. #} |
3 | 3 | <script{% if csp_script_nonce is defined and csp_script_nonce %} nonce={{ csp_script_nonce }}{% endif %}>/*<![CDATA[*/
|
4 | 4 | {# Caution: the contents of this file are processed by Twig before loading
|
5 | 5 | them as JavaScript source code. Always use '/*' comments instead
|
|
8 | 8 | Sfjs = (function() {
|
9 | 9 | "use strict";
|
10 | 10 |
|
11 |
| - var classListIsSupported = 'classList' in document.documentElement; |
12 |
| -
|
13 |
| - if (classListIsSupported) { |
| 11 | + if ('classList' in document.documentElement) { |
14 | 12 | var hasClass = function (el, cssClass) { return el.classList.contains(cssClass); };
|
15 | 13 | var removeClass = function(el, cssClass) { el.classList.remove(cssClass); };
|
16 | 14 | var addClass = function(el, cssClass) { el.classList.add(cssClass); };
|
|
22 | 20 | var toggleClass = function(el, cssClass) { hasClass(el, cssClass) ? removeClass(el, cssClass) : addClass(el, cssClass); };
|
23 | 21 | }
|
24 | 22 |
|
25 |
| - var noop = function() {}; |
26 |
| -
|
27 |
| - var profilerStorageKey = 'sf2/profiler/'; |
28 |
| -
|
29 |
| - var request = function(url, onSuccess, onError, payload, options) { |
30 |
| - var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); |
31 |
| - options = options || {}; |
32 |
| - options.maxTries = options.maxTries || 0; |
33 |
| - xhr.open(options.method || 'GET', url, true); |
34 |
| - xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); |
35 |
| - xhr.onreadystatechange = function(state) { |
36 |
| - if (4 !== xhr.readyState) { |
37 |
| - return null; |
38 |
| - } |
39 |
| -
|
40 |
| - if (xhr.status == 404 && options.maxTries > 1) { |
41 |
| - setTimeout(function(){ |
42 |
| - options.maxTries--; |
43 |
| - request(url, onSuccess, onError, payload, options); |
44 |
| - }, 500); |
45 |
| -
|
46 |
| - return null; |
47 |
| - } |
48 |
| -
|
49 |
| - if (200 === xhr.status) { |
50 |
| - (onSuccess || noop)(xhr); |
51 |
| - } else { |
52 |
| - (onError || noop)(xhr); |
53 |
| - } |
54 |
| - }; |
55 |
| - xhr.send(payload || ''); |
56 |
| - }; |
57 |
| -
|
58 |
| - var getPreference = function(name) { |
59 |
| - if (!window.localStorage) { |
60 |
| - return null; |
61 |
| - } |
62 |
| -
|
63 |
| - return localStorage.getItem(profilerStorageKey + name); |
64 |
| - }; |
65 |
| -
|
66 |
| - var setPreference = function(name, value) { |
67 |
| - if (!window.localStorage) { |
68 |
| - return null; |
69 |
| - } |
70 |
| -
|
71 |
| - localStorage.setItem(profilerStorageKey + name, value); |
72 |
| - }; |
73 |
| -
|
74 |
| - var requestStack = []; |
75 |
| -
|
76 |
| - var extractHeaders = function(xhr, stackElement) { |
77 |
| - /* Here we avoid to call xhr.getResponseHeader in order to */ |
78 |
| - /* prevent polluting the console with CORS security errors */ |
79 |
| - var allHeaders = xhr.getAllResponseHeaders(); |
80 |
| - var ret; |
81 |
| -
|
82 |
| - if (ret = allHeaders.match(/^x-debug-token:\s+(.*)$/im)) { |
83 |
| - stackElement.profile = ret[1]; |
84 |
| - } |
85 |
| - if (ret = allHeaders.match(/^x-debug-token-link:\s+(.*)$/im)) { |
86 |
| - stackElement.profilerUrl = ret[1]; |
87 |
| - } |
88 |
| - }; |
89 |
| -
|
90 |
| - var successStreak = 4; |
91 |
| - var pendingRequests = 0; |
92 |
| - var renderAjaxRequests = function() { |
93 |
| - var requestCounter = document.querySelector('.sf-toolbar-ajax-request-counter'); |
94 |
| - if (!requestCounter) { |
95 |
| - return; |
96 |
| - } |
97 |
| - requestCounter.textContent = requestStack.length; |
98 |
| -
|
99 |
| - var infoSpan = document.querySelector(".sf-toolbar-ajax-info"); |
100 |
| - if (infoSpan) { |
101 |
| - infoSpan.textContent = requestStack.length + ' AJAX request' + (requestStack.length !== 1 ? 's' : ''); |
102 |
| - } |
103 |
| -
|
104 |
| - var ajaxToolbarPanel = document.querySelector('.sf-toolbar-block-ajax'); |
105 |
| - if (requestStack.length) { |
106 |
| - ajaxToolbarPanel.style.display = 'block'; |
107 |
| - } else { |
108 |
| - ajaxToolbarPanel.style.display = 'none'; |
109 |
| - } |
110 |
| - if (pendingRequests > 0) { |
111 |
| - addClass(ajaxToolbarPanel, 'sf-ajax-request-loading'); |
112 |
| - } else if (successStreak < 4) { |
113 |
| - addClass(ajaxToolbarPanel, 'sf-toolbar-status-red'); |
114 |
| - removeClass(ajaxToolbarPanel, 'sf-ajax-request-loading'); |
115 |
| - } else { |
116 |
| - removeClass(ajaxToolbarPanel, 'sf-ajax-request-loading'); |
117 |
| - removeClass(ajaxToolbarPanel, 'sf-toolbar-status-red'); |
118 |
| - } |
119 |
| - }; |
120 |
| -
|
121 |
| - var startAjaxRequest = function(index) { |
122 |
| - var tbody = document.querySelector('.sf-toolbar-ajax-request-list'); |
123 |
| - if (!tbody) { |
124 |
| - return; |
125 |
| - } |
126 |
| -
|
127 |
| - var request = requestStack[index]; |
128 |
| - pendingRequests++; |
129 |
| - var row = document.createElement('tr'); |
130 |
| - request.DOMNode = row; |
131 |
| -
|
132 |
| - var methodCell = document.createElement('td'); |
133 |
| - methodCell.textContent = request.method; |
134 |
| - row.appendChild(methodCell); |
135 |
| -
|
136 |
| - var typeCell = document.createElement('td'); |
137 |
| - typeCell.textContent = request.type; |
138 |
| - row.appendChild(typeCell); |
139 |
| -
|
140 |
| - var statusCodeCell = document.createElement('td'); |
141 |
| - var statusCode = document.createElement('span'); |
142 |
| - statusCode.textContent = 'n/a'; |
143 |
| - statusCodeCell.appendChild(statusCode); |
144 |
| - row.appendChild(statusCodeCell); |
145 |
| -
|
146 |
| - var pathCell = document.createElement('td'); |
147 |
| - pathCell.className = 'sf-ajax-request-url'; |
148 |
| - if ('GET' === request.method) { |
149 |
| - var pathLink = document.createElement('a'); |
150 |
| - pathLink.setAttribute('href', request.url); |
151 |
| - pathLink.textContent = request.url; |
152 |
| - pathCell.appendChild(pathLink); |
153 |
| - } else { |
154 |
| - pathCell.textContent = request.url; |
155 |
| - } |
156 |
| - pathCell.setAttribute('title', request.url); |
157 |
| - row.appendChild(pathCell); |
158 |
| -
|
159 |
| - var durationCell = document.createElement('td'); |
160 |
| - durationCell.className = 'sf-ajax-request-duration'; |
161 |
| - durationCell.textContent = 'n/a'; |
162 |
| - row.appendChild(durationCell); |
163 |
| -
|
164 |
| - var profilerCell = document.createElement('td'); |
165 |
| - profilerCell.textContent = 'n/a'; |
166 |
| - row.appendChild(profilerCell); |
167 |
| -
|
168 |
| - row.className = 'sf-ajax-request sf-ajax-request-loading'; |
169 |
| - tbody.insertBefore(row, tbody.firstChild); |
170 |
| -
|
171 |
| - renderAjaxRequests(); |
172 |
| - }; |
173 |
| -
|
174 |
| - var finishAjaxRequest = function(index) { |
175 |
| - var request = requestStack[index]; |
176 |
| - if (!request.DOMNode) { |
177 |
| - return; |
178 |
| - } |
179 |
| - pendingRequests--; |
180 |
| - var row = request.DOMNode; |
181 |
| - /* Unpack the children from the row */ |
182 |
| - var methodCell = row.children[0]; |
183 |
| - var statusCodeCell = row.children[2]; |
184 |
| - var statusCodeElem = statusCodeCell.children[0]; |
185 |
| - var durationCell = row.children[4]; |
186 |
| - var profilerCell = row.children[5]; |
187 |
| -
|
188 |
| - if (request.error) { |
189 |
| - row.className = 'sf-ajax-request sf-ajax-request-error'; |
190 |
| - methodCell.className = 'sf-ajax-request-error'; |
191 |
| - successStreak = 0; |
192 |
| - } else { |
193 |
| - row.className = 'sf-ajax-request sf-ajax-request-ok'; |
194 |
| - successStreak++; |
195 |
| - } |
196 |
| -
|
197 |
| - if (request.statusCode) { |
198 |
| - if (request.statusCode < 300) { |
199 |
| - statusCodeElem.setAttribute('class', 'sf-toolbar-status'); |
200 |
| - } else if (request.statusCode < 400) { |
201 |
| - statusCodeElem.setAttribute('class', 'sf-toolbar-status sf-toolbar-status-yellow'); |
202 |
| - } else { |
203 |
| - statusCodeElem.setAttribute('class', 'sf-toolbar-status sf-toolbar-status-red'); |
204 |
| - } |
205 |
| - statusCodeElem.textContent = request.statusCode; |
206 |
| - } else { |
207 |
| - statusCodeElem.setAttribute('class', 'sf-toolbar-status sf-toolbar-status-red'); |
208 |
| - } |
209 |
| -
|
210 |
| - if (request.duration) { |
211 |
| - durationCell.textContent = request.duration + 'ms'; |
212 |
| - } |
213 |
| -
|
214 |
| - if (request.profilerUrl) { |
215 |
| - profilerCell.textContent = ''; |
216 |
| - var profilerLink = document.createElement('a'); |
217 |
| - profilerLink.setAttribute('href', request.profilerUrl); |
218 |
| - profilerLink.textContent = request.profile; |
219 |
| - profilerCell.appendChild(profilerLink); |
220 |
| - } |
221 |
| -
|
222 |
| - renderAjaxRequests(); |
223 |
| - }; |
224 |
| -
|
225 | 23 | var addEventListener;
|
226 | 24 |
|
227 | 25 | var el = document.createElement('div');
|
|
235 | 33 | };
|
236 | 34 | }
|
237 | 35 |
|
238 |
| - {% if excluded_ajax_paths is defined %} |
239 |
| - if (window.fetch && window.fetch.polyfill === undefined) { |
240 |
| - var oldFetch = window.fetch; |
241 |
| - window.fetch = function () { |
242 |
| - var promise = oldFetch.apply(this, arguments); |
243 |
| - var url = arguments[0]; |
244 |
| - var params = arguments[1]; |
245 |
| - var paramType = Object.prototype.toString.call(arguments[0]); |
246 |
| - if (paramType === '[object Request]') { |
247 |
| - url = arguments[0].url; |
248 |
| - params = { |
249 |
| - method: arguments[0].method, |
250 |
| - credentials: arguments[0].credentials, |
251 |
| - headers: arguments[0].headers, |
252 |
| - mode: arguments[0].mode, |
253 |
| - redirect: arguments[0].redirect |
254 |
| - }; |
255 |
| - } |
256 |
| - if (!url.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) { |
257 |
| - var method = 'GET'; |
258 |
| - if (params && params.method !== undefined) { |
259 |
| - method = params.method; |
260 |
| - } |
261 |
| -
|
262 |
| - var stackElement = { |
263 |
| - error: false, |
264 |
| - url: url, |
265 |
| - method: method, |
266 |
| - type: 'fetch', |
267 |
| - start: new Date() |
268 |
| - }; |
269 |
| -
|
270 |
| - var idx = requestStack.push(stackElement) - 1; |
271 |
| - promise.then(function (r) { |
272 |
| - stackElement.duration = new Date() - stackElement.start; |
273 |
| - stackElement.error = r.status < 200 || r.status >= 400; |
274 |
| - stackElement.statusCode = r.status; |
275 |
| - stackElement.profile = r.headers.get('x-debug-token'); |
276 |
| - stackElement.profilerUrl = r.headers.get('x-debug-token-link'); |
277 |
| - finishAjaxRequest(idx); |
278 |
| - }, function (e){ |
279 |
| - stackElement.error = true; |
280 |
| - finishAjaxRequest(idx); |
281 |
| - }); |
282 |
| - startAjaxRequest(idx); |
283 |
| - } |
284 |
| -
|
285 |
| - return promise; |
286 |
| - }; |
287 |
| - } |
288 |
| - if (window.XMLHttpRequest && XMLHttpRequest.prototype.addEventListener) { |
289 |
| - var proxied = XMLHttpRequest.prototype.open; |
290 |
| -
|
291 |
| - XMLHttpRequest.prototype.open = function(method, url, async, user, pass) { |
292 |
| - var self = this; |
293 |
| -
|
294 |
| - /* prevent logging AJAX calls to static and inline files, like templates */ |
295 |
| - var path = url; |
296 |
| - if (url.substr(0, 1) === '/') { |
297 |
| - if (0 === url.indexOf('{{ request.basePath|e('js') }}')) { |
298 |
| - path = url.substr({{ request.basePath|length }}); |
299 |
| - } |
300 |
| - } |
301 |
| - else if (0 === url.indexOf('{{ (request.schemeAndHttpHost ~ request.basePath)|e('js') }}')) { |
302 |
| - path = url.substr({{ (request.schemeAndHttpHost ~ request.basePath)|length }}); |
303 |
| - } |
304 |
| -
|
305 |
| - if (!path.match(new RegExp({{ excluded_ajax_paths|json_encode|raw }}))) { |
306 |
| - var stackElement = { |
307 |
| - error: false, |
308 |
| - url: url, |
309 |
| - method: method, |
310 |
| - type: 'xhr', |
311 |
| - start: new Date() |
312 |
| - }; |
313 |
| -
|
314 |
| - var idx = requestStack.push(stackElement) - 1; |
315 |
| -
|
316 |
| - this.addEventListener('readystatechange', function() { |
317 |
| - if (self.readyState == 4) { |
318 |
| - stackElement.duration = new Date() - stackElement.start; |
319 |
| - stackElement.error = self.status < 200 || self.status >= 400; |
320 |
| - stackElement.statusCode = self.status; |
321 |
| - extractHeaders(self, stackElement); |
322 |
| -
|
323 |
| - finishAjaxRequest(idx); |
324 |
| - } |
325 |
| - }, false); |
326 |
| -
|
327 |
| - startAjaxRequest(idx); |
328 |
| - } |
329 |
| -
|
330 |
| - proxied.apply(this, Array.prototype.slice.call(arguments)); |
331 |
| - }; |
332 |
| - } |
333 |
| - {% endif %} |
334 |
| -
|
335 | 36 | return {
|
336 |
| - hasClass: hasClass, |
337 |
| -
|
338 |
| - removeClass: removeClass, |
339 |
| -
|
340 |
| - addClass: addClass, |
341 |
| -
|
342 |
| - toggleClass: toggleClass, |
343 |
| -
|
344 |
| - getPreference: getPreference, |
345 |
| -
|
346 |
| - setPreference: setPreference, |
347 |
| -
|
348 | 37 | addEventListener: addEventListener,
|
349 | 38 |
|
350 |
| - request: request, |
351 |
| -
|
352 |
| - renderAjaxRequests: renderAjaxRequests, |
353 |
| -
|
354 |
| - load: function(selector, url, onSuccess, onError, options) { |
355 |
| - var el = document.getElementById(selector); |
356 |
| -
|
357 |
| - if (el && el.getAttribute('data-sfurl') !== url) { |
358 |
| - request( |
359 |
| - url, |
360 |
| - function(xhr) { |
361 |
| - el.innerHTML = xhr.responseText; |
362 |
| - el.setAttribute('data-sfurl', url); |
363 |
| - removeClass(el, 'loading'); |
364 |
| - for (var i = 0; i < requestStack.length; i++) { |
365 |
| - startAjaxRequest(i); |
366 |
| - if (requestStack[i].duration) { |
367 |
| - finishAjaxRequest(i); |
368 |
| - } |
369 |
| - } |
370 |
| - (onSuccess || noop)(xhr, el); |
371 |
| - }, |
372 |
| - function(xhr) { (onError || noop)(xhr, el); }, |
373 |
| - '', |
374 |
| - options |
375 |
| - ); |
376 |
| - } |
377 |
| -
|
378 |
| - return this; |
379 |
| - }, |
380 |
| -
|
381 |
| - toggle: function(selector, elOn, elOff) { |
382 |
| - var tmp = elOn.style.display, |
383 |
| - el = document.getElementById(selector); |
384 |
| -
|
385 |
| - elOn.style.display = elOff.style.display; |
386 |
| - elOff.style.display = tmp; |
387 |
| -
|
388 |
| - if (el) { |
389 |
| - el.style.display = 'none' === tmp ? 'none' : 'block'; |
390 |
| - } |
391 |
| -
|
392 |
| - return this; |
393 |
| - }, |
394 |
| -
|
395 | 39 | createTabs: function() {
|
396 | 40 | var tabGroups = document.querySelectorAll('.sf-tabs');
|
397 | 41 |
|
|
0 commit comments