[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
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 /*<![CDATA[*/ 4 if (typeof Sfjs === 'undefined') { 5 Sfjs = (function() { 6 "use strict"; 7 8 if ('classList' in document.documentElement) { 9 var hasClass = function (el, cssClass) { return el.classList.contains(cssClass); }; 10 var removeClass = function(el, cssClass) { el.classList.remove(cssClass); }; 11 var addClass = function(el, cssClass) { el.classList.add(cssClass); }; 12 var toggleClass = function(el, cssClass) { el.classList.toggle(cssClass); }; 13 } else { 14 var hasClass = function (el, cssClass) { return el.className.match(new RegExp('\\b' + cssClass + '\\b')); }; 15 var removeClass = function(el, cssClass) { el.className = el.className.replace(new RegExp('\\b' + cssClass + '\\b'), ' '); }; 16 var addClass = function(el, cssClass) { if (!hasClass(el, cssClass)) { el.className += " " + cssClass; } }; 17 var toggleClass = function(el, cssClass) { hasClass(el, cssClass) ? removeClass(el, cssClass) : addClass(el, cssClass); }; 18 } 19 20 var addEventListener; 21 22 var el = document.createElement('div'); 23 if (!('addEventListener' in el)) { 24 addEventListener = function (element, eventName, callback) { 25 element.attachEvent('on' + eventName, callback); 26 }; 27 } else { 28 addEventListener = function (element, eventName, callback) { 29 element.addEventListener(eventName, callback, false); 30 }; 31 } 32 33 if (navigator.clipboard) { 34 document.querySelectorAll('[data-clipboard-text]').forEach(function(element) { 35 removeClass(element, 'hidden'); 36 element.addEventListener('click', function() { 37 navigator.clipboard.writeText(element.getAttribute('data-clipboard-text')); 38 }) 39 }); 40 } 41 42 return { 43 addEventListener: addEventListener, 44 45 createTabs: function() { 46 var tabGroups = document.querySelectorAll('.sf-tabs:not([data-processed=true])'); 47 48 /* create the tab navigation for each group of tabs */ 49 for (var i = 0; i < tabGroups.length; i++) { 50 var tabs = tabGroups[i].querySelectorAll(':scope > .tab'); 51 var tabNavigation = document.createElement('ul'); 52 tabNavigation.className = 'tab-navigation'; 53 54 var selectedTabId = 'tab-' + i + '-0'; /* select the first tab by default */ 55 for (var j = 0; j < tabs.length; j++) { 56 var tabId = 'tab-' + i + '-' + j; 57 var tabTitle = tabs[j].querySelector('.tab-title').innerHTML; 58 59 var tabNavigationItem = document.createElement('li'); 60 tabNavigationItem.setAttribute('data-tab-id', tabId); 61 if (hasClass(tabs[j], 'active')) { selectedTabId = tabId; } 62 if (hasClass(tabs[j], 'disabled')) { addClass(tabNavigationItem, 'disabled'); } 63 tabNavigationItem.innerHTML = tabTitle; 64 tabNavigation.appendChild(tabNavigationItem); 65 66 var tabContent = tabs[j].querySelector('.tab-content'); 67 tabContent.parentElement.setAttribute('id', tabId); 68 } 69 70 tabGroups[i].insertBefore(tabNavigation, tabGroups[i].firstChild); 71 addClass(document.querySelector('[data-tab-id="' + selectedTabId + '"]'), 'active'); 72 } 73 74 /* display the active tab and add the 'click' event listeners */ 75 for (i = 0; i < tabGroups.length; i++) { 76 tabNavigation = tabGroups[i].querySelectorAll(':scope >.tab-navigation li'); 77 78 for (j = 0; j < tabNavigation.length; j++) { 79 tabId = tabNavigation[j].getAttribute('data-tab-id'); 80 document.getElementById(tabId).querySelector('.tab-title').className = 'hidden'; 81 82 if (hasClass(tabNavigation[j], 'active')) { 83 document.getElementById(tabId).className = 'block'; 84 } else { 85 document.getElementById(tabId).className = 'hidden'; 86 } 87 88 tabNavigation[j].addEventListener('click', function(e) { 89 var activeTab = e.target || e.srcElement; 90 91 /* needed because when the tab contains HTML contents, user can click */ 92 /* on any of those elements instead of their parent '<li>' element */ 93 while (activeTab.tagName.toLowerCase() !== 'li') { 94 activeTab = activeTab.parentNode; 95 } 96 97 /* get the full list of tabs through the parent of the active tab element */ 98 var tabNavigation = activeTab.parentNode.children; 99 for (var k = 0; k < tabNavigation.length; k++) { 100 var tabId = tabNavigation[k].getAttribute('data-tab-id'); 101 document.getElementById(tabId).className = 'hidden'; 102 removeClass(tabNavigation[k], 'active'); 103 } 104 105 addClass(activeTab, 'active'); 106 var activeTabId = activeTab.getAttribute('data-tab-id'); 107 document.getElementById(activeTabId).className = 'block'; 108 }); 109 } 110 111 tabGroups[i].setAttribute('data-processed', 'true'); 112 } 113 }, 114 115 createToggles: function() { 116 var toggles = document.querySelectorAll('.sf-toggle:not([data-processed=true])'); 117 118 for (var i = 0; i < toggles.length; i++) { 119 var elementSelector = toggles[i].getAttribute('data-toggle-selector'); 120 var element = document.querySelector(elementSelector); 121 122 addClass(element, 'sf-toggle-content'); 123 124 if (toggles[i].hasAttribute('data-toggle-initial') && toggles[i].getAttribute('data-toggle-initial') == 'display') { 125 addClass(toggles[i], 'sf-toggle-on'); 126 addClass(element, 'sf-toggle-visible'); 127 } else { 128 addClass(toggles[i], 'sf-toggle-off'); 129 addClass(element, 'sf-toggle-hidden'); 130 } 131 132 addEventListener(toggles[i], 'click', function(e) { 133 e.preventDefault(); 134 135 if ('' !== window.getSelection().toString()) { 136 /* Don't do anything on text selection */ 137 return; 138 } 139 140 var toggle = e.target || e.srcElement; 141 142 /* needed because when the toggle contains HTML contents, user can click */ 143 /* on any of those elements instead of their parent '.sf-toggle' element */ 144 while (!hasClass(toggle, 'sf-toggle')) { 145 toggle = toggle.parentNode; 146 } 147 148 var element = document.querySelector(toggle.getAttribute('data-toggle-selector')); 149 150 toggleClass(toggle, 'sf-toggle-on'); 151 toggleClass(toggle, 'sf-toggle-off'); 152 toggleClass(element, 'sf-toggle-hidden'); 153 toggleClass(element, 'sf-toggle-visible'); 154 155 /* the toggle doesn't change its contents when clicking on it */ 156 if (!toggle.hasAttribute('data-toggle-alt-content')) { 157 return; 158 } 159 160 if (!toggle.hasAttribute('data-toggle-original-content')) { 161 toggle.setAttribute('data-toggle-original-content', toggle.innerHTML); 162 } 163 164 var currentContent = toggle.innerHTML; 165 var originalContent = toggle.getAttribute('data-toggle-original-content'); 166 var altContent = toggle.getAttribute('data-toggle-alt-content'); 167 toggle.innerHTML = currentContent !== altContent ? altContent : originalContent; 168 }); 169 170 /* Prevents from disallowing clicks on links inside toggles */ 171 var toggleLinks = toggles[i].querySelectorAll('a'); 172 for (var j = 0; j < toggleLinks.length; j++) { 173 addEventListener(toggleLinks[j], 'click', function(e) { 174 e.stopPropagation(); 175 }); 176 } 177 178 /* Prevents from disallowing clicks on "copy to clipboard" elements inside toggles */ 179 var copyToClipboardElements = toggles[i].querySelectorAll('span[data-clipboard-text]'); 180 for (var k = 0; k < copyToClipboardElements.length; k++) { 181 addEventListener(copyToClipboardElements[k], 'click', function(e) { 182 e.stopPropagation(); 183 }); 184 } 185 186 toggles[i].setAttribute('data-processed', 'true'); 187 } 188 }, 189 190 createFilters: function() { 191 document.querySelectorAll('[data-filters] [data-filter]').forEach(function (filter) { 192 var filters = filter.closest('[data-filters]'), 193 type = 'choice', 194 name = filter.dataset.filter, 195 ucName = name.charAt(0).toUpperCase()+name.slice(1), 196 list = document.createElement('ul'), 197 values = filters.dataset['filter'+ucName] || filters.querySelectorAll('[data-filter-'+name+']'), 198 labels = {}, 199 defaults = null, 200 indexed = {}, 201 processed = {}; 202 if (typeof values === 'string') { 203 type = 'level'; 204 labels = values.split(','); 205 values = values.toLowerCase().split(','); 206 defaults = values.length - 1; 207 } 208 addClass(list, 'filter-list'); 209 addClass(list, 'filter-list-'+type); 210 values.forEach(function (value, i) { 211 if (value instanceof HTMLElement) { 212 value = value.dataset['filter'+ucName]; 213 } 214 if (value in processed) { 215 return; 216 } 217 var option = document.createElement('li'), 218 label = i in labels ? labels[i] : value, 219 active = false, 220 matches; 221 if ('' === label) { 222 option.innerHTML = '<em>(none)</em>'; 223 } else { 224 option.innerText = label; 225 } 226 option.dataset.filter = value; 227 option.setAttribute('title', 1 === (matches = filters.querySelectorAll('[data-filter-'+name+'="'+value+'"]').length) ? 'Matches 1 row' : 'Matches '+matches+' rows'); 228 indexed[value] = i; 229 list.appendChild(option); 230 addEventListener(option, 'click', function () { 231 if ('choice' === type) { 232 filters.querySelectorAll('[data-filter-'+name+']').forEach(function (row) { 233 if (option.dataset.filter === row.dataset['filter'+ucName]) { 234 toggleClass(row, 'filter-hidden-'+name); 235 } 236 }); 237 toggleClass(option, 'active'); 238 } else if ('level' === type) { 239 if (i === this.parentNode.querySelectorAll('.active').length - 1) { 240 return; 241 } 242 this.parentNode.querySelectorAll('li').forEach(function (currentOption, j) { 243 if (j <= i) { 244 addClass(currentOption, 'active'); 245 if (i === j) { 246 addClass(currentOption, 'last-active'); 247 } else { 248 removeClass(currentOption, 'last-active'); 249 } 250 } else { 251 removeClass(currentOption, 'active'); 252 removeClass(currentOption, 'last-active'); 253 } 254 }); 255 filters.querySelectorAll('[data-filter-'+name+']').forEach(function (row) { 256 if (i < indexed[row.dataset['filter'+ucName]]) { 257 addClass(row, 'filter-hidden-'+name); 258 } else { 259 removeClass(row, 'filter-hidden-'+name); 260 } 261 }); 262 } 263 }); 264 if ('choice' === type) { 265 active = null === defaults || 0 <= defaults.indexOf(value); 266 } else if ('level' === type) { 267 active = i <= defaults; 268 if (active && i === defaults) { 269 addClass(option, 'last-active'); 270 } 271 } 272 if (active) { 273 addClass(option, 'active'); 274 } else { 275 filters.querySelectorAll('[data-filter-'+name+'="'+value+'"]').forEach(function (row) { 276 toggleClass(row, 'filter-hidden-'+name); 277 }); 278 } 279 processed[value] = true; 280 }); 281 282 if (1 < list.childNodes.length) { 283 filter.appendChild(list); 284 filter.dataset.filtered = ''; 285 } 286 }); 287 } 288 }; 289 })(); 290 291 Sfjs.addEventListener(document, 'DOMContentLoaded', function() { 292 Sfjs.createTabs(); 293 Sfjs.createToggles(); 294 Sfjs.createFilters(); 295 }); 296 } 297 /*]]>*/
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |