vendor/symfony/web-profiler-bundle/Resources/views/Profiler/base_js.html.twig line 1

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